mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2025-03-10 05:29:12 +01:00
Add KeepAliveFrequency check, add missing @GlobalConfig.
Limit the number of keep-alive packets to one per second.
This commit is contained in:
parent
c4b6845b8f
commit
85dcb33a98
@ -0,0 +1,51 @@
|
||||
package fr.neatmonster.nocheatplus.checks.net.protocollib;
|
||||
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.events.ListenerOptions;
|
||||
import com.comphenix.protocol.events.ListenerPriority;
|
||||
import com.comphenix.protocol.events.PacketAdapter;
|
||||
|
||||
import fr.neatmonster.nocheatplus.NCPAPIProvider;
|
||||
import fr.neatmonster.nocheatplus.checks.CheckType;
|
||||
import fr.neatmonster.nocheatplus.checks.net.NetConfigCache;
|
||||
import fr.neatmonster.nocheatplus.checks.net.NetDataFactory;
|
||||
import fr.neatmonster.nocheatplus.stats.Counters;
|
||||
|
||||
/**
|
||||
* Convenience base class for PacketAdapter creation with using config, data, counters.
|
||||
* @author asofold
|
||||
*
|
||||
*/
|
||||
public abstract class BaseAdapter extends PacketAdapter {
|
||||
|
||||
protected final Counters counters = NCPAPIProvider.getNoCheatPlusAPI().getGenericInstance(Counters.class);
|
||||
protected final NetConfigCache configFactory = (NetConfigCache) CheckType.NET.getConfigFactory();
|
||||
protected final NetDataFactory dataFactory = (NetDataFactory) CheckType.NET.getDataFactory();
|
||||
|
||||
public BaseAdapter(AdapterParameteters params) {
|
||||
super(params);
|
||||
}
|
||||
|
||||
public BaseAdapter(Plugin plugin, Iterable<? extends PacketType> types) {
|
||||
super(plugin, types);
|
||||
}
|
||||
|
||||
public BaseAdapter(Plugin plugin, ListenerPriority listenerPriority, Iterable<? extends PacketType> types, ListenerOptions... options) {
|
||||
super(plugin, listenerPriority, types, options);
|
||||
}
|
||||
|
||||
public BaseAdapter(Plugin plugin, ListenerPriority listenerPriority, Iterable<? extends PacketType> types) {
|
||||
super(plugin, listenerPriority, types);
|
||||
}
|
||||
|
||||
public BaseAdapter(Plugin plugin, ListenerPriority listenerPriority, PacketType... types) {
|
||||
super(plugin, listenerPriority, types);
|
||||
}
|
||||
|
||||
public BaseAdapter(Plugin plugin, PacketType... types) {
|
||||
super(plugin, types);
|
||||
}
|
||||
|
||||
}
|
@ -7,7 +7,6 @@ import org.bukkit.plugin.Plugin;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.events.ListenerPriority;
|
||||
import com.comphenix.protocol.events.PacketAdapter;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
|
||||
@ -16,12 +15,8 @@ import fr.neatmonster.nocheatplus.checks.Check;
|
||||
import fr.neatmonster.nocheatplus.checks.CheckType;
|
||||
import fr.neatmonster.nocheatplus.checks.moving.MovingData;
|
||||
import fr.neatmonster.nocheatplus.checks.net.NetConfig;
|
||||
import fr.neatmonster.nocheatplus.checks.net.NetConfigCache;
|
||||
import fr.neatmonster.nocheatplus.checks.net.NetData;
|
||||
import fr.neatmonster.nocheatplus.checks.net.NetDataFactory;
|
||||
import fr.neatmonster.nocheatplus.logging.Streams;
|
||||
import fr.neatmonster.nocheatplus.stats.Counters;
|
||||
import fr.neatmonster.nocheatplus.time.monotonic.Monotonic;
|
||||
import fr.neatmonster.nocheatplus.utilities.CheckUtils;
|
||||
import fr.neatmonster.nocheatplus.utilities.TrigUtil;
|
||||
|
||||
@ -32,7 +27,7 @@ import fr.neatmonster.nocheatplus.utilities.TrigUtil;
|
||||
* @author dev1mc
|
||||
*
|
||||
*/
|
||||
public class FlyingFrequency extends PacketAdapter {
|
||||
public class FlyingFrequency extends BaseAdapter {
|
||||
|
||||
// Setup for flying packets.
|
||||
public static final int numBooleans = 3;
|
||||
@ -44,40 +39,31 @@ public class FlyingFrequency extends PacketAdapter {
|
||||
public static final double minMoveDistSq = 1f / 256; // PlayerConnection magic.
|
||||
public static final float minLookChange = 10f;
|
||||
|
||||
/** Dummy check to access hasBypass for FlyingFrequency. */
|
||||
private final Check frequency = new Check(CheckType.NET_FLYINGFREQUENCY) {
|
||||
// Dummy check to access hasBypass.
|
||||
};
|
||||
/** Dummy check for bypass checking and actions execution. */
|
||||
private final Check frequency = new Check(CheckType.NET_FLYINGFREQUENCY) {};
|
||||
|
||||
private final Counters counters = NCPAPIProvider.getNoCheatPlusAPI().getGenericInstance(Counters.class);
|
||||
private final int idNullPlayer = counters.registerKey("packet.flying.nullplayer");
|
||||
private final int idHandled = counters.registerKey("packet.flying.handled");
|
||||
private final int idAsyncFlying = counters.registerKey("packet.flying.asynchronous");
|
||||
|
||||
private boolean cancelRedundant = true;
|
||||
|
||||
private final NetConfigCache configs;
|
||||
private final NetDataFactory dataFactory;
|
||||
|
||||
public FlyingFrequency(Plugin plugin) {
|
||||
// PacketPlayInFlying[3, legacy: 10]
|
||||
super(plugin, ListenerPriority.LOW, PacketType.Play.Client.FLYING); // TODO: How does POS and POS_LOOK relate/translate?
|
||||
this.configs = (NetConfigCache) CheckType.NET.getConfigFactory();
|
||||
this.dataFactory = (NetDataFactory) CheckType.NET.getDataFactory();
|
||||
super(plugin, ListenerPriority.LOW, PacketType.Play.Client.FLYING);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPacketReceiving(final PacketEvent event) {
|
||||
|
||||
final long time = System.currentTimeMillis();
|
||||
final Player player = event.getPlayer();
|
||||
if (player == null) {
|
||||
// TODO: Need config?
|
||||
counters.add(idNullPlayer, 1);
|
||||
counters.add(ProtocolLibComponent.idNullPlayer, 1);
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
final NetConfig cc = configs.getConfig(player.getWorld());
|
||||
final NetConfig cc = configFactory.getConfig(player.getWorld());
|
||||
if (!cc.flyingFrequencyActive) {
|
||||
return;
|
||||
}
|
||||
@ -85,7 +71,7 @@ public class FlyingFrequency extends PacketAdapter {
|
||||
counters.add(idHandled, 1);
|
||||
|
||||
final NetData data = dataFactory.getData(player);
|
||||
final long time = Monotonic.millis();
|
||||
|
||||
// Counting all packets.
|
||||
// TODO: Consider using the NetStatic check.
|
||||
data.flyingFrequencyAll.add(time, 1f);
|
||||
@ -141,7 +127,7 @@ public class FlyingFrequency extends PacketAdapter {
|
||||
lastTime = data.flyingFrequencyTimeNotOnGround;
|
||||
data.flyingFrequencyTimeNotOnGround = time;
|
||||
}
|
||||
if (time - lastTime > 1000) {
|
||||
if (time < lastTime || time - lastTime > 1000) {
|
||||
// Override
|
||||
onGroundSkip = true;
|
||||
}
|
||||
|
@ -0,0 +1,57 @@
|
||||
package fr.neatmonster.nocheatplus.checks.net.protocollib;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.events.ListenerPriority;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
|
||||
import fr.neatmonster.nocheatplus.checks.Check;
|
||||
import fr.neatmonster.nocheatplus.checks.CheckType;
|
||||
import fr.neatmonster.nocheatplus.checks.net.NetConfig;
|
||||
import fr.neatmonster.nocheatplus.checks.net.NetData;
|
||||
|
||||
public class KeepAliveFrequency extends BaseAdapter {
|
||||
|
||||
/** Dummy check for bypass checking and actions execution. */
|
||||
private final Check check = new Check(CheckType.NET_KEEPALIVEFREQUENCY) {};
|
||||
|
||||
public KeepAliveFrequency(Plugin plugin) {
|
||||
super(plugin, ListenerPriority.LOW, PacketType.Play.Client.KEEP_ALIVE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPacketReceiving(final PacketEvent event) {
|
||||
final long time = System.currentTimeMillis();
|
||||
final Player player = event.getPlayer();
|
||||
if (player == null) {
|
||||
counters.add(ProtocolLibComponent.idNullPlayer, 1);
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
final NetConfig cc = configFactory.getConfig(player);
|
||||
if (!cc.keepAliveFrequencyActive) {
|
||||
return;
|
||||
}
|
||||
final NetData data = dataFactory.getData(player);
|
||||
// TODO: Better modeling of actual packet sequences (flying vs. keep alive vs. request/ping).
|
||||
// TODO: Better integration wih god-mode check / trigger reset ndt.
|
||||
data.keepAliveFreq.add(time, 1f);
|
||||
// Use last time accepted as a hard reference.
|
||||
final float first = data.keepAliveFreq.bucketScore(0);
|
||||
if (first > 1f && !check.hasBypass(player)) {
|
||||
// Trigger a violation.
|
||||
final double vl = Math.max(first - 1f, data.keepAliveFreq.score(1f) - data.keepAliveFreq.numberOfBuckets());
|
||||
if (check.executeActions(player, vl, 1.0, cc.keepAliveFrequencyActions)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPacketSending(PacketEvent event) {
|
||||
// TODO: Maybe detect if keep alive wasn't asked for + allow cancel.
|
||||
}
|
||||
|
||||
}
|
@ -19,6 +19,7 @@ import fr.neatmonster.nocheatplus.components.NoCheatPlusAPI;
|
||||
import fr.neatmonster.nocheatplus.config.ConfPaths;
|
||||
import fr.neatmonster.nocheatplus.config.ConfigManager;
|
||||
import fr.neatmonster.nocheatplus.logging.StaticLog;
|
||||
import fr.neatmonster.nocheatplus.stats.Counters;
|
||||
import fr.neatmonster.nocheatplus.utilities.StringUtil;
|
||||
|
||||
/**
|
||||
@ -28,6 +29,9 @@ import fr.neatmonster.nocheatplus.utilities.StringUtil;
|
||||
*/
|
||||
public class ProtocolLibComponent implements DisableListener, INotifyReload {
|
||||
|
||||
// TODO: Static reference is problematic (needs a static and accessible Counters instance?).
|
||||
public static final int idNullPlayer = NCPAPIProvider.getNoCheatPlusAPI().getGenericInstance(Counters.class).registerKey("packet.flying.nullplayer");
|
||||
|
||||
private final List<PacketAdapter> registeredPacketAdapters = new LinkedList<PacketAdapter>();
|
||||
|
||||
public ProtocolLibComponent(Plugin plugin) {
|
||||
@ -40,6 +44,9 @@ public class ProtocolLibComponent implements DisableListener, INotifyReload {
|
||||
if (ConfigManager.isTrueForAnyConfig(ConfPaths.NET_FLYINGFREQUENCY_ACTIVE)) {
|
||||
register("fr.neatmonster.nocheatplus.checks.net.protocollib.FlyingFrequency", plugin);
|
||||
}
|
||||
if (ConfigManager.isTrueForAnyConfig(ConfPaths.NET_KEEPALIVEFREQUENCY_ACTIVE)) {
|
||||
register("fr.neatmonster.nocheatplus.checks.net.protocollib.KeepAliveFrequency", plugin);
|
||||
}
|
||||
if (ConfigManager.isTrueForAnyConfig(ConfPaths.NET_SOUNDDISTANCE_ACTIVE)) {
|
||||
register("fr.neatmonster.nocheatplus.checks.net.protocollib.SoundDistance", plugin);
|
||||
}
|
||||
@ -91,7 +98,7 @@ public class ProtocolLibComponent implements DisableListener, INotifyReload {
|
||||
@Override
|
||||
public void onReload() {
|
||||
unregister();
|
||||
CheckType.NET.getDataFactory().removeAllData(); // Currently needed for FlyingFRequency.
|
||||
CheckType.NET.getDataFactory().removeAllData(); // Currently needed for FlyingFrequency.
|
||||
register(Bukkit.getPluginManager().getPlugin("NoCheatPlus")); // Store instead ?
|
||||
}
|
||||
|
||||
|
@ -100,6 +100,7 @@ public enum CheckType {
|
||||
|
||||
NET(new NetConfigCache(), new NetDataFactory(), Permissions.NET),
|
||||
NET_FLYINGFREQUENCY(NET, Permissions.NET_FLYINGFREQUENCY),
|
||||
NET_KEEPALIVEFREQUENCY(NET, Permissions.NET_KEEPALIVEFREQUENCY),
|
||||
NET_SOUNDDISTANCE(NET), // Can not exempt players from this one.
|
||||
|
||||
UNKNOWN;
|
||||
|
@ -23,6 +23,9 @@ public class NetConfig extends ACheckConfig {
|
||||
public final int flyingFrequencyRedundantSeconds;
|
||||
public final ActionList flyingFrequencyRedundantActions;
|
||||
|
||||
public final boolean keepAliveFrequencyActive;
|
||||
public final ActionList keepAliveFrequencyActions;
|
||||
|
||||
public final boolean soundDistanceActive;
|
||||
/** Maximum distance for lightning effects (squared). */
|
||||
public final double soundDistanceSq;
|
||||
@ -40,6 +43,9 @@ public class NetConfig extends ACheckConfig {
|
||||
// Same permission for "silent".
|
||||
flyingFrequencyRedundantActions = config.getOptimizedActionList(ConfPaths.NET_FLYINGFREQUENCY_REDUNDANT_ACTIONS, Permissions.NET_FLYINGFREQUENCY);
|
||||
|
||||
keepAliveFrequencyActive = config.getBoolean(ConfPaths.NET_KEEPALIVEFREQUENCY_ACTIVE);
|
||||
keepAliveFrequencyActions = config.getOptimizedActionList(ConfPaths.NET_KEEPALIVEFREQUENCY_ACTIONS, Permissions.NET_KEEPALIVEFREQUENCY);
|
||||
|
||||
soundDistanceActive = config.getBoolean(ConfPaths.NET_SOUNDDISTANCE_ACTIVE);
|
||||
double dist = config.getDouble(ConfPaths.NET_SOUNDDISTANCE_MAXDISTANCE);
|
||||
soundDistanceSq = dist * dist;
|
||||
@ -53,6 +59,8 @@ public class NetConfig extends ACheckConfig {
|
||||
return flyingFrequencyActive;
|
||||
case NET_SOUNDDISTANCE:
|
||||
return soundDistanceActive;
|
||||
case NET_KEEPALIVEFREQUENCY:
|
||||
return keepAliveFrequencyActive;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
|
@ -4,23 +4,32 @@ import fr.neatmonster.nocheatplus.checks.access.ACheckData;
|
||||
import fr.neatmonster.nocheatplus.utilities.ActionFrequency;
|
||||
|
||||
/**
|
||||
* Primary thread only.
|
||||
* Data for net checks. Some data structures may not be thread-safe, but
|
||||
* accessing each checks data individually respecting the sequence of events
|
||||
* should work.
|
||||
*
|
||||
* @author asofold
|
||||
*
|
||||
*/
|
||||
public class NetData extends ACheckData {
|
||||
|
||||
/** All flying packets, use Monotonic.millis() for time. */
|
||||
/** All flying packets, use System.currentTimeMillis() for time. */
|
||||
public final ActionFrequency flyingFrequencyAll;
|
||||
public boolean flyingFrequencyOnGround = false;
|
||||
public long flyingFrequencyTimeOnGround = 0L;
|
||||
public long flyingFrequencyTimeNotOnGround = 0L;
|
||||
/**
|
||||
* Monitors redundant packets, when more than 20 packets per second are
|
||||
* sent. Use Monotonic.millis() for time.
|
||||
* sent. Use System.currentTimeMillis() for time.
|
||||
*/
|
||||
public final ActionFrequency flyingFrequencyRedundantFreq;
|
||||
|
||||
/**
|
||||
* Last 20 seconds keep alive packets counting. Use lastUpdate() for the
|
||||
* time of the last event. System.currentTimeMillis() is used.
|
||||
*/
|
||||
public ActionFrequency keepAliveFreq = new ActionFrequency(20, 1000);
|
||||
|
||||
public NetData(final NetConfig config) {
|
||||
super(config);
|
||||
flyingFrequencyAll = new ActionFrequency(config.flyingFrequencySeconds, 1000L);
|
||||
|
@ -7,7 +7,7 @@ import fr.neatmonster.nocheatplus.checks.access.CheckDataFactory;
|
||||
import fr.neatmonster.nocheatplus.utilities.ds.corw.LinkedHashMapCOW;
|
||||
|
||||
/**
|
||||
* Currently primary thread only!
|
||||
* Copy on write, right now.
|
||||
* @author asofold
|
||||
*
|
||||
*/
|
||||
|
@ -600,10 +600,6 @@ public abstract class ConfPaths {
|
||||
|
||||
public static final String NET = CHECKS + "net.";
|
||||
|
||||
private static final String NET_SOUNDDISTANCE = NET + "sounddistance.";
|
||||
public static final String NET_SOUNDDISTANCE_ACTIVE = NET_SOUNDDISTANCE + "active";
|
||||
public static final String NET_SOUNDDISTANCE_MAXDISTANCE = NET_SOUNDDISTANCE + "maxdistance";
|
||||
|
||||
private static final String NET_FLYINGFREQUENCY = NET + "flyingfrequency.";
|
||||
public static final String NET_FLYINGFREQUENCY_ACTIVE = NET_FLYINGFREQUENCY + "active";
|
||||
@GlobalConfig
|
||||
@ -613,9 +609,17 @@ public abstract class ConfPaths {
|
||||
public static final String NET_FLYINGFREQUENCY_ACTIONS = NET_FLYINGFREQUENCY + "actions";
|
||||
private static final String NET_FLYINGFREQUENCY_REDUNDANT = NET_FLYINGFREQUENCY + "reduceredundant.";
|
||||
public static final String NET_FLYINGFREQUENCY_REDUNDANT_ACTIVE = NET_FLYINGFREQUENCY_REDUNDANT + "active";
|
||||
@GlobalConfig
|
||||
public static final String NET_FLYINGFREQUENCY_REDUNDANT_SECONDS = NET_FLYINGFREQUENCY_REDUNDANT + "seconds";
|
||||
public static final String NET_FLYINGFREQUENCY_REDUNDANT_ACTIONS = NET_FLYINGFREQUENCY_REDUNDANT + "actions";
|
||||
|
||||
private static final String NET_KEEPALIVEFREQUENCY = NET + "keepalivefrequency.";
|
||||
public static final String NET_KEEPALIVEFREQUENCY_ACTIVE = NET_KEEPALIVEFREQUENCY + "active";
|
||||
public static final String NET_KEEPALIVEFREQUENCY_ACTIONS = NET_KEEPALIVEFREQUENCY + "actions";
|
||||
|
||||
private static final String NET_SOUNDDISTANCE = NET + "sounddistance.";
|
||||
public static final String NET_SOUNDDISTANCE_ACTIVE = NET_SOUNDDISTANCE + "active";
|
||||
public static final String NET_SOUNDDISTANCE_MAXDISTANCE = NET_SOUNDDISTANCE + "maxdistance";
|
||||
|
||||
public static final String STRINGS = "strings";
|
||||
|
||||
|
@ -447,6 +447,10 @@ public class DefaultConfig extends ConfigFile {
|
||||
set(ConfPaths.NET_FLYINGFREQUENCY_REDUNDANT_SECONDS, 3);
|
||||
set(ConfPaths.NET_FLYINGFREQUENCY_REDUNDANT_ACTIONS, "cancel"); // TODO: Log actions.
|
||||
|
||||
// KeepAliveFrequency
|
||||
set(ConfPaths.NET_KEEPALIVEFREQUENCY_ACTIVE, true);
|
||||
set(ConfPaths.NET_KEEPALIVEFREQUENCY_ACTIONS, "cancel vl>10 cancel log:keepalive:0:10:if vl>40 cancel log:keepalive:0:10:icf vl>100 cancel log:keepalive:0:10:icf cmd:kickalive");
|
||||
|
||||
// SoundDistance
|
||||
set(ConfPaths.NET_SOUNDDISTANCE_ACTIVE, true);
|
||||
set(ConfPaths.NET_SOUNDDISTANCE_MAXDISTANCE, 320);
|
||||
@ -493,7 +497,9 @@ public class DefaultConfig extends ConfigFile {
|
||||
set(ConfPaths.STRINGS + ".improbable", start + "meets the improbable more than expected" + end);
|
||||
set(ConfPaths.STRINGS + ".instantbow", start + "fires bow too fast" + end);
|
||||
set(ConfPaths.STRINGS + ".instanteat", start + "eats food [food] too fast" + end);
|
||||
set(ConfPaths.STRINGS + ".keepalive", start + "spams keep-alive packets (god/freecam?)" + end);
|
||||
set(ConfPaths.STRINGS + ".kick", "kick [player]");
|
||||
set(ConfPaths.STRINGS + ".kickalive", "ncp kick [player] Too many keep-alive packets.");
|
||||
set(ConfPaths.STRINGS + ".kickbedleave", "ncp delay ncp kick [player] Go find a bed!");
|
||||
set(ConfPaths.STRINGS + ".kickbspeed", "ncp kick [player] You interacted too fast!");
|
||||
set(ConfPaths.STRINGS + ".kickcaptcha", "ncp kick [player] Enter the captcha!");
|
||||
|
@ -116,6 +116,7 @@ public class Permissions {
|
||||
|
||||
public static final String NET = CHECKS + ".net";
|
||||
public static final String NET_FLYINGFREQUENCY = NET + ".flyingfrequency";
|
||||
public static final String NET_KEEPALIVEFREQUENCY = NET + ".keepalivefrequency";
|
||||
|
||||
public static final String MOVING = CHECKS + ".moving";
|
||||
public static final String MOVING_CREATIVEFLY = MOVING + ".creativefly";
|
||||
|
Loading…
Reference in New Issue
Block a user