mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2024-11-09 12:10:37 +01:00
Move the new packet frequency check to a static utility, minor cleanups.
* Always use lag. * Let the morepackets check decide how to treat "just look" events. * Optimizations. * Renames.
This commit is contained in:
parent
3d5bbbbedd
commit
1441859ced
@ -7,16 +7,14 @@ import fr.neatmonster.nocheatplus.actions.ParameterName;
|
|||||||
import fr.neatmonster.nocheatplus.checks.Check;
|
import fr.neatmonster.nocheatplus.checks.Check;
|
||||||
import fr.neatmonster.nocheatplus.checks.CheckType;
|
import fr.neatmonster.nocheatplus.checks.CheckType;
|
||||||
import fr.neatmonster.nocheatplus.checks.ViolationData;
|
import fr.neatmonster.nocheatplus.checks.ViolationData;
|
||||||
|
import fr.neatmonster.nocheatplus.net.NetStatic;
|
||||||
import fr.neatmonster.nocheatplus.utilities.PlayerLocation;
|
import fr.neatmonster.nocheatplus.utilities.PlayerLocation;
|
||||||
import fr.neatmonster.nocheatplus.utilities.TickTask;
|
import fr.neatmonster.nocheatplus.utilities.TrigUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The MorePackets check (previously called Speedhack check) will try to identify players that send more than the usual
|
* The MorePackets check will try to identify players that send more than the usual
|
||||||
* amount of move-packets to the server to be able to move faster than normal, without getting caught by the other
|
* amount of move-packets to the server to be able to move faster than normal, without getting caught by the other
|
||||||
* checks (flying/running).
|
* checks (flying/running).
|
||||||
*
|
|
||||||
* It monitors the number of packets sent to the server within 1 second and compares it to the "legal" number of packets
|
|
||||||
* for that timeframe (22).
|
|
||||||
*/
|
*/
|
||||||
public class MorePackets extends Check {
|
public class MorePackets extends Check {
|
||||||
|
|
||||||
@ -34,12 +32,10 @@ public class MorePackets extends Check {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks a player.
|
* Check for speeding by sending too many packets. We assume 22 packets per
|
||||||
*
|
* second to be legitimate, while 20 would be ideal. See
|
||||||
* Players get assigned a certain amount of "free" packets as a limit initially. Every move packet reduces that
|
* PlayerData.morePacketsFreq for the monitored amount of time and the
|
||||||
* limit by 1. If more than 1 second of time passed, the limit gets increased by 22 * time in seconds, up to 50 and
|
* resolution. See NetStatic for the actual check code.
|
||||||
* they get a new "setback" location. If the player reaches limit = 0 -> teleport them back to "setback". If there was
|
|
||||||
* a long pause (maybe lag), limit may be up to 100.
|
|
||||||
*
|
*
|
||||||
* @param player
|
* @param player
|
||||||
* the player
|
* the player
|
||||||
@ -53,8 +49,15 @@ public class MorePackets extends Check {
|
|||||||
// Take time once, first:
|
// Take time once, first:
|
||||||
final long time = System.currentTimeMillis();
|
final long time = System.currentTimeMillis();
|
||||||
|
|
||||||
|
if (from.isSamePos(to)) {
|
||||||
|
// Ignore moves with "just look" for now.
|
||||||
|
// TODO: Extra ActionFrequency for "just look" + use to burn, maybe also check individually.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure we have a set-back location.
|
||||||
if (!data.hasMorePacketsSetBack()){
|
if (!data.hasMorePacketsSetBack()){
|
||||||
// TODO: Check if other set-back is appropriate or if to set on other events.
|
// TODO: Check if other set-back is appropriate or if to set/reset on other events.
|
||||||
if (data.hasSetBack()) {
|
if (data.hasSetBack()) {
|
||||||
data.setMorePacketsSetBack(data.getSetBack(to));
|
data.setMorePacketsSetBack(data.getSetBack(to));
|
||||||
}
|
}
|
||||||
@ -63,54 +66,10 @@ public class MorePackets extends Check {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add packet to frequency count.
|
// Check for a violation of the set limits.
|
||||||
data.morePacketsFreq.add(time, 1f);
|
final double violation = NetStatic.morePacketsCheck(data.morePacketsFreq, time, 1f, maxPackets, idealPackets);
|
||||||
|
|
||||||
// Fill up all "used" time windows (minimum we can do without other events).
|
// Process violation result.
|
||||||
final float burnScore = (float) idealPackets * (float) data.morePacketsFreq.bucketDuration() / 1000f;
|
|
||||||
// Find index.
|
|
||||||
int i;
|
|
||||||
int empty = 0;
|
|
||||||
boolean used = false;
|
|
||||||
for (i = 1; i < data.morePacketsFreq.numberOfBuckets(); i++) {
|
|
||||||
if (data.morePacketsFreq.bucketScore(i) > 0f) {
|
|
||||||
if (used) {
|
|
||||||
for (int j = i; j < data.morePacketsFreq.numberOfBuckets(); j ++) {
|
|
||||||
if (data.morePacketsFreq.bucketScore(j) == 0f) {
|
|
||||||
empty += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
used = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adjust empty based on server side lag.
|
|
||||||
final float lag = cc.lag ? TickTask.getLag(data.morePacketsFreq.bucketDuration() * data.morePacketsFreq.numberOfBuckets(), true): 1f;
|
|
||||||
if (lag >= 1f) {
|
|
||||||
// This is more strict than without lag adaption (!).
|
|
||||||
empty = Math.min(empty, (int) Math.round((lag - 1f) * data.morePacketsFreq.numberOfBuckets()));
|
|
||||||
}
|
|
||||||
|
|
||||||
final double fullCount;
|
|
||||||
if (i < data.morePacketsFreq.numberOfBuckets()) {
|
|
||||||
// Assume all following time windows are burnt.
|
|
||||||
final float trailing = Math.max(data.morePacketsFreq.trailingScore(i, 1f), burnScore * (data.morePacketsFreq.numberOfBuckets() - i - empty));
|
|
||||||
final float leading = data.morePacketsFreq.leadingScore(i, 1f);
|
|
||||||
fullCount = leading + trailing;
|
|
||||||
} else {
|
|
||||||
// All time windows are used.
|
|
||||||
fullCount = data.morePacketsFreq.score(1f);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
final double violation = (double) fullCount - (double) (maxPackets * data.morePacketsFreq.numberOfBuckets() * data.morePacketsFreq.bucketDuration() / 1000f);
|
|
||||||
|
|
||||||
// TODO: Burn time windows based on other activity counting [e.g. same resolution ActinFrequency with keep-alive].
|
|
||||||
|
|
||||||
// Player used up buffer, they fail the check.
|
|
||||||
if (violation > 0.0) {
|
if (violation > 0.0) {
|
||||||
|
|
||||||
// Increment violation level.
|
// Increment violation level.
|
||||||
@ -122,11 +81,12 @@ public class MorePackets extends Check {
|
|||||||
vd.setParameter(ParameterName.PACKETS, Integer.toString(new Double(violation).intValue()));
|
vd.setParameter(ParameterName.PACKETS, Integer.toString(new Double(violation).intValue()));
|
||||||
}
|
}
|
||||||
if (executeActions(vd)) {
|
if (executeActions(vd)) {
|
||||||
|
// Set to cancel the move.
|
||||||
return data.getMorePacketsSetBack();
|
return data.getMorePacketsSetBack();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Set the new "setback" location. (CHANGED to only update, if not a violation.)
|
// Update the set-back location. (CHANGED to only update, if not a violation.)
|
||||||
// (Might update whenever newTo == null)
|
// (Might update whenever newTo == null)
|
||||||
data.setMorePacketsSetBack(from);
|
data.setMorePacketsSetBack(from);
|
||||||
}
|
}
|
||||||
|
@ -601,12 +601,10 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Morepackets.
|
// Morepackets.
|
||||||
|
// TODO: Also update counters if newTo == null?
|
||||||
if (newTo == null && cc.morePacketsCheck && !NCPExemptionManager.isExempted(player, CheckType.MOVING_MOREPACKETS) && !player.hasPermission(Permissions.MOVING_MOREPACKETS)) {
|
if (newTo == null && cc.morePacketsCheck && !NCPExemptionManager.isExempted(player, CheckType.MOVING_MOREPACKETS) && !player.hasPermission(Permissions.MOVING_MOREPACKETS)) {
|
||||||
// If it hasn't been stopped by any other check and is handled by the more packets check, execute it.
|
// If it hasn't been stopped by any other check and is handled by the more packets check, execute it.
|
||||||
// TODO: Still feed morepackets even if cancelled.
|
|
||||||
if (TrigUtil.distanceSquared(pFrom, pTo) > 0.0) {
|
|
||||||
newTo = morePackets.check(player, pFrom, pTo, data, cc);
|
newTo = morePackets.check(player, pFrom, pTo, data, cc);
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Otherwise we need to clear their data.
|
// Otherwise we need to clear their data.
|
||||||
data.clearMorePacketsData();
|
data.clearMorePacketsData();
|
||||||
|
@ -0,0 +1,86 @@
|
|||||||
|
package fr.neatmonster.nocheatplus.net;
|
||||||
|
|
||||||
|
import fr.neatmonster.nocheatplus.utilities.ActionFrequency;
|
||||||
|
import fr.neatmonster.nocheatplus.utilities.TickTask;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Static method utility for networking related stuff.
|
||||||
|
* <hr>
|
||||||
|
* Not sure about final location and naming... and content :p.
|
||||||
|
* @author dev1mc
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class NetStatic {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Packet-cheating check, for catching clients that send more packets than
|
||||||
|
* allowed. Intention is to have a more accurate check than just preventing
|
||||||
|
* "extreme spamming".
|
||||||
|
*
|
||||||
|
* @param packetFreq
|
||||||
|
* Records the packets. This check will update packetFreq
|
||||||
|
* according to the given time and packets.
|
||||||
|
* @param time
|
||||||
|
* Milliseconds time to update the ActionFrequency instance with.
|
||||||
|
* @param packets
|
||||||
|
* Amount to add to packetFreq with time.
|
||||||
|
* @param maxPackets
|
||||||
|
* The amount of packets per second (!), that is considered
|
||||||
|
* legitimate.
|
||||||
|
* @param idealPackets
|
||||||
|
* The "ideal" amount of packets per second. Used for "burning"
|
||||||
|
* time frames by setting them to this amount.
|
||||||
|
* @return The violation amount, i.e. "count above limit".
|
||||||
|
*/
|
||||||
|
public static double morePacketsCheck(final ActionFrequency packetFreq, final long time, final float packets, final float maxPackets, final float idealPackets) {
|
||||||
|
// Pull down stuff.
|
||||||
|
final long winDur = packetFreq.bucketDuration();
|
||||||
|
final int winNum = packetFreq.numberOfBuckets();
|
||||||
|
// Add packet to frequency count.
|
||||||
|
packetFreq.add(time, packets);
|
||||||
|
|
||||||
|
// Fill up all "used" time windows (minimum we can do without other events).
|
||||||
|
final float burnScore = (float) idealPackets * (float) winDur / 1000f;
|
||||||
|
// Find index.
|
||||||
|
int burnStart;
|
||||||
|
int empty = 0;
|
||||||
|
boolean used = false;
|
||||||
|
for (burnStart = 1; burnStart < winNum; burnStart ++) {
|
||||||
|
if (packetFreq.bucketScore(burnStart) > 0f) {
|
||||||
|
if (used) {
|
||||||
|
for (int j = burnStart; j < winNum; j ++) {
|
||||||
|
if (packetFreq.bucketScore(j) == 0f) {
|
||||||
|
empty += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
used = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Burn time windows based on other activity counting [e.g. same resolution ActinFrequency with keep-alive].
|
||||||
|
|
||||||
|
// Adjust empty based on server side lag, this makes the check more strict.
|
||||||
|
// TODO: Consider to add a config flag for skipping the lag adaption (e.g. strict).
|
||||||
|
final float lag = TickTask.getLag(winDur * winNum, true);
|
||||||
|
// TODO: Consider increasing the allowed maximum, for extreme server-side lag.
|
||||||
|
empty = Math.min(empty, (int) Math.round((lag - 1f) * winNum));
|
||||||
|
|
||||||
|
final double fullCount;
|
||||||
|
if (burnStart < winNum) {
|
||||||
|
// Assume all following time windows are burnt.
|
||||||
|
final float trailing = Math.max(packetFreq.trailingScore(burnStart, 1f), burnScore * (winNum - burnStart - empty));
|
||||||
|
final float leading = packetFreq.leadingScore(burnStart, 1f);
|
||||||
|
fullCount = leading + trailing;
|
||||||
|
} else {
|
||||||
|
// All time windows are used.
|
||||||
|
fullCount = packetFreq.score(1f);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (double) fullCount - (double) (maxPackets * winNum * winDur / 1000f);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user