-
-
Notifications
You must be signed in to change notification settings - Fork 4
Feature: Block Break Guard
Tsu edited this page Jun 6, 2026
·
4 revisions
This feature validates block-break progress server-side before accepting the break.
stratum.default.json has a dedicated BlockBreakGuards section:
"BlockBreakGuards": {
"Enabled": true,
"RequireServerSelection": false,
"DropViolations": true,
"LogViolations": false,
"KickViolations": false,
"KickAfterViolations": 12,
"ViolationWindowSeconds": 20,
"RequiredProgressRatio": 0.5,
"GraceSeconds": 0.5,
"MinimumTrackedBreakSeconds": 0.5,
"PartialProgressRetentionSeconds": 8.0,
"MaxRememberedProgressRatio": 0.95,
"MaxRememberedPartialBreaksPerClient": 24,
"KickMessage": "Disconnected by Stratum block break protection"
}Implementation class: StratumBlockBreakGuard.
ObserveMining tracks progress while the player is actively mining:
state.RequiredResistance = resistance;
state.DamagePerSecond = damagePerSecond;
state.ObservedDamage += damage;
state.LastObservedMs = server.ElapsedMilliseconds;When the player releases the mouse or moves to another block, Stratum now keeps a short-lived remembered progress entry for that client/block. This avoids false positives when vanilla leaves a block partly broken and the player finishes it shortly after.
TryAcceptBreak checks whether observed progress meets the configured threshold.
Fast breaks can bypass tracking by design:
if (resistance <= 0f || expectedBreakSeconds <= Math.Max(0f, config.MinimumTrackedBreakSeconds))
{
return true;
}Progress requirement:
float ratio = Math.Max(0.1f, Math.Min(1f, config.RequiredProgressRatio));
float requiredDamage = resistance * ratio;
float observedDamage = hasTrackedProgress ? state.ObservedDamage : rememberedDamage;
float observedWithGrace = observedDamage + Math.Max(0f, config.GraceSeconds) * Math.Max(state.DamagePerSecond, damagePerSecond);
if (observedWithGrace < requiredDamage)
{
reason = $"insufficient mining progress {observedWithGrace:0.###}/{requiredDamage:0.###} on {requestedSelection.Position}";
}state.RegisterViolation(now, Math.Max(1, config.ViolationWindowSeconds));
shouldKick = config.KickViolations && config.KickAfterViolations > 0 && state.ViolationsInWindow >= config.KickAfterViolations;Result behavior:
- Accept break
- Drop break
- Kick client (if enabled and threshold reached)
-
DropViolations=true: reject suspicious breaks without always disconnecting -
KickViolations=false: default behavior is protection without aggressive disconnects -
MinimumTrackedBreakSeconds=0.5: very fast blocks can bypass progress tracking -
RequiredProgressRatio=0.5: accept breaks once at least half required progress is observed, plus grace window -
PartialProgressRetentionSeconds=8.0: keep short-lived server-observed partial progress after the player stops mining or changes target -
MaxRememberedProgressRatio=0.95: remembered progress cannot count as a full block break by itself -
MaxRememberedPartialBreaksPerClient=24: cap remembered entries per client
sources/VintagestoryLib/Vintagestory.Server/StratumBlockBreakGuard.cs-
sources/VintagestoryLib/Vintagestory.Server/StratumConfig.cs(StratumBlockBreakGuardsConfig) StratumServer/stratum.default.json-
sources/VintagestoryLib/Vintagestory.Server/CmdStratum.cs(/stratum packetsreport)