Skip to content

fix(anticheat): stop duplicate module reports flooding the database and Sentry - #79

Open
tintinhamans wants to merge 3 commits into
GeneralsOnlineDevelopmentTeam:mainfrom
tintinhamans:arctic/fix/services-47
Open

tintinhamans wants to merge 3 commits into
GeneralsOnlineDevelopmentTeam:mainfrom
tintinhamans:arctic/fix/services-47

Conversation

@tintinhamans

Copy link
Copy Markdown
Contributor

Remembers which modules were already flagged for the current match on the session, so repeated anti-cheat probes no longer re-insert the same modules. Each probe response now writes the remaining ones in a single batched INSERT ... ON DUPLICATE KEY UPDATE instead of one DbContext and insert per module. Before this, every repeat hit the user_id_match_id_module_name unique key and was logged and sent to Sentry, roughly a million times every six hours in prod. That used up the Sentry error quota, so nothing from the service has reached Sentry since 2026-10-11.

The allowlists are parsed once and refreshed on config reload instead of per module, and expected duplicate keys are no longer reported. Connection outcomes, service stats, player stats, device registration, leaderboard rows and the CRC review insert had the same lost ON DUPLICATE behaviour from the EF Core move, so they're atomic upserts now too, keeping their old semantics (in-database increments, GREATEST peaks, per-stat JSON_SET, no-op on existing rows). All statements were checked against the prod schema on MariaDB 10.11.

This adds raw MySQL SQL back, which conflicts with #77. Once that lands I'll move the upserts to the provider-neutral setup; the session dedupe doesn't depend on the database and covers almost all of the volume on its own.

…nd Sentry

Every anti-cheat probe response re-inserted each non-allowlisted module, one DbContext per module, and every repeat in the same match hit the user_id_match_id_module_name unique key. Each failure was logged and sent to Sentry: millions of events that exhausted the error quota, so all project errors have been dropped since 2026-10-11.

Modules already flagged for the current match are now remembered on the session, the remaining ones are written in one batched INSERT ... ON DUPLICATE KEY UPDATE per probe response, the allowlists are parsed once and refreshed on config reload, and expected duplicate keys are never reported. The CRC review insert gets the same idempotent upsert.

Fixes SERVICES-47
Fixes SERVICES-4B
The EF Core migration lost the original ON DUPLICATE semantics. Connection outcomes and service stats raced on their day/hour keys at rollover, player stats lost concurrent updates in a read-modify-write of the JSON document, device registration could collide on concurrent logins, and leaderboard row creation rolled back all three tables when one row existed. Each now uses a single INSERT ... ON DUPLICATE KEY UPDATE that preserves the original behaviour (increments, GREATEST peaks, JSON_SET per stat, no-op on existing rows).

Fixes SERVICES-41
…cates

ac_reviews_crc's primary key spans all four columns, including most_recent_match, so a duplicate is an identical report and there is nothing to refresh. Update the comment and statement to say so.

@Skyaero42 Skyaero42 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I struggle with the AntiCheat.cs file because I'm not familiar with the implemention yet.
The rest looks good.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants