Make moving.morepackets check server lag independent

This commit is contained in:
Evenprime 2012-02-05 18:13:45 +01:00
parent 03688f6e86
commit bf9450aceb
2 changed files with 46 additions and 52 deletions

View File

@ -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;

View File

@ -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