Add automatic punishment ladder for repeat anticheat violations - #268
Merged
Conversation
Off by default (Anticheat.Punishments.Enabled). Once a player's persistent flag count crosses a configurable threshold, escalates through inventory drop/wipe, freeze, jail, then a timed ban, reusing the existing primitives for each (InventoryBase.DropAll/Clear, StratumStaffCommandState.Freeze, CmdStratumStaffCommands jailing, PlayerDataManager.BanPlayer) rather than inventing new enforcement. Standing survives relogs and restarts via CustomPlayerData, separately from the reporter's in-memory rolling counts. Runs synchronously right after RecordViolation's lock releases, the same place every Record*Violation call site already calls DisconnectPlayer for KickConfirmedCheats today, so no new queue or scheduling was needed. /stratum ac now shows a player's accumulated flags and the next tier due. StratumRuntime's config safety check warns on the risky combinations (punishments enabled with anticheat itself off, wipe instead of drop, a very low first threshold, or a permanent ban with no recovery).
tehtelev
reviewed
Aug 19, 2026
tehtelev
left a comment
Contributor
There was a problem hiding this comment.
Looks good. No complaints.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds an opt-in escalation ladder for players who keep accumulating confirmed anticheat flags: inventory drop/wipe, then freeze, then jail, then a timed ban, in that order, based on a persistent per-player flag count that survives relogs and restarts.
Every action the ladder takes reuses an existing, already-tested primitive:
InventoryBase.DropAll/Clear, same as normal death handling, skipping the creative inventory the same wayEntityPlayer.WalkInventoryalready does.StratumStaffCommandState.Freeze, the same as/freeze.CmdStratumStaffCommands.JailAutomaticallyentry point that reuses the existingTryGetJailLocation+JailSingleTargetmethods unchanged, reached through a minimalinternal static Instancereference since the active-jail tracking and enforcement tick loop are instance state with no prior external access point.PlayerDataManager.BanPlayer+DisconnectPlayer, same as/ban.Nothing new is invented for enforcement; only the threshold ladder and the persistent standing behind it are new.
Standing is tracked separately from
StratumAnticheatReporter's existing in-memoryPlayerViolationsdictionary, which is intentionally rolling and prunes a player out afterKeepPlayerViolationsMinutesof inactivity. A newStratumAnticheatHistorystore persistsTotalFlagsand the highest tier already applied inCustomPlayerData, the same patternStratumModerationStore/StratumCustodyStorealready use, so a repeat offender who logs off can't reset their standing by relogging.The escalation check runs synchronously right after
RecordViolation's lock releases, in the same place everyRecord*Violationcall site already callsDisconnectPlayerdirectly forKickConfirmedCheatstoday. That existing pattern already proves the calling context is safe for real game-state actions, not only logging, so this needed no new queue or deferred-execution scheduling./stratum ac <player>now also shows accumulated flags and the next tier due.StratumRuntime's config safety check gained four warnings for risky combinations: punishments enabled while anticheat itself is disabled, wipe-instead-of-drop, a very low first threshold, and a permanent (non-recovering) ban duration.Off by default (
Anticheat.Punishments.Enabled = false), same posture asKickConfirmedCheatsper rule: an operator has to opt in with eyes open, since chaining these into automatic consequences on a false positive is a materially different risk than an alert or a single kick.Type
Checklist
scripts/extract-patches.shran clean (no vanilla-file changes; every edit here is undersources/, nopatches/diffs touched).dotnet build VintageStory.slnx -c Releaseis green (0 errors, 0 new warnings; verified no warnings in any touched file).// Stratummarker. (N/A: no vanilla files touched, only Stratum-original files undersources/.)make smoke: PASS, reachedWorldReady, no fatal errors).Related issues
Fixes #221