Add basic (mostly global) configuration for net checks.

Currently the parameters except for the "active" flag are not available
per-world, but this can be added later.
This commit is contained in:
asofold 2014-07-27 23:21:04 +02:00
parent 02eea231b7
commit 289da86c35
5 changed files with 92 additions and 28 deletions

View File

@ -11,6 +11,9 @@ import com.comphenix.protocol.events.PacketEvent;
import fr.neatmonster.nocheatplus.NCPAPIProvider;
import fr.neatmonster.nocheatplus.components.JoinLeaveListener;
import fr.neatmonster.nocheatplus.config.ConfPaths;
import fr.neatmonster.nocheatplus.config.ConfigFile;
import fr.neatmonster.nocheatplus.config.ConfigManager;
import fr.neatmonster.nocheatplus.stats.Counters;
import fr.neatmonster.nocheatplus.utilities.ActionFrequency;
import fr.neatmonster.nocheatplus.utilities.ds.LinkedHashMapCOW;
@ -33,9 +36,15 @@ public class FlyingFrequency extends PacketAdapter implements JoinLeaveListener
private final Counters counters = NCPAPIProvider.getNoCheatPlusAPI().getGenericInstance(Counters.class);
private final int idSilent = counters.registerKey("packet.flying.silentcancel");
private final int seconds;
private final float maxPackets;
public FlyingFrequency(Plugin plugin) {
// PacketPlayInFlying[3, legacy: 10]
super(plugin, PacketType.Play.Client.FLYING); // TODO: How does POS and POS_LOOK relate/translate?
ConfigFile config = ConfigManager.getConfigFile();
seconds = Math.max(1, config.getInt(ConfPaths.NET_FLYINGFREQUENCY_SECONDS));
maxPackets = Math.max(1, config.getInt(ConfPaths.NET_FLYINGFREQUENCY_MAXPACKETS));
}
@Override
@ -53,10 +62,10 @@ public class FlyingFrequency extends PacketAdapter implements JoinLeaveListener
if (freq != null) {
return freq;
} else {
final ActionFrequency newFreq = new ActionFrequency(5, 1000);
final ActionFrequency newFreq = new ActionFrequency(seconds, 1000);
this.freqMap.put(name, newFreq);
return newFreq;
}
}
}
@Override
@ -64,7 +73,7 @@ public class FlyingFrequency extends PacketAdapter implements JoinLeaveListener
// TODO: Add several (at least has look + has pos individually, maybe none/onground)
final ActionFrequency freq = getFreq(event.getPlayer().getName());
freq.add(System.currentTimeMillis(), 1f);
if (freq.score(1f) > 300) {
if (freq.score(1f) > maxPackets) {
event.setCancelled(true);
counters.add(idSilent, 1); // Until it is sure if we can get these async.
}

View File

@ -1,17 +1,22 @@
package fr.neatmonster.nocheatplus.net.protocollib;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.ProtocolManager;
import com.comphenix.protocol.events.PacketAdapter;
import fr.neatmonster.nocheatplus.NCPAPIProvider;
import fr.neatmonster.nocheatplus.components.DisableListener;
import fr.neatmonster.nocheatplus.components.INotifyReload;
import fr.neatmonster.nocheatplus.components.NoCheatPlusAPI;
import fr.neatmonster.nocheatplus.config.ConfPaths;
import fr.neatmonster.nocheatplus.config.ConfigManager;
import fr.neatmonster.nocheatplus.logging.LogUtil;
import fr.neatmonster.nocheatplus.utilities.StringUtil;
@ -20,46 +25,64 @@ import fr.neatmonster.nocheatplus.utilities.StringUtil;
* @author dev1mc
*
*/
public class ProtocolLibComponent implements DisableListener{
public class ProtocolLibComponent implements DisableListener, INotifyReload{
private final List<PacketAdapter> registeredPacketAdapters = new LinkedList<PacketAdapter>();
public ProtocolLibComponent(Plugin plugin) {
// Register with ProtocolLib
final ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager();
LogUtil.logInfo("[NoCheatPlus] ProtocolLib seems to be available, attempt to add packet level hooks...");
// Classes having a constructor with Plugin as argument.
List<Class<? extends PacketAdapter>> adapterClasses = Arrays.asList(
FlyingFrequency.class,
SoundDistance.class // Need too: SPAWN_ENTITY_WEATHER, wither/dragon: WORLD_EVENT
);
// TODO: Configurability (INotifyConfig, method to set up hooks).
for (Class<? extends PacketAdapter> clazz : adapterClasses) {
try {
// Construct a new instance using reflection.
PacketAdapter adapter = clazz.getDeclaredConstructor(Plugin.class).newInstance(plugin);
protocolManager.addPacketListener(adapter);
registeredPacketAdapters.add(adapter);
} catch (Throwable t) {
LogUtil.logWarning("[NoCheatPlus] Could not register packet level hook: " + clazz.getSimpleName());
LogUtil.logWarning(t); // TODO: Maybe temporary.
}
LogUtil.logInfo("Adding packet level hooks for ProtocolLib (MC " + ProtocolLibrary.getProtocolManager().getMinecraftVersion().getVersion() + ")...");
register(plugin);
}
private void register(Plugin plugin) {
// REgister Classes having a constructor with Plugin as argument.
// TODO: Config paths for activation flags ...
// TODO: @GlobalConfig simple setup at first.
if (ConfigManager.isTrueForAnyConfig(ConfPaths.NET_FLYINGFREQUENCY_ACTIVE)) {
register(FlyingFrequency.class, plugin);
}
if (ConfigManager.isTrueForAnyConfig(ConfPaths.NET_SOUNDDISTANCE_ACTIVE)) {
register(SoundDistance.class, plugin);
}
if (!registeredPacketAdapters.isEmpty()) {
List<String> names = new ArrayList<String>(registeredPacketAdapters.size());
for (PacketAdapter adapter : registeredPacketAdapters) {
names.add(adapter.getClass().getSimpleName());
}
LogUtil.logInfo("[NoCheatPlus] Available packet level hooks: " + StringUtil.join(names, " | "));
LogUtil.logInfo("[NoCheatPlus] Available (and activated) packet level hooks: " + StringUtil.join(names, " | "));
}
}
private void register(Class<? extends PacketAdapter> clazz, Plugin plugin) {
try {
// Construct a new instance using reflection.
PacketAdapter adapter = clazz.getDeclaredConstructor(Plugin.class).newInstance(plugin);
ProtocolLibrary.getProtocolManager().addPacketListener(adapter);
registeredPacketAdapters.add(adapter);
} catch (Throwable t) {
LogUtil.logWarning("[NoCheatPlus] Could not register packet level hook: " + clazz.getSimpleName());
LogUtil.logWarning(t);
}
}
@Override
public void onDisable() {
unregister();
}
@Override
public void onReload() {
unregister();
register(Bukkit.getPluginManager().getPlugin("NoCheatPlus")); // Store instead ?
}
private void unregister() {
final ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager();
final NoCheatPlusAPI api = NCPAPIProvider.getNoCheatPlusAPI();
for (PacketAdapter adapter : registeredPacketAdapters) {
try {
protocolManager.removePacketListener(adapter);
api.removeComponent(adapter); // Bit heavy, but consistent.
} catch (Throwable t) {
LogUtil.logWarning("[NoCheatPlus] Failed to unregister packet level hook: " + adapter.getClass().getName());
}

View File

@ -10,15 +10,15 @@ import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.reflect.StructureModifier;
import fr.neatmonster.nocheatplus.config.ConfPaths;
import fr.neatmonster.nocheatplus.config.ConfigFile;
import fr.neatmonster.nocheatplus.config.ConfigManager;
import fr.neatmonster.nocheatplus.utilities.TrigUtil;
public class SoundDistance extends PacketAdapter {
// TODO: Will not be effective with 512 radius, if they add the patch by @Amranth.
// TODO: For lower distances more packets might need to be intercepted.
/** Maximum distance for thunder effects (squared). */
private static final double distSq = 320.0 * 320.0; // TODO:configurable.
private static final String[] effectNames = new String[] { // Prefix tree?
"ambient.weather.thunder",
@ -35,9 +35,15 @@ public class SoundDistance extends PacketAdapter {
}
return false;
}
/** Maximum distance for thunder effects (squared). */
private final double distSq;
public SoundDistance(Plugin plugin) {
super(plugin, PacketType.Play.Server.NAMED_SOUND_EFFECT);
ConfigFile config = ConfigManager.getConfigFile();
double dist = config.getDouble(ConfPaths.NET_SOUNDDISTANCE_MAXDISTANCE);
distSq = dist * dist;
}
@Override

View File

@ -585,6 +585,20 @@ public abstract class ConfPaths {
public static final String MOVING_TRACE_SIZE = MOVING_TRACE + "size";
public static final String MOVING_TRACE_MERGEDIST = MOVING_TRACE + "mergedist";
private static final String NET = CHECKS + "net.";
private static final String NET_SOUNDDISTANCE = NET + "sounddistance.";
public static final String NET_SOUNDDISTANCE_ACTIVE = NET_SOUNDDISTANCE + "active";
@GlobalConfig
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
public static final String NET_FLYINGFREQUENCY_SECONDS = NET_FLYINGFREQUENCY + "seconds";
@GlobalConfig
public static final String NET_FLYINGFREQUENCY_MAXPACKETS = NET_FLYINGFREQUENCY + "maxpackets";
public static final String STRINGS = "strings";

View File

@ -423,6 +423,18 @@ public class DefaultConfig extends ConfigFile {
set(ConfPaths.MOVING_SPEEDGRACE, 4.0);
set(ConfPaths.MOVING_ENFORCELOCATION, true);
// NET
// FlyingFrequency
set(ConfPaths.NET_FLYINGFREQUENCY_ACTIVE, true);
set(ConfPaths.NET_FLYINGFREQUENCY_SECONDS, 5);
set(ConfPaths.NET_FLYINGFREQUENCY_MAXPACKETS, 300);
// SoundDistance
set(ConfPaths.NET_SOUNDDISTANCE_ACTIVE, true);
set(ConfPaths.NET_SOUNDDISTANCE_MAXDISTANCE, 320);
// TODO: An extra file might suit these.
final String start = "[player] failed [check]: ";
final String end = ". VL [violations].";