From bf9450acebfa7c0488134acc19c4282329fb846d Mon Sep 17 00:00:00 2001 From: Evenprime Date: Sun, 5 Feb 2012 18:13:45 +0100 Subject: [PATCH] Make moving.morepackets check server lag independent --- .../checks/moving/MorePacketsCheck.java | 85 +++++++++---------- .../nocheat/checks/moving/MovingData.java | 13 +-- 2 files changed, 46 insertions(+), 52 deletions(-) diff --git a/src/cc/co/evenprime/bukkit/nocheat/checks/moving/MorePacketsCheck.java b/src/cc/co/evenprime/bukkit/nocheat/checks/moving/MorePacketsCheck.java index 1086d660..34a43fb1 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/checks/moving/MorePacketsCheck.java +++ b/src/cc/co/evenprime/bukkit/nocheat/checks/moving/MorePacketsCheck.java @@ -1,7 +1,6 @@ package cc.co.evenprime.bukkit.nocheat.checks.moving; import java.util.Locale; - import cc.co.evenprime.bukkit.nocheat.NoCheat; import cc.co.evenprime.bukkit.nocheat.NoCheatPlayer; import cc.co.evenprime.bukkit.nocheat.actions.ParameterName; @@ -21,78 +20,78 @@ import cc.co.evenprime.bukkit.nocheat.data.PreciseLocation; public class MorePacketsCheck extends MovingCheck { private final static int packetsPerTimeframe = 22; - private final static int bufferLimit = 30; public MorePacketsCheck(NoCheat plugin) { super(plugin, "moving.morepackets", Permissions.MOVING_MOREPACKETS); } /** - * 1. Collect packets processed within 20 server ticks = packetCounter - * 2. Measure time taken for those 20 server ticks = elapsedTime - * 3. elapsedTime >> 1 second -> ignore next check - * 4. limit = 22 x elapsedTime - * 5. difference = limit - packetCounter - * 6. buffer = buffer + difference; if(buffer > 20) buffer = 20; - * 7. if(buffer < 0) -> violation of size "buffer". - * 8. reset packetCounter, wait for next 20 ticks to pass by. + * 1. Players get assigned a certain amount of "free" packets as a limit initially + * 2. Every move packet reduces that limit by 1 + * 3. If more than 1 second of time passed, the limit gets increased + * by 22 * time in seconds, up to 50 and he gets a new "setback" location + * 4. If the player reaches limit = 0 -> teleport him back to "setback" + * 5. If there was a long pause (maybe lag), limit may be up to 100 * */ public PreciseLocation check(NoCheatPlayer player, MovingData data, MovingConfig cc) { PreciseLocation newToLocation = null; - data.morePacketsCounter++; if(!data.morePacketsSetbackPoint.isSet()) { data.morePacketsSetbackPoint.set(data.from); } - int ingameSeconds = plugin.getIngameSeconds(); - // Is at least a second gone by and has the server at least processed 20 - // ticks since last time - if(ingameSeconds != data.lastElapsedIngameSeconds) { + long time = System.currentTimeMillis(); - int limit = (int) ((packetsPerTimeframe * plugin.getIngameSecondDuration()) / 1000L); + // Take a packet from the buffer + data.morePacketsBuffer--; - int difference = limit - data.morePacketsCounter; + // Player used up buffer, he fails the check + if(data.morePacketsBuffer < 0) { - data.morePacketsBuffer += difference; - if(data.morePacketsBuffer > bufferLimit) - data.morePacketsBuffer = bufferLimit; - // Are we over the 22 event limit for that time frame now? (limit - // increases with time) + data.morePacketsVL = -data.morePacketsBuffer; + data.morePacketsTotalVL++; + data.morePacketsFailed++; - int packetsAboveLimit = (int) -data.morePacketsBuffer; + data.packets = -data.morePacketsBuffer; - if(data.morePacketsBuffer < 0) - data.morePacketsBuffer = 0; + final boolean cancel = executeActions(player, cc.morePacketsActions.getActions(data.morePacketsVL)); - // Should we react? Only if the check doesn't get skipped and we - // went over the limit - if(!plugin.skipCheck() && packetsAboveLimit > 0) { - data.morePacketsVL += packetsAboveLimit; - data.morePacketsTotalVL += packetsAboveLimit; - data.morePacketsFailed++; + if(cancel) + newToLocation = data.morePacketsSetbackPoint; + } - data.packets = packetsAboveLimit; + if(data.morePacketsLastTime + 1000 < time) { + // More than 1 second elapsed, but how many? + double seconds = ((double)(time - data.morePacketsLastTime)) / 1000D; - final boolean cancel = executeActions(player, cc.morePacketsActions.getActions(data.morePacketsVL)); + // For each second, fill the buffer + data.morePacketsBuffer += packetsPerTimeframe * seconds; - if(cancel) - newToLocation = data.morePacketsSetbackPoint; + // If there was a long pause (maybe server lag?) + // Allow buffer to grow up to 100 + if(seconds > 2) { + if(data.morePacketsBuffer > 100) { + data.morePacketsBuffer = 100; + } + // Else only allow growth up to 50 + } else { + if(data.morePacketsBuffer > 50) { + data.morePacketsBuffer = 50; + } } - // No new setbackLocation was chosen + // Set the new "last" time + data.morePacketsLastTime = time; + + // Set the new "setback" location if(newToLocation == null) { data.morePacketsSetbackPoint.set(data.from); } - - if(data.morePacketsVL > 0) - // Shrink the "over limit" value by 20 % every second - data.morePacketsVL *= 0.8; - - data.morePacketsCounter = 0; // Count from zero again - data.lastElapsedIngameSeconds = ingameSeconds; + } else if(data.morePacketsLastTime > time) { + // Security check, maybe system time changed + data.morePacketsLastTime = time; } return newToLocation; diff --git a/src/cc/co/evenprime/bukkit/nocheat/checks/moving/MovingData.java b/src/cc/co/evenprime/bukkit/nocheat/checks/moving/MovingData.java index 82a8aedd..8af07bde 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/checks/moving/MovingData.java +++ b/src/cc/co/evenprime/bukkit/nocheat/checks/moving/MovingData.java @@ -33,6 +33,7 @@ public class MovingData implements DataItem { public int jumpPhase; public double lastJumpAmplifier; + public int onIce = 0; public final PreciseLocation runflySetBackPoint = new PreciseLocation(); @@ -48,16 +49,13 @@ public class MovingData implements DataItem { public double horizontalBuffer; public int bunnyhopdelay; - public int morePacketsCounter; - public int morePacketsBuffer = 30; - public int packets; + public long morePacketsLastTime; + public int morePacketsBuffer = 50; public final PreciseLocation morePacketsSetbackPoint = new PreciseLocation(); public final PreciseLocation teleportTo = new PreciseLocation(); - public int lastElapsedIngameSeconds; - public final PreciseLocation from = new PreciseLocation(); public final PreciseLocation to = new PreciseLocation(); @@ -66,7 +64,7 @@ public class MovingData implements DataItem { public String checknamesuffix = ""; - public int onIce = 0; + public int packets; public void clearRunFlyData() { runflySetBackPoint.reset(); @@ -78,9 +76,6 @@ public class MovingData implements DataItem { public void clearMorePacketsData() { morePacketsSetbackPoint.reset(); - morePacketsBuffer = 30; - lastElapsedIngameSeconds = 0; - morePacketsCounter = 0; } @Override