[BROKEN] Data storage overhaul (basics). (+)

(SAFETY COMMIT)

Largely breaking change.
* Interfaces in front of data types (and 'managers'), some interfaces
removed.
* Data and configuration fetching.
* Check activation checking (config flags, isEnabled, hasBypass).
* CheckType (activation checks, factories removed).
* Lots of collateral signature changes, including IPlayerData.

The (I)WorldDataManager stores per-world data (+ per world per check
type).
* Raw configurations.
* Typical flags: check activation, debug, lag adaption.
* Generic data, such as check configurations or per world check data.

The (I)PlayerDataManager stores per player data.
* Check Data.
* Typical flags: debug
* Exemption
* Check data (and config cache).
* Further mappings and later OfflinePlayerData.
* The registration interface will allow defining, how instances are
handled for registered types (factory, proxy, what on world change, what
on logout, global removal handler, per player removal handler).

(I)PlayerData is intended to be/become the central access point.
* External interface is IPlayerData now.
* Per player debug flags, exemptions.
* Fetching configuration and data: local cache, relaying fetching to
registered factories and proxy-registries/storage (e.g. fetching
configuration from per world storage).

Other fixes/changes:
(+) Extend the debug player command (set true/false, reset to world
default, arbitrary check types).
(+) PlayerData maintains a currentWorldIdentifier (to be used instead of
ChatData in future).
(+) The WorldConfigProvider getAll implementation returns a
LinkedHashSet now, avoiding duplicates.
(+) Move DefaultGenericInstanceRegistry to NCPCore.
(+) Thread-safety considerations for DefaultGenericInstanceRegistry.
(+) Don't log errors on hasBypass checking. TBD: Instead intercept
during listener methods (or even as a feature within the listener node:
e.g. @ThreadContext(primaryThread=true, skipOffContext=true,
cancelOffContext=true).
(+) Add fight.wrongturn permissions to plugin.yml.
(+) Missing GPLv3 headers.

Broken/Missing:
* WorldData inheritance from default: propagate all changes done
directly to the default config to children (all worlds that don't have
an explicit world_config.yml set) - possibly add an OverrideState or
similar, (NONE, FROM_DEFAULT, EXPLICIT) and don't override EXPLICIT if
coming from the default. Calling override on the default WorldData is
not to be confused with calling override for WorldDataManager (override
for all worlds as EXPLICIT).
* Organize overriding for special circumstances (version dependent
activation  and the like). Might want to add registered override
handlers to be called on reload automatically.
* Store generic per check type per world data in the WorldDataManager,
such as configurations and per-world check data. TBD: Factories, cleanup
(!).
* Most efficient referencing (IWorldCheckTypeNode, IHandle<something>?).
* All the registry stuff (see PlayerData).
* Use interfaces for auto registry (and a flag within
RegistrationContext?) - world unload, world change, player join / leave.
* (Data expiration handling including transition to IOfflinePlayerData,
because now data is a little heavier.)
* Further details.
This commit is contained in:
asofold 2018-02-13 15:15:23 +01:00
commit 30902ec352
167 changed files with 6752 additions and 4479 deletions

View File

@ -276,6 +276,38 @@ public class ActionFrequency {
return buffer.toString();
}
/**
* Update and then reduce all given ActionFrequency instances by the given
* amount, capped at a maximum of 0 for the resulting first bucket score.
*
* @param amount
* The amount to subtract.
* @param freqs
*/
public static void reduce(final long time, final float amount, final ActionFrequency... freqs) {
for (int i = 0; i < freqs.length; i++) {
final ActionFrequency freq = freqs[i];
freq.update(time);
freq.setBucket(0, Math.max(0f, freq.bucketScore(0) - amount));
}
}
/**
* Update and then reduce all given ActionFrequency instances by the given
* amount, without capping the result.
*
* @param amount
* The amount to subtract.
* @param freqs
*/
public static void subtract(final long time, final float amount, final ActionFrequency... freqs) {
for (int i = 0; i < freqs.length; i++) {
final ActionFrequency freq = freqs[i];
freq.update(time);
freq.setBucket(0, freq.bucketScore(0) - amount);
}
}
/**
* Deserialize from a string.
* @param line

View File

@ -321,7 +321,7 @@ public class HashMapLOW <K, V> {
private LHMEntry<K, V> currentEntry = null;
private K lastReturnedKey = null;
public LHMIterator(HashMapLOW<K, V> map, LHMBucket<K, V>[] buckets) {
LHMIterator(HashMapLOW<K, V> map, LHMBucket<K, V>[] buckets) {
this.map = map;
this.buckets = buckets;
// (Lazily advance.)
@ -412,6 +412,21 @@ public class HashMapLOW <K, V> {
}
static class LHMIterable<K, V> implements Iterable<Entry<K,V>> {
private final Iterator<Entry<K, V>> iterator;
LHMIterable(Iterator<Entry<K, V>> iterator) {
this.iterator = iterator;
}
@Override
public Iterator<Entry<K, V>> iterator() {
return iterator;
}
}
///////////////////////
// Instance members
@ -697,6 +712,16 @@ public class HashMapLOW <K, V> {
return size == 0 ? new LHMIterator<K, V>(null, null) : new LHMIterator<K, V>(this, buckets);
}
/**
* Get an Iterable containing the same iterator, as is returned by
* iterator(). See: {@link #iterator()}
*
* @return
*/
public Iterable<Entry<K, V>> iterable() {
return new LHMIterable<K, V>(iterator());
}
/**
* Get all keys as a LinkedHashSet fit for iteration. The returned set is a
* new instance, so changes don't affect the original HashMapLOW instance.

View File

@ -27,12 +27,13 @@ import fr.neatmonster.nocheatplus.actions.ParameterName;
import fr.neatmonster.nocheatplus.checks.Check;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.ViolationData;
import fr.neatmonster.nocheatplus.compat.AlmostBoolean;
import fr.neatmonster.nocheatplus.compat.BridgeHealth;
import fr.neatmonster.nocheatplus.components.config.value.OverrideType;
import fr.neatmonster.nocheatplus.components.registry.feature.INotifyReload;
import fr.neatmonster.nocheatplus.config.ConfPaths;
import fr.neatmonster.nocheatplus.config.ConfigManager;
import fr.neatmonster.nocheatplus.logging.StaticLog;
import fr.neatmonster.nocheatplus.players.DataManager;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.stats.Counters;
import fr.neatmonster.nocheatplus.utilities.InventoryUtil;
import fr.neatmonster.nocheatplus.utilities.TickTask;
@ -62,7 +63,9 @@ public class FastConsume extends Check implements Listener, INotifyReload {
private void disableInstantEat() {
// TODO: Do this kind of thing via registries later on.
ConfigManager.setForAllConfigs(ConfPaths.INVENTORY_INSTANTEAT_CHECK, false);
//ConfigManager.setForAllConfigs(ConfPaths.INVENTORY_INSTANTEAT_CHECK, false);
NCPAPIProvider.getNoCheatPlusAPI().getWorldDataManager().overrideCheckActivation(
this.type, AlmostBoolean.NO, OverrideType.PERMANENT, true);
StaticLog.logInfo("Inventory checks: FastConsume is available, disabled InstantEat.");
}
@ -75,18 +78,20 @@ public class FastConsume extends Check implements Listener, INotifyReload {
counters.addPrimaryThread(idCancelDead, 1);
return;
}
if (!isEnabled(player)) {
final IPlayerData pData = DataManager.getPlayerData(player);
if (!pData.isCheckActive(type, player)) {
return;
}
final InventoryData data = InventoryData.getData(player);
final InventoryData data = pData.getGenericInstance(InventoryData.class);
final long time = System.currentTimeMillis();
if (check(player, event.getItem(), time, data)){
if (check(player, event.getItem(), time, data, pData)){
event.setCancelled(true);
DataManager.getPlayerData(player).requestUpdateInventory();
}
}
private boolean check(final Player player, final ItemStack stack, final long time, final InventoryData data){
private boolean check(final Player player, final ItemStack stack,
final long time, final InventoryData data, final IPlayerData pData){
// Uses the instant-eat data for convenience.
// Consistency checks...
if (stack == null){ // || stack.getType() != data.instantEatFood){
@ -100,7 +105,7 @@ public class FastConsume extends Check implements Listener, INotifyReload {
return false;
}
// Check exceptions.
final InventoryConfig cc = InventoryConfig.getConfig(player);
final InventoryConfig cc = pData.getGenericInstance(InventoryConfig.class);
final Material mat = stack == null ? null : stack.getType();
if (mat != null){
if (cc.fastConsumeWhitelist){
@ -144,8 +149,9 @@ public class FastConsume extends Check implements Listener, INotifyReload {
final ItemStack actualStack = InventoryUtil.getFirstConsumableItemInHand(player);
data.instantEatFood = actualStack == null ? null : actualStack.getType();
// TODO: Allows some abuse: 1. try instantly eat (cancelled) 2. consume item directly when needed.
} else {
if (data.debug) {
}
else {
if (pData.isDebugActive(type)) {
debug(player, "PlayerItemConsumeEvent, reset fastconsume: " + data.instantEatFood);
}
data.instantEatFood = null;

View File

@ -23,6 +23,8 @@ import org.bukkit.inventory.meta.BookMeta;
import fr.neatmonster.nocheatplus.checks.Check;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.players.DataManager;
import fr.neatmonster.nocheatplus.players.IPlayerData;
public class Gutenberg extends Check implements Listener {
@ -42,7 +44,8 @@ public class Gutenberg extends Check implements Listener {
if (!isEnabled(player)) {
return;
}
final InventoryConfig cc = InventoryConfig.getConfig(player);
final IPlayerData pData = DataManager.getPlayerData(player);
final InventoryConfig cc = pData.getGenericInstance(InventoryConfig.class);
final BookMeta newMeta = event.getNewBookMeta();
final int pages = newMeta.getPageCount();
if (pages <= 50) {

View File

@ -33,6 +33,7 @@ import fr.neatmonster.nocheatplus.utilities.location.LocUtil;
import fr.neatmonster.nocheatplus.utilities.map.BlockCache;
import fr.neatmonster.nocheatplus.utilities.map.BlockProperties;
import fr.neatmonster.nocheatplus.utilities.map.WrapBlockCache;
import fr.neatmonster.nocheatplus.worlds.IWorldData;
/**
* Hot fix for 1.9 and 1.10 (possibly later?): falling block duplication via end
@ -87,7 +88,8 @@ public class HotFixFallingBlockPortalEnter implements Listener {
if (mat != null) {
final Location loc = entity.getLocation(useLoc);
final World world = loc.getWorld();
if (InventoryConfig.getConfig(world).hotFixFallingBlockEndPortalActive) {
final IWorldData worldData = NCPAPIProvider.getNoCheatPlusAPI().getWorldDataManager().getWorldData(world);
if (worldData.getGenericInstance(InventoryConfig.class).hotFixFallingBlockEndPortalActive) {
final BlockCache blockCache = wrapBlockCache.getBlockCache();
blockCache.setAccess(world);
final boolean nearbyPortal = BlockProperties.collidesId(blockCache, loc.getX() - 2.0, loc.getY() - 2.0, loc.getZ() - 2.0, loc.getX() + 3.0, loc.getY() + 3.0, loc.getZ() + 3.0, Material.ENDER_PORTAL);

View File

@ -24,8 +24,6 @@ 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.components.debug.IDebugPlayer;
import fr.neatmonster.nocheatplus.stats.Counters;
import fr.neatmonster.nocheatplus.utilities.CheckUtils;
@ -38,8 +36,6 @@ import fr.neatmonster.nocheatplus.utilities.CheckUtils;
public abstract class BaseAdapter extends PacketAdapter implements IDebugPlayer {
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();
/** Override for specific output on the debug method. */
protected CheckType checkType = CheckType.NET;

View File

@ -27,10 +27,9 @@ import com.comphenix.protocol.events.PacketEvent;
import fr.neatmonster.nocheatplus.NCPAPIProvider;
import fr.neatmonster.nocheatplus.checks.net.NetConfig;
import fr.neatmonster.nocheatplus.checks.net.NetData;
import fr.neatmonster.nocheatplus.checks.net.NetStatic;
import fr.neatmonster.nocheatplus.checks.net.PacketFrequency;
import fr.neatmonster.nocheatplus.players.DataManager;
import fr.neatmonster.nocheatplus.players.PlayerData;
import fr.neatmonster.nocheatplus.players.IPlayerData;
/**
* Pre-1.9.
@ -74,22 +73,12 @@ public class CatchAllAdapter extends BaseAdapter {
// TODO: Is this a problem, as the server has the player so it could break a block)?
return;
}
final NetConfig cc;
try {
cc = NetStatic.getWorldConfig(player, configFactory, dataFactory);
}
catch (UnsupportedOperationException e) {
// Legacy +-.
// TODO: Get from PlayerData, once HashMapLOW is used.
return;
}
if (cc.packetFrequencyActive) {
final PlayerData pData = DataManager.getPlayerData(player);
if (packetFrequency.isEnabled(player, cc, pData)) {
final NetData data = dataFactory.getData(player);
if (packetFrequency.check(player, data, cc)) {
event.setCancelled(true);
}
final IPlayerData pData = DataManager.getPlayerData(player);
if (packetFrequency.isEnabled(player, pData)) {
final NetConfig cc = pData.getGenericInstance(NetConfig.class);
final NetData data = pData.getGenericInstance(NetData.class);
if (packetFrequency.check(player, data, cc)) {
event.setCancelled(true);
}
}
}

View File

@ -21,6 +21,9 @@ import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.events.ListenerPriority;
import com.comphenix.protocol.events.PacketEvent;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.players.DataManager;
public class DebugAdapter extends BaseAdapter {
public DebugAdapter(Plugin plugin) {
@ -33,7 +36,7 @@ public class DebugAdapter extends BaseAdapter {
@Override
public void onPacketReceiving(PacketEvent event) {
final Player player = event.getPlayer();
if (dataFactory.getData(player).debug) {
if (DataManager.getPlayerData(player).isDebugActive(CheckType.NET)) {
debug(player, "packet: " + event.getPacketType());
}
}

View File

@ -24,13 +24,12 @@ import com.comphenix.protocol.events.ListenerPriority;
import com.comphenix.protocol.events.PacketEvent;
import fr.neatmonster.nocheatplus.NCPAPIProvider;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.net.KeepAliveFrequency;
import fr.neatmonster.nocheatplus.checks.net.NetConfig;
import fr.neatmonster.nocheatplus.checks.net.NetData;
import fr.neatmonster.nocheatplus.config.ConfPaths;
import fr.neatmonster.nocheatplus.config.ConfigManager;
import fr.neatmonster.nocheatplus.players.DataManager;
import fr.neatmonster.nocheatplus.players.PlayerData;
import fr.neatmonster.nocheatplus.players.IPlayerData;
/**
* Limit keep alive packet frequency, set lastKeepAliveTime (even if disabled,
@ -46,10 +45,12 @@ public class KeepAliveAdapter extends BaseAdapter {
public KeepAliveAdapter(Plugin plugin) {
super(plugin, ListenerPriority.LOW, PacketType.Play.Client.KEEP_ALIVE);
this.checkType = CheckType.NET_KEEPALIVEFREQUENCY;
// Add feature tags for checks.
if (ConfigManager.isTrueForAnyConfig(ConfPaths.NET_KEEPALIVEFREQUENCY_ACTIVE)) {
NCPAPIProvider.getNoCheatPlusAPI().addFeatureTags("checks", Arrays.asList(KeepAliveFrequency.class.getSimpleName()));
if (NCPAPIProvider.getNoCheatPlusAPI().getWorldDataManager().isActiveAnywhere(
CheckType.NET_KEEPALIVEFREQUENCY)) {
NCPAPIProvider.getNoCheatPlusAPI().addFeatureTags(
"checks", Arrays.asList(KeepAliveFrequency.class.getSimpleName()));
}
NCPAPIProvider.getNoCheatPlusAPI().addComponent(frequencyCheck);
}
@ -64,16 +65,17 @@ public class KeepAliveAdapter extends BaseAdapter {
return;
}
// Always update last received time.
final PlayerData pData = DataManager.getPlayerData(player);
final NetData data = dataFactory.getData(player);
final IPlayerData pData = DataManager.getPlayerData(player);
final NetData data = pData.getGenericInstance(NetData.class);
data.lastKeepAliveTime = time;
final NetConfig cc = configFactory.getConfig(player);
final NetConfig cc = pData.getGenericInstance(NetConfig.class);
// Run check(s).
// TODO: Match vs. outgoing keep alive requests.
// TODO: Better modeling of actual packet sequences (flying vs. keep alive vs. request/ping).
// TODO: Better integration with god-mode check / trigger reset ndt.
if (cc.keepAliveFrequencyActive && frequencyCheck.check(player, time, data, cc, pData)) {
if (frequencyCheck.isEnabled(player, pData)
&& frequencyCheck.check(player, time, data, cc, pData)) {
event.setCancelled(true);
}
}

View File

@ -33,6 +33,7 @@ import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.reflect.StructureModifier;
import fr.neatmonster.nocheatplus.NCPAPIProvider;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.net.FlyingFrequency;
import fr.neatmonster.nocheatplus.checks.net.NetConfig;
import fr.neatmonster.nocheatplus.checks.net.NetData;
@ -40,16 +41,16 @@ import fr.neatmonster.nocheatplus.checks.net.model.DataPacketFlying;
import fr.neatmonster.nocheatplus.checks.net.model.DataPacketFlying.PACKET_CONTENT;
import fr.neatmonster.nocheatplus.checks.net.model.TeleportQueue.AckReference;
import fr.neatmonster.nocheatplus.compat.AlmostBoolean;
import fr.neatmonster.nocheatplus.config.ConfPaths;
import fr.neatmonster.nocheatplus.config.ConfigManager;
import fr.neatmonster.nocheatplus.logging.StaticLog;
import fr.neatmonster.nocheatplus.logging.Streams;
import fr.neatmonster.nocheatplus.players.DataManager;
import fr.neatmonster.nocheatplus.players.PlayerData;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.time.monotonic.Monotonic;
import fr.neatmonster.nocheatplus.utilities.CheckUtils;
import fr.neatmonster.nocheatplus.utilities.StringUtil;
import fr.neatmonster.nocheatplus.utilities.ds.count.ActionFrequency;
import fr.neatmonster.nocheatplus.utilities.location.LocUtil;
import fr.neatmonster.nocheatplus.worlds.IWorldData;
/**
* Run checks related to moving (pos/look/flying). Skip packets that shouldn't
@ -110,10 +111,12 @@ public class MovingFlying extends BaseAdapter {
public MovingFlying(Plugin plugin) {
// PacketPlayInFlying[3, legacy: 10]
super(plugin, ListenerPriority.LOW, initPacketTypes());
// Keep the CheckType NET for now.
// Add feature tags for checks.
if (ConfigManager.isTrueForAnyConfig(ConfPaths.NET_FLYINGFREQUENCY_ACTIVE)) {
NCPAPIProvider.getNoCheatPlusAPI().addFeatureTags("checks", Arrays.asList(FlyingFrequency.class.getSimpleName()));
if (NCPAPIProvider.getNoCheatPlusAPI().getWorldDataManager().isActiveAnywhere(
CheckType.NET_FLYINGFREQUENCY)) {
NCPAPIProvider.getNoCheatPlusAPI().addFeatureTags(
"checks", Arrays.asList(FlyingFrequency.class.getSimpleName()));
}
NCPAPIProvider.getNoCheatPlusAPI().addComponent(flyingFrequency);
}
@ -155,12 +158,13 @@ public class MovingFlying extends BaseAdapter {
return;
}
final Player player = event.getPlayer();
final NetData data = dataFactory.getData(player);
final IPlayerData pData = DataManager.getPlayerData(player);
final NetData data = pData.getGenericInstance(NetData.class);
final AlmostBoolean matched = data.teleportQueue.processAck(teleportId);
if (matched.decideOptimistically()) {
CheckUtils.subtract(System.currentTimeMillis(), 1, data.flyingFrequencyAll);
ActionFrequency.subtract(System.currentTimeMillis(), 1, data.flyingFrequencyAll);
}
if (data.debug) {
if (pData.isDebugActive(this.checkType)) { // TODO: FlyingFrequency / NET_MOVING? + check others who depend
debug(player, "Confirm teleport packet" + (matched.decideOptimistically() ? (" (matched=" + matched + ")") : "") + ": " + teleportId);
}
}
@ -191,14 +195,17 @@ public class MovingFlying extends BaseAdapter {
return;
}
final NetConfig cc = configFactory.getConfig(player.getWorld());
final IPlayerData pData = DataManager.getPlayerData(player);
// Always update last received time.
final NetData data = dataFactory.getData(player);
final NetData data = pData.getGenericInstance(NetData.class);
data.lastKeepAliveTime = time; // Update without much of a contract.
// TODO: Leniency options too (packet order inversion). -> current: flyingQueue is fetched.
if (!cc.flyingFrequencyActive) {
final IWorldData worldData = pData.getCurrentWorldDataSafe();
if (!worldData.isCheckActive(CheckType.NET_FLYINGFREQUENCY)) {
return;
}
final NetConfig cc = pData.getGenericInstance(NetConfig.class);
boolean cancel = false;
// Interpret the packet content.
@ -211,14 +218,14 @@ public class MovingFlying extends BaseAdapter {
if (isInvalidContent(packetData)) {
// TODO: extra actions: log and kick (cancel state is not evaluated)
event.setCancelled(true);
if (data.debug) {
if (pData.isDebugActive(this.checkType)) {
debug(player, "Incoming packet, cancel due to malicious content: " + packetData.toString());
}
return;
}
switch(data.teleportQueue.processAck(packetData)) {
case WAITING: {
if (data.debug) {
if (pData.isDebugActive(this.checkType)) {
debug(player, "Incoming packet, still waiting for ACK on outgoing position.");
}
if (confirmTeleportType != null && cc.supersededFlyingCancelWaiting) {
@ -250,7 +257,7 @@ public class MovingFlying extends BaseAdapter {
case ACK: {
// Skip processing ACK packets, no cancel.
skipFlyingFrequency = true;
if (data.debug) {
if (pData.isDebugActive(this.checkType)) {
debug(player, "Incoming packet, interpret as ACK for outgoing position.");
}
}
@ -267,8 +274,8 @@ public class MovingFlying extends BaseAdapter {
// Actual packet frequency check.
// TODO: Consider using the NetStatic check.
final PlayerData pData = DataManager.getPlayerData(player);
if (!cancel && !skipFlyingFrequency
&& !pData.hasBypass(CheckType.NET_FLYINGFREQUENCY, player)
&& flyingFrequency.check(player, packetData, time, data, cc, pData)) {
cancel = true;
}
@ -285,7 +292,7 @@ public class MovingFlying extends BaseAdapter {
if (cancel) {
event.setCancelled(true);
}
if (data.debug) {
if (pData.isDebugActive(this.checkType)) {
debug(player, (packetData == null ? "(Incompatible data)" : packetData.toString()) + (event.isCancelled() ? " CANCEL" : ""));
}
}

View File

@ -24,9 +24,12 @@ import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.reflect.StructureModifier;
import fr.neatmonster.nocheatplus.NCPAPIProvider;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.net.NetData;
import fr.neatmonster.nocheatplus.checks.net.model.CountableLocation;
import fr.neatmonster.nocheatplus.logging.Streams;
import fr.neatmonster.nocheatplus.players.DataManager;
import fr.neatmonster.nocheatplus.players.IPlayerData;
public class OutgoingPosition extends BaseAdapter {
@ -37,7 +40,7 @@ public class OutgoingPosition extends BaseAdapter {
public static final int indexPitch = 1;
private final Integer ID_OUTGOING_POSITION_UNTRACKED = counters.registerKey("packet.outgoing_position.untracked");
private boolean hasTeleportId = true;
public OutgoingPosition(Plugin plugin) {
@ -55,12 +58,17 @@ public class OutgoingPosition extends BaseAdapter {
}
final long time = System.currentTimeMillis();
final Player player = event.getPlayer();
if (configFactory.getConfig(player).flyingFrequencyActive) {
interpretPacket(player, event.getPacket(), time, dataFactory.getData(player));
final IPlayerData pData = DataManager.getPlayerData(player);
// TODO: In future multiple checks might use this (!)
if (pData.isCheckActive(CheckType.NET_FLYINGFREQUENCY, player)) {
interpretPacket(player, event.getPacket(), time,
pData.getGenericInstance(NetData.class),
pData.isDebugActive(CheckType.NET_FLYINGFREQUENCY));
}
}
private void interpretPacket(final Player player, final PacketContainer packet, final long time, final NetData data) {
private void interpretPacket(final Player player, final PacketContainer packet,
final long time, final NetData data, final boolean debug) {
final StructureModifier<Double> doubles = packet.getDoubles();
final StructureModifier<Float> floats = packet.getFloat();
@ -78,7 +86,7 @@ public class OutgoingPosition extends BaseAdapter {
final float yaw = floats.read(indexYaw);
final float pitch = floats.read(indexPitch);
Integer teleportId = Integer.MIN_VALUE;
if (hasTeleportId) {
try {
final StructureModifier<Integer> integers = packet.getIntegers();
@ -88,7 +96,7 @@ public class OutgoingPosition extends BaseAdapter {
if (teleportId == null) {
teleportId = Integer.MIN_VALUE;
}
if (teleportId != Integer.MIN_VALUE && data.debug) {
if (teleportId != Integer.MIN_VALUE && debug) {
debug(player, "Outgoing confirm teleport id: " + teleportId);
}
}
@ -108,12 +116,12 @@ public class OutgoingPosition extends BaseAdapter {
// Add counter for untracked (by Bukkit API) outgoing teleport.
// TODO: There may be other cases which are indicated by Bukkit API events.
counters.add(ID_OUTGOING_POSITION_UNTRACKED, 1);
if (data.debug) {
if (debug) {
debug(player, "Untracked outgoing position: " + x + ", " + y + ", " + z + " (yaw=" + yaw + ", pitch=" + pitch + ").");
}
}
else {
if (data.debug) {
if (debug) {
debug(player, "Expect ACK on outgoing position: " + packetData);
}
}

View File

@ -37,10 +37,7 @@ import com.comphenix.protocol.events.PacketAdapter;
import fr.neatmonster.nocheatplus.NCPAPIProvider;
import fr.neatmonster.nocheatplus.checks.CheckType;
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.compat.versions.ServerVersion;
import fr.neatmonster.nocheatplus.components.NoCheatPlusAPI;
import fr.neatmonster.nocheatplus.components.registry.feature.IDisableListener;
@ -50,8 +47,11 @@ import fr.neatmonster.nocheatplus.config.ConfPaths;
import fr.neatmonster.nocheatplus.config.ConfigManager;
import fr.neatmonster.nocheatplus.logging.StaticLog;
import fr.neatmonster.nocheatplus.logging.Streams;
import fr.neatmonster.nocheatplus.players.DataManager;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.stats.Counters;
import fr.neatmonster.nocheatplus.utilities.StringUtil;
import fr.neatmonster.nocheatplus.worlds.IWorldDataManager;
/**
* Quick and dirty ProtocolLib setup.
@ -89,15 +89,17 @@ public class ProtocolLibComponent implements IDisableListener, INotifyReload, Jo
private final List<PacketAdapter> registeredPacketAdapters = new LinkedList<PacketAdapter>();
protected final NetConfigCache configFactory = (NetConfigCache) CheckType.NET.getConfigFactory();
protected final NetDataFactory dataFactory = (NetDataFactory) CheckType.NET.getDataFactory();
public ProtocolLibComponent(Plugin plugin) {
register(plugin);
/*
* TODO: Register listeners iff any check is enabled - unregister from
* EventRegistry with unregister.
*/
}
private void register(Plugin plugin) {
StaticLog.logInfo("Adding packet level hooks for ProtocolLib (MC " + ProtocolLibrary.getProtocolManager().getMinecraftVersion().getVersion() + ")...");
final IWorldDataManager worldMan = NCPAPIProvider.getNoCheatPlusAPI().getWorldDataManager();
//Special purpose.
if (ConfigManager.isTrueForAnyConfig(ConfPaths.NET + ConfPaths.SUB_DEBUG) || ConfigManager.isTrueForAnyConfig(ConfPaths.CHECKS_DEBUG) ) {
// (Debug logging. Only activates if debug is set for checks or checks.net, not on the fly.)
@ -108,25 +110,29 @@ public class ProtocolLibComponent implements IDisableListener, INotifyReload, Jo
// Don't use this listener.
NCPAPIProvider.getNoCheatPlusAPI().getLogManager().info(Streams.STATUS, "Disable EntityUseAdapter due to incompatibilities. Use fight.speed instead of net.attackfrequency.");
}
else if (ConfigManager.isTrueForAnyConfig(ConfPaths.NET_ATTACKFREQUENCY_ACTIVE)) {
else if (worldMan.isActiveAnywhere(CheckType.NET_ATTACKFREQUENCY)) {
// (Also sets lastKeepAliveTime, if enabled.)
register("fr.neatmonster.nocheatplus.checks.net.protocollib.UseEntityAdapter", plugin);
}
if (ConfigManager.isTrueForAnyConfig(ConfPaths.NET_FLYINGFREQUENCY_ACTIVE)) {
if (worldMan.isActiveAnywhere(CheckType.NET_FLYINGFREQUENCY)) {
// (Also sets lastKeepAliveTime, if enabled.)
register("fr.neatmonster.nocheatplus.checks.net.protocollib.MovingFlying", plugin);
register("fr.neatmonster.nocheatplus.checks.net.protocollib.OutgoingPosition", plugin);
}
if (ConfigManager.isTrueForAnyConfig(ConfPaths.NET_KEEPALIVEFREQUENCY_ACTIVE) || ConfigManager.isTrueForAnyConfig(ConfPaths.FIGHT_GODMODE_CHECK)) {
if (worldMan.isActiveAnywhere(CheckType.NET_KEEPALIVEFREQUENCY)
|| worldMan.isActiveAnywhere(CheckType.FIGHT_GODMODE)) {
// (Set lastKeepAlive if this or fight.godmode is enabled.)
register("fr.neatmonster.nocheatplus.checks.net.protocollib.KeepAliveAdapter", plugin);
}
if (ConfigManager.isTrueForAnyConfig(ConfPaths.NET_SOUNDDISTANCE_ACTIVE)) {
if (worldMan.isActiveAnywhere(CheckType.NET_SOUNDDISTANCE)) {
register("fr.neatmonster.nocheatplus.checks.net.protocollib.SoundDistance", plugin);
}
if (ConfigManager.isAlmostTrueForAnyConfig(ConfPaths.NET_PACKETFREQUENCY_ACTIVE, ServerVersion.compareMinecraftVersion("1.9") < 0, false)) {
register("fr.neatmonster.nocheatplus.checks.net.protocollib.CatchAllAdapter", plugin);
if (ServerVersion.compareMinecraftVersion("1.9") < 0) {
if (worldMan.isActiveAnywhere(CheckType.NET_PACKETFREQUENCY)) {
register("fr.neatmonster.nocheatplus.checks.net.protocollib.CatchAllAdapter", plugin);
}
}
if (!registeredPacketAdapters.isEmpty()) {
List<String> names = new ArrayList<String>(registeredPacketAdapters.size());
for (PacketAdapter adapter : registeredPacketAdapters) {
@ -178,8 +184,8 @@ public class ProtocolLibComponent implements IDisableListener, INotifyReload, Jo
@Override
public void onReload() {
unregister();
CheckType.NET.getDataFactory().removeAllData(); // Currently needed for FlyingFrequency.
register(Bukkit.getPluginManager().getPlugin("NoCheatPlus")); // Store instead ?
NCPAPIProvider.getNoCheatPlusAPI().getPlayerDataManager().removeGenericInstance(NetData.class); // Currently needed for FlyingFrequency.
register(Bukkit.getPluginManager().getPlugin("NoCheatPlus")); // TODO: static plugin getter?
}
private void unregister() {
@ -200,14 +206,14 @@ public class ProtocolLibComponent implements IDisableListener, INotifyReload, Jo
@Override
public void playerJoins(final Player player) {
if (!registeredPacketAdapters.isEmpty()) {
dataFactory.getData(player).onJoin(player);
DataManager.getGenericInstance(player, NetData.class).onJoin(player);
}
}
@Override
public void playerLeaves(final Player player) {
if (!registeredPacketAdapters.isEmpty()) {
dataFactory.getData(player).onLeave(player);
DataManager.getGenericInstance(player, NetData.class).onLeave(player);
}
}
@ -215,7 +221,7 @@ public class ProtocolLibComponent implements IDisableListener, INotifyReload, Jo
public void onPlayerRespawn(final PlayerRespawnEvent event) {
if (!registeredPacketAdapters.isEmpty()) {
final Player player = event.getPlayer();
final NetData data = dataFactory.getData(player);
final NetData data = DataManager.getGenericInstance(player, NetData.class);
data.onJoin(player);
final Location loc = event.getRespawnLocation();
data.teleportQueue.onTeleportEvent(loc.getX(), loc.getY(), loc.getZ(), loc.getYaw(), loc.getPitch());
@ -232,9 +238,9 @@ public class ProtocolLibComponent implements IDisableListener, INotifyReload, Jo
return;
}
final Player player = event.getPlayer();
final NetConfig cc = configFactory.getConfig(player);
final NetData data = dataFactory.getData(player);
if (cc.flyingFrequencyActive) {
final IPlayerData pData = DataManager.getPlayerData(player);
final NetData data = pData.getGenericInstance(NetData.class);
if (pData.isCheckActive(CheckType.NET_FLYINGFREQUENCY, player)) {
// Register expected location for comparison with outgoing packets.
data.teleportQueue.onTeleportEvent(to.getX(), to.getY(), to.getZ(), to.getYaw(), to.getPitch());
}

View File

@ -33,8 +33,9 @@ import com.comphenix.protocol.reflect.StructureModifier;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.net.NetConfig;
import fr.neatmonster.nocheatplus.checks.net.NetConfigCache;
import fr.neatmonster.nocheatplus.compat.versions.ServerVersion;
import fr.neatmonster.nocheatplus.players.DataManager;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.utilities.location.TrigUtil;
public class SoundDistance extends BaseAdapter {
@ -92,14 +93,12 @@ public class SoundDistance extends BaseAdapter {
));
private final Integer idSoundEffectCancel = counters.registerKey("packet.sound.cancel");
private final NetConfigCache configs;
private final Location useLoc = new Location(null, 0, 0, 0);
/** Legacy check behavior. */
private final boolean pre1_9;
public SoundDistance(Plugin plugin) {
super(plugin, ListenerPriority.LOW, PacketType.Play.Server.NAMED_SOUND_EFFECT);
this.configs = (NetConfigCache) CheckType.NET.getConfigFactory(); // TODO: DataManager.getConfig(NetConfigCache.class);
this.checkType = CheckType.NET_SOUNDDISTANCE;
pre1_9 = ServerVersion.compareMinecraftVersion("1.9") < 0;
inflateEffectNames();
@ -151,8 +150,8 @@ public class SoundDistance extends BaseAdapter {
}
final Player player = event.getPlayer();
final NetConfig cc = configs.getConfig(player.getWorld());
if (!cc.soundDistanceActive) {
final IPlayerData pData = DataManager.getPlayerData(player);
if (!pData.isCheckActive(CheckType.NET_SOUNDDISTANCE, player)) {
return;
}
@ -163,6 +162,7 @@ public class SoundDistance extends BaseAdapter {
// if (data.debug) {
// debug(player, "SoundDistance(" + soundName + "): " + StringUtil.fdec1.format(Math.sqrt(dSq)));
// }
final NetConfig cc = pData.getGenericInstance(NetConfig.class);
if (dSq > cc.soundDistanceSq) {
event.setCancelled(true);
counters.add(idSoundEffectCancel, 1);

View File

@ -27,13 +27,12 @@ import com.comphenix.protocol.reflect.StructureModifier;
import com.comphenix.protocol.wrappers.EnumWrappers.EntityUseAction;
import fr.neatmonster.nocheatplus.NCPAPIProvider;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.net.AttackFrequency;
import fr.neatmonster.nocheatplus.checks.net.NetConfig;
import fr.neatmonster.nocheatplus.checks.net.NetData;
import fr.neatmonster.nocheatplus.config.ConfPaths;
import fr.neatmonster.nocheatplus.config.ConfigManager;
import fr.neatmonster.nocheatplus.players.DataManager;
import fr.neatmonster.nocheatplus.players.PlayerData;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.utilities.ReflectionUtil;
public class UseEntityAdapter extends BaseAdapter {
@ -100,10 +99,12 @@ public class UseEntityAdapter extends BaseAdapter {
public UseEntityAdapter(Plugin plugin) {
super(plugin, PacketType.Play.Client.USE_ENTITY);
this.checkType = CheckType.NET_ATTACKFREQUENCY;
// Add feature tags for checks.
if (ConfigManager.isTrueForAnyConfig(ConfPaths.NET_ATTACKFREQUENCY_ACTIVE)) {
NCPAPIProvider.getNoCheatPlusAPI().addFeatureTags("checks", Arrays.asList(AttackFrequency.class.getSimpleName()));
if (NCPAPIProvider.getNoCheatPlusAPI().getWorldDataManager().isActiveAnywhere(
CheckType.NET_ATTACKFREQUENCY)) {
NCPAPIProvider.getNoCheatPlusAPI().addFeatureTags(
"checks", Arrays.asList(AttackFrequency.class.getSimpleName()));
}
attackFrequency = new AttackFrequency();
@ -129,14 +130,14 @@ public class UseEntityAdapter extends BaseAdapter {
// TODO: Warn once?
return;
}
final NetConfig cc = configFactory.getConfig(player);
final NetData data = dataFactory.getData(player);
final IPlayerData pData = DataManager.getPlayerData(player);
final NetData data = pData.getGenericInstance(NetData.class);
// Always set last received time.
data.lastKeepAliveTime = time;
// Quick return, if no checks are active.
if (!cc.attackFrequencyActive) {
if (!pData.isCheckActive(CheckType.NET_ATTACKFREQUENCY, player)) {
return;
}
@ -174,8 +175,9 @@ public class UseEntityAdapter extends BaseAdapter {
// AttackFrequency
if (isAttack) {
final PlayerData pData = DataManager.getPlayerData(player);
if (attackFrequency.isEnabled(player, cc, pData) && attackFrequency.check(player, time, data, cc)) {
final NetConfig cc = pData.getGenericInstance(NetConfig.class);
if (attackFrequency.isEnabled(player, pData)
&& attackFrequency.check(player, time, data, cc, pData)) {
cancel = true;
}
}

View File

@ -23,16 +23,16 @@ import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.NCPAPIProvider;
import fr.neatmonster.nocheatplus.actions.ActionList;
import fr.neatmonster.nocheatplus.actions.types.penalty.IPenaltyList;
import fr.neatmonster.nocheatplus.checks.access.ICheckConfig;
import fr.neatmonster.nocheatplus.compat.MCAccess;
import fr.neatmonster.nocheatplus.components.debug.IDebugPlayer;
import fr.neatmonster.nocheatplus.components.registry.event.IGenericInstanceHandle;
import fr.neatmonster.nocheatplus.hooks.NCPHookManager;
import fr.neatmonster.nocheatplus.players.DataManager;
import fr.neatmonster.nocheatplus.players.ExecutionHistory;
import fr.neatmonster.nocheatplus.players.PlayerData;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.utilities.CheckUtils;
import fr.neatmonster.nocheatplus.utilities.TickTask;
import fr.neatmonster.nocheatplus.worlds.IWorldData;
/**
* The parent class of all checks. Don't let this implement Listener without
@ -71,6 +71,7 @@ import fr.neatmonster.nocheatplus.utilities.TickTask;
* actual check.</li>
*
*/
// TODO: javadocs redo (above)
public abstract class Check implements IDebugPlayer {
// TODO: Do these get cleaned up ?
@ -102,6 +103,7 @@ public abstract class Check implements IDebugPlayer {
* @param type
* the type
*/
@SuppressWarnings("deprecation")
public Check(final CheckType type) {
this.type = type;
mcAccess = NCPAPIProvider.getNoCheatPlusAPI().getGenericInstanceHandle(MCAccess.class);
@ -185,51 +187,38 @@ public abstract class Check implements IDebugPlayer {
}
/**
* Checks both configuration flags and if the player is exempted from this
* check (hasBypass). Intended for higher efficiency with multiple calls.
* Full activation check (configuration, exemption, permission).
*
* @param player
* @param data
* @param cc
* @param worldData
* @return
*/
public boolean isEnabled(final Player player, final ICheckConfig cc, final PlayerData pData) {
return cc.isEnabled(type) && !CheckUtils.hasBypass(type, player, pData);
public boolean isEnabled(final Player player, final IPlayerData pData,
final IWorldData worldData) {
return pData.isCheckActive(type, player, worldData);
}
/**
* Checks both configuration flags and if the player is exempted from this
* check (hasBypass). Intended for higher efficiency with multiple calls.
* Full activation check (configuration, exemption, permission).
*
* @param player
* @param cc
* @param data
* @return
*/
public boolean isEnabled(final Player player, final ICheckConfig cc) {
return cc.isEnabled(type) && !CheckUtils.hasBypass(type, player, DataManager.getPlayerData(player));
public boolean isEnabled(final Player player, final IPlayerData pData) {
return pData.isCheckActive(type, player);
}
/**
* Checks both configuration flags and if the player is exempted from this
* check (hasBypass).
* Full activation check (configuration, exemption, permission).
*
* @param player
* the player
* @return true, if the check is enabled
*/
public boolean isEnabled(final Player player) {
return type.isEnabled(player) && !CheckUtils.hasBypass(type, player, DataManager.getPlayerData(player));
}
/**
* Check if the player is exempted by permissions or otherwise.<br>
*
*
* @param player
* @return
*/
public boolean hasBypass(final Player player) {
return CheckUtils.hasBypass(type, player, DataManager.getPlayerData(player));
return isEnabled(player, DataManager.getPlayerData(player));
}
@Override

View File

@ -14,28 +14,7 @@
*/
package fr.neatmonster.nocheatplus.checks;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.checks.access.CheckConfigFactory;
import fr.neatmonster.nocheatplus.checks.access.CheckDataFactory;
import fr.neatmonster.nocheatplus.checks.blockbreak.BlockBreakConfig;
import fr.neatmonster.nocheatplus.checks.blockbreak.BlockBreakData;
import fr.neatmonster.nocheatplus.checks.blockinteract.BlockInteractConfig;
import fr.neatmonster.nocheatplus.checks.blockinteract.BlockInteractData;
import fr.neatmonster.nocheatplus.checks.blockplace.BlockPlaceConfig;
import fr.neatmonster.nocheatplus.checks.blockplace.BlockPlaceData;
import fr.neatmonster.nocheatplus.checks.chat.ChatConfig;
import fr.neatmonster.nocheatplus.checks.chat.ChatData;
import fr.neatmonster.nocheatplus.checks.combined.CombinedConfig;
import fr.neatmonster.nocheatplus.checks.combined.CombinedData;
import fr.neatmonster.nocheatplus.checks.fight.FightConfig;
import fr.neatmonster.nocheatplus.checks.fight.FightData;
import fr.neatmonster.nocheatplus.checks.inventory.InventoryConfig;
import fr.neatmonster.nocheatplus.checks.inventory.InventoryData;
import fr.neatmonster.nocheatplus.checks.moving.MovingConfig;
import fr.neatmonster.nocheatplus.checks.moving.MovingData;
import fr.neatmonster.nocheatplus.checks.net.NetConfigCache;
import fr.neatmonster.nocheatplus.checks.net.NetDataFactory;
import fr.neatmonster.nocheatplus.config.ConfPaths;
import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.permissions.RegisteredPermission;
@ -46,86 +25,88 @@ import fr.neatmonster.nocheatplus.permissions.RegisteredPermission;
public enum CheckType {
ALL(Permissions.CHECKS),
BLOCKBREAK(CheckType.ALL, BlockBreakConfig.factory, BlockBreakData.factory, Permissions.BLOCKBREAK),
/** This will allow breaking all special blocks, currently only liquid. Later there might be more sub-types. */
BLOCKBREAK_BREAK(BLOCKBREAK, Permissions.BLOCKBREAK_BREAK),
BLOCKBREAK_DIRECTION(BLOCKBREAK, Permissions.BLOCKBREAK_DIRECTION),
BLOCKBREAK_FASTBREAK(BLOCKBREAK, Permissions.BLOCKBREAK_FASTBREAK),
BLOCKBREAK_FREQUENCY(BLOCKBREAK, Permissions.BLOCKBREAK_FREQUENCY),
BLOCKBREAK_NOSWING(BLOCKBREAK, Permissions.BLOCKBREAK_NOSWING),
BLOCKBREAK_REACH(BLOCKBREAK, Permissions.BLOCKBREAK_REACH),
BLOCKBREAK_WRONGBLOCK(BLOCKBREAK, Permissions.BLOCKBREAK_WRONGBLOCK),
BLOCKBREAK(CheckTypeType.GROUP, CheckType.ALL, Permissions.BLOCKBREAK),
/**
* This will allow breaking all special blocks, currently only liquid. Later
* there might be more sub-types.
*/
BLOCKBREAK_BREAK(CheckTypeType.CHECK, BLOCKBREAK, Permissions.BLOCKBREAK_BREAK),
BLOCKBREAK_DIRECTION(CheckTypeType.CHECK, BLOCKBREAK, Permissions.BLOCKBREAK_DIRECTION),
BLOCKBREAK_FASTBREAK(CheckTypeType.CHECK, BLOCKBREAK, Permissions.BLOCKBREAK_FASTBREAK),
BLOCKBREAK_FREQUENCY(CheckTypeType.CHECK, BLOCKBREAK, Permissions.BLOCKBREAK_FREQUENCY),
BLOCKBREAK_NOSWING(CheckTypeType.CHECK, BLOCKBREAK, Permissions.BLOCKBREAK_NOSWING),
BLOCKBREAK_REACH(CheckTypeType.CHECK, BLOCKBREAK, Permissions.BLOCKBREAK_REACH),
BLOCKBREAK_WRONGBLOCK(CheckTypeType.CHECK, BLOCKBREAK, Permissions.BLOCKBREAK_WRONGBLOCK),
BLOCKINTERACT(CheckType.ALL, BlockInteractConfig.factory, BlockInteractData.factory, Permissions.BLOCKINTERACT),
BLOCKINTERACT_DIRECTION(BLOCKINTERACT, Permissions.BLOCKINTERACT_DIRECTION),
BLOCKINTERACT_REACH(BLOCKINTERACT, Permissions.BLOCKINTERACT_REACH),
BLOCKINTERACT_SPEED(BLOCKINTERACT, Permissions.BLOCKINTERACT_SPEED),
BLOCKINTERACT_VISIBLE(BLOCKINTERACT, Permissions.BLOCKINTERACT_VISIBLE),
BLOCKINTERACT(CheckTypeType.GROUP, CheckType.ALL, Permissions.BLOCKINTERACT),
BLOCKINTERACT_DIRECTION(CheckTypeType.CHECK, BLOCKINTERACT, Permissions.BLOCKINTERACT_DIRECTION),
BLOCKINTERACT_REACH(CheckTypeType.CHECK, BLOCKINTERACT, Permissions.BLOCKINTERACT_REACH),
BLOCKINTERACT_SPEED(CheckTypeType.CHECK, BLOCKINTERACT, Permissions.BLOCKINTERACT_SPEED),
BLOCKINTERACT_VISIBLE(CheckTypeType.CHECK, BLOCKINTERACT, Permissions.BLOCKINTERACT_VISIBLE),
BLOCKPLACE(CheckType.ALL, BlockPlaceConfig.factory, BlockPlaceData.factory, Permissions.BLOCKPLACE),
BLOCKPLACE_AGAINST(BLOCKPLACE, Permissions.BLOCKPLACE_AGAINST),
BLOCKPLACE_AUTOSIGN(BLOCKPLACE, Permissions.BLOCKPLACE_AUTOSIGN),
BLOCKPLACE_DIRECTION(BLOCKPLACE, Permissions.BLOCKPLACE_DIRECTION),
BLOCKPLACE_FASTPLACE(BLOCKPLACE, Permissions.BLOCKPLACE_FASTPLACE),
BLOCKPLACE_NOSWING(BLOCKPLACE, Permissions.BLOCKPLACE_NOSWING),
BLOCKPLACE_REACH(BLOCKPLACE, Permissions.BLOCKBREAK_REACH),
BLOCKPLACE_SPEED(BLOCKPLACE, Permissions.BLOCKPLACE_SPEED),
BLOCKPLACE(CheckTypeType.GROUP, CheckType.ALL, Permissions.BLOCKPLACE),
BLOCKPLACE_AGAINST(CheckTypeType.CHECK, BLOCKPLACE, Permissions.BLOCKPLACE_AGAINST),
BLOCKPLACE_AUTOSIGN(CheckTypeType.CHECK, BLOCKPLACE, Permissions.BLOCKPLACE_AUTOSIGN),
BLOCKPLACE_DIRECTION(CheckTypeType.CHECK, BLOCKPLACE, Permissions.BLOCKPLACE_DIRECTION),
BLOCKPLACE_FASTPLACE(CheckTypeType.CHECK, BLOCKPLACE, Permissions.BLOCKPLACE_FASTPLACE),
BLOCKPLACE_NOSWING(CheckTypeType.CHECK, BLOCKPLACE, Permissions.BLOCKPLACE_NOSWING),
BLOCKPLACE_REACH(CheckTypeType.CHECK, BLOCKPLACE, Permissions.BLOCKBREAK_REACH),
BLOCKPLACE_SPEED(CheckTypeType.CHECK, BLOCKPLACE, Permissions.BLOCKPLACE_SPEED),
CHAT(CheckType.ALL, ChatConfig.factory, ChatData.factory, Permissions.CHAT),
CHAT_CAPTCHA(CHAT, Permissions.CHAT_CAPTCHA),
CHAT_COLOR(CHAT, Permissions.CHAT_COLOR),
CHAT_COMMANDS(CHAT, Permissions.CHAT_COMMANDS),
CHAT_TEXT(CHAT, Permissions.CHAT_TEXT),
CHAT_LOGINS(CHAT, Permissions.CHAT_LOGINS),
CHAT_RELOG(CHAT, Permissions.CHAT_RELOG),
CHAT(CheckTypeType.GROUP, CheckType.ALL, Permissions.CHAT),
CHAT_CAPTCHA(CheckTypeType.CHECK, CHAT, Permissions.CHAT_CAPTCHA),
CHAT_COLOR(CheckTypeType.CHECK, CHAT, Permissions.CHAT_COLOR),
CHAT_COMMANDS(CheckTypeType.CHECK, CHAT, Permissions.CHAT_COMMANDS),
CHAT_TEXT(CheckTypeType.CHECK, CHAT, Permissions.CHAT_TEXT),
CHAT_LOGINS(CheckTypeType.CHECK, CHAT, Permissions.CHAT_LOGINS),
CHAT_RELOG(CheckTypeType.CHECK, CHAT, Permissions.CHAT_RELOG),
COMBINED(CheckType.ALL, CombinedConfig.factory, CombinedData.factory, Permissions.COMBINED),
COMBINED_BEDLEAVE(COMBINED, Permissions.COMBINED_BEDLEAVE),
COMBINED_IMPROBABLE(COMBINED, Permissions.COMBINED_IMPROBABLE),
COMBINED_MUNCHHAUSEN(COMBINED, Permissions.COMBINED_MUNCHHAUSEN),
COMBINED(CheckTypeType.GROUP, CheckType.ALL, Permissions.COMBINED),
COMBINED_BEDLEAVE(CheckTypeType.CHECK, COMBINED, Permissions.COMBINED_BEDLEAVE),
COMBINED_IMPROBABLE(CheckTypeType.CHECK, COMBINED, Permissions.COMBINED_IMPROBABLE),
COMBINED_MUNCHHAUSEN(CheckTypeType.CHECK, COMBINED, Permissions.COMBINED_MUNCHHAUSEN),
/** Rather for data removal and exemption. */
COMBINED_YAWRATE(COMBINED),
COMBINED_YAWRATE(CheckTypeType.CHECK, COMBINED),
FIGHT(CheckType.ALL, FightConfig.factory, FightData.factory, Permissions.FIGHT),
FIGHT_ANGLE(FIGHT, Permissions.FIGHT_ANGLE),
FIGHT_CRITICAL(FIGHT, Permissions.FIGHT_CRITICAL),
FIGHT_DIRECTION(FIGHT, Permissions.FIGHT_DIRECTION),
FIGHT_FASTHEAL(FIGHT, Permissions.FIGHT_FASTHEAL),
FIGHT_GODMODE(FIGHT, Permissions.FIGHT_GODMODE),
FIGHT_NOSWING(FIGHT, Permissions.FIGHT_NOSWING),
FIGHT_REACH(FIGHT, Permissions.FIGHT_REACH),
FIGHT_SELFHIT(CheckTypeType.CHECK, FIGHT, Permissions.FIGHT_SELFHIT,
FightConfig.factory, FightData.selfHitDataFactory),
FIGHT_SPEED(FIGHT, Permissions.FIGHT_SPEED),
FIGHT_WRONGTURN(FIGHT, null),
FIGHT(CheckTypeType.CHECK, CheckType.ALL, Permissions.FIGHT),
FIGHT_ANGLE(CheckTypeType.CHECK, FIGHT, Permissions.FIGHT_ANGLE),
FIGHT_CRITICAL(CheckTypeType.CHECK, FIGHT, Permissions.FIGHT_CRITICAL),
FIGHT_DIRECTION(CheckTypeType.CHECK, FIGHT, Permissions.FIGHT_DIRECTION),
FIGHT_FASTHEAL(CheckTypeType.CHECK, FIGHT, Permissions.FIGHT_FASTHEAL),
FIGHT_GODMODE(CheckTypeType.CHECK, FIGHT, Permissions.FIGHT_GODMODE),
FIGHT_NOSWING(CheckTypeType.CHECK, FIGHT, Permissions.FIGHT_NOSWING),
FIGHT_REACH(CheckTypeType.CHECK, FIGHT, Permissions.FIGHT_REACH),
FIGHT_SELFHIT(CheckTypeType.CHECK, FIGHT, Permissions.FIGHT_SELFHIT),
FIGHT_SPEED(CheckTypeType.CHECK, FIGHT, Permissions.FIGHT_SPEED),
FIGHT_WRONGTURN(CheckTypeType.CHECK, FIGHT, null),
INVENTORY(CheckType.ALL, InventoryConfig.factory, InventoryData.factory, Permissions.INVENTORY),
INVENTORY_DROP(INVENTORY, Permissions.INVENTORY_DROP),
INVENTORY_FASTCLICK(INVENTORY, Permissions.INVENTORY_FASTCLICK),
INVENTORY_FASTCONSUME(INVENTORY, Permissions.INVENTORY_FASTCONSUME),
INVENTORY_GUTENBERG(INVENTORY, Permissions.INVENTORY_GUTENBERG),
INVENTORY_INSTANTBOW(INVENTORY, Permissions.INVENTORY_INSTANTBOW),
INVENTORY_INSTANTEAT(INVENTORY, Permissions.INVENTORY_INSTANTEAT),
INVENTORY_ITEMS(INVENTORY, Permissions.INVENTORY_ITEMS),
INVENTORY_OPEN(INVENTORY, Permissions.INVENTORY_OPEN),
INVENTORY(CheckTypeType.GROUP, CheckType.ALL, Permissions.INVENTORY),
INVENTORY_DROP(CheckTypeType.CHECK, INVENTORY, Permissions.INVENTORY_DROP),
INVENTORY_FASTCLICK(CheckTypeType.CHECK, INVENTORY, Permissions.INVENTORY_FASTCLICK),
INVENTORY_FASTCONSUME(CheckTypeType.CHECK, INVENTORY, Permissions.INVENTORY_FASTCONSUME),
INVENTORY_GUTENBERG(CheckTypeType.CHECK, INVENTORY, Permissions.INVENTORY_GUTENBERG),
INVENTORY_INSTANTBOW(CheckTypeType.CHECK, INVENTORY, Permissions.INVENTORY_INSTANTBOW),
INVENTORY_INSTANTEAT(CheckTypeType.CHECK, INVENTORY, Permissions.INVENTORY_INSTANTEAT),
INVENTORY_ITEMS(CheckTypeType.CHECK, INVENTORY, Permissions.INVENTORY_ITEMS),
INVENTORY_OPEN(CheckTypeType.CHECK, INVENTORY, Permissions.INVENTORY_OPEN),
MOVING(CheckType.ALL, MovingConfig.factory, MovingData.factory, Permissions.MOVING),
MOVING_CREATIVEFLY(MOVING, Permissions.MOVING_CREATIVEFLY),
MOVING_MOREPACKETS(MOVING, Permissions.MOVING_MOREPACKETS),
MOVING_NOFALL(MOVING, Permissions.MOVING_NOFALL),
MOVING_PASSABLE(MOVING, Permissions.MOVING_PASSABLE),
MOVING_SURVIVALFLY(MOVING, Permissions.MOVING_SURVIVALFLY),
MOVING_VEHICLE(MOVING, Permissions.MOVING_VEHICLE),
MOVING_VEHICLE_MOREPACKETS(MOVING_VEHICLE, Permissions.MOVING_VEHICLE_MOREPACKETS),
MOVING_VEHICLE_ENVELOPE(MOVING_VEHICLE, Permissions.MOVING_VEHICLE_ENVELOPE),
MOVING(CheckTypeType.GROUP, CheckType.ALL, Permissions.MOVING),
MOVING_CREATIVEFLY(CheckTypeType.CHECK, MOVING, Permissions.MOVING_CREATIVEFLY),
MOVING_MOREPACKETS(CheckTypeType.CHECK, MOVING, Permissions.MOVING_MOREPACKETS),
MOVING_NOFALL(CheckTypeType.CHECK, MOVING, Permissions.MOVING_NOFALL),
MOVING_PASSABLE(CheckTypeType.CHECK, MOVING, Permissions.MOVING_PASSABLE),
MOVING_SURVIVALFLY(CheckTypeType.CHECK, MOVING, Permissions.MOVING_SURVIVALFLY),
MOVING_VEHICLE(CheckTypeType.GROUP, MOVING, Permissions.MOVING_VEHICLE),
MOVING_VEHICLE_MOREPACKETS(CheckTypeType.CHECK, MOVING_VEHICLE, Permissions.MOVING_VEHICLE_MOREPACKETS),
MOVING_VEHICLE_ENVELOPE(CheckTypeType.CHECK, MOVING_VEHICLE, Permissions.MOVING_VEHICLE_ENVELOPE),
NET(CheckType.ALL, new NetConfigCache(), new NetDataFactory(), Permissions.NET),
NET_ATTACKFREQUENCY(NET, Permissions.NET_ATTACKFREQUENCY),
NET_FLYINGFREQUENCY(NET, Permissions.NET_FLYINGFREQUENCY),
NET_KEEPALIVEFREQUENCY(NET, Permissions.NET_KEEPALIVEFREQUENCY),
NET_PACKETFREQUENCY(NET, Permissions.NET_PACKETFREQUENCY),
NET_SOUNDDISTANCE(NET), // Can not exempt players from this one.
NET(CheckTypeType.GROUP, CheckType.ALL, Permissions.NET),
NET_ATTACKFREQUENCY(CheckTypeType.CHECK, NET, Permissions.NET_ATTACKFREQUENCY),
NET_FLYINGFREQUENCY(CheckTypeType.CHECK, NET, Permissions.NET_FLYINGFREQUENCY),
NET_KEEPALIVEFREQUENCY(CheckTypeType.CHECK, NET, Permissions.NET_KEEPALIVEFREQUENCY),
NET_PACKETFREQUENCY(CheckTypeType.CHECK, NET, Permissions.NET_PACKETFREQUENCY),
NET_SOUNDDISTANCE(CheckTypeType.CHECK, NET), // Can not exempt players from this one.
;
@ -144,56 +125,36 @@ public enum CheckType {
/** If not null, this is the check group usually. */
private final CheckType parent;
/** The check config factory (access CheckConfig instances by CheckType). */
private final CheckConfigFactory configFactory;
/** The check data factory (access CheckData instances by CheckType). */
private final CheckDataFactory dataFactory;
/** The bypass permission. */
private final RegisteredPermission permission;
/** Configuration path for the active flag. */
private final String configPathActive;
/** Configuration path for the debug flag. */
private final String configPathDebug;
/** Configuration path for the lag flag. */
private final String configPathLag;
/**
* Special purpose for grouping (ALL).
*
* @param permission
*/
private CheckType(final RegisteredPermission permission){
this(CheckTypeType.SPECIAL, null, permission, null, null);
// TODO: Might as well interpret as GROUP.
this(CheckTypeType.SPECIAL, null, permission);
}
/**
* Constructor for root checks or check groups, that are not grouped under
* another check type.
*
* @param configFactory
* @param dataFactory
* @param permission
*/
private CheckType(final CheckType parent,
final CheckConfigFactory configFactory, final CheckDataFactory dataFactory,
final RegisteredPermission permission) {
this(CheckTypeType.GROUP, parent, permission, configFactory, dataFactory);
}
/**
* Constructor for sub-checks grouped under another check type, without
* having a permission set.
* Constructor for checks or groups grouped under another check type,
* without having a permission set, with default activation flag path.
*
* @param parent
*/
private CheckType(final CheckType parent) {
this(parent, null);
}
/**
* Constructor for sub-checks grouped under another check type.
*
* @param parent
* @param permission
*/
private CheckType(final CheckType parent, final RegisteredPermission permission) {
this(CheckTypeType.CHECK, parent, permission, parent.getConfigFactory(), parent.getDataFactory());
private CheckType(final CheckTypeType type, final CheckType parent) {
this(type, parent, null);
}
/**
@ -205,43 +166,48 @@ public enum CheckType {
* Super check type (usually the group).
* @param permission
* Bypass permission.
* @param configFactory
* Check config factory.
* @param dataFactory
* Check data factory.
*/
private CheckType(final CheckTypeType type, final CheckType parent,
final RegisteredPermission permission) {
this(type, parent, permission, null);
}
/**
* General constructor (bottom).
*
* @param type
* @param parent
* @param permission
* @param configPathActive
*/
private CheckType(final CheckTypeType type, final CheckType parent,
final RegisteredPermission permission,
final CheckConfigFactory configFactory, final CheckDataFactory dataFactory) {
final String configPathActive) {
this.type = type;
this.parent = parent;
this.permission = permission;
this.configFactory = configFactory;
this.dataFactory = dataFactory;
this.configPathActive = configPathActive == null ? guessConfigPathActive() : configPathActive ;
this.configPathDebug = guessConfigPath(this.configPathActive, ConfPaths.SUB_DEBUG);
this.configPathLag = guessConfigPath(this.configPathActive, ConfPaths.SUB_LAG);
}
private String guessConfigPathActive() {
return guessConfigPathRoot() + ConfPaths.SUB_ACTIVE;
}
private String guessConfigPath(String configPathActive, String suffix) {
final int index = configPathActive.lastIndexOf(".");
return index == -1 ? suffix: configPathActive.substring(0, index + 1) + suffix;
}
private String guessConfigPathRoot() {
return name().toLowerCase().replace('_', '.') + ".";
}
public CheckTypeType getType() {
return type;
}
/**
* Gets the configFactory.
*
* @return the configFactory
*/
public CheckConfigFactory getConfigFactory() {
return configFactory;
}
/**
* Gets the dataFactory.
*
* @return the dataFactory
*/
public CheckDataFactory getDataFactory() {
return dataFactory;
}
/**
* Gets the name.
*
@ -270,14 +236,20 @@ public enum CheckType {
}
/**
* Check if the check is enabled by configuration (no permission check).
* Return the configuration path for the activation flag.
*
* @param player
* the player
* @return true, if the check is enabled
* @return
*/
public final boolean isEnabled(final Player player) {
return configFactory.getConfig(player).isEnabled(this);
public String getConfigPathActive() {
return configPathActive;
}
public String getConfigPathDebug() {
return configPathDebug;
}
public String getConfigPathLag() {
return configPathLag;
}
}

View File

@ -14,21 +14,17 @@
*/
package fr.neatmonster.nocheatplus.checks.access;
import fr.neatmonster.nocheatplus.config.ConfPaths;
import fr.neatmonster.nocheatplus.config.ConfigFile;
import fr.neatmonster.nocheatplus.worlds.IWorldData;
/**
* Minimal implementation, doing nothing.
* @author mc_dev
* @author asofold
*
*/
public abstract class ACheckConfig implements ICheckConfig {
/** For on the fly debug setting. */
public boolean debug = false; // TODO: Might make private.
/** If to adapt to server side lag. */
public final boolean lag;
/** World data storage for this world. */
public final IWorldData worldData;
/**
*
@ -36,21 +32,9 @@ public abstract class ACheckConfig implements ICheckConfig {
* @param pathPrefix Path prefix for the check section (example for use: prefix+"debug").
* @param cachePermissions cachePermissions Permissions to hold in player data cache. Can be null.
*/
public ACheckConfig(final ConfigFile config, final String pathPrefix){
// TODO: Path prefix construction is somewhat inconsistent with debug hierarchy ?
debug = config.getBoolean(pathPrefix + ConfPaths.SUB_DEBUG, config.getBoolean(ConfPaths.CHECKS_DEBUG, false));
// TODO: Use lag flag where appropriate and document it (or get rid of it).
lag = config.getBoolean(pathPrefix + ConfPaths.SUB_LAG, true) && config.getBoolean(ConfPaths.MISCELLANEOUS_LAG, true);
public ACheckConfig(final IWorldData worldData){
this.worldData = worldData;
}
@Override
public boolean getDebug() {
return debug;
}
@Override
public void setDebug(final boolean debug) {
this.debug = debug;
}
}

View File

@ -16,25 +16,11 @@ package fr.neatmonster.nocheatplus.checks.access;
/**
* Abstract implementation to do nothing.
* @author mc_dev
*
* @author asofold
* @TODO: Keep/remove.
*
*/
public abstract class ACheckData implements ICheckData {
public boolean debug; // TODO: Might make private.
public ACheckData(ICheckConfig config) {
setDebug(config.getDebug());
}
@Override
public void setDebug(boolean debug) {
this.debug = debug;
}
@Override
public boolean getDebug() {
return debug;
}
}

View File

@ -15,16 +15,11 @@
package fr.neatmonster.nocheatplus.checks.access;
/**
* ChecData for async checks like chat, actually implementing cached permissions.
* @author mc_dev
*
* @author asofold
* @TODO Keep / remove.
*
*/
public abstract class AsyncCheckData extends ACheckData {
// TODO: Still needed ?
public AsyncCheckData(ICheckConfig config) {
super(config);
}
}

View File

@ -1,54 +0,0 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package fr.neatmonster.nocheatplus.checks.access;
import java.util.UUID;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.components.registry.feature.IRemoveData;
/**
* A factory for creating and accessing data. This design may be outdated, due
* to PlayerData soon holding the check data instances and factories becoming
* factories again.
*
* @author asofold
*/
public interface CheckDataFactory extends IRemoveData{
/**
* Gets the data of the specified player. Data might get created, if not
* present already.
*
* @param player
* the player
* @return the data
*/
public ICheckData getData(Player player);
/**
* Get data, but don't create if not present.
*
* @param playerId
* @param playerName
* @return The data instance, if present. Null otherwise.
*/
public ICheckData getDataIfPresent(UUID playerId, String playerName);
@Override
public ICheckData removeData(String playerName);
}

View File

@ -14,28 +14,12 @@
*/
package fr.neatmonster.nocheatplus.checks.access;
import fr.neatmonster.nocheatplus.checks.CheckType;
/**
* This interface must be implemented by all configuration classes.
* TODO: Keep / Remove.
*
* @author asofold
*/
public interface ICheckConfig {
/**
* Checks if a check is enabled.
*
* @param checkType
* the check type
* @return true, if the check is enabled
*/
public boolean isEnabled(CheckType checkType);
/** On the fly debug flags, to be set by commands and similar. */
public boolean getDebug();
/** On the fly debug flags, to be set by commands and similar. */
public void setDebug(boolean debug);
}

View File

@ -18,24 +18,15 @@ import fr.neatmonster.nocheatplus.components.data.IData;
/**
* This is for future purposes. Might remove...<br>
* Some checks in chat synchronize over data, so using this from exectueActions can deadlock.<br>
* One might think of making this an interface not for the internally used data, but for copy of data for external use
* only. Then sync could go over other objects for async access.
* Some checks in chat synchronize over data, so using this from exectueActions
* can deadlock.<br>
* One might think of making this an interface not for the internally used data,
* but for copy of data for external use only. Then sync could go over other
* objects for async access.
*
* @author asofold
* @TODO Keep/Remove
*/
public interface ICheckData extends IData{
/**
* Set if to trace/debug this player for the associated checks.
* @param debug
*/
public void setDebug(boolean debug);
/**
* Test if to trace/debug this player for the associated checks.
* @return
*/
public boolean getDebug();
}

View File

@ -1,105 +0,0 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package fr.neatmonster.nocheatplus.checks.access;
import java.util.Collection;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.checks.CheckType;
/**
* Quick and dirty way to add factories for sub checks for more precise data removal from a more general data object.
* @author mc_dev
*
*/
public abstract class SubCheckDataFactory<D extends ICheckData> implements CheckDataFactory {
protected final CheckDataFactory parentFactory;
protected final CheckType checkType;
public SubCheckDataFactory(CheckType checkType, CheckDataFactory parentFactory) {
this.checkType = checkType;
this.parentFactory = parentFactory;
}
/* (non-Javadoc)
* @see fr.neatmonster.nocheatplus.components.IRemoveData#removeAllData()
*/
@Override
public void removeAllData() {
for (String playerName : getPresentData()) {
D data = getData(playerName);
if (data != null) {
removeFromData(playerName, data);
}
}
}
/* (non-Javadoc)
* @see fr.neatmonster.nocheatplus.checks.access.CheckDataFactory#getData(org.bukkit.entity.Player)
*/
@Override
public ICheckData getData(Player player) {
return parentFactory.getData(player);
}
/* (non-Javadoc)
* @see fr.neatmonster.nocheatplus.checks.access.CheckDataFactory#removeData(java.lang.String)
*/
@Override
public ICheckData removeData(String playerName) {
if (!hasData(playerName)) {
return null;
}
D data = getData(playerName);
if (data != null) {
if (removeFromData(playerName, data)) {
// Return data instance, if changed.
return data;
}
}
return null;
}
/**
*
* @param playerName Exact case lookup.
* @return Can return null.
*/
protected abstract D getData(String playerName);
/**
* Names are expected to be exact case. This collection is demanded to be iterable (eclipse: adorable) in case the check runs asynchronously.<br>
* This method might change "a lot" with time.
* @return
*/
protected abstract Collection<String> getPresentData();
/**
* Fast check, if there is data for the player.
* @param playerName Exact case lookup.
* @return
*/
protected abstract boolean hasData(String playerName);
/**
* Remove the specific data from the given data instance.<br>
* TODO: Might add timestamp as argument (ms).
* @param playerName Exact case. Just for reference.
* @param data The data from which to remove the checkType-specific parts. This will never be null.
* @return If changed.
*/
protected abstract boolean removeFromData(String playerName, D data);
}

View File

@ -14,20 +14,12 @@
*/
package fr.neatmonster.nocheatplus.checks.blockbreak;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.actions.ActionList;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.access.ACheckConfig;
import fr.neatmonster.nocheatplus.checks.access.CheckConfigFactory;
import fr.neatmonster.nocheatplus.checks.access.ICheckConfig;
import fr.neatmonster.nocheatplus.config.ConfPaths;
import fr.neatmonster.nocheatplus.config.ConfigFile;
import fr.neatmonster.nocheatplus.config.ConfigManager;
import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.worlds.IWorldData;
/**
* Configurations specific for the block break checks. Every world gets one of these assigned to it, or if a world
@ -35,47 +27,8 @@ import fr.neatmonster.nocheatplus.permissions.Permissions;
*/
public class BlockBreakConfig extends ACheckConfig {
/** The factory creating configurations. */
public static final CheckConfigFactory factory = new CheckConfigFactory() {
@Override
public final ICheckConfig getConfig(final Player player) {
return BlockBreakConfig.getConfig(player);
}
@Override
public void removeAllConfigs() {
clear(); // Band-aid.
}
};
/** The map containing the configurations per world. */
private static final Map<String, BlockBreakConfig> worldsMap = new HashMap<String, BlockBreakConfig>();
/**
* Clear all the configurations.
*/
public static void clear() {
worldsMap.clear();
}
/**
* Gets the configuration for a specified player.
*
* @param player
* the player
* @return the configuration
*/
public static BlockBreakConfig getConfig(final Player player) {
if (!worldsMap.containsKey(player.getWorld().getName()))
worldsMap.put(player.getWorld().getName(),
new BlockBreakConfig(ConfigManager.getConfigFile(player.getWorld().getName())));
return worldsMap.get(player.getWorld().getName());
}
public final boolean directionCheck;
public final ActionList directionActions;
public final boolean fastBreakCheck;
public final boolean fastBreakStrict;
public final int fastBreakBuckets;
public final long fastBreakBucketDur;
@ -86,7 +39,6 @@ public class BlockBreakConfig extends ACheckConfig {
public final ActionList fastBreakActions;
public final boolean frequencyCheck;
public final int frequencyBuckets;
public final long frequencyBucketDur;
public final float frequencyBucketFactor;
@ -99,13 +51,10 @@ public class BlockBreakConfig extends ACheckConfig {
public boolean improbableFastBreakCheck;
public final boolean noSwingCheck;
public final ActionList noSwingActions;
public final boolean reachCheck;
public final ActionList reachActions;
public final boolean wrongBlockCheck;
public final float wrongBLockLevel;
public final ActionList wrongBlockActions;
@ -115,67 +64,38 @@ public class BlockBreakConfig extends ACheckConfig {
* @param data
* the data
*/
public BlockBreakConfig(final ConfigFile data) {
super(data, ConfPaths.BLOCKBREAK);
directionCheck = data.getBoolean(ConfPaths.BLOCKBREAK_DIRECTION_CHECK);
directionActions = data.getOptimizedActionList(ConfPaths.BLOCKBREAK_DIRECTION_ACTIONS, Permissions.BLOCKBREAK_DIRECTION);
public BlockBreakConfig(final IWorldData worldData) {
super(worldData);
final ConfigFile config = worldData.getRawConfiguration();
directionActions = config.getOptimizedActionList(ConfPaths.BLOCKBREAK_DIRECTION_ACTIONS, Permissions.BLOCKBREAK_DIRECTION);
// Fastbreak.
fastBreakCheck = data.getBoolean(ConfPaths.BLOCKBREAK_FASTBREAK_CHECK);
fastBreakStrict = data.getBoolean(ConfPaths.BLOCKBREAK_FASTBREAK_STRICT);
fastBreakDelay = data.getLong(ConfPaths.BLOCKBREAK_FASTBREAK_DELAY);
fastBreakGrace = data.getLong(ConfPaths.BLOCKBREAK_FASTBREAK_BUCKETS_CONTENTION,
data.getLong(ConfPaths.BLOCKBREAK_FASTBREAK_GRACE, 2000));
fastBreakBucketDur = data.getInt(ConfPaths.BLOCKBREAK_FASTBREAK_BUCKETS_DUR, 4000);
fastBreakBucketFactor = (float) data.getDouble(ConfPaths.BLOCKBREAK_FASTBREAK_BUCKETS_FACTOR, 0.99);
fastBreakBuckets = data.getInt(ConfPaths.BLOCKBREAK_FASTBREAK_BUCKETS_N, 30);
fastBreakModSurvival = data.getInt(ConfPaths.BLOCKBREAK_FASTBREAK_MOD_SURVIVAL);
fastBreakStrict = config.getBoolean(ConfPaths.BLOCKBREAK_FASTBREAK_STRICT);
fastBreakDelay = config.getLong(ConfPaths.BLOCKBREAK_FASTBREAK_DELAY);
fastBreakGrace = config.getLong(ConfPaths.BLOCKBREAK_FASTBREAK_BUCKETS_CONTENTION,
config.getLong(ConfPaths.BLOCKBREAK_FASTBREAK_GRACE, 2000));
fastBreakBucketDur = config.getInt(ConfPaths.BLOCKBREAK_FASTBREAK_BUCKETS_DUR, 4000);
fastBreakBucketFactor = (float) config.getDouble(ConfPaths.BLOCKBREAK_FASTBREAK_BUCKETS_FACTOR, 0.99);
fastBreakBuckets = config.getInt(ConfPaths.BLOCKBREAK_FASTBREAK_BUCKETS_N, 30);
fastBreakModSurvival = config.getInt(ConfPaths.BLOCKBREAK_FASTBREAK_MOD_SURVIVAL);
// Fastbreak actions, shared.
fastBreakActions = data.getOptimizedActionList(ConfPaths.BLOCKBREAK_FASTBREAK_ACTIONS, Permissions.BLOCKBREAK_FASTBREAK);
fastBreakActions = config.getOptimizedActionList(ConfPaths.BLOCKBREAK_FASTBREAK_ACTIONS, Permissions.BLOCKBREAK_FASTBREAK);
frequencyCheck = data.getBoolean(ConfPaths.BLOCKBREAK_FREQUENCY_CHECK);
frequencyBuckets = data.getInt(ConfPaths.BLOCKBREAK_FREQUENCY_BUCKETS_N, 2);
frequencyBucketDur = data.getLong(ConfPaths.BLOCKBREAK_FREQUENCY_BUCKETS_DUR, 1000);
frequencyBucketFactor = (float) data.getDouble(ConfPaths.BLOCKBREAK_FREQUENCY_BUCKETS_FACTOR, 1f);
frequencyIntervalCreative = data.getInt(ConfPaths.BLOCKBREAK_FREQUENCY_MOD_CREATIVE);
frequencyIntervalSurvival = data.getInt(ConfPaths.BLOCKBREAK_FREQUENCY_MOD_SURVIVAL);
frequencyShortTermLimit = data.getInt(ConfPaths.BLOCKBREAK_FREQUENCY_SHORTTERM_LIMIT);
frequencyShortTermTicks = data.getInt(ConfPaths.BLOCKBREAK_FREQUENCY_SHORTTERM_TICKS);
frequencyActions = data.getOptimizedActionList(ConfPaths.BLOCKBREAK_FREQUENCY_ACTIONS, Permissions.BLOCKBREAK_FREQUENCY);
frequencyBuckets = config.getInt(ConfPaths.BLOCKBREAK_FREQUENCY_BUCKETS_N, 2);
frequencyBucketDur = config.getLong(ConfPaths.BLOCKBREAK_FREQUENCY_BUCKETS_DUR, 1000);
frequencyBucketFactor = (float) config.getDouble(ConfPaths.BLOCKBREAK_FREQUENCY_BUCKETS_FACTOR, 1f);
frequencyIntervalCreative = config.getInt(ConfPaths.BLOCKBREAK_FREQUENCY_MOD_CREATIVE);
frequencyIntervalSurvival = config.getInt(ConfPaths.BLOCKBREAK_FREQUENCY_MOD_SURVIVAL);
frequencyShortTermLimit = config.getInt(ConfPaths.BLOCKBREAK_FREQUENCY_SHORTTERM_LIMIT);
frequencyShortTermTicks = config.getInt(ConfPaths.BLOCKBREAK_FREQUENCY_SHORTTERM_TICKS);
frequencyActions = config.getOptimizedActionList(ConfPaths.BLOCKBREAK_FREQUENCY_ACTIONS, Permissions.BLOCKBREAK_FREQUENCY);
noSwingCheck = data.getBoolean(ConfPaths.BLOCKBREAK_NOSWING_CHECK);
noSwingActions = data.getOptimizedActionList(ConfPaths.BLOCKBREAK_NOSWING_ACTIONS, Permissions.BLOCKBREAK_NOSWING);
noSwingActions = config.getOptimizedActionList(ConfPaths.BLOCKBREAK_NOSWING_ACTIONS, Permissions.BLOCKBREAK_NOSWING);
reachCheck = data.getBoolean(ConfPaths.BLOCKBREAK_REACH_CHECK);
reachActions = data.getOptimizedActionList(ConfPaths.BLOCKBREAK_REACH_ACTIONS, Permissions.BLOCKBREAK_REACH);
reachActions = config.getOptimizedActionList(ConfPaths.BLOCKBREAK_REACH_ACTIONS, Permissions.BLOCKBREAK_REACH);
wrongBlockCheck = data.getBoolean(ConfPaths.BLOCKBREAK_WRONGBLOCK_CHECK);
wrongBLockLevel = data.getInt(ConfPaths.BLOCKBREAK_WRONGBLOCK_LEVEL);
wrongBlockActions = data.getOptimizedActionList(ConfPaths.BLOCKBREAK_WRONGBLOCK_ACTIONS, Permissions.BLOCKBREAK_WRONGBLOCK);
wrongBLockLevel = config.getInt(ConfPaths.BLOCKBREAK_WRONGBLOCK_LEVEL);
wrongBlockActions = config.getOptimizedActionList(ConfPaths.BLOCKBREAK_WRONGBLOCK_ACTIONS, Permissions.BLOCKBREAK_WRONGBLOCK);
}
/* (non-Javadoc)
* @see fr.neatmonster.nocheatplus.checks.ICheckConfig#isEnabled(fr.neatmonster.nocheatplus.checks.CheckType)
*/
@Override
public final boolean isEnabled(final CheckType checkType) {
switch (checkType) {
case BLOCKBREAK_DIRECTION:
return directionCheck;
case BLOCKBREAK_FASTBREAK:
return fastBreakCheck;
case BLOCKBREAK_FREQUENCY:
return frequencyCheck;
case BLOCKBREAK_NOSWING:
return noSwingCheck;
case BLOCKBREAK_REACH:
return reachCheck;
case BLOCKBREAK_WRONGBLOCK:
return wrongBlockCheck;
case BLOCKBREAK_BREAK:
return true;
default:
return true;
}
}
}

View File

@ -14,18 +14,11 @@
*/
package fr.neatmonster.nocheatplus.checks.blockbreak;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import fr.neatmonster.nocheatplus.checks.access.ACheckData;
import fr.neatmonster.nocheatplus.checks.access.CheckDataFactory;
import fr.neatmonster.nocheatplus.checks.access.ICheckData;
import fr.neatmonster.nocheatplus.stats.Timings;
import fr.neatmonster.nocheatplus.utilities.ds.count.ActionFrequency;
import fr.neatmonster.nocheatplus.utilities.map.BlockProperties;
@ -35,53 +28,6 @@ import fr.neatmonster.nocheatplus.utilities.map.BlockProperties;
*/
public class BlockBreakData extends ACheckData {
/** The factory creating data. */
public static final CheckDataFactory factory = new CheckDataFactory() {
@Override
public final ICheckData getData(final Player player) {
return BlockBreakData.getData(player);
}
@Override
public ICheckData getDataIfPresent(UUID playerId, String playerName) {
return BlockBreakData.playersMap.get(playerName);
}
@Override
public ICheckData removeData(final String playerName) {
return BlockBreakData.removeData(playerName);
}
@Override
public void removeAllData() {
clear();
}
};
/** The map containing the data per players. */
private static final Map<String, BlockBreakData> playersMap = new HashMap<String, BlockBreakData>();
/**
* Gets the data of a specified player.
*
* @param player
* the player
* @return the data
*/
public static BlockBreakData getData(final Player player) {
if (!playersMap.containsKey(player.getName()))
playersMap.put(player.getName(), new BlockBreakData(BlockBreakConfig.getConfig(player)));
return playersMap.get(player.getName());
}
public static ICheckData removeData(final String playerName) {
return playersMap.remove(playerName);
}
public static void clear(){
playersMap.clear();
}
// Violation levels.
public double directionVL;
public double fastBreakVL;
@ -121,26 +67,15 @@ public class BlockBreakData extends ACheckData {
public BlockBreakData(final BlockBreakConfig cc) {
super(cc);
setStats();
fastBreakPenalties = new ActionFrequency(cc.fastBreakBuckets, cc.fastBreakBucketDur);
frequencyBuckets = new ActionFrequency(cc.frequencyBuckets, cc.frequencyBucketDur);
wrongBlockVL = new ActionFrequency(6, 20000);
}
@Override
public void setDebug(boolean debug) {
super.setDebug(debug);
setStats();
}
private void setStats() {
if (getDebug()) {
if (stats == null) {
stats = new Timings("NCP/FASTBREAK");
}
} else {
stats = null;
void setStats() {
if (stats == null) {
stats = new Timings("NCP/FASTBREAK");
}
}

View File

@ -44,7 +44,7 @@ import fr.neatmonster.nocheatplus.compat.Bridge1_9;
import fr.neatmonster.nocheatplus.hooks.NCPExemptionManager;
import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.players.DataManager;
import fr.neatmonster.nocheatplus.players.PlayerData;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.stats.Counters;
import fr.neatmonster.nocheatplus.utilities.TickTask;
import fr.neatmonster.nocheatplus.utilities.map.BlockProperties;
@ -96,10 +96,11 @@ public class BlockBreakListener extends CheckListener {
public void onBlockBreak(final BlockBreakEvent event) {
final long now = System.currentTimeMillis();
final Player player = event.getPlayer();
final IPlayerData pData = DataManager.getPlayerData(player);
// Illegal enchantments hotfix check.
// TODO: Legacy / encapsulate fully there.
if (Items.checkIllegalEnchantmentsAllHands(player)) {
if (Items.checkIllegalEnchantmentsAllHands(player, pData)) {
event.setCancelled(true);
counters.addPrimaryThread(idCancelDIllegalItem, 1);
}
@ -122,10 +123,9 @@ public class BlockBreakListener extends CheckListener {
// Do the actual checks, if still needed. It's a good idea to make computationally cheap checks first, because
// it may save us from doing the computationally expensive checks.
final PlayerData pData = DataManager.getPlayerData(player); // TODO: Use for data + config getting etc.
final BlockBreakConfig cc = BlockBreakConfig.getConfig(player);
final BlockBreakData data = BlockBreakData.getData(player);
final BlockInteractData bdata = BlockInteractData.getData(player);
final BlockBreakConfig cc = pData.getGenericInstance(BlockBreakConfig.class);
final BlockBreakData data = pData.getGenericInstance(BlockBreakData.class);
final BlockInteractData bdata = pData.getGenericInstance(BlockInteractData.class);
/*
* Re-check if this is a block interacted with before. With instantly
* broken blocks, this may be off by one orthogonally.
@ -138,30 +138,35 @@ public class BlockBreakListener extends CheckListener {
final GameMode gameMode = player.getGameMode();
// Has the player broken a block that was not damaged before?
final boolean wrongBlockEnabled = wrongBlock.isEnabled(player);
final boolean wrongBlockEnabled = wrongBlock.isEnabled(player, pData);
if (wrongBlockEnabled && wrongBlock.check(player, block, cc, data, pData, isInstaBreak)) {
cancelled = true;
}
// Has the player broken more blocks per second than allowed?
if (!cancelled && frequency.isEnabled(player) && frequency.check(player, tick, cc, data)) {
if (!cancelled && frequency.isEnabled(player, pData)
&& frequency.check(player, tick, cc, data, pData)) {
cancelled = true;
}
// Has the player broken blocks faster than possible?
if (!cancelled && gameMode != GameMode.CREATIVE
&& fastBreak.isEnabled(player) && fastBreak.check(player, block, isInstaBreak, cc, data, pData)) {
&& fastBreak.isEnabled(player, pData)
&& fastBreak.check(player, block, isInstaBreak, cc, data, pData)) {
cancelled = true;
}
// Did the arm of the player move before breaking this block?
if (!cancelled && noSwing.isEnabled(player) && noSwing.check(player, data)) {
if (!cancelled && noSwing.isEnabled(player, pData)
&& noSwing.check(player, data, pData)) {
cancelled = true;
}
final FlyingQueueHandle flyingHandle;
if (cc.reachCheck || cc.directionCheck) {
flyingHandle = new FlyingQueueHandle(player);
final boolean reachEnabled = reach.isEnabled(player, pData);
final boolean directionEnabled = direction.isEnabled(player, pData);
if (reachEnabled || directionEnabled) {
flyingHandle = new FlyingQueueHandle(pData);
final Location loc = player.getLocation(useLoc);
final double eyeHeight = MovingUtil.getEyeHeight(player);
// Is the block really in reach distance?
@ -169,7 +174,7 @@ public class BlockBreakListener extends CheckListener {
if (isInteractBlock && bdata.isPassedCheck(CheckType.BLOCKINTERACT_REACH)) {
skippedRedundantChecks ++;
}
else if (reach.isEnabled(player) && reach.check(player, eyeHeight, block, data)) {
else if (reachEnabled && reach.check(player, eyeHeight, block, data, cc)) {
cancelled = true;
}
}
@ -181,8 +186,8 @@ public class BlockBreakListener extends CheckListener {
|| bdata.isPassedCheck(CheckType.BLOCKINTERACT_VISIBLE))) {
skippedRedundantChecks ++;
}
else if (direction.isEnabled(player) && direction.check(player, loc, eyeHeight, block,
flyingHandle, data, cc)) {
else if (directionEnabled && direction.check(player, loc, eyeHeight, block,
flyingHandle, data, cc, pData)) {
cancelled = true;
}
}
@ -212,8 +217,9 @@ public class BlockBreakListener extends CheckListener {
// Invalidate last damage position:
// data.clickedX = Integer.MAX_VALUE;
// Debug log (only if not cancelled, to avoid spam).
if (data.debug) {
debugBlockBreakResult(player, block, skippedRedundantChecks, flyingHandle);
if (pData.isDebugActive(CheckType.BLOCKBREAK)) {
debugBlockBreakResult(player, block, skippedRedundantChecks,
flyingHandle, pData);
}
}
@ -231,10 +237,10 @@ public class BlockBreakListener extends CheckListener {
}
private void debugBlockBreakResult(final Player player, final Block block, final int skippedRedundantChecks,
final FlyingQueueHandle flyingHandle) {
final FlyingQueueHandle flyingHandle, final IPlayerData pData) {
debug(player, "Block break(" + block.getType() + "): " + block.getX() + ", " + block.getY() + ", " + block.getZ());
BlockInteractListener.debugBlockVSBlockInteract(player, checkType, block, "onBlockBreak",
Action.LEFT_CLICK_BLOCK);
Action.LEFT_CLICK_BLOCK, pData);
if (skippedRedundantChecks > 0) {
debug(player, "Skipped redundant checks: " + skippedRedundantChecks);
}
@ -260,7 +266,7 @@ public class BlockBreakListener extends CheckListener {
public void onPlayerAnimation(final PlayerAnimationEvent event) {
// Just set a flag to true when the arm was swung.
// debug(player, "Animation");
BlockBreakData.getData(event.getPlayer()).noSwingArmSwung = true;
DataManager.getPlayerData(event.getPlayer()).getGenericInstance(BlockBreakData.class).noSwingArmSwung = true;
}
/**
@ -317,7 +323,8 @@ public class BlockBreakListener extends CheckListener {
private void checkBlockDamage(final Player player, final Block block, final Cancellable event){
final long now = System.currentTimeMillis();
final BlockBreakData data = BlockBreakData.getData(player);
final IPlayerData pData = DataManager.getPlayerData(player);
final BlockBreakData data = pData.getGenericInstance(BlockBreakData.class);
// if (event.isCancelled()){
// // Reset the time, to avoid certain kinds of cheating. => WHICH ?
@ -351,9 +358,9 @@ public class BlockBreakListener extends CheckListener {
// Only record first damage:
data.setClickedBlock(block, tick, now, tool);
// Compare with BlockInteract data (debug first).
if (data.debug) {
BlockInteractListener.debugBlockVSBlockInteract(player, this.checkType, block, "checkBlockDamage",
Action.LEFT_CLICK_BLOCK);
if (pData.isDebugActive(CheckType.BLOCKBREAK)) {
BlockInteractListener.debugBlockVSBlockInteract(player, this.checkType,
block, "checkBlockDamage", Action.LEFT_CLICK_BLOCK, pData);
}
}
@ -362,7 +369,7 @@ public class BlockBreakListener extends CheckListener {
// Reset clicked block.
// TODO: Not for 1.5.2 and before?
final Player player = event.getPlayer();
final BlockBreakData data = BlockBreakData.getData(player);
final BlockBreakData data = DataManager.getPlayerData(player).getGenericInstance(BlockBreakData.class);
if (data.toolChanged(player.getInventory().getItem(event.getNewSlot()))) {
data.resetClickedBlock();
}

View File

@ -27,7 +27,7 @@ import fr.neatmonster.nocheatplus.checks.ViolationData;
import fr.neatmonster.nocheatplus.compat.AlmostBoolean;
import fr.neatmonster.nocheatplus.compat.Bridge1_9;
import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.players.PlayerData;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.utilities.PotionUtil;
import fr.neatmonster.nocheatplus.utilities.TickTask;
import fr.neatmonster.nocheatplus.utilities.map.BlockProperties;
@ -58,7 +58,7 @@ public class FastBreak extends Check {
* @return true, if successful
*/
public boolean check(final Player player, final Block block, final AlmostBoolean isInstaBreak,
final BlockBreakConfig cc, final BlockBreakData data, final PlayerData pData) {
final BlockBreakConfig cc, final BlockBreakData data, final IPlayerData pData) {
final long now = System.currentTimeMillis();
boolean cancel = false;
@ -91,57 +91,71 @@ public class FastBreak extends Check {
// lag or cheat or Minecraft.
// Count in server side lag, if desired.
final float lag = cc.lag ? TickTask.getLag(expectedBreakingTime, true) : 1f;
final float lag = pData.getCurrentWorldDataSafe().shouldAdjustToLag(type)
? TickTask.getLag(expectedBreakingTime, true) : 1f;
final long missingTime = expectedBreakingTime - (long) (lag * elapsedTime);
final long missingTime = expectedBreakingTime - (long) (lag * elapsedTime);
if (missingTime > 0) {
// Add as penalty
data.fastBreakPenalties.add(now, (float) missingTime);
if (missingTime > 0) {
// Add as penalty
data.fastBreakPenalties.add(now, (float) missingTime);
// Only raise a violation, if the total penalty score exceeds the contention duration (for lag, delay).
if (data.fastBreakPenalties.score(cc.fastBreakBucketFactor) > cc.fastBreakGrace) {
// TODO: maybe add one absolute penalty time for big amounts to stop breaking until then
final double vlAdded = (double) missingTime / 1000.0;
data.fastBreakVL += vlAdded;
final ViolationData vd = new ViolationData(this, player, data.fastBreakVL, vlAdded, cc.fastBreakActions);
if (vd.needsParameters()) {
vd.setParameter(ParameterName.BLOCK_TYPE, blockType.toString());
// Only raise a violation, if the total penalty score exceeds the contention duration (for lag, delay).
if (data.fastBreakPenalties.score(cc.fastBreakBucketFactor) > cc.fastBreakGrace) {
// TODO: maybe add one absolute penalty time for big amounts to stop breaking until then
final double vlAdded = (double) missingTime / 1000.0;
data.fastBreakVL += vlAdded;
final ViolationData vd = new ViolationData(this, player, data.fastBreakVL, vlAdded, cc.fastBreakActions);
if (vd.needsParameters()) {
vd.setParameter(ParameterName.BLOCK_TYPE, blockType.toString());
}
cancel = executeActions(vd).willCancel();
}
// else: still within contention limits.
}
cancel = executeActions(vd).willCancel();
}
// else: still within contention limits.
}
}
else if (expectedBreakingTime > cc.fastBreakDelay) {
// Fast breaking does not decrease violation level.
data.fastBreakVL *= 0.9D;
}
if ((data.debug) && pData.hasPermission(Permissions.ADMINISTRATION_DEBUG, player)) {
// General stats:
// TODO: Replace stats by new system (BlockBreakKey once complete), commands to inspect / auto-config.
if (data.stats != null) {
data.stats.addStats(data.stats.getId(blockType+ "/u", true), elapsedTime);
data.stats.addStats(data.stats.getId(blockType + "/r", true), expectedBreakingTime);
player.sendMessage(data.stats.getStatsStr(true));
}
// Send info about current break:
final ItemStack stack = Bridge1_9.getItemInMainHand(player);
final boolean isValidTool = BlockProperties.isValidTool(blockType, stack);
final double haste = PotionUtil.getPotionEffectAmplifier(player, PotionEffectType.FAST_DIGGING);
String msg = (isInstaBreak.decideOptimistically() ? ("[Insta=" + isInstaBreak + "]") : "[Normal]") + "[" + blockType + "] "+ elapsedTime + "u / " + expectedBreakingTime +"r (" + (isValidTool?"tool":"no-tool") + ")" + (Double.isInfinite(haste) ? "" : " haste=" + ((int) haste + 1));
player.sendMessage(msg);
// net.minecraft.server.Item mcItem = net.minecraft.server.Item.byId[stack.getTypeId()];
// if (mcItem != null) {
// double x = mcItem.getDestroySpeed(((CraftItemStack) stack).getHandle(), net.minecraft.server.Block.byId[blockId]);
// player.sendMessage("mc speed: " + x);
// }
// TODO: Rework to use (then hopefully completed) BlockBreakKey.
if (pData.isDebugActive(type)) {
tailDebugStats(player, isInstaBreak, blockType,
elapsedTime, expectedBreakingTime, data, pData);
}
else {
data.stats = null;
}
// (The break time is set in the listener).
return cancel;
}
private void tailDebugStats(final Player player, final AlmostBoolean isInstaBreak,
final Material blockType, final long elapsedTime, final long expectedBreakingTime,
final BlockBreakData data, final IPlayerData pData) {
if (pData.hasPermission(Permissions.ADMINISTRATION_DEBUG, player)) {
// General stats:
// TODO: Replace stats by new system (BlockBreakKey once complete), commands to inspect / auto-config.
data.setStats();
data.stats.addStats(data.stats.getId(blockType+ "/u", true), elapsedTime);
data.stats.addStats(data.stats.getId(blockType + "/r", true), expectedBreakingTime);
player.sendMessage(data.stats.getStatsStr(true));
// Send info about current break:
final ItemStack stack = Bridge1_9.getItemInMainHand(player);
final boolean isValidTool = BlockProperties.isValidTool(blockType, stack);
final double haste = PotionUtil.getPotionEffectAmplifier(player, PotionEffectType.FAST_DIGGING);
String msg = (isInstaBreak.decideOptimistically() ? ("[Insta=" + isInstaBreak + "]") : "[Normal]") + "[" + blockType + "] "+ elapsedTime + "u / " + expectedBreakingTime +"r (" + (isValidTool?"tool":"no-tool") + ")" + (Double.isInfinite(haste) ? "" : " haste=" + ((int) haste + 1));
player.sendMessage(msg);
// net.minecraft.server.Item mcItem = net.minecraft.server.Item.byId[stack.getTypeId()];
// if (mcItem != null) {
// double x = mcItem.getDestroySpeed(((CraftItemStack) stack).getHandle(), net.minecraft.server.Block.byId[blockId]);
// player.sendMessage("mc speed: " + x);
// }
}
}
}

View File

@ -19,6 +19,7 @@ import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.checks.Check;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.utilities.TickTask;
/**
@ -33,7 +34,8 @@ public class Frequency extends Check {
}
public boolean check(final Player player, final int tick,
final BlockBreakConfig cc, final BlockBreakData data){
final BlockBreakConfig cc, final BlockBreakData data,
final IPlayerData pData){
final float interval = (float) ((player.getGameMode() == GameMode.CREATIVE)?(cc.frequencyIntervalCreative):(cc.frequencyIntervalSurvival));
data.frequencyBuckets.add(System.currentTimeMillis(), interval);
@ -41,6 +43,7 @@ public class Frequency extends Check {
// Full period frequency.
final float fullScore = data.frequencyBuckets.score(cc.frequencyBucketFactor);
final long fullTime = cc.frequencyBucketDur * cc.frequencyBuckets;
final boolean lag = pData.getCurrentWorldData().shouldAdjustToLag(type);
// Short term arrivals.
if (tick < data.frequencyShortTermTick){
@ -50,7 +53,7 @@ public class Frequency extends Check {
}
else if (tick - data.frequencyShortTermTick < cc.frequencyShortTermTicks){
// Account for server side lag.
final float stLag = cc.lag ? TickTask.getLag(50L * (tick - data.frequencyShortTermTick), true) : 1f;
final float stLag = lag ? TickTask.getLag(50L * (tick - data.frequencyShortTermTick), true) : 1f;
if (stLag < 1.5){
// Within range, add.
data.frequencyShortTermCount ++;
@ -67,7 +70,7 @@ public class Frequency extends Check {
}
// Account for server side lag.
final float fullLag = cc.lag ? TickTask.getLag(fullTime, true) : 1f;
final float fullLag = lag ? TickTask.getLag(fullTime, true) : 1f;
// Find if one of both or both are violations:
final float fullViolation = (fullScore > fullTime * fullLag) ? (fullScore - fullTime * fullLag) : 0;

View File

@ -18,6 +18,7 @@ import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.checks.Check;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.players.IPlayerData;
/**
* We require that the player moves their arm between block breaks, this is what gets checked here.
@ -38,7 +39,8 @@ public class NoSwing extends Check {
* the player
* @return true, if successful
*/
public boolean check(final Player player, final BlockBreakData data) {
public boolean check(final Player player, final BlockBreakData data,
final IPlayerData pData) {
boolean cancel = false;
@ -54,7 +56,7 @@ public class NoSwing extends Check {
// Execute whatever actions are associated with this check and the violation level and find out if we should
// cancel the event.
cancel = executeActions(player, data.noSwingVL, 1D, BlockBreakConfig.getConfig(player).noSwingActions).willCancel();
cancel = executeActions(player, data.noSwingVL, 1D, pData.getGenericInstance(BlockBreakConfig.class).noSwingActions).willCancel();
}
return cancel;

View File

@ -51,11 +51,13 @@ public class Reach extends Check {
*
* @param player
* the player
* @param cc
* @param location
* the location
* @return true, if successful
*/
public boolean check(final Player player, final double eyeHeight, final Block block, final BlockBreakData data) {
public boolean check(final Player player, final double eyeHeight, final Block block,
final BlockBreakData data, final BlockBreakConfig cc) {
boolean cancel = false;
@ -77,7 +79,7 @@ public class Reach extends Check {
// Execute whatever actions are associated with this check and the violation level and find out if we should
// cancel the event.
final ViolationData vd = new ViolationData(this, player, data.reachVL, distance, BlockBreakConfig.getConfig(player).reachActions);
final ViolationData vd = new ViolationData(this, player, data.reachVL, distance, cc.reachActions);
vd.setParameter(ParameterName.REACH_DISTANCE, String.valueOf(Math.round(data.reachDistance)));
cancel = executeActions(vd).willCancel();
} else{

View File

@ -22,7 +22,7 @@ import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.combined.Improbable;
import fr.neatmonster.nocheatplus.compat.AlmostBoolean;
import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.players.PlayerData;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.utilities.location.TrigUtil;
public class WrongBlock extends Check {
@ -43,7 +43,7 @@ public class WrongBlock extends Check {
* @return
*/
public boolean check(final Player player, final Block block,
final BlockBreakConfig cc, final BlockBreakData data, final PlayerData pData,
final BlockBreakConfig cc, final BlockBreakData data, final IPlayerData pData,
final AlmostBoolean isInstaBreak) {
boolean cancel = false;
@ -52,6 +52,7 @@ public class WrongBlock extends Check {
final int dist = Math.min(4, data.clickedX == Integer.MAX_VALUE ? 100 : TrigUtil.manhattan(data.clickedX, data.clickedY, data.clickedZ, block));
final boolean wrongBlock;
final long now = System.currentTimeMillis();
final boolean debug = pData.isDebugActive(type);
// TODO: Remove isInstaBreak argument or use it.
if (dist == 0) {
if (wrongTime) {
@ -65,7 +66,7 @@ public class WrongBlock extends Check {
// One might to a concession in case of instant breaking.
// TODO: WHY ?
if (now - data.wasInstaBreak < 60) {
if (data.debug) {
if (debug) {
debug(player, "Skip on Manhattan 1 and wasInstaBreak within 60 ms.");
}
wrongBlock = false;
@ -80,7 +81,7 @@ public class WrongBlock extends Check {
}
if (wrongBlock) {
if ((data.debug) && pData.hasPermission(Permissions.ADMINISTRATION_DEBUG, player)) {
if ((debug) && pData.hasPermission(Permissions.ADMINISTRATION_DEBUG, player)) {
player.sendMessage("WrongBlock failure with dist: " + dist);
}
data.wrongBlockVL.add(now, (float) (dist + 1) / 2f);
@ -89,7 +90,7 @@ public class WrongBlock extends Check {
if (executeActions(player, score, 1D, cc.wrongBlockActions).willCancel()) {
cancel = true;
}
if (Improbable.check(player, 2.0f, now, "blockbreak.wrongblock")) {
if (Improbable.check(player, 2.0f, now, "blockbreak.wrongblock", pData)) {
cancel = true;
}
}

View File

@ -14,20 +14,12 @@
*/
package fr.neatmonster.nocheatplus.checks.blockinteract;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.actions.ActionList;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.access.ACheckConfig;
import fr.neatmonster.nocheatplus.checks.access.CheckConfigFactory;
import fr.neatmonster.nocheatplus.checks.access.ICheckConfig;
import fr.neatmonster.nocheatplus.config.ConfPaths;
import fr.neatmonster.nocheatplus.config.ConfigFile;
import fr.neatmonster.nocheatplus.config.ConfigManager;
import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.worlds.IWorldData;
/**
* Configurations specific for the block interact checks. Every world gets one of these assigned to it, or if a world
@ -35,55 +27,14 @@ import fr.neatmonster.nocheatplus.permissions.Permissions;
*/
public class BlockInteractConfig extends ACheckConfig {
/** The factory creating configurations. */
public static final CheckConfigFactory factory = new CheckConfigFactory() {
@Override
public final ICheckConfig getConfig(final Player player) {
return BlockInteractConfig.getConfig(player);
}
@Override
public void removeAllConfigs() {
clear(); // Band-aid.
}
};
/** The map containing the configurations per world. */
private static final Map<String, BlockInteractConfig> worldsMap = new HashMap<String, BlockInteractConfig>();
/**
* Clear all the configurations.
*/
public static void clear() {
worldsMap.clear();
}
/**
* Gets the configuration for a specified player.
*
* @param player
* the player
* @return the configuration
*/
public static BlockInteractConfig getConfig(final Player player) {
if (!worldsMap.containsKey(player.getWorld().getName()))
worldsMap.put(player.getWorld().getName(),
new BlockInteractConfig(ConfigManager.getConfigFile(player.getWorld().getName())));
return worldsMap.get(player.getWorld().getName());
}
public final boolean directionCheck;
public final ActionList directionActions;
public final boolean reachCheck;
public final ActionList reachActions;
public final boolean speedCheck;
public final long speedInterval;
public final int speedLimit;
public final ActionList speedActions;
public final boolean visibleCheck;
public final ActionList visibleActions;
/**
@ -92,40 +43,19 @@ public class BlockInteractConfig extends ACheckConfig {
* @param data
* the data
*/
public BlockInteractConfig(final ConfigFile data) {
super(data, ConfPaths.BLOCKINTERACT);
directionCheck = data.getBoolean(ConfPaths.BLOCKINTERACT_DIRECTION_CHECK);
public BlockInteractConfig(final IWorldData worldData) {
super(worldData);
final ConfigFile data = worldData.getRawConfiguration();
directionActions = data.getOptimizedActionList(ConfPaths.BLOCKINTERACT_DIRECTION_ACTIONS,
Permissions.BLOCKINTERACT_DIRECTION);
reachCheck = data.getBoolean(ConfPaths.BLOCKINTERACT_REACH_CHECK);
reachActions = data.getOptimizedActionList(ConfPaths.BLOCKINTERACT_REACH_ACTIONS, Permissions.BLOCKINTERACT_REACH);
speedCheck = data.getBoolean(ConfPaths.BLOCKINTERACT_SPEED_CHECK);
speedInterval = data.getLong(ConfPaths.BLOCKINTERACT_SPEED_INTERVAL);
speedLimit = data.getInt(ConfPaths.BLOCKINTERACT_SPEED_LIMIT);
speedActions = data.getOptimizedActionList(ConfPaths.BLOCKINTERACT_SPEED_ACTIONS, Permissions.BLOCKINTERACT_SPEED);
visibleCheck = data.getBoolean(ConfPaths.BLOCKINTERACT_VISIBLE_CHECK);
visibleActions = data.getOptimizedActionList(ConfPaths.BLOCKINTERACT_VISIBLE_ACTIONS, Permissions.BLOCKINTERACT_VISIBLE);
}
/* (non-Javadoc)
* @see fr.neatmonster.nocheatplus.checks.ICheckConfig#isEnabled(fr.neatmonster.nocheatplus.checks.CheckType)
*/
@Override
public final boolean isEnabled(final CheckType checkType) {
switch (checkType) {
case BLOCKINTERACT_SPEED:
return speedCheck;
case BLOCKINTERACT_DIRECTION:
return directionCheck;
case BLOCKINTERACT_REACH:
return reachCheck;
case BLOCKINTERACT_VISIBLE:
return visibleCheck;
default:
return true;
}
}
}

View File

@ -16,23 +16,17 @@ package fr.neatmonster.nocheatplus.checks.blockinteract;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.Event.Result;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.access.ACheckData;
import fr.neatmonster.nocheatplus.checks.access.CheckDataFactory;
import fr.neatmonster.nocheatplus.checks.access.ICheckData;
import fr.neatmonster.nocheatplus.utilities.TickTask;
import fr.neatmonster.nocheatplus.utilities.location.TrigUtil;
@ -41,53 +35,6 @@ import fr.neatmonster.nocheatplus.utilities.location.TrigUtil;
*/
public class BlockInteractData extends ACheckData {
/** The factory creating data. */
public static final CheckDataFactory factory = new CheckDataFactory() {
@Override
public final ICheckData getData(final Player player) {
return BlockInteractData.getData(player);
}
@Override
public ICheckData getDataIfPresent(UUID playerId, String playerName) {
return BlockInteractData.playersMap.get(playerName);
}
@Override
public ICheckData removeData(final String playerName) {
return BlockInteractData.removeData(playerName);
}
@Override
public void removeAllData() {
clear();
}
};
/** The map containing the data per players. */
private static final Map<String, BlockInteractData> playersMap = new HashMap<String, BlockInteractData>();
/**
* Gets the data of a specified player.
*
* @param player
* the player
* @return the data
*/
public static BlockInteractData getData(final Player player) {
if (!playersMap.containsKey(player.getName()))
playersMap.put(player.getName(), new BlockInteractData(BlockInteractConfig.getConfig(player)));
return playersMap.get(player.getName());
}
public static ICheckData removeData(final String playerName) {
return playersMap.remove(playerName);
}
public static void clear(){
playersMap.clear();
}
// Violation levels.
public double directionVL = 0;
public double reachVL = 0;
@ -136,10 +83,6 @@ public class BlockInteractData extends ACheckData {
*/
private final Set<CheckType> consumedChecks = new HashSet<CheckType>();
public BlockInteractData(final BlockInteractConfig config) {
super(config);
}
/**
* Set last interacted block (coordinates, type, tick). Also resets the
* passed checks.

View File

@ -37,6 +37,8 @@ import fr.neatmonster.nocheatplus.checks.net.model.DataPacketFlying;
import fr.neatmonster.nocheatplus.compat.Bridge1_9;
import fr.neatmonster.nocheatplus.compat.BridgeHealth;
import fr.neatmonster.nocheatplus.compat.BridgeMisc;
import fr.neatmonster.nocheatplus.players.DataManager;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.stats.Counters;
import fr.neatmonster.nocheatplus.utilities.CheckUtils;
import fr.neatmonster.nocheatplus.utilities.InventoryUtil;
@ -52,8 +54,9 @@ import fr.neatmonster.nocheatplus.utilities.map.BlockProperties;
public class BlockInteractListener extends CheckListener {
public static void debugBlockVSBlockInteract(final Player player, final CheckType checkType,
final Block block, final String prefix, final Action expectedAction) {
final BlockInteractData bdata = BlockInteractData.getData(player);
final Block block, final String prefix, final Action expectedAction,
final IPlayerData pData) {
final BlockInteractData bdata = pData.getGenericInstance(BlockInteractData.class);
final int manhattan = bdata.manhattanLastBlock(block);
String msg;
if (manhattan == Integer.MAX_VALUE) {
@ -109,7 +112,8 @@ public class BlockInteractListener extends CheckListener {
@EventHandler(ignoreCancelled = false, priority = EventPriority.LOWEST)
public void onPlayerInteract(final PlayerInteractEvent event) {
final Player player = event.getPlayer();
final BlockInteractData data = BlockInteractData.getData(player);
final IPlayerData pData = DataManager.getPlayerData(player);
final BlockInteractData data = pData.getGenericInstance(BlockInteractData.class);
data.resetLastBlock();
// Early cancel for interact events with dead players and other.
final int cancelId;
@ -168,7 +172,7 @@ public class BlockInteractListener extends CheckListener {
case RIGHT_CLICK_BLOCK:
stack = Bridge1_9.getUsedItem(player, event);
if (stack != null && stack.getType() == Material.ENDER_PEARL) {
checkEnderPearlRightClickBlock(player, block, face, event, previousLastTick, data);
checkEnderPearlRightClickBlock(player, block, face, event, previousLastTick, data, pData);
}
break;
default:
@ -189,16 +193,16 @@ public class BlockInteractListener extends CheckListener {
}
}
final BlockInteractConfig cc = BlockInteractConfig.getConfig(player);
final BlockInteractConfig cc = pData.getGenericInstance(BlockInteractConfig.class);
boolean preventUseItem = false;
final Location loc = player.getLocation(useLoc);
final FlyingQueueHandle flyingHandle = new FlyingQueueHandle(player);
final FlyingQueueHandle flyingHandle = new FlyingQueueHandle(pData);
// TODO: Always run all checks, also for !isBlock ?
// Interaction speed.
if (!cancelled && speed.isEnabled(player)
if (!cancelled && speed.isEnabled(player, pData)
&& speed.check(player, data, cc)) {
cancelled = true;
preventUseItem = true;
@ -207,27 +211,30 @@ public class BlockInteractListener extends CheckListener {
if (blockChecks) {
final double eyeHeight = MovingUtil.getEyeHeight(player);
// First the reach check.
if (!cancelled && reach.isEnabled(player)
if (!cancelled && reach.isEnabled(player, pData)
&& reach.check(player, loc, eyeHeight, block, data, cc)) {
cancelled = true;
}
// Second the direction check
if (!cancelled && direction.isEnabled(player)
&& direction.check(player, loc, eyeHeight, block, flyingHandle, data, cc)) {
if (!cancelled && direction.isEnabled(player, pData)
&& direction.check(player, loc, eyeHeight, block, flyingHandle,
data, cc, pData)) {
cancelled = true;
}
// Ray tracing for freecam use etc.
if (!cancelled && visible.isEnabled(player)
&& visible.check(player, loc, eyeHeight, block, face, action, flyingHandle, data, cc)) {
if (!cancelled && visible.isEnabled(player, pData)
&& visible.check(player, loc, eyeHeight, block, face, action, flyingHandle,
data, cc, pData)) {
cancelled = true;
}
}
// If one of the checks requested to cancel the event, do so.
if (cancelled) {
onCancelInteract(player, block, face, event, previousLastTick, preventUseItem, data, cc);
onCancelInteract(player, block, face, event, previousLastTick, preventUseItem,
data, cc, pData);
}
else {
if (flyingHandle.isFlyingQueueFetched()) {
@ -241,7 +248,7 @@ public class BlockInteractListener extends CheckListener {
cId = idInteractLookFlyingOther;
}
counters.add(cId, 1);
if (data.debug) {
if (pData.isDebugActive(CheckType.BLOCKINTERACT)) {
// Log which entry was used.
logUsedFlyingPacket(player, flyingHandle, flyingIndex);
}
@ -266,11 +273,12 @@ public class BlockInteractListener extends CheckListener {
private void onCancelInteract(final Player player, final Block block, final BlockFace face,
final PlayerInteractEvent event, final int previousLastTick, final boolean preventUseItem,
final BlockInteractData data, final BlockInteractConfig cc) {
final BlockInteractData data, final BlockInteractConfig cc, final IPlayerData pData) {
final boolean debug = pData.isDebugActive(CheckType.BLOCKINTERACT);
if (event.isCancelled()) {
// Just prevent using the block.
event.setUseInteractedBlock(Result.DENY);
if (data.debug) {
if (debug) {
genericDebug(player, block, face, event, "already cancelled: deny use block", previousLastTick, data, cc);
}
}
@ -284,7 +292,7 @@ public class BlockInteractListener extends CheckListener {
|| !InventoryUtil.isConsumable(Bridge1_9.getUsedItem(player, event))
) {
event.setUseItemInHand(Result.DENY);
if (data.debug) {
if (debug) {
genericDebug(player, block, face, event, "deny item use", previousLastTick, data, cc);
}
}
@ -292,7 +300,7 @@ public class BlockInteractListener extends CheckListener {
// Consumable and not prevented otherwise.
// TODO: Ender pearl?
event.setUseItemInHand(Result.ALLOW);
if (data.debug) {
if (debug) {
genericDebug(player, block, face, event, "allow edible item use", previousLastTick, data, cc);
}
}
@ -303,7 +311,8 @@ public class BlockInteractListener extends CheckListener {
public void onPlayerInteractMonitor(final PlayerInteractEvent event) {
// Set event resolution.
final Player player = event.getPlayer();
final BlockInteractData data = BlockInteractData.getData(player);
final IPlayerData pData = DataManager.getPlayerData(player);
final BlockInteractData data = pData.getGenericInstance(BlockInteractData.class);
data.setPlayerInteractEventResolution(event);
/*
* TODO: BlockDamageEvent fires before BlockInteract/MONITOR level,
@ -332,14 +341,14 @@ public class BlockInteractListener extends CheckListener {
final ItemStack stack = Bridge1_9.getUsedItem(player, event);
if (stack != null && BridgeMisc.maybeElytraBoost(player, stack.getType())) {
final int power = BridgeMisc.getFireworksPower(stack);
final MovingData mData = MovingData.getData(player);
final MovingData mData = pData.getGenericInstance(MovingData.class);
final int ticks = Math.max((1 + power) * 20, 30);
mData.fireworksBoostDuration = ticks;
// Expiration tick: not general latency, rather a minimum margin for sudden congestion.
mData.fireworksBoostTickExpire = TickTask.getTick() + ticks;
// TODO: Invalidation mechanics: by tick/time well ?
// TODO: Implement using it in CreativeFly.
if (data.debug) {
if (pData.isDebugActive(CheckType.MOVING)) {
debug(player, "Elytra boost (power " + power + "): " + stack);
}
}
@ -348,13 +357,14 @@ public class BlockInteractListener extends CheckListener {
private void checkEnderPearlRightClickBlock(final Player player, final Block block,
final BlockFace face, final PlayerInteractEvent event,
final int previousLastTick, final BlockInteractData data) {
final int previousLastTick, final BlockInteractData data,
final IPlayerData pData) {
if (block == null || !BlockProperties.isPassable(block.getType())) {
final CombinedConfig ccc = CombinedConfig.getConfig(player);
final CombinedConfig ccc = pData.getGenericInstance(CombinedConfig.class);
if (ccc.enderPearlCheck && ccc.enderPearlPreventClickBlock) {
event.setUseItemInHand(Result.DENY);
if (data.debug) {
final BlockInteractConfig cc = BlockInteractConfig.getConfig(player);
if (pData.isDebugActive(CheckType.BLOCKINTERACT)) {
final BlockInteractConfig cc = pData.getGenericInstance(BlockInteractConfig.class);
genericDebug(player, block, face, event, "click block: deny use ender pearl", previousLastTick, data, cc);
}
}

View File

@ -29,6 +29,7 @@ import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.ViolationData;
import fr.neatmonster.nocheatplus.checks.net.FlyingQueueHandle;
import fr.neatmonster.nocheatplus.checks.net.FlyingQueueLookBlockChecker;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.utilities.StringUtil;
import fr.neatmonster.nocheatplus.utilities.collision.InteractRayTracing;
import fr.neatmonster.nocheatplus.utilities.location.TrigUtil;
@ -113,7 +114,8 @@ public class Visible extends Check {
public boolean check(final Player player, final Location loc, final double eyeHeight, final Block block,
final BlockFace face, final Action action, final FlyingQueueHandle flyingHandle,
final BlockInteractData data, final BlockInteractConfig cc) {
final BlockInteractData data, final BlockInteractConfig cc,
final IPlayerData pData) {
// TODO: This check might make parts of interact/blockbreak/... + direction (+?) obsolete.
// TODO: Might confine what to check for (left/right-click, target blocks depending on item in hand, container blocks).
boolean collides;
@ -124,6 +126,8 @@ public class Visible extends Check {
final double eyeY = loc.getY() + eyeHeight;
final double eyeZ = loc.getZ();
final boolean debug = pData.isDebugActive(type);
tags.clear();
if (TrigUtil.isSameBlock(blockX, blockY, blockZ, eyeX, eyeY, eyeZ)) {
// Player is interacting with the block their head is in.
@ -137,7 +141,7 @@ public class Visible extends Check {
blockCache.setAccess(loc.getWorld());
rayTracing.setBlockCache(blockCache);
collides = !checker.checkFlyingQueue(eyeX, eyeY, eyeZ, loc.getYaw(), loc.getPitch(),
blockX, blockY, blockZ, flyingHandle, face, tags, data.debug, player);
blockX, blockY, blockZ, flyingHandle, face, tags, debug, player);
checker.cleanup();
useLoc.setWorld(null);
// Cleanup.
@ -161,7 +165,7 @@ public class Visible extends Check {
else {
data.visibleVL *= 0.99;
data.addPassedCheck(this.type);
if (data.debug) {
if (debug) {
debug(player, "pitch=" + loc.getPitch() + ",yaw=" + loc.getYaw() + " tags=" + StringUtil.join(tags, "+"));
}
}

View File

@ -25,7 +25,7 @@ import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.ViolationData;
import fr.neatmonster.nocheatplus.checks.blockinteract.BlockInteractData;
import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.players.PlayerData;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.utilities.map.BlockProperties;
/**
* Check if the placing is legitimate in terms of surrounding materials.
@ -40,16 +40,16 @@ public class Against extends Check {
public boolean check(final Player player, final Block block, final Material placedMat,
final Block blockAgainst, final boolean isInteractBlock,
final BlockPlaceData data, final BlockPlaceConfig cc, final PlayerData pData) {
final BlockPlaceData data, final BlockPlaceConfig cc, final IPlayerData pData) {
boolean violation = false;
// TODO: Make more precise (workarounds like WATER_LILY, general points, such as action?).
// Workaround for signs on cactus and similar.
final BlockInteractData bdata = BlockInteractData.getData(player); // TODO: pass as argument.
final BlockInteractData bdata = pData.getGenericInstance(BlockInteractData.class); // TODO: pass as argument.
final Material againstType = blockAgainst.getType();
if (bdata.isConsumedCheck(this.type) && !bdata.isPassedCheck(this.type)) {
// TODO: Awareness of repeated violation probably is to be implemented below somewhere.
violation = true;
if (data.debug) {
if (pData.isDebugActive(type)) {
debug(player, "Cancel due to block having been consumed by this check.");
}
}

View File

@ -27,6 +27,7 @@ import fr.neatmonster.nocheatplus.actions.ParameterName;
import fr.neatmonster.nocheatplus.checks.Check;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.ViolationData;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.utilities.StringUtil;
import fr.neatmonster.nocheatplus.utilities.TickTask;
@ -50,19 +51,20 @@ public class AutoSign extends Check {
super(CheckType.BLOCKPLACE_AUTOSIGN);
}
public boolean check(final Player player, final Block block, final String[] lines) {
public boolean check(final Player player, final Block block, final String[] lines,
final IPlayerData pData) {
// TODO: Might want to reset time + hash ?
final long time = System.currentTimeMillis();
tags.clear();
final BlockPlaceData data = BlockPlaceData.getData(player);
final BlockPlaceConfig cc = BlockPlaceConfig.getConfig(player);
final BlockPlaceData data = pData.getGenericInstance(BlockPlaceData.class);
final BlockPlaceConfig cc = pData.getGenericInstance(BlockPlaceConfig.class);
Material mat = block.getType();
if (mat == Material.SIGN_POST || mat == Material.WALL_SIGN) {
mat = Material.SIGN;
}
if (data.autoSignPlacedHash != BlockPlaceListener.getBlockPlaceHash(block, mat)){
tags.add("block_mismatch");
return handleViolation(player, maxEditTime, data);
return handleViolation(player, maxEditTime, data, cc);
}
if (time < data.autoSignPlacedTime){
data.autoSignPlacedTime = 0;
@ -80,7 +82,7 @@ public class AutoSign extends Check {
if (expected > editTime){
tags.add("edit_time");
return handleViolation(player, expected - editTime, data);
return handleViolation(player, expected - editTime, data, cc);
}
return false;
}
@ -117,10 +119,12 @@ public class AutoSign extends Check {
* @param data
* @return
*/
private boolean handleViolation(final Player player, final long violationTime, final BlockPlaceData data) {
private boolean handleViolation(final Player player, final long violationTime,
final BlockPlaceData data, final BlockPlaceConfig cc) {
final double addedVL = 10.0 * Math.min(maxEditTime, violationTime) / maxEditTime;
data.autoSignVL += addedVL;
final ViolationData vd = new ViolationData(this, player, data.autoSignVL, addedVL, BlockPlaceConfig.getConfig(player).autoSignActions);
final ViolationData vd = new ViolationData(
this, player, data.autoSignVL, addedVL, cc.autoSignActions);
if (vd.needsParameters()){
vd.setParameter(ParameterName.TAGS, StringUtil.join(tags, "+"));
}

View File

@ -14,23 +14,17 @@
*/
package fr.neatmonster.nocheatplus.checks.blockplace;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.actions.ActionList;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.access.ACheckConfig;
import fr.neatmonster.nocheatplus.checks.access.CheckConfigFactory;
import fr.neatmonster.nocheatplus.checks.access.ICheckConfig;
import fr.neatmonster.nocheatplus.config.ConfPaths;
import fr.neatmonster.nocheatplus.config.ConfigFile;
import fr.neatmonster.nocheatplus.config.ConfigManager;
import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.worlds.IWorldData;
/**
* Configurations specific for the block place checks. Every world gets one of these assigned to it, or if a world
@ -38,67 +32,23 @@ import fr.neatmonster.nocheatplus.permissions.Permissions;
*/
public class BlockPlaceConfig extends ACheckConfig {
/** The factory creating configurations. */
public static final CheckConfigFactory factory = new CheckConfigFactory() {
@Override
public final ICheckConfig getConfig(final Player player) {
return BlockPlaceConfig.getConfig(player);
}
@Override
public void removeAllConfigs() {
clear(); // Band-aid.
}
};
/** The map containing the configurations per world. */
private static final Map<String, BlockPlaceConfig> worldsMap = new HashMap<String, BlockPlaceConfig>();
/**
* Clear all the configurations.
*/
public static void clear() {
worldsMap.clear();
}
/**
* Gets the configuration for a specified player.
*
* @param player
* the player
* @return the configuration
*/
public static BlockPlaceConfig getConfig(final Player player) {
if (!worldsMap.containsKey(player.getWorld().getName()))
worldsMap.put(player.getWorld().getName(),
new BlockPlaceConfig(ConfigManager.getConfigFile(player.getWorld().getName())));
return worldsMap.get(player.getWorld().getName());
}
public final boolean againstCheck;
public final ActionList againstActions;
public final boolean autoSignCheck;
public final boolean autoSignSkipEmpty;
public final ActionList autoSignActions;
public final boolean directionCheck;
public final ActionList directionActions;
public final boolean fastPlaceCheck;
public final int fastPlaceLimit;
public final int fastPlaceShortTermTicks;
public final int fastPlaceShortTermLimit;
public final ActionList fastPlaceActions;
public final boolean noSwingCheck;
public final Set<Material> noSwingExceptions = new HashSet<Material>();
public final ActionList noSwingActions;
public final boolean reachCheck;
public final ActionList reachActions;
public final boolean speedCheck;
public final long speedInterval;
public final ActionList speedActions;
@ -111,34 +61,28 @@ public class BlockPlaceConfig extends ACheckConfig {
* @param config
*
*/
public BlockPlaceConfig(final ConfigFile config) {
super(config, ConfPaths.BLOCKPLACE);
public BlockPlaceConfig(final IWorldData worldData) {
super(worldData);
final ConfigFile config = worldData.getRawConfiguration();
againstCheck = config.getBoolean(ConfPaths.BLOCKPLACE_AGAINST_CHECK);
againstActions = config.getOptimizedActionList(ConfPaths.BLOCKPLACE_AGAINST_ACTIONS, Permissions.BLOCKPLACE_AGAINST);
autoSignCheck = config.getBoolean(ConfPaths.BLOCKPLACE_AUTOSIGN_CHECK);
autoSignSkipEmpty = config.getBoolean(ConfPaths.BLOCKPLACE_AUTOSIGN_SKIPEMPTY);
autoSignActions = config.getOptimizedActionList(ConfPaths.BLOCKPLACE_AUTOSIGN_ACTIONS, Permissions.BLOCKPLACE_AUTOSIGN);
directionCheck = config.getBoolean(ConfPaths.BLOCKPLACE_DIRECTION_CHECK);
directionActions = config.getOptimizedActionList(ConfPaths.BLOCKPLACE_DIRECTION_ACTIONS, Permissions.BLOCKPLACE_DIRECTION);
fastPlaceCheck = config.getBoolean(ConfPaths.BLOCKPLACE_FASTPLACE_CHECK);
fastPlaceLimit = config.getInt(ConfPaths.BLOCKPLACE_FASTPLACE_LIMIT);
fastPlaceShortTermTicks = config.getInt(ConfPaths.BLOCKPLACE_FASTPLACE_SHORTTERM_TICKS);
fastPlaceShortTermLimit = config.getInt(ConfPaths.BLOCKPLACE_FASTPLACE_SHORTTERM_LIMIT);
fastPlaceActions = config.getOptimizedActionList(ConfPaths.BLOCKPLACE_FASTPLACE_ACTIONS, Permissions.BLOCKPLACE_FASTPLACE);
noSwingCheck = config.getBoolean(ConfPaths.BLOCKPLACE_NOSWING_CHECK);
config.readMaterialFromList(ConfPaths.BLOCKPLACE_NOSWING_EXCEPTIONS, noSwingExceptions);
noSwingActions = config.getOptimizedActionList(ConfPaths.BLOCKPLACE_NOSWING_ACTIONS, Permissions.BLOCKPLACE_NOSWING);
reachCheck = config.getBoolean(ConfPaths.BLOCKPLACE_REACH_CHECK);
reachActions = config.getOptimizedActionList(ConfPaths.BLOCKPLACE_REACH_ACTIONS, Permissions.BLOCKPLACE_REACH);
speedCheck = config.getBoolean(ConfPaths.BLOCKPLACE_SPEED_CHECK);
speedInterval = config.getLong(ConfPaths.BLOCKPLACE_SPEED_INTERVAL);
speedActions = config.getOptimizedActionList(ConfPaths.BLOCKPLACE_SPEED_ACTIONS, Permissions.BLOCKPLACE_SPEED);
@ -152,28 +96,4 @@ public class BlockPlaceConfig extends ACheckConfig {
*/
}
/* (non-Javadoc)
* @see fr.neatmonster.nocheatplus.checks.ICheckConfig#isEnabled(fr.neatmonster.nocheatplus.checks.CheckType)
*/
@Override
public final boolean isEnabled(final CheckType checkType) {
switch (checkType) {
case BLOCKPLACE_DIRECTION:
return directionCheck;
case BLOCKPLACE_FASTPLACE:
return fastPlaceCheck;
case BLOCKPLACE_NOSWING:
return noSwingCheck;
case BLOCKPLACE_REACH:
return reachCheck;
case BLOCKPLACE_SPEED:
return speedCheck;
case BLOCKPLACE_AGAINST:
return againstCheck;
case BLOCKPLACE_AUTOSIGN:
return autoSignCheck;
default:
return true;
}
}
}

View File

@ -14,15 +14,7 @@
*/
package fr.neatmonster.nocheatplus.checks.blockplace;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.checks.access.ACheckData;
import fr.neatmonster.nocheatplus.checks.access.CheckDataFactory;
import fr.neatmonster.nocheatplus.checks.access.ICheckData;
import fr.neatmonster.nocheatplus.utilities.ds.count.ActionFrequency;
/**
@ -30,53 +22,6 @@ import fr.neatmonster.nocheatplus.utilities.ds.count.ActionFrequency;
*/
public class BlockPlaceData extends ACheckData {
/** The factory creating data. */
public static final CheckDataFactory factory = new CheckDataFactory() {
@Override
public final ICheckData getData(final Player player) {
return BlockPlaceData.getData(player);
}
@Override
public ICheckData getDataIfPresent(UUID playerId, String playerName) {
return BlockPlaceData.playersMap.get(playerName);
}
@Override
public ICheckData removeData(final String playerName) {
return BlockPlaceData.removeData(playerName);
}
@Override
public void removeAllData() {
clear();
}
};
/** The map containing the data per players. */
private static final Map<String, BlockPlaceData> playersMap = new HashMap<String, BlockPlaceData>();
/**
* Gets the data of a specified player.
*
* @param player
* the player
* @return the data
*/
public static BlockPlaceData getData(final Player player) {
if (!playersMap.containsKey(player.getName()))
playersMap.put(player.getName(), new BlockPlaceData(BlockPlaceConfig.getConfig(player)));
return playersMap.get(player.getName());
}
public static ICheckData removeData(final String playerName) {
return playersMap.remove(playerName);
}
public static void clear(){
playersMap.clear();
}
// Violation levels.
public double againstVL = 0;
public double autoSignVL = 0;
@ -106,8 +51,4 @@ public class BlockPlaceData extends ACheckData {
public boolean speedLastRefused;
public long speedLastTime;
public BlockPlaceData(final BlockPlaceConfig config) {
super (config);
}
}

View File

@ -49,7 +49,7 @@ import fr.neatmonster.nocheatplus.compat.Bridge1_9;
import fr.neatmonster.nocheatplus.compat.BridgeMisc;
import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.players.DataManager;
import fr.neatmonster.nocheatplus.players.PlayerData;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.stats.Counters;
import fr.neatmonster.nocheatplus.utilities.InventoryUtil;
import fr.neatmonster.nocheatplus.utilities.ReflectionUtil;
@ -153,14 +153,15 @@ public class BlockPlaceListener extends CheckListener {
}
boolean cancelled = false;
final PlayerData pData = DataManager.getPlayerData(player); // TODO: Use for data + config getting etc.
final BlockPlaceData data = BlockPlaceData.getData(player);
final BlockPlaceConfig cc = BlockPlaceConfig.getConfig(player);
final BlockInteractData bdata = BlockInteractData.getData(player);
final IPlayerData pData = DataManager.getPlayerData(player); // TODO: Use for data + config getting etc.
final BlockPlaceData data = pData.getGenericInstance(BlockPlaceData.class);
final BlockPlaceConfig cc = pData.getGenericInstance(BlockPlaceConfig.class);
final BlockInteractData bdata = pData.getGenericInstance(BlockInteractData.class);
final int tick = TickTask.getTick();
// isInteractBlock - the block placed against is the block last interacted with.
final boolean isInteractBlock = !bdata.getLastIsCancelled() && bdata.matchesLastBlock(tick, blockAgainst);
int skippedRedundantChecks = 0;
final boolean debug = pData.isDebugActive(CheckType.BLOCKPLACE);
final boolean shouldSkipSome;
if (blockMultiPlaceEvent != null && event.getClass() == blockMultiPlaceEvent) {
@ -169,7 +170,7 @@ public class BlockPlaceListener extends CheckListener {
shouldSkipSome = true;
}
else {
if (data.debug) {
if (debug) {
debug(player, "Block place " + event.getClass().getName() + " " + placedMat);
}
shouldSkipSome = false;
@ -187,31 +188,33 @@ public class BlockPlaceListener extends CheckListener {
}
// Don't run checks, if a set back is scheduled.
if (!cancelled && MovingUtil.hasScheduledPlayerSetBack(player)) {
if (!cancelled && pData.isPlayerSetBackScheduled()) {
cancelled = true;
}
// Fast place check.
if (!cancelled && fastPlace.isEnabled(player)) {
if (fastPlace.check(player, block, tick, data, cc)) {
if (!cancelled && fastPlace.isEnabled(player, pData)) {
if (fastPlace.check(player, block, tick, data, cc, pData)) {
cancelled = true;
}
else {
// Feed the improbable.
Improbable.feed(player, 0.5f, System.currentTimeMillis());
Improbable.feed(player, 0.5f, System.currentTimeMillis(), pData);
}
}
// No swing check (player doesn't swing their arm when placing a lily pad).
if (!cancelled && !cc.noSwingExceptions.contains(placedMat)
&& noSwing.isEnabled(player) && noSwing.check(player, data, cc)) {
&& noSwing.isEnabled(player, pData) && noSwing.check(player, data, cc)) {
// Consider skipping all insta placables or using simplified version (true or true within time frame).
cancelled = true;
}
final FlyingQueueHandle flyingHandle;
if (cc.reachCheck || cc.directionCheck) {
flyingHandle = new FlyingQueueHandle(player);
final boolean reachCheck = pData.isCheckActive(CheckType.BLOCKPLACE_REACH, player);
final boolean directionCheck = pData.isCheckActive(CheckType.BLOCKPLACE_DIRECTION, player);
if (reachCheck || directionCheck) {
flyingHandle = new FlyingQueueHandle(pData);
final Location loc = player.getLocation(useLoc);
final double eyeHeight = MovingUtil.getEyeHeight(player);
// Reach check (distance).
@ -219,7 +222,7 @@ public class BlockPlaceListener extends CheckListener {
if (isInteractBlock && bdata.isPassedCheck(CheckType.BLOCKINTERACT_REACH)) {
skippedRedundantChecks ++;
}
else if (reach.isEnabled(player) && reach.check(player, eyeHeight, block, data, cc)) {
else if (reachCheck && reach.check(player, eyeHeight, block, data, cc)) {
cancelled = true;
}
}
@ -229,8 +232,8 @@ public class BlockPlaceListener extends CheckListener {
if (isInteractBlock && bdata.isPassedCheck(CheckType.BLOCKINTERACT_DIRECTION)) {
skippedRedundantChecks ++;
}
else if (direction.isEnabled(player) && direction.check(player, loc, eyeHeight, block,
flyingHandle, data, cc)) {
else if (directionCheck && direction.check(player, loc, eyeHeight, block,
flyingHandle, data, cc, pData)) {
cancelled = true;
}
}
@ -241,7 +244,7 @@ public class BlockPlaceListener extends CheckListener {
}
// Surrounding material.
if (!cancelled && against.isEnabled(player) && against.check(player, block, placedMat, blockAgainst,
if (!cancelled && against.isEnabled(player, pData) && against.check(player, block, placedMat, blockAgainst,
isInteractBlock, data, cc, pData)) {
cancelled = true;
}
@ -252,8 +255,9 @@ public class BlockPlaceListener extends CheckListener {
}
else {
// Debug log (only if not cancelled, to avoid spam).
if (data.debug) {
debugBlockPlace(player, placedMat, block, blockAgainst, skippedRedundantChecks, flyingHandle);
if (debug) {
debugBlockPlace(player, placedMat, block, blockAgainst,
skippedRedundantChecks, flyingHandle, pData);
}
}
// Cleanup
@ -262,10 +266,12 @@ public class BlockPlaceListener extends CheckListener {
private void debugBlockPlace(final Player player, final Material placedMat,
final Block block, final Block blockAgainst,
final int skippedRedundantChecks, final FlyingQueueHandle flyingHandle) {
final int skippedRedundantChecks, final FlyingQueueHandle flyingHandle,
final IPlayerData pData) {
debug(player, "Block place(" + placedMat + "): " + block.getX() + ", " + block.getY() + ", " + block.getZ());
BlockInteractListener.debugBlockVSBlockInteract(player, checkType, blockAgainst, "onBlockPlace(blockAgainst)",
Action.RIGHT_CLICK_BLOCK);
BlockInteractListener.debugBlockVSBlockInteract(player, checkType,
blockAgainst, "onBlockPlace(blockAgainst)", Action.RIGHT_CLICK_BLOCK,
pData);
if (skippedRedundantChecks > 0) {
debug(player, "Skipped redundant checks: " + skippedRedundantChecks);
}
@ -293,7 +299,8 @@ public class BlockPlaceListener extends CheckListener {
// Somewhat defensive.
return;
}
if (autoSign.isEnabled(player) && autoSign.check(player, block, lines)) {
final IPlayerData pData = DataManager.getPlayerData(player);
if (autoSign.isEnabled(player, pData) && autoSign.check(player, block, lines, pData)) {
event.setCancelled(true);
}
}
@ -309,7 +316,7 @@ public class BlockPlaceListener extends CheckListener {
priority = EventPriority.MONITOR)
public void onPlayerAnimation(final PlayerAnimationEvent event) {
// Just set a flag to true when the arm was swung.
BlockPlaceData.getData(event.getPlayer()).noSwingArmSwung = true;
DataManager.getPlayerData(event.getPlayer()).getGenericInstance(BlockPlaceData.class).noSwingArmSwung = true;
}
/**
@ -334,11 +341,11 @@ public class BlockPlaceListener extends CheckListener {
return;
}
final BlockPlaceConfig cc = BlockPlaceConfig.getConfig(player);
final IPlayerData pData = DataManager.getPlayerData(player);
final BlockPlaceConfig cc = pData.getGenericInstance(BlockPlaceConfig.class);
final Material type = stack.getType();
if (InventoryUtil.isBoat(type)) {
if (cc.preventBoatsAnywhere) {
final PlayerData pData = DataManager.getPlayerData(player); // TODO: Use for data + config getting etc.
// TODO: Alter config (activation, allow on top of ground).
// TODO: Version/plugin specific alteration for 'default'.
checkBoatsAnywhere(player, event, cc, pData);
@ -346,7 +353,7 @@ public class BlockPlaceListener extends CheckListener {
}
else if (type == Material.MONSTER_EGG) {
// Check blockplace.speed.
if (speed.isEnabled(player, cc) && speed.check(player, cc)) {
if (speed.isEnabled(player, pData) && speed.check(player, cc, pData)) {
// If the check was positive, cancel the event.
event.setCancelled(true);
}
@ -354,7 +361,7 @@ public class BlockPlaceListener extends CheckListener {
}
private void checkBoatsAnywhere(final Player player, final PlayerInteractEvent event,
final BlockPlaceConfig cc, final PlayerData pData) {
final BlockPlaceConfig cc, final IPlayerData pData) {
// Check boats-anywhere.
final Block block = event.getClickedBlock();
final Material mat = block.getType();
@ -426,20 +433,21 @@ public class BlockPlaceListener extends CheckListener {
}
// Do the actual check...
final BlockPlaceConfig cc = BlockPlaceConfig.getConfig(player);
final IPlayerData pData = DataManager.getPlayerData(player);
final BlockPlaceConfig cc = pData.getGenericInstance(BlockPlaceConfig.class);
boolean cancel = false;
if (speed.isEnabled(player)) {
if (speed.isEnabled(player, pData)) {
final long now = System.currentTimeMillis();
final Location loc = player.getLocation(useLoc);
if (Combined.checkYawRate(player, loc.getYaw(), now, loc.getWorld().getName())) {
if (Combined.checkYawRate(player, loc.getYaw(), now, loc.getWorld().getName(), pData)) {
// Yawrate (checked extra).
cancel = true;
}
if (speed.check(player, cc)) {
if (speed.check(player, cc, pData)) {
// If the check was positive, cancel the event.
cancel = true;
}
else if (Improbable.check(player, 0.6f, now, "blockplace.speed")) {
else if (Improbable.check(player, 0.6f, now, "blockplace.speed", pData)) {
// Combined fighting speed.
cancel = true;
}
@ -447,7 +455,7 @@ public class BlockPlaceListener extends CheckListener {
// Ender pearl glitch (ab-) use.
if (!cancel && type == EntityType.ENDER_PEARL) {
if (!CombinedConfig.getConfig(player).enderPearlCheck) {
if (!pData.getGenericInstance(CombinedConfig.class).enderPearlCheck) {
// Do nothing !
// TODO: Might have further flags?
}
@ -468,7 +476,9 @@ public class BlockPlaceListener extends CheckListener {
final long flags = BlockProperties.F_CLIMBABLE | BlockProperties.F_LIQUID | BlockProperties.F_IGN_PASSABLE;
if (!BlockProperties.isAir(mat) && (BlockProperties.getBlockFlags(mat) & flags) == 0 && !mcAccess.getHandle().hasGravity(mat)) {
// Still fails on piston traps etc.
if (!BlockProperties.isPassable(player.getLocation(), projectile.getLocation()) && !BlockProperties.isOnGroundOrResetCond(player, player.getLocation(), MovingConfig.getConfig(player).yOnGround)) {
if (!BlockProperties.isPassable(player.getLocation(), projectile.getLocation())
&& !BlockProperties.isOnGroundOrResetCond(player, player.getLocation(),
pData.getGenericInstance(MovingConfig.class).yOnGround)) {
cancel = true;
}
}

View File

@ -19,6 +19,7 @@ import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.checks.Check;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.utilities.TickTask;
/**
@ -44,9 +45,11 @@ public class FastPlace extends Check {
* @return true, if successful
*/
public boolean check(final Player player, final Block block, final int tick,
final BlockPlaceData data, final BlockPlaceConfig cc) {
final BlockPlaceData data, final BlockPlaceConfig cc,
final IPlayerData pData) {
data.fastPlaceBuckets.add(System.currentTimeMillis(), 1f);
final boolean lag = pData.getCurrentWorldData().shouldAdjustToLag(type);
// Full period frequency.
final float fullScore = data.fastPlaceBuckets.score(1f);
@ -59,7 +62,7 @@ public class FastPlace extends Check {
}
else if (tick - data.fastPlaceShortTermTick < cc.fastPlaceShortTermTicks){
// Account for server side lag.
if (!cc.lag || TickTask.getLag(50L * (tick - data.fastPlaceShortTermTick), true) < 1.2f){
if (!lag || TickTask.getLag(50L * (tick - data.fastPlaceShortTermTick), true) < 1.2f){
// Within range, add.
data.fastPlaceShortTermCount ++;
}
@ -78,7 +81,7 @@ public class FastPlace extends Check {
final float fullViolation;
if (fullScore > cc.fastPlaceLimit) {
// Account for server side lag.
if (cc.lag) {
if (lag) {
fullViolation = fullScore / TickTask.getLag(data.fastPlaceBuckets.bucketDuration() * data.fastPlaceBuckets.numberOfBuckets(), true) - cc.fastPlaceLimit;
}
else{

View File

@ -18,6 +18,7 @@ import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.checks.Check;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.players.IPlayerData;
/**
* This check verifies if the player isn't throwing items too quickly, like eggs or arrows.
@ -39,8 +40,9 @@ public class Speed extends Check {
* @param cc
* @return true, if successful
*/
public boolean check(final Player player, final BlockPlaceConfig cc) {
final BlockPlaceData data = BlockPlaceData.getData(player);
public boolean check(final Player player,
final BlockPlaceConfig cc, final IPlayerData pData) {
final BlockPlaceData data = pData.getGenericInstance(BlockPlaceData.class);
boolean cancel = false;

View File

@ -20,9 +20,8 @@ import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.checks.Check;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.players.DataManager;
import fr.neatmonster.nocheatplus.players.PlayerData;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.utilities.CheckUtils;
import fr.neatmonster.nocheatplus.utilities.ColorUtil;
@ -91,14 +90,15 @@ public class Captcha extends Check implements ICaptcha{
@Override
public void resetCaptcha(Player player){
ChatData data = ChatData.getData(player);
final IPlayerData pData = DataManager.getPlayerData(player);
ChatData data = pData.getGenericInstance(ChatData.class);
synchronized (data) {
resetCaptcha(player, ChatConfig.getConfig(player), data, DataManager.getPlayerData(player));
resetCaptcha(player, pData.getGenericInstance(ChatConfig.class), data, pData);
}
}
@Override
public void resetCaptcha(Player player, ChatConfig cc, ChatData data, PlayerData pData){
public void resetCaptcha(Player player, ChatConfig cc, ChatData data, IPlayerData pData){
data.captchTries = 0;
if (shouldCheckCaptcha(player, cc, data, pData)
|| shouldStartCaptcha(player, cc, data, pData)){
@ -113,12 +113,15 @@ public class Captcha extends Check implements ICaptcha{
}
@Override
public boolean shouldStartCaptcha(Player player, ChatConfig cc, ChatData data, PlayerData pData) {
return cc.captchaCheck && !data.captchaStarted && !pData.hasPermission(Permissions.CHAT_CAPTCHA, player);
public boolean shouldStartCaptcha(Player player, ChatConfig cc, ChatData data, IPlayerData pData) {
// TODO: Only call if IWorldData.isCheckActive(CHAT_CAPTCHA) has returned true?
return !data.captchaStarted && pData.isCheckActive(CheckType.CHAT_CAPTCHA, player);
}
@Override
public boolean shouldCheckCaptcha(Player player, ChatConfig cc, ChatData data, PlayerData pData) {
return cc.captchaCheck && data.captchaStarted && !pData.hasPermission(Permissions.CHAT_CAPTCHA, player);
public boolean shouldCheckCaptcha(Player player, ChatConfig cc, ChatData data, IPlayerData pData) {
// TODO: Only call if IWorldData.isCheckActive(CHAT_CAPTCHA) has returned true?
return data.captchaStarted && pData.isCheckActive(CheckType.CHAT_CAPTCHA, player);
}
}

View File

@ -14,23 +14,15 @@
*/
package fr.neatmonster.nocheatplus.checks.chat;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.actions.ActionList;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.access.ACheckConfig;
import fr.neatmonster.nocheatplus.checks.access.CheckConfigFactory;
import fr.neatmonster.nocheatplus.checks.access.ICheckConfig;
import fr.neatmonster.nocheatplus.checks.chat.analysis.engine.EnginePlayerConfig;
import fr.neatmonster.nocheatplus.config.ConfPaths;
import fr.neatmonster.nocheatplus.config.ConfigFile;
import fr.neatmonster.nocheatplus.config.ConfigManager;
import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.permissions.RegisteredPermission;
import fr.neatmonster.nocheatplus.utilities.ColorUtil;
import fr.neatmonster.nocheatplus.worlds.IWorldData;
/**
* Configurations specific for the "chat" checks. Every world gets one of these assigned to it, or if a world doesn't
@ -38,20 +30,8 @@ import fr.neatmonster.nocheatplus.utilities.ColorUtil;
*/
public class ChatConfig extends ACheckConfig {
/** The factory creating configurations. */
public static final CheckConfigFactory factory = new CheckConfigFactory() {
@Override
public final ICheckConfig getConfig(final Player player) {
return ChatConfig.getConfig(player);
}
@Override
public void removeAllConfigs() {
clear(); // Band-aid.
}
};
private static RegisteredPermission[] preferKeepUpdatedPermissions = new RegisteredPermission[]{
private static final RegisteredPermission[] preferKeepUpdatedPermissions = new RegisteredPermission[]{
// Only the permissions needed for async. checking.
Permissions.CHAT_COLOR,
Permissions.CHAT_TEXT,
@ -59,39 +39,10 @@ public class ChatConfig extends ACheckConfig {
// TODO: COMMANDS, in case of handleascommand?
};
/** The map containing the configurations per world. */
private static final Map<String, ChatConfig> worldsMap = new HashMap<String, ChatConfig>();
public static RegisteredPermission[] getPreferKeepUpdatedPermissions() {
return preferKeepUpdatedPermissions;
}
/**
* Clear all the configurations.
*/
public static void clear() {
synchronized (worldsMap) {
worldsMap.clear();
}
}
/**
* Gets the configuration for a specified player.
*
* @param player
* the player
* @return the configuration
*/
public static ChatConfig getConfig(final Player player) {
synchronized (worldsMap) {
if (!worldsMap.containsKey(player.getWorld().getName()))
worldsMap.put(player.getWorld().getName(),
new ChatConfig(ConfigManager.getConfigFile(player.getWorld().getName())));
return worldsMap.get(player.getWorld().getName());
}
}
public final boolean captchaCheck;
public final boolean captchaSkipCommands;
public final String captchaCharacters;
public final int captchaLength;
@ -100,16 +51,14 @@ public class ChatConfig extends ACheckConfig {
public final int captchaTries;
public final ActionList captchaActions;
public final boolean colorCheck;
public final ActionList colorActions;
public final boolean commandsCheck;
public final double commandsLevel;
public final int commandsShortTermTicks;
public final double commandsShortTermLevel;
public final ActionList commandsActions;
public final boolean textCheck;
// TODO: Sub check types ?
public final boolean textGlobalCheck;
public final boolean textPlayerCheck;
public final EnginePlayerConfig textEnginePlayerConfig;
@ -147,7 +96,6 @@ public class ChatConfig extends ACheckConfig {
public final String chatWarningMessage;
public final long chatWarningTimeout;
public final boolean loginsCheck;
public final boolean loginsPerWorldCount;
public final int loginsSeconds;
public final int loginsLimit;
@ -157,8 +105,6 @@ public class ChatConfig extends ACheckConfig {
public final boolean consoleOnlyCheck;
public final String consoleOnlyMessage;
public final boolean relogCheck;
public final String relogKickMessage;
public final long relogTimeout;
public final String relogWarningMessage;
@ -172,10 +118,10 @@ public class ChatConfig extends ACheckConfig {
* @param config
* the data
*/
public ChatConfig(final ConfigFile config) {
super(config, ConfPaths.CHAT);
public ChatConfig(final IWorldData worldData) {
super(worldData);
final ConfigFile config = worldData.getRawConfiguration();
captchaCheck = config.getBoolean(ConfPaths.CHAT_CAPTCHA_CHECK);
captchaSkipCommands = config.getBoolean(ConfPaths.CHAT_CAPTCHA_SKIP_COMMANDS);
captchaCharacters = config.getString(ConfPaths.CHAT_CAPTCHA_CHARACTERS);
captchaLength = config.getInt(ConfPaths.CHAT_CAPTCHA_LENGTH);
@ -184,17 +130,13 @@ public class ChatConfig extends ACheckConfig {
captchaTries = config.getInt(ConfPaths.CHAT_CAPTCHA_TRIES);
captchaActions = config.getOptimizedActionList(ConfPaths.CHAT_CAPTCHA_ACTIONS, Permissions.CHAT_CAPTCHA);
colorCheck = config.getBoolean(ConfPaths.CHAT_COLOR_CHECK);
colorActions = config.getOptimizedActionList(ConfPaths.CHAT_COLOR_ACTIONS, Permissions.CHAT_COLOR);
commandsCheck = config.getBoolean(ConfPaths.CHAT_COMMANDS_CHECK);
commandsLevel = config.getDouble(ConfPaths.CHAT_COMMANDS_LEVEL);
commandsShortTermTicks = config.getInt(ConfPaths.CHAT_COMMANDS_SHORTTERM_TICKS);
commandsShortTermLevel = config.getDouble(ConfPaths.CHAT_COMMANDS_SHORTTERM_LEVEL);;
commandsActions = config.getOptimizedActionList(ConfPaths.CHAT_COMMANDS_ACTIONS, Permissions.CHAT_COMMANDS);
textCheck = config.getBoolean(ConfPaths.CHAT_TEXT_CHECK);
textGlobalCheck = config.getBoolean(ConfPaths.CHAT_TEXT_GL_CHECK, true);
textPlayerCheck = config.getBoolean(ConfPaths.CHAT_TEXT_PP_CHECK, true);
textEnginePlayerConfig = new EnginePlayerConfig(config);
@ -231,14 +173,12 @@ public class ChatConfig extends ACheckConfig {
chatWarningMessage = config.getString(ConfPaths.CHAT_WARNING_MESSAGE);
chatWarningTimeout = config.getLong(ConfPaths.CHAT_WARNING_TIMEOUT) * 1000;
loginsCheck = config.getBoolean(ConfPaths.CHAT_LOGINS_CHECK);
loginsPerWorldCount = config.getBoolean(ConfPaths.CHAT_LOGINS_PERWORLDCOUNT);
loginsSeconds = config.getInt(ConfPaths.CHAT_LOGINS_SECONDS);
loginsLimit = config.getInt(ConfPaths.CHAT_LOGINS_LIMIT);
loginsKickMessage = config.getString(ConfPaths.CHAT_LOGINS_KICKMESSAGE);
loginsStartupDelay = config.getInt(ConfPaths.CHAT_LOGINS_STARTUPDELAY) * 1000;
relogCheck = config.getBoolean(ConfPaths.CHAT_RELOG_CHECK);
relogKickMessage = config.getString(ConfPaths.CHAT_RELOG_KICKMESSAGE);
relogTimeout = config.getLong(ConfPaths.CHAT_RELOG_TIMEOUT);
relogWarningMessage = config.getString(ConfPaths.CHAT_RELOG_WARNING_MESSAGE);
@ -251,26 +191,4 @@ public class ChatConfig extends ACheckConfig {
}
/* (non-Javadoc)
* @see fr.neatmonster.nocheatplus.checks.ICheckConfig#isEnabled(fr.neatmonster.nocheatplus.checks.CheckType)
*/
@Override
public boolean isEnabled(final CheckType checkType) {
switch (checkType) {
case CHAT_COLOR:
return colorCheck;
case CHAT_TEXT:
return textCheck;
case CHAT_COMMANDS:
return commandsCheck;
case CHAT_CAPTCHA:
return captchaCheck;
case CHAT_RELOG:
return relogCheck;
case CHAT_LOGINS:
return loginsCheck;
default:
return true;
}
}
}

View File

@ -14,68 +14,13 @@
*/
package fr.neatmonster.nocheatplus.checks.chat;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.checks.access.AsyncCheckData;
import fr.neatmonster.nocheatplus.checks.access.CheckDataFactory;
import fr.neatmonster.nocheatplus.checks.access.ICheckData;
import fr.neatmonster.nocheatplus.utilities.ds.count.ActionFrequency;
/**
* Player specific data for the chat checks.
*/
public class ChatData extends AsyncCheckData {
/** The factory creating data. */
public static final CheckDataFactory factory = new CheckDataFactory() {
@Override
public final ICheckData getData(final Player player) {
return ChatData.getData(player);
}
@Override
public ICheckData getDataIfPresent(UUID playerId, String playerName) {
return ChatData.playersMap.get(playerName);
}
@Override
public ICheckData removeData(final String playerName) {
return ChatData.removeData(playerName);
}
@Override
public void removeAllData() {
clear();
}
};
/** The map containing the data per players. */
private static final Map<String, ChatData> playersMap = new HashMap<String, ChatData>();
/**
* Gets the data of a specified player.
*
* @param player
* the player
* @return the data
*/
public static synchronized ChatData getData(final Player player) {
if (!playersMap.containsKey(player.getName()))
playersMap.put(player.getName(), new ChatData(ChatConfig.getConfig(player)));
return playersMap.get(player.getName());
}
public static synchronized ICheckData removeData(final String playerName) {
return playersMap.remove(playerName);
}
public static synchronized void clear(){
playersMap.clear();
}
public class ChatData extends AsyncCheckData {
// Violation levels.
public double captchaVL;
@ -109,15 +54,6 @@ public class ChatData extends AsyncCheckData {
public int relogWarnings;
public long relogWarningTime;
/**
* Keep track of current world name, to be used for asynchronous world
* config getting. Set on join and world change, reset on leave.
*/
public String currentWorldName = null;
public ChatData(final ChatConfig config) {
super(config);
}
/**
* Clear the data of the no pwnage check.

View File

@ -23,7 +23,6 @@ import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.PlayerChangedWorldEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerLoginEvent.Result;
@ -42,7 +41,7 @@ import fr.neatmonster.nocheatplus.config.ConfigFile;
import fr.neatmonster.nocheatplus.config.ConfigManager;
import fr.neatmonster.nocheatplus.logging.Streams;
import fr.neatmonster.nocheatplus.players.DataManager;
import fr.neatmonster.nocheatplus.players.PlayerData;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.utilities.StringUtil;
import fr.neatmonster.nocheatplus.utilities.ds.prefixtree.SimpleCharPrefixTree;
@ -100,13 +99,6 @@ public class ChatListener extends CheckListener implements INotifyReload, JoinLe
CommandUtil.feedCommands(commandExclusions, config, ConfPaths.CHAT_COMMANDS_EXCLUSIONS, true);
}
@EventHandler(priority=EventPriority.MONITOR)
public void onPlayerChangedWorld(final PlayerChangedWorldEvent event) {
final Player player = event.getPlayer();
ChatData.getData(player).currentWorldName = player.getWorld().getName();
}
/**
* We listen to PlayerChat events for obvious reasons.
*
@ -121,11 +113,11 @@ public class ChatListener extends CheckListener implements INotifyReload, JoinLe
// Tell TickTask to update cached permissions.
// (Might omit this if already cancelled.)
final PlayerData pData = DataManager.getPlayerData(player);
final ChatConfig cc = ChatConfig.getConfig(player);
final IPlayerData pData = DataManager.getPlayerData(player);
final ChatConfig cc = pData.getGenericInstance(ChatConfig.class);
// First the color check.
if (!alreadyCancelled && color.isEnabled(player)) {
if (!alreadyCancelled && color.isEnabled(player, pData)) {
event.setMessage(color.check(player, event.getMessage(), false));
}
@ -148,11 +140,11 @@ public class ChatListener extends CheckListener implements INotifyReload, JoinLe
final Player player = event.getPlayer();
// Tell TickTask to update cached permissions.
final PlayerData pData = DataManager.getPlayerData(player);
final ChatConfig cc = ChatConfig.getConfig(player);
final IPlayerData pData = DataManager.getPlayerData(player);
final ChatConfig cc = pData.getGenericInstance(ChatConfig.class);
// Checks that replace parts of the message (color).
if (color.isEnabled(player)) {
if (color.isEnabled(player, pData)) {
event.setMessage(color.check(player, event.getMessage(), true));
}
@ -198,15 +190,15 @@ public class ChatListener extends CheckListener implements INotifyReload, JoinLe
}
else if (!commandExclusions.hasAnyPrefixWords(messageVars)) {
// Treat as command.
if (commands.isEnabled(player) && commands.check(player, checkMessage, cc, pData, captcha)) {
if (commands.isEnabled(player, pData) && commands.check(player, checkMessage, cc, pData, captcha)) {
event.setCancelled(true);
}
else {
// TODO: Consider always checking these?
// Note that this checks for prefixes, not prefix words.
final MovingConfig mcc = MovingConfig.getConfig(player);
final MovingConfig mcc = pData.getGenericInstance(MovingConfig.class);
if (mcc.passableUntrackedCommandCheck && mcc.passableUntrackedCommandPrefixes.hasAnyPrefix(messageVars)) {
if (checkUntrackedLocation(player, message, mcc)) {
if (checkUntrackedLocation(player, message, mcc, pData)) {
event.setCancelled(true);
}
}
@ -215,10 +207,11 @@ public class ChatListener extends CheckListener implements INotifyReload, JoinLe
}
private boolean checkUntrackedLocation(final Player player, final String message, final MovingConfig mcc) {
private boolean checkUntrackedLocation(final Player player, final String message,
final MovingConfig mcc, final IPlayerData pData) {
final Location loc = player.getLocation(useLoc);
boolean cancel = false;
if (MovingUtil.shouldCheckUntrackedLocation(player, loc)) {
if (MovingUtil.shouldCheckUntrackedLocation(player, loc, pData)) {
final Location newTo = MovingUtil.checkUntrackedLocation(loc);
if (newTo != null) {
if (mcc.passableUntrackedCommandTryTeleport
@ -237,9 +230,9 @@ public class ChatListener extends CheckListener implements INotifyReload, JoinLe
}
private boolean textChecks(final Player player, final String message,
final ChatConfig cc, final PlayerData pData,
final ChatConfig cc, final IPlayerData pData,
final boolean isMainThread, final boolean alreadyCancelled) {
return text.isEnabled(player) && text.check(player, message, cc, pData,
return text.isEnabled(player, pData) && text.check(player, message, cc, pData,
captcha, isMainThread, alreadyCancelled);
}
@ -254,9 +247,9 @@ public class ChatListener extends CheckListener implements INotifyReload, JoinLe
public void onPlayerLogin(final PlayerLoginEvent event) {
if (event.getResult() != Result.ALLOWED) return;
final Player player = event.getPlayer();
final PlayerData pData = DataManager.getPlayerData(player);
final ChatConfig cc = ChatConfig.getConfig(player);
final ChatData data = ChatData.getData(player);
final IPlayerData pData = DataManager.getPlayerData(player);
final ChatConfig cc = pData.getGenericInstance(ChatConfig.class);
final ChatData data = pData.getGenericInstance(ChatData.class);
// (No forced permission update, because the associated permissions are treated as hints rather.)
@ -265,10 +258,10 @@ public class ChatListener extends CheckListener implements INotifyReload, JoinLe
captcha.resetCaptcha(player, cc, data, pData);
}
// Fast relog check.
if (relog.isEnabled(player) && relog.unsafeLoginCheck(player, cc, data)) {
if (relog.isEnabled(player, pData) && relog.unsafeLoginCheck(player, cc, data,pData)) {
event.disallow(Result.KICK_OTHER, cc.relogKickMessage);
}
else if (logins.isEnabled(player) && logins.check(player, cc, data)) {
else if (logins.isEnabled(player, pData) && logins.check(player, cc, data)) {
event.disallow(Result.KICK_OTHER, cc.loginsKickMessage);
}
}
@ -284,13 +277,17 @@ public class ChatListener extends CheckListener implements INotifyReload, JoinLe
@Override
public void playerJoins(final Player player) {
final PlayerData pData = DataManager.getPlayerData(player);
final ChatConfig cc = ChatConfig.getConfig(player);
final ChatData data = ChatData.getData(player);
// Cross-check hack: ChatData holds the current world name (TBD: PlayerData.getWorldInfo() rather).
data.currentWorldName = player.getWorld().getName();
final IPlayerData pData = DataManager.getPlayerData(player);
final ChatConfig cc = pData.getGenericInstance(ChatConfig.class);
final ChatData data = pData.getGenericInstance(ChatData.class);
/*
* TODO: The isEnabled check must be done with IWorldData (no locking).
* Specifically because enabling/disabling checks should be done in the
* primary thread, regardless of the capabilities of WorldDataManager
* implementation.
*/
synchronized (data) {
if (captcha.isEnabled(player, cc, pData)) {
if (captcha.isEnabled(player, pData)) {
if (captcha.shouldCheckCaptcha(player, cc, data, pData)) {
// shouldCheckCaptcha: only if really enabled.
// TODO: Later: add check for cc.captchaOnLogin or so (before shouldCheckCaptcha).
@ -303,7 +300,6 @@ public class ChatListener extends CheckListener implements INotifyReload, JoinLe
@Override
public void playerLeaves(final Player player) {
ChatData.getData(player).currentWorldName = null;
}
}

View File

@ -18,6 +18,8 @@ import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.checks.Check;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.players.DataManager;
import fr.neatmonster.nocheatplus.players.IPlayerData;
/**
* The Color check verifies that no color codes are sent in players' messages.
@ -44,9 +46,10 @@ public class Color extends Check {
*/
public String check(final Player player, final String message, final boolean isMainThread) {
final ChatConfig cc = ChatConfig.getConfig(player);
final IPlayerData pData = DataManager.getPlayerData(player);
final ChatConfig cc = pData.getGenericInstance(ChatConfig.class);
final ChatData data = pData.getGenericInstance(ChatData.class);
final ChatData data = ChatData.getData(player);
// Keep related to ChatData used lock.
synchronized (data) {
// If the message contains colors...

View File

@ -18,8 +18,7 @@ import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.checks.Check;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.players.PlayerData;
import fr.neatmonster.nocheatplus.utilities.CheckUtils;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.utilities.ColorUtil;
import fr.neatmonster.nocheatplus.utilities.TickTask;
@ -34,16 +33,16 @@ public class Commands extends Check {
}
public boolean check(final Player player, final String message,
final ChatConfig cc, final PlayerData pData,
final ChatConfig cc, final IPlayerData pData,
final ICaptcha captcha) {
final long now = System.currentTimeMillis();
final int tick = TickTask.getTick();
final ChatData data = ChatData.getData(player);
final ChatData data = pData.getGenericInstance(ChatData.class);
final boolean captchaEnabled = !cc.captchaSkipCommands
&& CheckUtils.isEnabled(CheckType.CHAT_CAPTCHA, player, cc, pData);
&& pData.isCheckActive(CheckType.CHAT_CAPTCHA, player);
if (captchaEnabled){
synchronized (data) {
if (captcha.shouldCheckCaptcha(player, cc, data, pData)){
@ -65,7 +64,8 @@ public class Commands extends Check {
data.commandsShortTermWeight = 1.0;
}
else if (tick - data.commandsShortTermTick < cc.commandsShortTermTicks){
if (!cc.lag || TickTask.getLag(50L * (tick - data.commandsShortTermTick), true) < 1.3f){
if (!pData.getCurrentWorldData().shouldAdjustToLag(type)
|| TickTask.getLag(50L * (tick - data.commandsShortTermTick), true) < 1.3f){
// Add up.
data.commandsShortTermWeight += weight;
}

View File

@ -16,7 +16,7 @@ package fr.neatmonster.nocheatplus.checks.chat;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.players.PlayerData;
import fr.neatmonster.nocheatplus.players.IPlayerData;
/**
* Captcha related operations.<br>
@ -62,7 +62,7 @@ public interface ICaptcha {
* @param pData
* @return
*/
public boolean shouldCheckCaptcha(Player player, ChatConfig cc, ChatData data, PlayerData pData);
public boolean shouldCheckCaptcha(Player player, ChatConfig cc, ChatData data, IPlayerData pData);
/**
* Check if captcha should be generated and send to the player.
@ -73,7 +73,7 @@ public interface ICaptcha {
* @param pData
* @return
*/
public boolean shouldStartCaptcha(Player player, ChatConfig cc, ChatData data, PlayerData pData);
public boolean shouldStartCaptcha(Player player, ChatConfig cc, ChatData data, IPlayerData pData);
/**
* Just resets tries, generate new captcha if necessary.
@ -83,7 +83,7 @@ public interface ICaptcha {
* @param data
* @param pData
*/
public void resetCaptcha(Player player, ChatConfig cc, ChatData data, PlayerData pData);
public void resetCaptcha(Player player, ChatConfig cc, ChatData data, IPlayerData pData);
/**
* Convenience method. Should synchronize over data of player (!).

View File

@ -19,6 +19,7 @@ import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.checks.Check;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.combined.CombinedData;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.utilities.ColorUtil;
public class Relog extends Check {
@ -38,12 +39,13 @@ public class Relog extends Check {
* the data
* @return true, if successful
*/
public boolean unsafeLoginCheck(final Player player, final ChatConfig cc, final ChatData data) {
public boolean unsafeLoginCheck(final Player player,
final ChatConfig cc, final ChatData data, final IPlayerData pData) {
boolean cancel = false;
final long now = System.currentTimeMillis();
final CombinedData cData = CombinedData.getData(player);
final CombinedData cData = pData.getGenericInstance(CombinedData.class);
// Enforce the player does not relog too fast.
if (now - cData.lastLogoutTime < cc.relogTimeout) {

View File

@ -32,7 +32,7 @@ import fr.neatmonster.nocheatplus.components.NoCheatPlusAPI;
import fr.neatmonster.nocheatplus.components.registry.feature.INotifyReload;
import fr.neatmonster.nocheatplus.config.ConfigFile;
import fr.neatmonster.nocheatplus.config.ConfigManager;
import fr.neatmonster.nocheatplus.players.PlayerData;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.utilities.ColorUtil;
import fr.neatmonster.nocheatplus.utilities.StringUtil;
@ -69,9 +69,9 @@ public class Text extends Check implements INotifyReload {
* @return
*/
public boolean check(final Player player, final String message,
final ChatConfig cc, final PlayerData pData,
final ChatConfig cc, final IPlayerData pData,
final ICaptcha captcha, boolean isMainThread, final boolean alreadyCancelled) {
final ChatData data = ChatData.getData(player);
final ChatData data = pData.getGenericInstance(ChatData.class);
synchronized (data) {
return unsafeCheck(player, message, captcha, cc, data, pData, isMainThread, alreadyCancelled);
@ -110,7 +110,7 @@ public class Text extends Check implements INotifyReload {
* @return
*/
private boolean unsafeCheck(final Player player, final String message, final ICaptcha captcha,
final ChatConfig cc, final ChatData data, final PlayerData pData,
final ChatConfig cc, final ChatData data, final IPlayerData pData,
boolean isMainThread, final boolean alreadyCancelled) {
// Test captcha.
@ -130,7 +130,7 @@ public class Text extends Check implements INotifyReload {
boolean cancel = false;
boolean debug = data.debug;
final boolean debug = pData.isDebugActive(type);
final List<String> debugParts;
if (debug) {
@ -180,7 +180,7 @@ public class Text extends Check implements INotifyReload {
}
}
final CombinedData cData = CombinedData.getData(player);
final CombinedData cData = pData.getGenericInstance(CombinedData.class);
final long timeout = 8000; // TODO: maybe set dynamically in data.
// Repetition of last message.
if (cc.textMsgRepeatSelf != 0f && time - data.chatLastTime < timeout) {

View File

@ -18,6 +18,7 @@ import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.checks.Check;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.players.IPlayerData;
public class BedLeave extends Check {
@ -32,8 +33,8 @@ public class BedLeave extends Check {
* the player
* @return If to prevent action (use the set back location of survivalfly).
*/
public boolean checkBed(final Player player) {
final CombinedData data = CombinedData.getData(player);
public boolean checkBed(final Player player, final IPlayerData pData) {
final CombinedData data = pData.getGenericInstance(CombinedData.class);
boolean cancel = false;
// Check if the player had been in bed at all.
@ -44,7 +45,8 @@ public class BedLeave extends Check {
// TODO: add tag
// And return if we need to do something or not.
if (executeActions(player, data.bedLeaveVL, 1D, CombinedConfig.getConfig(player).bedLeaveActions).willCancel()){
if (executeActions(player, data.bedLeaveVL, 1D,
pData.getGenericInstance(CombinedConfig.class).bedLeaveActions).willCancel()){
cancel = true;
}
} else{

View File

@ -18,6 +18,7 @@ import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.hooks.NCPExemptionManager;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.utilities.TickTask;
@ -40,8 +41,9 @@ public class Combined {
* @return
*/
public static final boolean checkYawRate(final Player player, final float yaw, final long now,
final String worldName) {
return checkYawRate(player, yaw, now, worldName, CombinedData.getData(player));
final String worldName, final IPlayerData pData) {
return checkYawRate(player, yaw, now, worldName,
pData.getGenericInstance(CombinedData.class), pData);
}
/**
@ -52,8 +54,9 @@ public class Combined {
* @param worldName
*/
public static final void feedYawRate(final Player player, final float yaw, final long now,
final String worldName) {
feedYawRate(player, yaw, now, worldName, CombinedData.getData(player));
final String worldName, final IPlayerData pData) {
feedYawRate(player, yaw, now, worldName,
pData.getGenericInstance(CombinedData.class), pData);
}
/**
@ -68,10 +71,10 @@ public class Combined {
* @return True, if the player was exempted from yawrate. False otherwise.
*/
public static final boolean feedYawRate(final Player player, float yaw, final long now,
final String worldName, final CombinedData data) {
final String worldName, final CombinedData data, final IPlayerData pData) {
// Check for exemption (hack, sort of).
if (NCPExemptionManager.isExempted(player, CheckType.COMBINED_YAWRATE)) {
resetYawRate(player, yaw, now, true);
resetYawRate(player, yaw, now, true, pData);
return true;
}
@ -145,13 +148,14 @@ public class Combined {
* otherwise.
*/
public static final boolean checkYawRate(final Player player, final float yaw, final long now,
final String worldName, final CombinedData data) {
final String worldName, final CombinedData data, final IPlayerData pData) {
if (feedYawRate(player, yaw, now, worldName, data)) {
if (feedYawRate(player, yaw, now, worldName, data, pData)) {
return false;
}
final CombinedConfig cc = CombinedConfig.getConfig(player);
final CombinedConfig cc = pData.getGenericInstance(CombinedConfig.class);
final boolean lag = pData.getCurrentWorldData().shouldAdjustToLag(CheckType.COMBINED_IMPROBABLE);
final float threshold = cc.yawRate;
@ -160,7 +164,7 @@ public class Combined {
final float stViol;
if (stScore > threshold) {
// Account for server side lag.
if (!cc.lag || TickTask.getLag(data.yawFreq.bucketDuration(), true) < 1.2) {
if (!lag || TickTask.getLag(data.yawFreq.bucketDuration(), true) < 1.2) {
stViol = stScore;
}
else {
@ -174,7 +178,7 @@ public class Combined {
final float fullViol;
if (fullScore > threshold) {
// Account for server side lag.
if (cc.lag) {
if (lag) {
fullViol = fullScore / TickTask.getLag(data.yawFreq.bucketDuration() * data.yawFreq.numberOfBuckets(), true);
}
else {
@ -194,7 +198,8 @@ public class Combined {
Math.max(cc.yawRatePenaltyFactor * amount , cc.yawRatePenaltyMin),
cc.yawRatePenaltyMax));
// TODO: balance (100 ... 200 ) ?
if (cc.yawRateImprobable && Improbable.check(player, amount / 100f, now, "combined.yawrate"))
if (cc.yawRateImprobable && Improbable.check(player, amount / 100f, now, "combined.yawrate",
pData))
cancel = true;
}
if (data.timeFreeze.isPenalty()) {
@ -210,14 +215,15 @@ public class Combined {
* @param time
* @param clear If to clear yaws.
*/
public static final void resetYawRate(final Player player, float yaw, final long time, final boolean clear) {
public static final void resetYawRate(final Player player, float yaw,
final long time, final boolean clear, final IPlayerData pData) {
if (yaw <= -360f) {
yaw = -((-yaw) % 360f);
}
else if (yaw >= 360f) {
yaw = yaw % 360f;
}
final CombinedData data = CombinedData.getData(player);
final CombinedData data = pData.getGenericInstance(CombinedData.class);
data.lastYaw = yaw;
data.lastYawTime = time; // TODO: One might set to some past-time to allow any move at first.
data.sumYaw = 0;
@ -235,12 +241,13 @@ public class Combined {
* @param yawRateCheck If to actually check the yaw rate, or just feed.
* @return
*/
public static final boolean checkYawRate(final Player player, final float yaw, final long now, final String worldName, final boolean yawRateCheck) {
public static final boolean checkYawRate(final Player player, final float yaw, final long now,
final String worldName, final boolean yawRateCheck, final IPlayerData pData) {
if (yawRateCheck) {
return checkYawRate(player, yaw, now, worldName);
return checkYawRate(player, yaw, now, worldName, pData);
}
else {
feedYawRate(player, yaw, now, worldName);
feedYawRate(player, yaw, now, worldName, pData);
return false;
}
}

View File

@ -21,51 +21,20 @@ import java.util.Map;
import java.util.Set;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import fr.neatmonster.nocheatplus.actions.ActionList;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.access.ACheckConfig;
import fr.neatmonster.nocheatplus.checks.access.CheckConfigFactory;
import fr.neatmonster.nocheatplus.checks.access.ICheckConfig;
import fr.neatmonster.nocheatplus.config.ConfPaths;
import fr.neatmonster.nocheatplus.config.ConfigFile;
import fr.neatmonster.nocheatplus.config.ConfigManager;
import fr.neatmonster.nocheatplus.logging.StaticLog;
import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.utilities.StringUtil;
import fr.neatmonster.nocheatplus.worlds.IWorldData;
public class CombinedConfig extends ACheckConfig {
/** The factory creating configurations. */
public static final CheckConfigFactory factory = new CheckConfigFactory() {
@Override
public final ICheckConfig getConfig(final Player player) {
return CombinedConfig.getConfig(player);
}
@Override
public void removeAllConfigs() {
clear(); // Band-aid.
}
};
private static final Map<String, CombinedConfig> worldsMap = new HashMap<String, CombinedConfig>();
public static CombinedConfig getConfig(final Player player) {
final String worldName = player.getWorld().getName();
CombinedConfig cc = worldsMap.get(worldName);
if (cc == null){
cc = new CombinedConfig(ConfigManager.getConfigFile(worldName));
worldsMap.put(worldName, cc);
}
return cc;
}
// Bedleave check.
public final boolean bedLeaveCheck;
public final ActionList bedLeaveActions;
// Ender pearl
@ -74,7 +43,6 @@ public class CombinedConfig extends ACheckConfig {
// Improbable check
/** Do mind that this flag is not used by all components. */
public final boolean improbableCheck;
public final float improbableLevel;
public final ActionList improbableActions;
@ -87,7 +55,6 @@ public class CombinedConfig extends ACheckConfig {
public final boolean invulnerableTriggerAlways;
public final boolean invulnerableTriggerFallDistance;
public final boolean munchHausenCheck;
public final ActionList munchHausenActions;
// Last yaw tracking
@ -97,16 +64,15 @@ public class CombinedConfig extends ACheckConfig {
public final int yawRatePenaltyMin;
public final int yawRatePenaltyMax;
public CombinedConfig(final ConfigFile config) {
super(config, ConfPaths.COMBINED);
public CombinedConfig(final IWorldData worldData) {
super(worldData);
final ConfigFile config = worldData.getRawConfiguration();
bedLeaveCheck = config.getBoolean(ConfPaths.COMBINED_BEDLEAVE_CHECK);
bedLeaveActions = config.getOptimizedActionList(ConfPaths.COMBINED_BEDLEAVE_ACTIONS, Permissions.COMBINED_BEDLEAVE);
enderPearlCheck = config.getBoolean(ConfPaths.COMBINED_ENDERPEARL_CHECK);
enderPearlPreventClickBlock = config.getBoolean(ConfPaths.COMBINED_ENDERPEARL_PREVENTCLICKBLOCK);
improbableCheck = config.getBoolean(ConfPaths.COMBINED_IMPROBABLE_CHECK);
improbableLevel = (float) config.getDouble(ConfPaths.COMBINED_IMPROBABLE_LEVEL);
improbableActions = config.getOptimizedActionList(ConfPaths.COMBINED_IMPROBABLE_ACTIONS, Permissions.COMBINED_IMPROBABLE);
@ -147,7 +113,6 @@ public class CombinedConfig extends ACheckConfig {
invulnerableTriggerAlways = config.getBoolean(ConfPaths.COMBINED_INVULNERABLE_TRIGGERS_ALWAYS);
invulnerableTriggerFallDistance = config.getBoolean(ConfPaths.COMBINED_INVULNERABLE_TRIGGERS_FALLDISTANCE);
munchHausenCheck = config.getBoolean(ConfPaths.COMBINED_MUNCHHAUSEN_CHECK);
munchHausenActions = config.getOptimizedActionList(ConfPaths.COMBINED_MUNCHHAUSEN_ACTIONS, Permissions.COMBINED_MUNCHHAUSEN);
yawRate = config.getInt(ConfPaths.COMBINED_YAWRATE_RATE);
@ -157,25 +122,4 @@ public class CombinedConfig extends ACheckConfig {
yawRatePenaltyMax = config.getInt(ConfPaths.COMBINED_YAWRATE_PENALTY_MAX);
}
@Override
public boolean isEnabled(final CheckType checkType) {
switch(checkType){
case COMBINED_IMPROBABLE:
return improbableCheck;
case COMBINED_BEDLEAVE:
return bedLeaveCheck;
case COMBINED_MUNCHHAUSEN:
return munchHausenCheck;
case COMBINED_YAWRATE:
// Always on, depends on other checks.
return true;
default:
return false;
}
}
public static void clear() {
worldsMap.clear();
}
}

View File

@ -14,65 +14,14 @@
*/
package fr.neatmonster.nocheatplus.checks.combined;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.access.ACheckData;
import fr.neatmonster.nocheatplus.checks.access.CheckDataFactory;
import fr.neatmonster.nocheatplus.checks.access.ICheckData;
import fr.neatmonster.nocheatplus.checks.access.IRemoveSubCheckData;
import fr.neatmonster.nocheatplus.utilities.PenaltyTime;
import fr.neatmonster.nocheatplus.utilities.ds.count.ActionFrequency;
public class CombinedData extends ACheckData implements IRemoveSubCheckData {
/** The factory creating data. */
public static final CheckDataFactory factory = new CheckDataFactory() {
@Override
public final ICheckData getData(final Player player) {
return CombinedData.getData(player);
}
@Override
public ICheckData getDataIfPresent(UUID playerId, String playerName) {
return CombinedData.playersMap.get(playerName);
}
@Override
public ICheckData removeData(final String playerName) {
return CombinedData.removeData(playerName);
}
@Override
public void removeAllData() {
clear();
}
};
private static final Map<String, CombinedData> playersMap = new HashMap<String, CombinedData>();
public static CombinedData getData(final Player player) {
final String playerName = player.getName();
CombinedData data = playersMap.get(playerName);
if (data == null){
data = new CombinedData(CombinedConfig.getConfig(player));
playersMap.put(playerName, data);
}
return data;
}
public static ICheckData removeData(final String playerName) {
return playersMap.remove(playerName);
}
public static void clear(){
playersMap.clear();
}
// VLs
public double bedLeaveVL = 0;
public double improbableVL = 0;
@ -98,15 +47,12 @@ public class CombinedData extends ACheckData implements IRemoveSubCheckData {
public final ActionFrequency improbableCount = new ActionFrequency(20, 3000);
// General data
// TODO: -> PlayerData (-> OfflinePlayerData)
public String lastWorld = "";
public long lastJoinTime;
public long lastLogoutTime;
public long lastMoveTime;
public CombinedData(final CombinedConfig config){
super(config);
}
@Override
public boolean removeSubCheckData(final CheckType checkType) {
switch(checkType) {

View File

@ -28,6 +28,8 @@ import org.bukkit.event.player.PlayerToggleSprintEvent;
import fr.neatmonster.nocheatplus.NCPAPIProvider;
import fr.neatmonster.nocheatplus.checks.CheckListener;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.players.DataManager;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.stats.Counters;
import fr.neatmonster.nocheatplus.utilities.TickTask;
@ -65,10 +67,13 @@ public class CombinedListener extends CheckListener {
// TODO: EventPriority
final Player player = event.getPlayer();
final CombinedData data = CombinedData.getData(player);
final CombinedConfig cc = CombinedConfig.getConfig(player);
final IPlayerData pData = DataManager.getPlayerData(player);
final CombinedData data = pData.getGenericInstance(CombinedData.class);
final CombinedConfig cc = pData.getGenericInstance(CombinedConfig.class);
if (cc.invulnerableCheck && (cc.invulnerableTriggerAlways || cc.invulnerableTriggerFallDistance && player.getFallDistance() > 0)){
if (cc.invulnerableCheck
&& (cc.invulnerableTriggerAlways || cc.invulnerableTriggerFallDistance
&& player.getFallDistance() > 0)){
// TODO: maybe make a heuristic for small fall distances with ground under feet (prevents future abuse with jumping) ?
final int invulnerableTicks = mcAccess.getHandle().getInvulnerableTicks(player);
if (invulnerableTicks == Integer.MAX_VALUE) {
@ -86,7 +91,8 @@ public class CombinedListener extends CheckListener {
final Entity entity = event.getEntity();
if (!(entity instanceof Player)) return;
final Player player = (Player) entity;
final CombinedConfig cc = CombinedConfig.getConfig(player);
final IPlayerData pData = DataManager.getPlayerData(player);
final CombinedConfig cc = pData.getGenericInstance(CombinedConfig.class);
if (!cc.invulnerableCheck) return;
final DamageCause cause = event.getCause();
// Ignored causes.
@ -94,7 +100,7 @@ public class CombinedListener extends CheckListener {
// Modified invulnerable ticks.
Integer modifier = cc.invulnerableModifiers.get(cause);
if (modifier == null) modifier = cc.invulnerableModifierDefault;
final CombinedData data = CombinedData.getData(player);
final CombinedData data = pData.getGenericInstance(CombinedData.class);
// TODO: account for tick task reset ? [it should not though, due to data resetting too, but API would allow it]
if (TickTask.getTick() >= data.invulnerableTick + modifier.intValue()) return;
// Still invulnerable.

View File

@ -21,6 +21,8 @@ import fr.neatmonster.nocheatplus.checks.Check;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.ViolationData;
import fr.neatmonster.nocheatplus.components.registry.feature.IDisableListener;
import fr.neatmonster.nocheatplus.players.DataManager;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.utilities.TickTask;
/**
@ -41,8 +43,21 @@ public class Improbable extends Check implements IDisableListener{
* @param now
* @return
*/
public static final boolean check(final Player player, final float weight, final long now, final String tags){
return instance.checkImprobable(player, weight, now, tags);
public static final boolean check(final Player player, final float weight, final long now,
final String tags, final IPlayerData pData){
return instance.checkImprobable(player, weight, now, tags, pData);
}
/**
* Feed the check but no violations processing (convenience method).
* @param player
* @param weight
* @param now
* @param pData
*/
public static final void feed(final Player player, final float weight, final long now,
final IPlayerData pData){
pData.getGenericInstance(CombinedData.class).improbableCount.add(now, weight);
}
/**
@ -51,8 +66,8 @@ public class Improbable extends Check implements IDisableListener{
* @param weight
* @param now
*/
public static final void feed(final Player player, final float weight, final long now){
CombinedData.getData(player).improbableCount.add(now, weight);
public static void feed(final Player player, final float weight, long now) {
feed(player, weight, now, DataManager.getPlayerData(player));
}
////////////////////////////////////
@ -64,16 +79,19 @@ public class Improbable extends Check implements IDisableListener{
instance = this;
}
private boolean checkImprobable(final Player player, final float weight, final long now, final String tags) {
if (!isEnabled(player)) return false;
final CombinedData data = CombinedData.getData(player);
final CombinedConfig cc = CombinedConfig.getConfig(player);
private boolean checkImprobable(final Player player, final float weight, final long now,
final String tags, final IPlayerData pData) {
if (!pData.isCheckActive(type, player)) {
return false;
}
final CombinedData data = pData.getGenericInstance(CombinedData.class);
final CombinedConfig cc = pData.getGenericInstance(CombinedConfig.class);
data.improbableCount.add(now, weight);
final float shortTerm = data.improbableCount.bucketScore(0);
double violation = 0;
boolean violated = false;
if (shortTerm * 0.8f > cc.improbableLevel / 20.0){
final float lag = cc.lag ? TickTask.getLag(data.improbableCount.bucketDuration(), true) : 1f;
final float lag = pData.getCurrentWorldData().shouldAdjustToLag(type) ? TickTask.getLag(data.improbableCount.bucketDuration(), true) : 1f;
if (shortTerm / lag > cc.improbableLevel / 20.0){
violation += shortTerm * 2d / lag;
violated = true;
@ -81,7 +99,7 @@ public class Improbable extends Check implements IDisableListener{
}
final double full = data.improbableCount.score(1.0f);
if (full > cc.improbableLevel){
final float lag = cc.lag ? TickTask.getLag(data.improbableCount.bucketDuration() * data.improbableCount.numberOfBuckets(), true) : 1f;
final float lag = pData.getCurrentWorldData().shouldAdjustToLag(type) ? TickTask.getLag(data.improbableCount.bucketDuration() * data.improbableCount.numberOfBuckets(), true) : 1f;
if (full / lag > cc.improbableLevel){
violation += full / lag;
violated = true;

View File

@ -20,6 +20,8 @@ import org.bukkit.event.player.PlayerFishEvent.State;
import fr.neatmonster.nocheatplus.checks.Check;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.players.DataManager;
import fr.neatmonster.nocheatplus.players.IPlayerData;
/**
* Very, very important check.
@ -34,10 +36,12 @@ public class MunchHausen extends Check {
public boolean checkFish(final Player player, final Entity caught, final State state) {
if (caught == null || !(caught instanceof Player)) return false;
final Player caughtPlayer = (Player) caught;
final CombinedData data = CombinedData.getData(player);
final IPlayerData pData = DataManager.getPlayerData(player);
final CombinedData data = pData.getGenericInstance(CombinedData.class);
if (player.equals(caughtPlayer)){
data.munchHausenVL += 1.0;
if (executeActions(player, data.munchHausenVL, 1.0, CombinedConfig.getConfig(player).munchHausenActions).willCancel()){
if (executeActions(player, data.munchHausenVL, 1.0,
pData.getGenericInstance(CombinedConfig.class).munchHausenActions).willCancel()){
return true;
}
}

View File

@ -32,7 +32,7 @@ import fr.neatmonster.nocheatplus.checks.moving.model.LiftOffEnvelope;
import fr.neatmonster.nocheatplus.checks.moving.model.PlayerMoveInfo;
import fr.neatmonster.nocheatplus.checks.moving.util.AuxMoving;
import fr.neatmonster.nocheatplus.checks.moving.util.MovingUtil;
import fr.neatmonster.nocheatplus.players.PlayerData;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.utilities.StringUtil;
import fr.neatmonster.nocheatplus.utilities.map.BlockProperties;
@ -58,13 +58,14 @@ public class Critical extends Check {
* @return true, if successful
*/
public boolean check(final Player player, final Location loc,
final FightData data, final FightConfig cc, final PlayerData pData) {
final FightData data, final FightConfig cc,
final IPlayerData pData) {
boolean cancel = false;
final double mcFallDistance = (double) player.getFallDistance();
final MovingConfig mCc = MovingConfig.getConfig(player);
final MovingConfig mCc = pData.getGenericInstance(MovingConfig.class);
if (data.debug) {
if (pData.isDebugActive(type)) {
debug(player, "y=" + loc.getY() + " mcfalldist=" + mcFallDistance);
}
@ -72,13 +73,17 @@ public class Critical extends Check {
// not in liquid, not in vehicle, and without blindness effect).
if (mcFallDistance > 0.0 && !player.isInsideVehicle() && !player.hasPotionEffect(PotionEffectType.BLINDNESS)) {
// Might be a violation.
final MovingData dataM = MovingData.getData(player);
final MovingData dataM = pData.getGenericInstance(MovingData.class);
/*
* TODO: NoFall data max y. (past moves too perhaps - low jump,
* number split moves without reason)
*/
// TODO: Skip near the highest jump height (needs check if head collided with something solid, which also detects low jump).
if (!dataM.isVelocityJumpPhase() &&
(dataM.sfLowJump && !dataM.sfNoLowJump && dataM.liftOffEnvelope == LiftOffEnvelope.NORMAL
|| mcFallDistance < cc.criticalFallDistance && !BlockProperties.isResetCond(player, loc, mCc.yOnGround))) {
final MovingConfig ccM = MovingConfig.getConfig(player);
final MovingConfig ccM = pData.getGenericInstance(MovingConfig.class);
// TODO: Use past move tracking to check for SurvivalFly and the like?
final PlayerMoveInfo moveInfo = auxMoving.usePlayerMoveInfo();
moveInfo.set(player, loc, null, ccM.yOnGround);

View File

@ -19,25 +19,27 @@ import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.checks.Check;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.players.DataManager;
import fr.neatmonster.nocheatplus.players.PlayerData;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.utilities.TickTask;
/**
* Legacy check (client side health regeneration).
*
* @author mc_dev
* @author asofold
*
*/
public class FastHeal extends Check {
public FastHeal(){
super(CheckType.FIGHT_FASTHEAL);
}
public boolean check(final Player player){
public boolean check(final Player player, final IPlayerData pData){
final long time = System.currentTimeMillis();
final PlayerData pData = DataManager.getPlayerData(player);
final FightConfig cc = FightConfig.getConfig(player);
final FightData data = FightData.getData(player);
final FightConfig cc = pData.getGenericInstance(FightConfig.class);
final FightData data = pData.getGenericInstance(FightData.class);
boolean cancel = false;
if (time < data.fastHealRefTime || time - data.fastHealRefTime >= cc.fastHealInterval){
// Reset.
@ -63,7 +65,7 @@ public class FastHeal extends Check {
}
}
if (data.debug && pData.hasPermission(Permissions.ADMINISTRATION_DEBUG, player)){
if (pData.isDebugActive(type) && pData.hasPermission(Permissions.ADMINISTRATION_DEBUG, player)){
player.sendMessage("Regain health(SATIATED): " + (time - data.fastHealRefTime) + " ms "+ "(buffer=" + data.fastHealBuffer + ")" +" , cancel=" + cancel);
}

View File

@ -14,23 +14,17 @@
*/
package fr.neatmonster.nocheatplus.checks.fight;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.actions.ActionList;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.access.ACheckConfig;
import fr.neatmonster.nocheatplus.checks.access.CheckConfigFactory;
import fr.neatmonster.nocheatplus.checks.access.ICheckConfig;
import fr.neatmonster.nocheatplus.compat.AlmostBoolean;
import fr.neatmonster.nocheatplus.compat.versions.Bugs;
import fr.neatmonster.nocheatplus.compat.versions.ServerVersion;
import fr.neatmonster.nocheatplus.components.config.value.OverrideType;
import fr.neatmonster.nocheatplus.config.ConfPaths;
import fr.neatmonster.nocheatplus.config.ConfigFile;
import fr.neatmonster.nocheatplus.config.ConfigManager;
import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.worlds.IWorldData;
/**
* Configurations specific for the "fight" checks. Every world gets one of these assigned to it, or if a world doesn't
@ -38,72 +32,28 @@ import fr.neatmonster.nocheatplus.permissions.Permissions;
*/
public class FightConfig extends ACheckConfig {
/** The factory creating configurations. */
public static final CheckConfigFactory factory = new CheckConfigFactory() {
@Override
public final ICheckConfig getConfig(final Player player) {
return FightConfig.getConfig(player);
}
@Override
public void removeAllConfigs() {
clear(); // Band-aid.
}
};
/** The map containing the configurations per world. */
private static final Map<String, FightConfig> worldsMap = new HashMap<String, FightConfig>();
/**
* Clear all the configurations.
*/
public static void clear() {
worldsMap.clear();
}
/**
* Gets the configuration for a specified player.
*
* @param player
* the player
* @return the configuration
*/
public static FightConfig getConfig(final Player player) {
if (!worldsMap.containsKey(player.getWorld().getName()))
worldsMap.put(player.getWorld().getName(),
new FightConfig(ConfigManager.getConfigFile(player.getWorld().getName())));
return worldsMap.get(player.getWorld().getName());
}
public final boolean angleCheck;
public final double angleThreshold;
public final ActionList angleActions;
public final long toolChangeAttackPenalty;
public final boolean criticalCheck;
public final double criticalFallDistance;
public final ActionList criticalActions;
public final boolean directionCheck;
public final boolean directionStrict;
public final long directionPenalty;
public final ActionList directionActions;
public final boolean fastHealCheck;
public final long fastHealInterval;
public final long fastHealBuffer;
public final ActionList fastHealActions;
public final boolean godModeCheck;
public final long godModeLagMinAge;
public final long godModeLagMaxAge;
public final ActionList godModeActions;
public final boolean noSwingCheck;
public final ActionList noSwingActions;
public final boolean reachCheck;
public final long reachPenalty;
public final boolean reachPrecision;
public final boolean reachReduce;
@ -113,10 +63,8 @@ public class FightConfig extends ACheckConfig {
public final ActionList reachActions;
public final boolean selfHitCheck;
public final ActionList selfHitActions;
public final boolean speedCheck;
public final int speedLimit;
public final int speedBuckets;
public final long speedBucketDur;
@ -126,11 +74,9 @@ public class FightConfig extends ACheckConfig {
public final int speedShortTermTicks;
public final ActionList speedActions;
public final boolean wrongTurnEnabled;
public final ActionList wrongTurnActions;
// Special flags:
public final boolean yawRateCheck;
public final boolean cancelDead;
public final boolean knockBackVelocityPvP;
@ -143,94 +89,61 @@ public class FightConfig extends ACheckConfig {
* @param data
* the data
*/
public FightConfig(final ConfigFile data) {
super(data, ConfPaths.FIGHT);
angleCheck = data.getBoolean(ConfPaths.FIGHT_ANGLE_CHECK);
angleThreshold = data.getDouble(ConfPaths.FIGHT_ANGLE_THRESHOLD);
angleActions = data.getOptimizedActionList(ConfPaths.FIGHT_ANGLE_ACTIONS, Permissions.FIGHT_ANGLE);
public FightConfig(final IWorldData worldData) {
super(worldData);
final ConfigFile config = worldData.getRawConfiguration();
angleThreshold = config.getDouble(ConfPaths.FIGHT_ANGLE_THRESHOLD);
angleActions = config.getOptimizedActionList(ConfPaths.FIGHT_ANGLE_ACTIONS, Permissions.FIGHT_ANGLE);
toolChangeAttackPenalty = data.getLong(ConfPaths.FIGHT_TOOLCHANGEPENALTY);
toolChangeAttackPenalty = config.getLong(ConfPaths.FIGHT_TOOLCHANGEPENALTY);
criticalCheck = data.getBoolean(ConfPaths.FIGHT_CRITICAL_CHECK);
criticalFallDistance = data.getDouble(ConfPaths.FIGHT_CRITICAL_FALLDISTANCE);
criticalActions = data.getOptimizedActionList(ConfPaths.FIGHT_CRITICAL_ACTIONS, Permissions.FIGHT_CRITICAL);
criticalFallDistance = config.getDouble(ConfPaths.FIGHT_CRITICAL_FALLDISTANCE);
criticalActions = config.getOptimizedActionList(ConfPaths.FIGHT_CRITICAL_ACTIONS, Permissions.FIGHT_CRITICAL);
directionCheck = data.getBoolean(ConfPaths.FIGHT_DIRECTION_CHECK);
directionStrict = data.getBoolean(ConfPaths.FIGHT_DIRECTION_STRICT);
directionPenalty = data.getLong(ConfPaths.FIGHT_DIRECTION_PENALTY);
directionActions = data.getOptimizedActionList(ConfPaths.FIGHT_DIRECTION_ACTIONS, Permissions.FIGHT_DIRECTION);
directionStrict = config.getBoolean(ConfPaths.FIGHT_DIRECTION_STRICT);
directionPenalty = config.getLong(ConfPaths.FIGHT_DIRECTION_PENALTY);
directionActions = config.getOptimizedActionList(ConfPaths.FIGHT_DIRECTION_ACTIONS, Permissions.FIGHT_DIRECTION);
fastHealCheck = ServerVersion.compareMinecraftVersion("1.9") < 0 ? data.getBoolean(ConfPaths.FIGHT_FASTHEAL_CHECK) : false;
fastHealInterval = data.getLong(ConfPaths.FIGHT_FASTHEAL_INTERVAL);
fastHealBuffer = data.getLong(ConfPaths.FIGHT_FASTHEAL_BUFFER);
fastHealActions = data.getOptimizedActionList(ConfPaths.FIGHT_FASTHEAL_ACTIONS, Permissions.FIGHT_FASTHEAL);
if (ServerVersion.compareMinecraftVersion("1.9") >= 0) {
worldData.overrideCheckActivation(CheckType.FIGHT_FASTHEAL,
AlmostBoolean.NO, OverrideType.PERMANENT,
true);
}
fastHealInterval = config.getLong(ConfPaths.FIGHT_FASTHEAL_INTERVAL);
fastHealBuffer = config.getLong(ConfPaths.FIGHT_FASTHEAL_BUFFER);
fastHealActions = config.getOptimizedActionList(ConfPaths.FIGHT_FASTHEAL_ACTIONS, Permissions.FIGHT_FASTHEAL);
godModeCheck = data.getBoolean(ConfPaths.FIGHT_GODMODE_CHECK);
godModeLagMinAge = data.getLong(ConfPaths.FIGHT_GODMODE_LAGMINAGE);
godModeLagMaxAge = data.getLong(ConfPaths.FIGHT_GODMODE_LAGMAXAGE);
godModeActions = data.getOptimizedActionList(ConfPaths.FIGHT_GODMODE_ACTIONS, Permissions.FIGHT_GODMODE);
godModeLagMinAge = config.getLong(ConfPaths.FIGHT_GODMODE_LAGMINAGE);
godModeLagMaxAge = config.getLong(ConfPaths.FIGHT_GODMODE_LAGMAXAGE);
godModeActions = config.getOptimizedActionList(ConfPaths.FIGHT_GODMODE_ACTIONS, Permissions.FIGHT_GODMODE);
noSwingCheck = data.getBoolean(ConfPaths.FIGHT_NOSWING_CHECK);
noSwingActions = data.getOptimizedActionList(ConfPaths.FIGHT_NOSWING_ACTIONS, Permissions.FIGHT_NOSWING);
noSwingActions = config.getOptimizedActionList(ConfPaths.FIGHT_NOSWING_ACTIONS, Permissions.FIGHT_NOSWING);
reachCheck = data.getBoolean(ConfPaths.FIGHT_REACH_CHECK);
reachSurvivalDistance = data.getDouble(ConfPaths.FIGHT_REACH_SURVIVALDISTANCE, 3.5, 6.0, 4.4);
reachPenalty = data.getLong(ConfPaths.FIGHT_REACH_PENALTY);
reachPrecision = data.getBoolean(ConfPaths.FIGHT_REACH_PRECISION);
reachReduce = data.getBoolean(ConfPaths.FIGHT_REACH_REDUCE);
reachReduceDistance = data.getDouble(ConfPaths.FIGHT_REACH_REDUCEDISTANCE, 0, reachSurvivalDistance, 0.9);
reachReduceStep = data.getDouble(ConfPaths.FIGHT_REACH_REDUCESTEP, 0, reachReduceDistance, 0.15);
reachActions = data.getOptimizedActionList(ConfPaths.FIGHT_REACH_ACTIONS, Permissions.FIGHT_REACH);
reachSurvivalDistance = config.getDouble(ConfPaths.FIGHT_REACH_SURVIVALDISTANCE, 3.5, 6.0, 4.4);
reachPenalty = config.getLong(ConfPaths.FIGHT_REACH_PENALTY);
reachPrecision = config.getBoolean(ConfPaths.FIGHT_REACH_PRECISION);
reachReduce = config.getBoolean(ConfPaths.FIGHT_REACH_REDUCE);
reachReduceDistance = config.getDouble(ConfPaths.FIGHT_REACH_REDUCEDISTANCE, 0, reachSurvivalDistance, 0.9);
reachReduceStep = config.getDouble(ConfPaths.FIGHT_REACH_REDUCESTEP, 0, reachReduceDistance, 0.15);
reachActions = config.getOptimizedActionList(ConfPaths.FIGHT_REACH_ACTIONS, Permissions.FIGHT_REACH);
selfHitCheck = data.getBoolean(ConfPaths.FIGHT_SELFHIT_CHECK);
selfHitActions = data.getOptimizedActionList(ConfPaths.FIGHT_SELFHIT_ACTIONS, Permissions.FIGHT_SELFHIT);
selfHitActions = config.getOptimizedActionList(ConfPaths.FIGHT_SELFHIT_ACTIONS, Permissions.FIGHT_SELFHIT);
speedCheck = data.getBoolean(ConfPaths.FIGHT_SPEED_CHECK);
speedLimit = data.getInt(ConfPaths.FIGHT_SPEED_LIMIT);
speedBuckets = data.getInt(ConfPaths.FIGHT_SPEED_BUCKETS_N, 6);
speedBucketDur = data.getLong(ConfPaths.FIGHT_SPEED_BUCKETS_DUR, 333);
speedBucketFactor = (float) data.getDouble(ConfPaths.FIGHT_SPEED_BUCKETS_FACTOR, 1f);
speedShortTermLimit = data.getInt(ConfPaths.FIGHT_SPEED_SHORTTERM_LIMIT);
speedShortTermTicks = data.getInt(ConfPaths.FIGHT_SPEED_SHORTTERM_TICKS);
speedActions = data.getOptimizedActionList(ConfPaths.FIGHT_SPEED_ACTIONS, Permissions.FIGHT_SPEED);
speedLimit = config.getInt(ConfPaths.FIGHT_SPEED_LIMIT);
speedBuckets = config.getInt(ConfPaths.FIGHT_SPEED_BUCKETS_N, 6);
speedBucketDur = config.getLong(ConfPaths.FIGHT_SPEED_BUCKETS_DUR, 333);
speedBucketFactor = (float) config.getDouble(ConfPaths.FIGHT_SPEED_BUCKETS_FACTOR, 1f);
speedShortTermLimit = config.getInt(ConfPaths.FIGHT_SPEED_SHORTTERM_LIMIT);
speedShortTermTicks = config.getInt(ConfPaths.FIGHT_SPEED_SHORTTERM_TICKS);
speedActions = config.getOptimizedActionList(ConfPaths.FIGHT_SPEED_ACTIONS, Permissions.FIGHT_SPEED);
wrongTurnEnabled = data.getBoolean(ConfPaths.FIGHT_WRONGTURN_CHECK);
wrongTurnActions = data.getOptimizedActionList(ConfPaths.FIGHT_WRONGTURN_ACTIONS,
wrongTurnActions = config.getOptimizedActionList(ConfPaths.FIGHT_WRONGTURN_ACTIONS,
CheckType.FIGHT_WRONGTURN.getPermission());
yawRateCheck = data.getBoolean(ConfPaths.FIGHT_YAWRATE_CHECK, true);
cancelDead = data.getBoolean(ConfPaths.FIGHT_CANCELDEAD);
AlmostBoolean ref = data.getAlmostBoolean(ConfPaths.FIGHT_PVP_KNOCKBACKVELOCITY, AlmostBoolean.MAYBE);
cancelDead = config.getBoolean(ConfPaths.FIGHT_CANCELDEAD);
AlmostBoolean ref = config.getAlmostBoolean(ConfPaths.FIGHT_PVP_KNOCKBACKVELOCITY, AlmostBoolean.MAYBE);
knockBackVelocityPvP = ref == AlmostBoolean.MAYBE ? Bugs.shouldPvpKnockBackVelocity() : ref.decide();
}
/* (non-Javadoc)
* @see fr.neatmonster.nocheatplus.checks.ICheckConfig#isEnabled(fr.neatmonster.nocheatplus.checks.CheckType)
*/
@Override
public final boolean isEnabled(final CheckType checkType) {
switch (checkType) {
case FIGHT_ANGLE:
return angleCheck;
case FIGHT_CRITICAL:
return criticalCheck;
case FIGHT_DIRECTION:
return directionCheck;
case FIGHT_GODMODE:
return godModeCheck;
case FIGHT_NOSWING:
return noSwingCheck;
case FIGHT_REACH:
return reachCheck;
case FIGHT_SPEED:
return speedCheck;
case FIGHT_SELFHIT:
return selfHitCheck;
case FIGHT_FASTHEAL:
return fastHealCheck;
default:
return true;
}
}
}

View File

@ -14,21 +14,11 @@
*/
package fr.neatmonster.nocheatplus.checks.fight;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.UUID;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.access.ACheckData;
import fr.neatmonster.nocheatplus.checks.access.CheckDataFactory;
import fr.neatmonster.nocheatplus.checks.access.ICheckData;
import fr.neatmonster.nocheatplus.checks.access.IRemoveSubCheckData;
import fr.neatmonster.nocheatplus.checks.access.SubCheckDataFactory;
import fr.neatmonster.nocheatplus.utilities.CheckTypeUtil;
import fr.neatmonster.nocheatplus.utilities.PenaltyTime;
import fr.neatmonster.nocheatplus.utilities.ds.count.ActionFrequency;
@ -37,112 +27,6 @@ import fr.neatmonster.nocheatplus.utilities.ds.count.ActionFrequency;
*/
public class FightData extends ACheckData implements IRemoveSubCheckData {
public static class FightDataFactory implements CheckDataFactory {
protected FightDataFactory() {
// Discourage creation here.
};
@Override
public final ICheckData getData(final Player player) {
return FightData.getData(player);
}
@Override
public ICheckData getDataIfPresent(UUID playerId, String playerName) {
return FightData.playersMap.get(playerName);
}
@Override
public ICheckData removeData(final String playerName) {
return FightData.removeData(playerName);
}
@Override
public void removeAllData() {
clear();
}
}
/** The factory for general fight data. */
public static final CheckDataFactory factory = new FightDataFactory();
/** SelfHit factory */
public static final CheckDataFactory selfHitDataFactory = new SubCheckDataFactory<FightData>(CheckType.FIGHT, factory) {
@Override
protected FightData getData(String playerName) {
return playersMap.get(playerName);
}
@Override
public ICheckData getDataIfPresent(UUID playerId, String playerName) {
return playersMap.get(playerName);
}
@Override
protected Collection<String> getPresentData() {
return playersMap.keySet();
}
@Override
protected boolean hasData(String playerName) {
return playersMap.containsKey(playerName);
}
@Override
protected boolean removeFromData(String playerName, FightData data) {
if (data.selfHitVL.score(1f) > 0f) {
data.selfHitVL.clear(System.currentTimeMillis());
return true;
}
else {
return false;
}
}
};
public static CheckDataFactory getCheckDataFactory(CheckType checkType) {
if (checkType != CheckType.FIGHT && !CheckTypeUtil.isAncestor(CheckType.FIGHT, checkType)) {
throw new IllegalArgumentException("Can only return a CheckDataFactory for the check group FIGHT.");
}
switch(checkType) {
// Note that CheckType does need adaption for new entries (!).
case FIGHT_SELFHIT:
return selfHitDataFactory;
default:
return factory;
}
}
/** The map containing the data per players. */
protected static final Map<String, FightData> playersMap = new HashMap<String, FightData>(); // Not sure about visibility (selfhit).
/**
* Gets the data of a specified player.
*
* @param player
* the player
* @return the data
*/
public static FightData getData(final Player player) {
if (!playersMap.containsKey(player.getName()))
playersMap.put(player.getName(), new FightData(FightConfig.getConfig(player)));
return playersMap.get(player.getName());
}
public static ICheckData removeData(final String playerName) {
return playersMap.remove(playerName);
}
public static void clear(){
playersMap.clear();
}
// Violation levels.
public double angleVL;
public double criticalVL;
@ -225,7 +109,6 @@ public class FightData extends ACheckData implements IRemoveSubCheckData {
public FightData(final FightConfig config){
super(config);
speedBuckets = new ActionFrequency(config.speedBuckets, config.speedBucketDur);
// Start with full fast-heal buffer.
fastHealBuffer = config.fastHealBuffer;

View File

@ -59,7 +59,7 @@ import fr.neatmonster.nocheatplus.components.registry.event.IGenericInstanceHand
import fr.neatmonster.nocheatplus.components.registry.feature.JoinLeaveListener;
import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.players.DataManager;
import fr.neatmonster.nocheatplus.players.PlayerData;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.stats.Counters;
import fr.neatmonster.nocheatplus.utilities.TickTask;
import fr.neatmonster.nocheatplus.utilities.build.BuildParameters;
@ -139,18 +139,19 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
*/
private boolean handleNormalDamage(final Player player, final boolean attackerIsFake,
final Entity damaged, final boolean damagedIsFake,
final double originalDamage, final double finalDamage, final int tick, final FightData data) {
final double originalDamage, final double finalDamage,
final int tick, final FightData data, final IPlayerData pData) {
final PlayerData pData = DataManager.getPlayerData(player);
final FightConfig cc = FightConfig.getConfig(player);
final FightConfig cc = pData.getGenericInstance(FightConfig.class);
// Hotfix attempt for enchanted books.
// TODO: maybe a generalized version for the future...
// Illegal enchantments hotfix check.
if (Items.checkIllegalEnchantmentsAllHands(player)) {
if (Items.checkIllegalEnchantmentsAllHands(player, pData)) {
return true;
}
final boolean debug = pData.isDebugActive(checkType);
boolean cancelled = false;
final String worldName = player.getWorld().getName();
@ -181,9 +182,11 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
else {
tickAge = tick - data.lastAttackTick;
// TODO: Maybe use 3d distance if dy(normalized) is too big.
targetMove = TrigUtil.distance(data.lastAttackedX, data.lastAttackedZ, damagedLoc.getX(), damagedLoc.getZ());
targetMove = TrigUtil.distance(data.lastAttackedX, data.lastAttackedZ,
damagedLoc.getX(), damagedLoc.getZ());
msAge = (long) (50f * TickTask.getLag(50L * tickAge, true) * (float) tickAge);
normalizedMove = msAge == 0 ? targetMove : targetMove * Math.min(20.0, 1000.0 / (double) msAge);
normalizedMove = msAge == 0 ? targetMove
: targetMove * Math.min(20.0, 1000.0 / (double) msAge);
}
// TODO: calculate factor for dists: ticks * 50 * lag
@ -199,18 +202,23 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
// damagedPlayer.getLocation(useLoc2);
// }
// Log.
if (data.debug && DataManager.getPlayerData(damagedPlayer).hasPermission(
if (debug && DataManager.getPlayerData(damagedPlayer).hasPermission(
Permissions.ADMINISTRATION_DEBUG, damagedPlayer)) {
damagedPlayer.sendMessage("Attacked by " + player.getName() + ": inv=" + mcAccess.getHandle().getInvulnerableTicks(damagedPlayer) + " ndt=" + damagedPlayer.getNoDamageTicks());
}
// Check for self hit exploits (mind that projectiles are excluded from this.)
if (selfHit.isEnabled(player) && selfHit.check(player, damagedPlayer, data, cc)) {
if (selfHit.isEnabled(player, pData) && selfHit.check(player, damagedPlayer, data, cc)) {
cancelled = true;
}
// Get+update the damaged players.
// TODO: Problem with NPCs: data stays (not a big problem).
// (This is done even if the event has already been cancelled, to keep track, if the player is on a horse.)
damagedTrace = MovingData.getData(damagedPlayer).updateTrace(damagedPlayer, damagedLoc, tick, damagedIsFake ? null : mcAccess.getHandle());
damagedTrace = DataManager.getPlayerData(damagedPlayer).getGenericInstance(
MovingData.class
).updateTrace(
damagedPlayer, damagedLoc, tick,
damagedIsFake ? null : mcAccess.getHandle()
);
}
else {
damagedPlayer = null; // TODO: This is a temporary workaround.
@ -222,7 +230,7 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
}
// Log generic properties of this attack.
if (data.debug) {
if (debug) {
debug(player, "Attacks " + (damagedPlayer == null ? ("entity " + damaged.getType()) : ("player" + damagedPlayer.getName())) + " damage=" + (finalDamage == originalDamage ? finalDamage : (originalDamage + "/" + finalDamage)));
}
@ -246,7 +254,7 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
if (tick == data.sweepTick && locHashCode == data.sweepLocationHashCode) {
// TODO: Might limit the amount of 'too far off' sweep hits, possibly silent cancel for low frequency.
// Could further guard by checking equality of loc to last location.
if (data.debug) {
if (debug) {
debug(player, "(Assume sweep attack follow up damage.)");
}
return cancelled;
@ -273,23 +281,25 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
// TODO: Add as real check.
// TODO: Add something on packet level already.
if (wrongTurn.isEnabled(player, cc, pData) && wrongTurn.check(damagedPlayer, loc, data, cc)) {
if (pData.isCheckActive(CheckType.FIGHT_WRONGTURN, damagedPlayer)
&& wrongTurn.check(damagedPlayer, loc, data, cc)) {
cancelled = true;
}
// Run through the main checks.
if (!cancelled && speed.isEnabled(player)) {
if (speed.check(player, now)) {
if (!cancelled && speed.isEnabled(player, pData)) {
if (speed.check(player, now, data, cc, pData)) {
cancelled = true;
// Still feed the improbable.
if (data.speedVL > 50) {
Improbable.check(player, 2f, now, "fight.speed");
Improbable.check(player, 2f, now, "fight.speed", pData);
}
else {
Improbable.feed(player, 2f, now);
}
}
else if (normalizedMove > 2.0 && Improbable.check(player, 1f, now, "fight.speed")) {
else if (normalizedMove > 2.0 && Improbable.check(player, 1f, now,
"fight.speed", pData)) {
// Feed improbable in case of ok-moves too.
// TODO: consider only feeding if attacking with higher average speed (!)
cancelled = true;
@ -297,12 +307,12 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
}
// TODO: Consider to always check improbable (first?). At least if config.always or speed or net.attackfrequency are enabled.
if (!cancelled && critical.isEnabled(player) && critical.check(player, loc, data, cc, pData)) {
if (!cancelled && critical.isEnabled(player, pData) && critical.check(player, loc, data, cc, pData)) {
// TODO: Check config for settings.
cancelled = true;
}
if (!cancelled && noSwing.isEnabled(player) && noSwing.check(player, data, cc)) {
if (!cancelled && noSwing.isEnabled(player, pData) && noSwing.check(player, data, cc)) {
cancelled = true;
}
@ -313,13 +323,14 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
}
if (!cancelled) {
final boolean reachEnabled = reach.isEnabled(player);
final boolean directionEnabled = direction.isEnabled(player);
final boolean reachEnabled = reach.isEnabled(player, pData);
final boolean directionEnabled = direction.isEnabled(player, pData);
if (reachEnabled || directionEnabled) {
if (damagedTrace != null) {
// Checks that use the LocationTrace instance of the attacked entity/player.
cancelled = locationTraceChecks(player, loc, data, cc, pData,
damaged, damagedIsFake, damagedLoc, damagedTrace, tick, now, reachEnabled, directionEnabled);
damaged, damagedIsFake, damagedLoc, damagedTrace, tick, now, debug,
reachEnabled, directionEnabled);
}
else {
// Still use the classic methods for non-players. maybe[]
@ -337,18 +348,19 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
// Check angle with allowed window.
// TODO: Actual angle needs to be related to the best matching trace element(s) (loop checks).
if (angle.isEnabled(player)) {
if (angle.isEnabled(player, pData)) {
// TODO: Revise, use own trace.
// The "fast turning" checks are checked in any case because they accumulate data.
// Improbable yaw changing: Moving events might be missing up to a ten degrees change.
if (Combined.checkYawRate(player, loc.getYaw(), now, worldName, cc.yawRateCheck)) {
if (Combined.checkYawRate(player, loc.getYaw(), now, worldName,
pData.isCheckActive(CheckType.COMBINED_YAWRATE, player), pData)) {
// (Check or just feed).
// TODO: Work into this somehow attacking the same aim and/or similar aim position (not cancel then).
cancelled = true;
}
// Angle check.
if (angle.check(player, loc, damaged, worldChanged, data, cc)) {
if (!cancelled && data.debug) {
if (!cancelled && debug) {
debug(player, "FIGHT_ANGLE cancel without yawrate cancel.");
}
cancelled = true;
@ -370,14 +382,14 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
// TODO: Confine further with simple pre-conditions.
// TODO: Evaluate if moving traces can help here.
if (!cancelled && TrigUtil.distance(loc.getX(), loc.getZ(), damagedLoc.getX(), damagedLoc.getZ()) < 4.5) {
final MovingData mData = MovingData.getData(player);
final MovingData mData = pData.getGenericInstance(MovingData.class);
// Check if fly checks is an issue at all, re-check "real sprinting".
final PlayerMoveData lastMove = mData.playerMoves.getFirstPastMove();
if (lastMove.valid && mData.liftOffEnvelope == LiftOffEnvelope.NORMAL) {
final double hDist = TrigUtil.xzDistance(loc, lastMove.from);
if (hDist >= 0.23) {
// TODO: Might need to check hDist relative to speed / modifiers.
final MovingConfig mCc = MovingConfig.getConfig(player);
final MovingConfig mCc = pData.getGenericInstance(MovingConfig.class);
final PlayerMoveInfo moveInfo = auxMoving.usePlayerMoveInfo();
moveInfo.set(player, loc, null, mCc.yOnGround);
if (now <= mData.timeSprinting + mCc.sprintingGrace
@ -385,7 +397,8 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
// Judge as "lost sprint" problem.
// TODO: What would mData.lostSprintCount > 0 mean here?
mData.lostSprintCount = 7;
if ((data.debug || mCc.debug) && BuildParameters.debugLevel > 0) {
if ((debug || pData.isDebugActive(CheckType.MOVING))
&& BuildParameters.debugLevel > 0) {
debug(player, "lostsprint: hDist to last from: " + hDist + " | targetdist=" + TrigUtil.distance(loc.getX(), loc.getZ(), damagedLoc.getX(), damagedLoc.getZ()) + " | sprinting=" + player.isSprinting() + " | food=" + player.getFoodLevel() +" | hbuf=" + mData.sfHorizontalBuffer);
}
}
@ -398,7 +411,7 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
// (Cancel after sprinting hacks, because of potential fp).
if (!cancelled && data.attackPenalty.isPenalty(now)) {
cancelled = true;
if (data.debug) {
if (debug) {
debug(player, "~ attack penalty.");
}
}
@ -426,10 +439,11 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
* @return If to cancel (true) or not (false).
*/
private boolean locationTraceChecks(final Player player, final Location loc,
final FightData data, final FightConfig cc, final PlayerData pData,
final FightData data, final FightConfig cc, final IPlayerData pData,
final Entity damaged, final boolean damagedIsFake,
final Location damagedLoc, LocationTrace damagedTrace,
final long tick, final long now, final boolean reachEnabled, final boolean directionEnabled) {
final long tick, final long now, final boolean debug,
final boolean reachEnabled, final boolean directionEnabled) {
// TODO: Order / splitting off generic stuff.
/*
* TODO: Abstract: interface with common setup/loop/post routine, only
@ -501,7 +515,7 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
}
}
// TODO: Log exact state, probably record min/max latency (individually).
if (data.debug && latencyEstimate >= 0) {
if (debug && latencyEstimate >= 0) {
debug(player, "Latency estimate: " + latencyEstimate + " ms."); // FCFS rather, at present.
}
return cancelled;
@ -518,33 +532,44 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
final Entity damaged = event.getEntity();
final Player damagedPlayer = damaged instanceof Player ? (Player) damaged : null;
final FightData damagedData = damagedPlayer == null ? null : FightData.getData(damagedPlayer);
final FightData damagedData;
final boolean damagedIsDead = damaged.isDead();
final boolean damagedIsFake = !crossPlugin.getHandle().isNativeEntity(damaged);
if (damagedPlayer != null && !damagedIsDead) {
// God mode check.
// (Do not test the savage.)
if (godMode.isEnabled(damagedPlayer)
&& godMode.check(damagedPlayer, damagedIsFake, BridgeHealth.getDamage(event), damagedData)) {
// It requested to "cancel" the players invulnerability, so set their noDamageTicks to 0.
damagedPlayer.setNoDamageTicks(0);
}
// Adjust buffer for fast heal checks.
if (BridgeHealth.getHealth(damagedPlayer) >= BridgeHealth.getMaxHealth(damagedPlayer)) {
// TODO: Might use the same FightData instance for GodMode.
if (damagedData.fastHealBuffer < 0) {
// Reduce negative buffer with each full health.
damagedData.fastHealBuffer /= 2;
if (damagedPlayer != null) {
final IPlayerData damagedPData = DataManager.getPlayerData(damagedPlayer);
damagedData = damagedPData.getGenericInstance(FightData.class);
if (!damagedIsDead) {
// God mode check.
// (Do not test the savage.)
if (damagedPData.isCheckActive(CheckType.FIGHT_GODMODE, damagedPlayer)
&& godMode.check(damagedPlayer, damagedIsFake,
BridgeHealth.getDamage(event), damagedData, damagedPData)) {
// It requested to "cancel" the players invulnerability, so set their noDamageTicks to 0.
damagedPlayer.setNoDamageTicks(0);
}
// Set reference time.
damagedData.fastHealRefTime = System.currentTimeMillis();
// Adjust buffer for fast heal checks.
if (BridgeHealth.getHealth(damagedPlayer) >= BridgeHealth.getMaxHealth(damagedPlayer)) {
// TODO: Might use the same FightData instance for GodMode.
if (damagedData.fastHealBuffer < 0) {
// Reduce negative buffer with each full health.
damagedData.fastHealBuffer /= 2;
}
// Set reference time.
damagedData.fastHealRefTime = System.currentTimeMillis();
}
// TODO: TEST: Check unused velocity for the damaged player. (Needs more efficient pre condition checks.)
}
// TODO: TEST: Check unused velocity for the damaged player. (Needs more efficient pre condition checks.)
if (damagedData.debug) {
if (damagedPData.isDebugActive(checkType)) {
// TODO: Pass result to further checks for reference?
UnusedVelocity.checkUnusedVelocity(damagedPlayer, CheckType.FIGHT);
UnusedVelocity.checkUnusedVelocity(damagedPlayer, CheckType.FIGHT, damagedPData);
}
}
else {
damagedData = null;
}
// Attacking entities.
if (event instanceof EntityDamageByEntityEvent) {
onEntityDamageByEntity(damaged, damagedPlayer, damagedIsDead, damagedIsFake,
@ -591,14 +616,16 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
}
}
final FightData attackerData;
final IPlayerData attackerPData = attacker == null ? null : DataManager.getPlayerData(attacker);
if (attacker != null) {
attackerData = FightData.getData(attacker);
attackerData = attackerPData.getGenericInstance(FightData.class);
// TODO: TEST: Check unused velocity for the attacker. (Needs more efficient pre condition checks.)
if (attackerData.debug) {
if (attackerPData.isDebugActive(checkType)) {
// TODO: Pass result to further checks for reference?
// TODO: attackerData.debug flag.
// TODO: Fake players likely have unused velocity, just clear unused?
UnusedVelocity.checkUnusedVelocity(attacker, CheckType.FIGHT);
UnusedVelocity.checkUnusedVelocity(attacker, CheckType.FIGHT, attackerPData);
}
// Workaround for subsequent melee damage eventsfor explosions. TODO: Legacy or not, need a KB.
if (damageCause == DamageCause.BLOCK_EXPLOSION || damageCause == DamageCause.ENTITY_EXPLOSION) {
@ -621,7 +648,7 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
}
// Prevent attacking if a set back is scheduled.
else if (MovingUtil.hasScheduledPlayerSetBack(player)) {
if (attackerData.debug) {
if (attackerPData.isDebugActive(checkType)) {
// Use fight data flag for efficiency.
debug(attacker, "Prevent melee attack, due to a scheduled set back.");
}
@ -631,7 +658,7 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
else if (handleNormalDamage(player, !crossPlugin.getHandle().isNativePlayer(player),
damaged, damagedIsFake,
BridgeHealth.getOriginalDamage(event), BridgeHealth.getFinalDamage(event),
tick, attackerData)) {
tick, attackerData, attackerPData)) {
event.setCancelled(true);
}
}
@ -643,7 +670,8 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
final Entity damaged = event.getEntity();
if (damaged instanceof Player) {
final Player damagedPlayer = (Player) damaged;
final FightData damagedData = FightData.getData(damagedPlayer);
final IPlayerData damagedPData = DataManager.getPlayerData(damagedPlayer);
final FightData damagedData = damagedPData.getGenericInstance(FightData.class);
final int ndt = damagedPlayer.getNoDamageTicks();
if (damagedData.lastDamageTick == TickTask.getTick() && damagedData.lastNoDamageTicks != ndt) {
// Plugin compatibility thing.
@ -654,9 +682,11 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
case ENTITY_ATTACK:
if (event instanceof EntityDamageByEntityEvent) {
final Entity entity = ((EntityDamageByEntityEvent) event).getDamager();
if ((entity instanceof Player) && !damagedPlayer.isInsideVehicle() && FightConfig.getConfig(damagedPlayer).knockBackVelocityPvP) {
if ((entity instanceof Player) && !damagedPlayer.isInsideVehicle()
&& damagedPData.getGenericInstance(FightConfig.class).knockBackVelocityPvP) {
// TODO: Use the velocity event that is sent anyway and replace x/z if 0 (queue max. values).
applyKnockBack((Player) entity, damagedPlayer, damagedData);
applyKnockBack((Player) entity, damagedPlayer,
damagedData, damagedPData);
}
}
default:
@ -671,17 +701,18 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
* @param damagedPlayer
* @param damagedData
*/
private void applyKnockBack(final Player attacker, final Player damagedPlayer, final FightData damagedData) {
private void applyKnockBack(final Player attacker, final Player damagedPlayer,
final FightData damagedData, final IPlayerData pData) {
final double level = getKnockBackLevel(attacker);
final MovingData mdata = MovingData.getData(damagedPlayer);
final MovingConfig mcc = MovingConfig.getConfig(damagedPlayer);
final MovingData mdata = pData.getGenericInstance(MovingData.class);
final MovingConfig mcc = pData.getGenericInstance(MovingConfig.class);
// TODO: How is the direction really calculated?
// Aim at sqrt(vx * vx + vz * vz, 2), not the exact direction.
final double vx = level / Math.sqrt(8.0);
final double vz = vx;
final double vy = 0.462; // TODO: (0.365) Needs other workarounds, to allow more when moving off ground (vel + GRAVITY_MAX or max jump gain + little?).
useLoc1.setWorld(null); // Cleanup.
if (damagedData.debug || mdata.debug) {
if (pData.isDebugActive(checkType) || pData.isDebugActive(CheckType.MOVING)) {
debug(damagedPlayer, "Received knockback level: " + level);
}
mdata.addVelocity(damagedPlayer, mcc, vx, vy, vz, VelocityFlags.ORIGIN_PVP);
@ -742,7 +773,8 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
* TODO: First one always fails: Packet inversion on 1.12.2? This could
* be moved to packet level (register either).
*/
FightData.getData(event.getPlayer()).noSwingArmSwung = true;
DataManager.getGenericInstance(event.getPlayer(),
FightData.class).noSwingArmSwung = true;
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
@ -763,7 +795,9 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
return;
}
// TODO: EATING reason / peaceful difficulty / regen potion - byCaptain SpigotMC
if (fastHeal.isEnabled(player) && fastHeal.check(player)) {
final IPlayerData pData = DataManager.getPlayerData(player);
if (pData.isCheckActive(CheckType.FIGHT_FASTHEAL, player)
&& fastHeal.check(player, pData)) {
// TODO: Can clients force events with 0-re-gain ?
event.setCancelled(true);
}
@ -776,7 +810,7 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
return;
}
final Player player = (Player) entity;
final FightData data = FightData.getData(player);
final FightData data = DataManager.getGenericInstance(player, FightData.class);
// Adjust god mode data:
// Remember the time.
data.regainHealthTime = System.currentTimeMillis();
@ -792,21 +826,23 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
@Override
public void playerLeaves(final Player player) {
final FightData data = FightData.getData(player);
final FightData data = DataManager.getGenericInstance(player, FightData.class);
data.angleHits.clear();
}
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerChangedWorld(final PlayerChangedWorldEvent event) {
FightData.getData(event.getPlayer()).onWorldChange();
DataManager.getGenericInstance(event.getPlayer(),
FightData.class).onWorldChange();
}
@EventHandler(ignoreCancelled = false, priority = EventPriority.MONITOR)
public void onItemHeld(final PlayerItemHeldEvent event) {
final Player player = event.getPlayer();
final long penalty = FightConfig.getConfig(player).toolChangeAttackPenalty;
final IPlayerData pData = DataManager.getPlayerData(player);
final long penalty = pData.getGenericInstance(FightConfig.class).toolChangeAttackPenalty;
if (penalty > 0 ) {
FightData.getData(player).attackPenalty.applyPenalty(penalty);
pData.getGenericInstance(FightData.class).attackPenalty.applyPenalty(penalty);
}
}

View File

@ -24,6 +24,7 @@ import fr.neatmonster.nocheatplus.checks.net.NetData;
import fr.neatmonster.nocheatplus.compat.BridgeHealth;
import fr.neatmonster.nocheatplus.compat.IBridgeCrossPlugin;
import fr.neatmonster.nocheatplus.components.registry.event.IGenericInstanceHandle;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.utilities.CheckUtils;
import fr.neatmonster.nocheatplus.utilities.TickTask;
@ -47,7 +48,8 @@ public class GodMode extends Check {
* @param damage
* @return
*/
public boolean check(final Player player, final boolean playerIsFake, final double damage, final FightData data){
public boolean check(final Player player, final boolean playerIsFake,
final double damage, final FightData data, final IPlayerData pData){
final int tick = TickTask.getTick();
final int noDamageTicks = Math.max(0, player.getNoDamageTicks());
@ -145,16 +147,16 @@ public class GodMode extends Check {
}
}
final FightConfig cc = FightConfig.getConfig(player);
final FightConfig cc = pData.getGenericInstance(FightConfig.class);
// Check for client side lag.
final long now = System.currentTimeMillis();
final long maxAge = cc.godModeLagMaxAge;
long keepAlive = Long.MIN_VALUE;
if (NCPAPIProvider.getNoCheatPlusAPI().hasFeatureTag("checks", "KeepAliveFrequency")) {
keepAlive = ((NetData) (CheckType.NET_KEEPALIVEFREQUENCY.getDataFactory().getData(player))).lastKeepAliveTime;
keepAlive = pData.getGenericInstance(NetData.class).lastKeepAliveTime;
}
keepAlive = Math.max(keepAlive, CheckUtils.guessKeepAliveTime(player, now, maxAge));
keepAlive = Math.max(keepAlive, CheckUtils.guessKeepAliveTime(player, now, maxAge, pData));
if (keepAlive != Double.MIN_VALUE && now - keepAlive > cc.godModeLagMinAge && now - keepAlive < maxAge){
// Assume lag.
@ -169,7 +171,8 @@ public class GodMode extends Check {
if (data.godModeAcc > 2){
// TODO: To match with old checks vls / actions, either change actions or apply a factor.
data.godModeVL += delta;
if (executeActions(player, data.godModeVL, delta, FightConfig.getConfig(player).godModeActions).willCancel()){
if (executeActions(player, data.godModeVL, delta,
pData.getGenericInstance(FightConfig.class).godModeActions).willCancel()){
cancel = true;
}
else {

View File

@ -29,7 +29,7 @@ import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.combined.Improbable;
import fr.neatmonster.nocheatplus.checks.moving.location.tracking.LocationTrace.ITraceEntry;
import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.players.PlayerData;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.utilities.StringUtil;
import fr.neatmonster.nocheatplus.utilities.TickTask;
import fr.neatmonster.nocheatplus.utilities.location.TrigUtil;
@ -71,7 +71,7 @@ public class Reach extends Check {
*/
public boolean check(final Player player, final Location pLoc,
final Entity damaged, final boolean damagedIsFake, final Location dRef,
final FightData data, final FightConfig cc, final PlayerData pData) {
final FightData data, final FightConfig cc, final IPlayerData pData) {
boolean cancel = false;
// The maximum distance allowed to interact with an entity in survival mode.
@ -114,7 +114,8 @@ public class Reach extends Check {
// Execute whatever actions are associated with this check and the violation level and find out if we should
// cancel the event.
cancel = executeActions(player, data.reachVL, violation, cc.reachActions).willCancel();
if (Improbable.check(player, (float) violation / 2f, System.currentTimeMillis(), "fight.reach")){
if (Improbable.check(player, (float) violation / 2f, System.currentTimeMillis(),
"fight.reach", pData)){
cancel = true;
}
if (cancel && cc.reachPenalty > 0){
@ -146,7 +147,7 @@ public class Reach extends Check {
data.reachMod = Math.min(1.0, data.reachMod + DYNAMIC_STEP);
}
if (data.debug && pData.hasPermission(Permissions.ADMINISTRATION_DEBUG, player)){
if (pData.isDebugActive(type) && pData.hasPermission(Permissions.ADMINISTRATION_DEBUG, player)){
player.sendMessage("NC+: Attack/reach " + damaged.getType()+ " height="+ StringUtil.fdec3.format(height) + " dist=" + StringUtil.fdec3.format(lenpRel) +" @" + StringUtil.fdec3.format(reachMod));
}
@ -163,7 +164,9 @@ public class Reach extends Check {
* @param cc
* @return
*/
public ReachContext getContext(final Player player, final Location pLoc, final Entity damaged, final Location damagedLoc, final FightData data, final FightConfig cc) {
public ReachContext getContext(final Player player, final Location pLoc,
final Entity damaged, final Location damagedLoc,
final FightData data, final FightConfig cc) {
final ReachContext context = new ReachContext();
context.distanceLimit = player.getGameMode() == GameMode.CREATIVE ? CREATIVE_DISTANCE : cc.reachSurvivalDistance + getDistMod(damaged);
context.distanceMin = (context.distanceLimit - cc.reachReduceDistance) / context.distanceLimit;
@ -234,7 +237,7 @@ public class Reach extends Check {
*/
public boolean loopFinish(final Player player, final Location pLoc, final Entity damaged,
final ReachContext context, final ITraceEntry traceEntry, final boolean forceViolation,
final FightData data, final FightConfig cc, final PlayerData pData) {
final FightData data, final FightConfig cc, final IPlayerData pData) {
final double lenpRel = forceViolation && context.minViolation != Double.MAX_VALUE ? context.minViolation : context.minResult;
if (lenpRel == Double.MAX_VALUE) {
return false;
@ -251,7 +254,8 @@ public class Reach extends Check {
// Execute whatever actions are associated with this check and the violation level and find out if we should
// cancel the event.
cancel = executeActions(player, data.reachVL, violation, cc.reachActions).willCancel();
if (Improbable.check(player, (float) violation / 2f, System.currentTimeMillis(), "fight.reach")){
if (Improbable.check(player, (float) violation / 2f, System.currentTimeMillis(),
"fight.reach", pData)){
cancel = true;
}
if (cancel && cc.reachPenalty > 0){
@ -284,7 +288,7 @@ public class Reach extends Check {
data.reachMod = Math.min(1.0, data.reachMod + DYNAMIC_STEP);
}
if (data.debug && pData.hasPermission(Permissions.ADMINISTRATION_DEBUG, player)){
if (pData.isDebugActive(type) && pData.hasPermission(Permissions.ADMINISTRATION_DEBUG, player)){
// TODO: Height: remember successful ITraceEntry
player.sendMessage("NC+: Attack/reach " + damaged.getType()+ (traceEntry == null ? "" : (" height=" + traceEntry.getBoxMarginVertical())) + " dist=" + StringUtil.fdec3.format(lenpRel) +" @" + StringUtil.fdec3.format(data.reachMod));
}

View File

@ -20,6 +20,7 @@ import fr.neatmonster.nocheatplus.actions.ParameterName;
import fr.neatmonster.nocheatplus.checks.Check;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.ViolationData;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.utilities.TickTask;
/**
@ -42,10 +43,11 @@ public class Speed extends Check {
* @param now
* @return true, if successful
*/
public boolean check(final Player player, final long now) {
final FightConfig cc = FightConfig.getConfig(player);
final FightData data = FightData.getData(player);
public boolean check(final Player player, final long now,
final FightData data, final FightConfig cc,
final IPlayerData pData) {
final boolean lag = pData.getCurrentWorldData().shouldAdjustToLag(type);
boolean cancel = false;
// Add to frequency.
@ -53,7 +55,7 @@ public class Speed extends Check {
// Medium term (normalized to one second), account for server side lag.
final long fullTime = cc.speedBucketDur * cc.speedBuckets;
final float fullLag = cc.lag ? TickTask.getLag(fullTime, true) : 1f;
final float fullLag = lag ? TickTask.getLag(fullTime, true) : 1f;
final float total = data.speedBuckets.score(cc.speedBucketFactor) * 1000f / (fullLag * fullTime);
// Short term.
@ -65,7 +67,7 @@ public class Speed extends Check {
}
else if (tick - data.speedShortTermTick < cc.speedShortTermTicks){
// Account for server side lag.
if (!cc.lag || TickTask.getLag(50L * (tick - data.speedShortTermTick), true) < 1.5f){
if (!lag || TickTask.getLag(50L * (tick - data.speedShortTermTick), true) < 1.5f){
// Within range, add.
data.speedShortTermCount ++;
}

View File

@ -1,3 +1,17 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package fr.neatmonster.nocheatplus.checks.fight;
import org.bukkit.Location;
@ -18,7 +32,8 @@ public class WrongTurn extends Check {
super(CheckType.FIGHT_WRONGTURN);
}
public boolean check (final Player player, final Location loc, final FightData data, final FightConfig cc) {
public boolean check (final Player player, final Location loc,
final FightData data, final FightConfig cc) {
final float pitch = loc.getPitch();

View File

@ -26,6 +26,7 @@ import fr.neatmonster.nocheatplus.checks.access.ICheckConfig;
import fr.neatmonster.nocheatplus.checks.access.ICheckData;
import fr.neatmonster.nocheatplus.checks.net.FlyingQueueHandle;
import fr.neatmonster.nocheatplus.checks.net.FlyingQueueLookBlockChecker;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.utilities.collision.CollideRayVsAABB;
import fr.neatmonster.nocheatplus.utilities.collision.ICollideRayVsAABB;
import fr.neatmonster.nocheatplus.utilities.location.LocUtil;
@ -128,7 +129,8 @@ public abstract class AbstractBlockDirectionCheck<D extends ICheckData, C extend
* @return True, if the check has been failed.
*/
public boolean check(final Player player, final Location loc, final double eyeHeight,
final Block block, final FlyingQueueHandle flyingHandle, final D data, final C cc) {
final Block block, final FlyingQueueHandle flyingHandle,
final D data, final C cc, final IPlayerData pData) {
boolean cancel = false;
// How far "off" is the player with their aim.
@ -151,7 +153,7 @@ public abstract class AbstractBlockDirectionCheck<D extends ICheckData, C extend
// TODO: Consider a protected field with a tolerance value.
if (distance != Double.MAX_VALUE) {
distance = Math.sqrt(distance);
if (data.getDebug()) {
if (pData.isDebugActive(type)) {
outputDebugFail(player, boulder, distance);
}

View File

@ -18,6 +18,8 @@ import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.checks.Check;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.players.DataManager;
import fr.neatmonster.nocheatplus.players.IPlayerData;
/**
* The Drop check will find out if a player drops too many items within a short amount of time.
@ -42,8 +44,9 @@ public class Drop extends Check {
// Take time once.
final long time = System.currentTimeMillis();
final InventoryConfig cc = InventoryConfig.getConfig(player);
final InventoryData data = InventoryData.getData(player);
final IPlayerData pData = DataManager.getPlayerData(player);
final InventoryConfig cc = pData.getGenericInstance(InventoryConfig.class);
final InventoryData data = pData.getGenericInstance(InventoryData.class);
boolean cancel = false;

View File

@ -23,7 +23,7 @@ import fr.neatmonster.nocheatplus.checks.Check;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.ViolationData;
import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.players.PlayerData;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.utilities.InventoryUtil;
import fr.neatmonster.nocheatplus.utilities.TickTask;
@ -92,7 +92,8 @@ public class FastClick extends Check {
public boolean check(final Player player, final long now,
final InventoryView view, final int slot, final ItemStack cursor,
final ItemStack clicked, final boolean isShiftClick,
final InventoryData data, final InventoryConfig cc, final PlayerData pData) {
final InventoryData data, final InventoryConfig cc,
final IPlayerData pData) {
// Take time once.
final float amount;
@ -149,7 +150,7 @@ public class FastClick extends Check {
cancel = executeActions(vd).willCancel();
}
if (data.debug && pData.hasPermission(Permissions.ADMINISTRATION_DEBUG, player)){
if (pData.isDebugActive(type) && pData.hasPermission(Permissions.ADMINISTRATION_DEBUG, player)){
player.sendMessage("FastClick: " + data.fastClickFreq.bucketScore(0) + " | " + data.fastClickFreq.score(1f) + " | cursor=" + cursor + " | clicked=" + clicked);
}

View File

@ -21,7 +21,7 @@ import fr.neatmonster.nocheatplus.checks.Check;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.players.DataManager;
import fr.neatmonster.nocheatplus.players.PlayerData;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.utilities.TickTask;
/**
@ -49,9 +49,9 @@ public class InstantBow extends Check {
*/
public boolean check(final Player player, final float force, final long now) {
final PlayerData pData = DataManager.getPlayerData(player);
final InventoryData data = InventoryData.getData(player);
final InventoryConfig cc = InventoryConfig.getConfig(player);
final IPlayerData pData = DataManager.getPlayerData(player);
final InventoryData data = pData.getGenericInstance(InventoryData.class);
final InventoryConfig cc = pData.getGenericInstance(InventoryConfig.class);
boolean cancel = false;
@ -81,7 +81,10 @@ public class InstantBow extends Check {
else {
// Account for server side lag.
// (Do not apply correction to invalid pulling.)
final long correctedPullduration = valid ? (cc.lag ? (long) (TickTask.getLag(expectedPullDuration, true) * pullDuration) : pullDuration) : 0;
final long correctedPullduration = valid ?
(pData.getCurrentWorldData().shouldAdjustToLag(type)
? (long) (TickTask.getLag(expectedPullDuration, true) * pullDuration)
: pullDuration) : 0;
if (correctedPullduration < expectedPullDuration) {
// TODO: Consider: Allow one time but set yawrate penalty time ?
final double difference = (expectedPullDuration - pullDuration) / 100D;
@ -95,7 +98,7 @@ public class InstantBow extends Check {
}
}
if (data.debug && pData.hasPermission(Permissions.ADMINISTRATION_DEBUG, player)) {
if (pData.isDebugActive(type) && pData.hasPermission(Permissions.ADMINISTRATION_DEBUG, player)) {
player.sendMessage(ChatColor.YELLOW + "NCP: " + ChatColor.GRAY + "Bow shot - force: " + force +", " + (cc.instantBowStrict || pullDuration < 2 * expectedPullDuration ? ("pull time: " + pullDuration) : "") + "(" + expectedPullDuration +")");
}

View File

@ -20,6 +20,8 @@ import fr.neatmonster.nocheatplus.actions.ParameterName;
import fr.neatmonster.nocheatplus.checks.Check;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.ViolationData;
import fr.neatmonster.nocheatplus.players.DataManager;
import fr.neatmonster.nocheatplus.players.IPlayerData;
/**
* The InstantEat check will find out if a player eats their food too fast.
@ -46,7 +48,8 @@ public class InstantEat extends Check {
// Take time once.
final long time = System.currentTimeMillis();
final InventoryData data = InventoryData.getData(player);
final IPlayerData pData = DataManager.getPlayerData(player);
final InventoryData data = pData.getGenericInstance(InventoryData.class);
boolean cancel = false;
@ -72,7 +75,8 @@ public class InstantEat extends Check {
// Execute whatever actions are associated with this check and the violation level and find out if we should
// cancel the event.
final ViolationData vd = new ViolationData(this, player, data.instantEatVL, difference, InventoryConfig.getConfig(player).instantEatActions);
final ViolationData vd = new ViolationData(this, player, data.instantEatVL,
difference, pData.getGenericInstance(InventoryConfig.class).instantEatActions);
if (data.instantEatFood != null) {
vd.setParameter(ParameterName.FOOD, data.instantEatFood.toString());
}

View File

@ -14,24 +14,17 @@
*/
package fr.neatmonster.nocheatplus.checks.inventory;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.actions.ActionList;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.access.ACheckConfig;
import fr.neatmonster.nocheatplus.checks.access.CheckConfigFactory;
import fr.neatmonster.nocheatplus.checks.access.ICheckConfig;
import fr.neatmonster.nocheatplus.config.ConfPaths;
import fr.neatmonster.nocheatplus.config.ConfigFile;
import fr.neatmonster.nocheatplus.config.ConfigManager;
import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.worlds.WorldData;
/**
* Configurations specific for the "inventory" checks. Every world gets one of
@ -40,87 +33,31 @@ import fr.neatmonster.nocheatplus.permissions.Permissions;
*/
public class InventoryConfig extends ACheckConfig {
/** The factory creating configurations. */
public static final CheckConfigFactory factory = new CheckConfigFactory() {
@Override
public final ICheckConfig getConfig(final Player player) {
return InventoryConfig.getConfig(player);
}
@Override
public void removeAllConfigs() {
clear(); // Band-aid.
}
};
/** The map containing the configurations per world. */
private static final Map<String, InventoryConfig> worldsMap = new HashMap<String, InventoryConfig>();
/**
* Clear all the configurations.
*/
public static void clear() {
worldsMap.clear();
}
/**
* Gets the configuration for a specified player.
*
* @param player
* the player
* @return the configuration
*/
public static InventoryConfig getConfig(final Player player) {
return getConfig(player.getWorld());
}
public static InventoryConfig getConfig(final World world) {
return getWorldConfig(world.getName());
}
public static final InventoryConfig getWorldConfig(final String worldName) {
InventoryConfig cc = worldsMap.get(worldName);
if (cc == null) {
cc = new InventoryConfig(ConfigManager.getConfigFile(worldName));
worldsMap.put(worldName, cc);
}
return cc;
}
public final boolean dropCheck;
public final int dropLimit;
public final long dropTimeFrame;
public final ActionList dropActions;
public final boolean fastClickCheck;
public final boolean fastClickSpareCreative;
public final boolean fastClickTweaks1_5;
public final float fastClickShortTermLimit;
public final float fastClickNormalLimit;
public final ActionList fastClickActions;
public final boolean fastConsumeCheck;
public final long fastConsumeDuration;
public final boolean fastConsumeWhitelist;
public final Set<Material> fastConsumeItems = new HashSet<Material>();
public final ActionList fastConsumeActions;
public final boolean gutenbergCheck;
public final ActionList gutenbergActions;
public final boolean instantBowCheck;
public final boolean instantBowStrict;
public final long instantBowDelay;
public final boolean instantBowImprobableFeedOnly;
public final float instantBowImprobableWeight;
public final ActionList instantBowActions;
public final boolean instantEatCheck;
public final ActionList instantEatActions;
public final boolean itemsCheck;
public final boolean openCheck;
public final boolean openClose;
public final boolean openCancelOther;
@ -133,77 +70,38 @@ public class InventoryConfig extends ACheckConfig {
* @param data
* the data
*/
public InventoryConfig(final ConfigFile data) {
super(data, ConfPaths.INVENTORY);
dropCheck = data.getBoolean(ConfPaths.INVENTORY_DROP_CHECK);
public InventoryConfig(final WorldData worldData) {
super(worldData);
final ConfigFile data = worldData.getRawConfiguration();
dropLimit = data.getInt(ConfPaths.INVENTORY_DROP_LIMIT);
dropTimeFrame = data.getLong(ConfPaths.INVENTORY_DROP_TIMEFRAME);
dropActions = data.getOptimizedActionList(ConfPaths.INVENTORY_DROP_ACTIONS, Permissions.INVENTORY_DROP);
fastClickCheck = data.getBoolean(ConfPaths.INVENTORY_FASTCLICK_CHECK);
fastClickSpareCreative = data.getBoolean(ConfPaths.INVENTORY_FASTCLICK_SPARECREATIVE);
fastClickTweaks1_5 = data.getBoolean(ConfPaths.INVENTORY_FASTCLICK_TWEAKS1_5);
fastClickShortTermLimit = (float) data.getDouble(ConfPaths.INVENTORY_FASTCLICK_LIMIT_SHORTTERM);
fastClickNormalLimit = (float) data.getDouble(ConfPaths.INVENTORY_FASTCLICK_LIMIT_NORMAL);
fastClickActions = data.getOptimizedActionList(ConfPaths.INVENTORY_FASTCLICK_ACTIONS, Permissions.INVENTORY_FASTCLICK);
fastConsumeCheck = data.getBoolean(ConfPaths.INVENTORY_FASTCONSUME_CHECK);
fastConsumeDuration = (long) (1000.0 * data.getDouble(ConfPaths.INVENTORY_FASTCONSUME_DURATION));
fastConsumeWhitelist = data.getBoolean(ConfPaths.INVENTORY_FASTCONSUME_WHITELIST);
data.readMaterialFromList(ConfPaths.INVENTORY_FASTCONSUME_ITEMS, fastConsumeItems);
fastConsumeActions = data.getOptimizedActionList(ConfPaths.INVENTORY_FASTCONSUME_ACTIONS, Permissions.INVENTORY_FASTCONSUME);
gutenbergCheck = data.getBoolean(ConfPaths.INVENTORY_GUTENBERG_CHECK);
gutenbergActions = data.getOptimizedActionList(ConfPaths.INVENTORY_GUTENBERG_ACTIONS, Permissions.INVENTORY_GUTENBERG);
instantBowCheck = data.getBoolean(ConfPaths.INVENTORY_INSTANTBOW_CHECK);
instantBowStrict = data.getBoolean(ConfPaths.INVENTORY_INSTANTBOW_STRICT);
instantBowDelay = data.getInt(ConfPaths.INVENTORY_INSTANTBOW_DELAY);
instantBowImprobableFeedOnly = data.getBoolean(ConfPaths.INVENTORY_INSTANTBOW_IMPROBABLE_FEEDONLY);
instantBowImprobableWeight = (float) data.getDouble(ConfPaths.INVENTORY_INSTANTBOW_IMPROBABLE_WEIGHT);
instantBowActions = data.getOptimizedActionList(ConfPaths.INVENTORY_INSTANTBOW_ACTIONS, Permissions.INVENTORY_INSTANTBOW);
instantEatCheck = data.getBoolean(ConfPaths.INVENTORY_INSTANTEAT_CHECK);
instantEatActions = data.getOptimizedActionList(ConfPaths.INVENTORY_INSTANTEAT_ACTIONS, Permissions.INVENTORY_INSTANTEAT);
itemsCheck = data.getBoolean(ConfPaths.INVENTORY_ITEMS_CHECK);
openCheck = data.getBoolean(ConfPaths.INVENTORY_OPEN_CHECK);
openClose = data.getBoolean(ConfPaths.INVENTORY_OPEN_CLOSE);
openCancelOther = data.getBoolean(ConfPaths.INVENTORY_OPEN_CANCELOTHER);
hotFixFallingBlockEndPortalActive = data.getBoolean(ConfPaths.INVENTORY_HOTFIX_DUPE_FALLINGBLOCKENDPORTAL);
}
/*
* (non-Javadoc)
*
* @see
* fr.neatmonster.nocheatplus.checks.ICheckConfig#isEnabled(fr.neatmonster
* .nocheatplus.checks.CheckType)
*/
@Override
public final boolean isEnabled(final CheckType checkType) {
switch (checkType) {
case INVENTORY_FASTCLICK:
return fastClickCheck;
case INVENTORY_ITEMS:
return itemsCheck;
case INVENTORY_OPEN:
return openCheck;
case INVENTORY_DROP:
return dropCheck;
case INVENTORY_INSTANTBOW:
return instantBowCheck;
case INVENTORY_INSTANTEAT:
return instantEatCheck;
case INVENTORY_FASTCONSUME:
return fastConsumeCheck;
case INVENTORY_GUTENBERG:
return gutenbergCheck;
default:
return true;
}
}
}

View File

@ -14,16 +14,9 @@
*/
package fr.neatmonster.nocheatplus.checks.inventory;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.checks.access.ACheckData;
import fr.neatmonster.nocheatplus.checks.access.CheckDataFactory;
import fr.neatmonster.nocheatplus.checks.access.ICheckData;
import fr.neatmonster.nocheatplus.utilities.ds.count.ActionFrequency;
/**
@ -31,53 +24,6 @@ import fr.neatmonster.nocheatplus.utilities.ds.count.ActionFrequency;
*/
public class InventoryData extends ACheckData {
/** The factory creating data. */
public static final CheckDataFactory factory = new CheckDataFactory() {
@Override
public final ICheckData getData(final Player player) {
return InventoryData.getData(player);
}
@Override
public ICheckData getDataIfPresent(UUID playerId, String playerName) {
return InventoryData.playersMap.get(playerName);
}
@Override
public ICheckData removeData(final String playerName) {
return InventoryData.removeData(playerName);
}
@Override
public void removeAllData() {
clear();
}
};
/** The map containing the data per players. */
private static final Map<String, InventoryData> playersMap = new HashMap<String, InventoryData>();
/**
* Gets the data of a specified player.
*
* @param player
* the player
* @return the data
*/
public static InventoryData getData(final Player player) {
if (!playersMap.containsKey(player.getName()))
playersMap.put(player.getName(), new InventoryData(InventoryConfig.getConfig(player)));
return playersMap.get(player.getName());
}
public static ICheckData removeData(final String playerName) {
return playersMap.remove(playerName);
}
public static void clear(){
playersMap.clear();
}
// Violation levels.
public double dropVL;
public double fastClickVL;
@ -107,8 +53,4 @@ public class InventoryData extends ACheckData {
public Material instantEatFood;
public long instantEatInteract;
public InventoryData(final InventoryConfig config) {
super(config);
}
}

View File

@ -56,7 +56,7 @@ import fr.neatmonster.nocheatplus.components.entity.IEntityAccessVehicle;
import fr.neatmonster.nocheatplus.components.registry.event.IGenericInstanceHandle;
import fr.neatmonster.nocheatplus.components.registry.feature.JoinLeaveListener;
import fr.neatmonster.nocheatplus.players.DataManager;
import fr.neatmonster.nocheatplus.players.PlayerData;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.stats.Counters;
import fr.neatmonster.nocheatplus.utilities.InventoryUtil;
@ -110,14 +110,16 @@ public class InventoryListener extends CheckListener implements JoinLeaveListen
// Only if a player shot the arrow.
if (event.getEntity() instanceof Player) {
final Player player = (Player) event.getEntity();
if (instantBow.isEnabled(player)) {
final IPlayerData pData = DataManager.getPlayerData(player);
if (instantBow.isEnabled(player, pData)) {
final long now = System.currentTimeMillis();
final Location loc = player.getLocation(useLoc);
if (Combined.checkYawRate(player, loc.getYaw(), now, loc.getWorld().getName())) {
if (Combined.checkYawRate(player, loc.getYaw(), now,
loc.getWorld().getName(), pData)) {
// No else if with this, could be cancelled due to other checks feeding, does not have actions.
event.setCancelled(true);
}
final InventoryConfig cc = InventoryConfig.getConfig(player);
final InventoryConfig cc = pData.getGenericInstance(InventoryConfig.class);
// Still check instantBow, whatever yawrate says.
if (instantBow.check(player, event.getForce(), now)) {
// The check requested the event to be cancelled.
@ -127,7 +129,8 @@ public class InventoryListener extends CheckListener implements JoinLeaveListen
if (cc.instantBowImprobableFeedOnly) {
Improbable.feed(player, cc.instantBowImprobableWeight, now);
}
else if (Improbable.check(player, cc.instantBowImprobableWeight, now, "inventory.instantbow")) {
else if (Improbable.check(player, cc.instantBowImprobableWeight,
now, "inventory.instantbow", pData)) {
// Combined fighting speed (Else if: Matter of taste, preventing extreme cascading and actions spam).
event.setCancelled(true);
}
@ -150,7 +153,9 @@ public class InventoryListener extends CheckListener implements JoinLeaveListen
// Only if a player ate food.
if (event.getEntity() instanceof Player) {
final Player player = (Player) event.getEntity();
if (instantEat.isEnabled(player) && instantEat.check(player, event.getFoodLevel())) {
final IPlayerData pData = DataManager.getPlayerData(player);
if (instantEat.isEnabled(player, pData)
&& instantEat.check(player, event.getFoodLevel())) {
event.setCancelled(true);
}
else if (player.isDead() && BridgeHealth.getHealth(player) <= 0.0) {
@ -179,9 +184,10 @@ public class InventoryListener extends CheckListener implements JoinLeaveListen
return;
}
final Player player = (Player) entity;
final InventoryData data = InventoryData.getData(player);
final IPlayerData pData = DataManager.getPlayerData(player);
final InventoryData data = pData.getGenericInstance(InventoryData.class);
final int slot = event.getSlot();
if (data.debug) {
if (pData.isDebugActive(checkType)) {
outputDebugInventoryClick(player, slot, event, data);
}
if (slot == InventoryView.OUTSIDE || slot < 0) {
@ -194,14 +200,14 @@ public class InventoryListener extends CheckListener implements JoinLeaveListen
boolean cancel = false;
// Illegal enchantment checks.
try{
if (!cancel && Items.checkIllegalEnchantments(player, clicked)) {
if (!cancel && Items.checkIllegalEnchantments(player, clicked, pData)) {
cancel = true;
counters.addPrimaryThread(idIllegalItem, 1);
}
}
catch(final ArrayIndexOutOfBoundsException e) {} // Hotfix (CB)
try{
if (!cancel && Items.checkIllegalEnchantments(player, cursor)) {
if (!cancel && Items.checkIllegalEnchantments(player, cursor, pData)) {
cancel = true;
counters.addPrimaryThread(idIllegalItem, 1);
}
@ -209,10 +215,9 @@ public class InventoryListener extends CheckListener implements JoinLeaveListen
catch(final ArrayIndexOutOfBoundsException e) {} // Hotfix (CB)
// Fast inventory manipulation check.
if (fastClick.isEnabled(player)) {
final InventoryConfig cc = InventoryConfig.getConfig(player);
if (fastClick.isEnabled(player, pData)) {
final InventoryConfig cc = pData.getGenericInstance(InventoryConfig.class);
if (player.getGameMode() != GameMode.CREATIVE || !cc.fastClickSpareCreative) {
final PlayerData pData = DataManager.getPlayerData(player);
if (fastClick.check(player, now,
event.getView(), slot, cursor, clicked, event.isShiftClick(),
data, cc, pData)) {
@ -301,20 +306,21 @@ public class InventoryListener extends CheckListener implements JoinLeaveListen
public void onPlayerDropItem(final PlayerDropItemEvent event) {
final Player player = event.getPlayer();
final IPlayerData pData = DataManager.getPlayerData(player);
// Illegal enchantments hotfix check.
final Item item = event.getItemDrop();
if (item != null) {
// No cancel here.
Items.checkIllegalEnchantments(player, item.getItemStack());
Items.checkIllegalEnchantments(player, item.getItemStack(), pData);
}
// If the player died, all their items are dropped so ignore them.
if (event.getPlayer().isDead())
return;
if (drop.isEnabled(event.getPlayer())) {
if (drop.check(event.getPlayer())) {
if (pData.isCheckActive(CheckType.INVENTORY_DROP, player)) {
if (drop.check(player)) {
// TODO: Is the following command still correct? If so, adapt actions.
/*
* Cancelling drop events is not save (in certain circumstances
@ -341,7 +347,8 @@ public class InventoryListener extends CheckListener implements JoinLeaveListen
return;
final Player player = event.getPlayer();
final InventoryData data = InventoryData.getData(player);
final IPlayerData pData = DataManager.getPlayerData(player);
final InventoryData data = pData.getGenericInstance(InventoryData.class);
boolean resetAll = false;
@ -366,7 +373,7 @@ public class InventoryListener extends CheckListener implements JoinLeaveListen
} else resetAll = true;
// Illegal enchantments hotfix check.
if (Items.checkIllegalEnchantments(player, item)) {
if (Items.checkIllegalEnchantments(player, item, pData)) {
event.setCancelled(true);
counters.addPrimaryThread(idIllegalItem, 1);
}
@ -377,7 +384,8 @@ public class InventoryListener extends CheckListener implements JoinLeaveListen
if (resetAll) {
// Nothing that we are interested in, reset data.
if (data.debug && data.instantEatFood != null) {
if (pData.isDebugActive(CheckType.INVENTORY_INSTANTEAT)
&& data.instantEatFood != null) {
debug(player, "PlayerInteractEvent, reset fastconsume (legacy: instanteat).");
}
data.instantBowInteract = 0;
@ -407,7 +415,7 @@ public class InventoryListener extends CheckListener implements JoinLeaveListen
Entity entity = event.getRightClicked();
if (stack != null && stack.getType() == Material.MONSTER_EGG
&& (entity == null || entity instanceof LivingEntity || entity instanceof ComplexEntityPart)
&& items.isEnabled(player)) {
&& items.isEnabled(player, DataManager.getPlayerData(player))) {
event.setCancelled(true);
counters.addPrimaryThread(idEggOnEntity, 1);
return;
@ -428,8 +436,9 @@ public class InventoryListener extends CheckListener implements JoinLeaveListen
@EventHandler(priority = EventPriority.MONITOR)
public void onItemHeldChange(final PlayerItemHeldEvent event) {
final Player player = event.getPlayer();
final InventoryData data = InventoryData.getData(player);
if (data.debug && data.instantEatFood != null) {
final IPlayerData pData = DataManager.getPlayerData(player);
final InventoryData data = pData.getGenericInstance(InventoryData.class);
if (pData.isDebugActive(checkType) && data.instantEatFood != null) {
debug(player, "PlayerItemHeldEvent, reset fastconsume (legacy: instanteat).");
}
data.instantBowInteract = 0;
@ -438,8 +447,8 @@ public class InventoryListener extends CheckListener implements JoinLeaveListen
// Illegal enchantments hotfix check.
final PlayerInventory inv = player.getInventory();
Items.checkIllegalEnchantments(player, inv.getItem(event.getNewSlot()));
Items.checkIllegalEnchantments(player, inv.getItem(event.getPreviousSlot()));
Items.checkIllegalEnchantments(player, inv.getItem(event.getNewSlot()), pData);
Items.checkIllegalEnchantments(player, inv.getItem(event.getPreviousSlot()), pData);
}
@EventHandler(priority = EventPriority.MONITOR)

View File

@ -25,6 +25,7 @@ import org.bukkit.inventory.ItemStack;
import fr.neatmonster.nocheatplus.checks.Check;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.compat.Bridge1_9;
import fr.neatmonster.nocheatplus.players.IPlayerData;
public class Items extends Check{
@ -42,12 +43,14 @@ public class Items extends Check{
* @param player
* @return True if the check is failed.
*/
public static final boolean checkIllegalEnchantmentsAllHands(final Player player) {
public static final boolean checkIllegalEnchantmentsAllHands(final Player player,
final IPlayerData pData) {
boolean result = false;
if (checkIllegalEnchantments(player, Bridge1_9.getItemInMainHand(player))) {
if (checkIllegalEnchantments(player, Bridge1_9.getItemInMainHand(player), pData)) {
result = true;
}
if (Bridge1_9.hasGetItemInOffHand() && checkIllegalEnchantments(player, Bridge1_9.getItemInOffHand(player))) {
if (Bridge1_9.hasGetItemInOffHand()
&& checkIllegalEnchantments(player, Bridge1_9.getItemInOffHand(player), pData)) {
result = true;
}
return result;
@ -61,7 +64,8 @@ public class Items extends Check{
* @param stack
* @return True if the check is failed.
*/
public static final boolean checkIllegalEnchantments(final Player player, final ItemStack stack){
public static final boolean checkIllegalEnchantments(final Player player,
final ItemStack stack, final IPlayerData pData){
if (stack == null) {
return false;
}
@ -70,7 +74,7 @@ public class Items extends Check{
// TODO: Make stuff configurable.
if (type == Material.WRITTEN_BOOK){
final Map<Enchantment, Integer> enchantments = stack.getEnchantments();
if (enchantments != null && !enchantments.isEmpty() && instance.isEnabled(player)){
if (enchantments != null && !enchantments.isEmpty() && pData.isCheckActive(instance.type, player)){
// TODO: differentiate sub checks maybe or add extra permissions, later.
for (final Enchantment ench : new HashSet<Enchantment>(enchantments.keySet())){
stack.removeEnchantment(ench);

View File

@ -24,6 +24,8 @@ import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.components.registry.event.IHandle;
import fr.neatmonster.nocheatplus.components.registry.feature.IDisableListener;
import fr.neatmonster.nocheatplus.hooks.ExemptionSettings;
import fr.neatmonster.nocheatplus.players.DataManager;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.utilities.InventoryUtil;
/**
@ -74,7 +76,8 @@ public class Open extends Check implements IDisableListener{
|| !InventoryUtil.hasInventoryOpen(player)) {
return false;
}
final InventoryConfig cc = InventoryConfig.getConfig(player);
final IPlayerData pData = DataManager.getPlayerData(player);
final InventoryConfig cc = pData.getGenericInstance(InventoryConfig.class);
if (cc.openClose) {
final UUID id = player.getUniqueId();
if (this.nestedPlayer == null || !id.equals(this.nestedPlayer)) {

View File

@ -29,8 +29,6 @@ import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.actions.ActionList;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.access.ACheckConfig;
import fr.neatmonster.nocheatplus.checks.access.CheckConfigFactory;
import fr.neatmonster.nocheatplus.checks.access.ICheckConfig;
import fr.neatmonster.nocheatplus.checks.moving.magic.Magic;
import fr.neatmonster.nocheatplus.checks.moving.model.ModelFlying;
import fr.neatmonster.nocheatplus.checks.moving.player.PlayerSetBackMethod;
@ -40,13 +38,14 @@ import fr.neatmonster.nocheatplus.compat.AlmostBoolean;
import fr.neatmonster.nocheatplus.compat.Bridge1_9;
import fr.neatmonster.nocheatplus.compat.versions.Bugs;
import fr.neatmonster.nocheatplus.compat.versions.ServerVersion;
import fr.neatmonster.nocheatplus.components.config.value.OverrideType;
import fr.neatmonster.nocheatplus.config.ConfPaths;
import fr.neatmonster.nocheatplus.config.ConfigFile;
import fr.neatmonster.nocheatplus.config.ConfigManager;
import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.utilities.ColorUtil;
import fr.neatmonster.nocheatplus.utilities.ds.prefixtree.SimpleCharPrefixTree;
import fr.neatmonster.nocheatplus.utilities.location.PlayerLocation;
import fr.neatmonster.nocheatplus.worlds.IWorldData;
/**
* Configurations specific for the moving checks. Every world gets one of these
@ -54,59 +53,6 @@ import fr.neatmonster.nocheatplus.utilities.location.PlayerLocation;
*/
public class MovingConfig extends ACheckConfig {
/** The factory creating configurations. */
public static final CheckConfigFactory factory = new CheckConfigFactory() {
@Override
public final ICheckConfig getConfig(final Player player) {
return MovingConfig.getConfig(player);
}
@Override
public void removeAllConfigs() {
clear(); // Band-aid.
}
};
/** The map containing the configurations per world. */
private static final Map<String, MovingConfig> worldsMap = new HashMap<String, MovingConfig>();
/**
* Clear all the configurations.
*/
public static void clear() {
worldsMap.clear();
}
/**
* Gets the configuration for a specified player . <br>
* NOTE: Currently only per-world configs are implemented. This method might
* or might not get removed some day.
*
* @param player
* the player
* @return the configuration
*/
public static MovingConfig getConfig(final Player player) {
return getConfig(player.getWorld().getName());
}
/**
* Get a per-world config.
*
* @param worldName
* Exact case world name.
* @return
*/
public static MovingConfig getConfig(final String worldName) {
final MovingConfig cc = worldsMap.get(worldName);
if (cc != null){
return cc;
}
final MovingConfig ccNew = new MovingConfig(ConfigManager.getConfigFile(worldName));
worldsMap.put(worldName, ccNew);
return ccNew;
}
// Model flying ids.
public static final String ID_JETPACK_ELYTRA = "jetpack.elytra";
public static final String ID_POTION_LEVITATION = "potion.levitation";
@ -116,13 +62,11 @@ public class MovingConfig extends ACheckConfig {
public final boolean ignoreCreative;
public final boolean ignoreAllowFlight;
public final boolean creativeFlyCheck;
private final Map<GameMode, ModelFlying> flyingModelGameMode = new HashMap<GameMode, ModelFlying>();
private final ModelFlying flyingModelElytra;
private final ModelFlying flyingModelLevitation;
public final ActionList creativeFlyActions;
public final boolean morePacketsCheck;
/** Assumed number of packets per second under ideal conditions. */
public final float morePacketsEPSIdeal;
/** The maximum number of packets per second that we accept. */
@ -134,7 +78,6 @@ public class MovingConfig extends ACheckConfig {
public final int morePacketsSetBackAge;
public final ActionList morePacketsActions;
public final boolean noFallCheck;
/**
* Deal damage instead of Minecraft, whenever a player is judged to be on
* ground.
@ -154,7 +97,6 @@ public class MovingConfig extends ACheckConfig {
public final boolean noFallAntiCriticals;
public final ActionList noFallActions;
public final boolean passableCheck;
// TODO: passableAccuracy: also use if not using ray-tracing
public final ActionList passableActions;
public final boolean passableUntrackedTeleportCheck;
@ -162,7 +104,6 @@ public class MovingConfig extends ACheckConfig {
public final boolean passableUntrackedCommandTryTeleport;
public final SimpleCharPrefixTree passableUntrackedCommandPrefixes = new SimpleCharPrefixTree();
public final boolean survivalFlyCheck;
public final int survivalFlyBlockingSpeed;
public final int survivalFlySneakingSpeed;
public final int survivalFlySpeedingSpeed;
@ -184,7 +125,7 @@ public class MovingConfig extends ACheckConfig {
public final long survivalFlyVLFreeze;
public final ActionList survivalFlyActions;
public final boolean sfHoverCheck;
public final boolean sfHoverCheck; // TODO: Sub check ?
public final int sfHoverTicks;
public final int sfHoverLoginTicks;
public final boolean sfHoverFallDamage;
@ -230,10 +171,8 @@ public class MovingConfig extends ACheckConfig {
public final Set<EntityType> ignoredVehicles = new HashSet<EntityType>();
public final boolean vehicleMorePacketsCheck;
public final ActionList vehicleMorePacketsActions;
public final boolean vehicleEnvelopeActive;
public final HashMap<EntityType, Double> vehicleEnvelopeHorizontalSpeedCap = new HashMap<EntityType, Double>();
public final ActionList vehicleEnvelopeActions;
@ -251,13 +190,13 @@ public class MovingConfig extends ACheckConfig {
* @param config
* the data
*/
public MovingConfig(final ConfigFile config) {
super(config, ConfPaths.MOVING);
public MovingConfig(final IWorldData worldData) {
super(worldData);
final ConfigFile config = worldData.getRawConfiguration();
ignoreCreative = config.getBoolean(ConfPaths.MOVING_CREATIVEFLY_IGNORECREATIVE);
ignoreAllowFlight = config.getBoolean(ConfPaths.MOVING_CREATIVEFLY_IGNOREALLOWFLIGHT);
creativeFlyCheck = config.getBoolean(ConfPaths.MOVING_CREATIVEFLY_CHECK);
final ModelFlying defaultModel = new ModelFlying("gamemode.creative", config,
ConfPaths.MOVING_CREATIVEFLY_MODEL + "creative.", new ModelFlying().lock());
for (final GameMode gameMode : GameMode.values()) {
@ -273,7 +212,6 @@ public class MovingConfig extends ACheckConfig {
creativeFlyActions = config.getOptimizedActionList(ConfPaths.MOVING_CREATIVEFLY_ACTIONS,
Permissions.MOVING_CREATIVEFLY);
morePacketsCheck = config.getBoolean(ConfPaths.MOVING_MOREPACKETS_CHECK);
morePacketsEPSIdeal = config.getInt(ConfPaths.MOVING_MOREPACKETS_EPSIDEAL);
morePacketsEPSMax = Math.max(morePacketsEPSIdeal, config.getInt(ConfPaths.MOVING_MOREPACKETS_EPSMAX));
morePacketsEPSBuckets = 2 * Math.max(1, Math.min(60, config.getInt(ConfPaths.MOVING_MOREPACKETS_SECONDS)));
@ -283,7 +221,6 @@ public class MovingConfig extends ACheckConfig {
morePacketsSetBackAge = config.getInt(ConfPaths.MOVING_MOREPACKETS_SETBACKAGE);
morePacketsActions = config.getOptimizedActionList(ConfPaths.MOVING_MOREPACKETS_ACTIONS, Permissions.MOVING_MOREPACKETS);
noFallCheck = config.getBoolean(ConfPaths.MOVING_NOFALL_CHECK);
noFallDealDamage = config.getBoolean(ConfPaths.MOVING_NOFALL_DEALDAMAGE);
noFallSkipAllowFlight = config.getBoolean(ConfPaths.MOVING_NOFALL_SKIPALLOWFLIGHT);
noFallViolationReset = config.getBoolean(ConfPaths.MOVING_NOFALL_RESETONVL);
@ -292,14 +229,12 @@ public class MovingConfig extends ACheckConfig {
noFallAntiCriticals = config.getBoolean(ConfPaths.MOVING_NOFALL_ANTICRITICALS);
noFallActions = config.getOptimizedActionList(ConfPaths.MOVING_NOFALL_ACTIONS, Permissions.MOVING_NOFALL);
passableCheck = config.getBoolean(ConfPaths.MOVING_PASSABLE_CHECK);
passableActions = config.getOptimizedActionList(ConfPaths.MOVING_PASSABLE_ACTIONS, Permissions.MOVING_PASSABLE);
passableUntrackedTeleportCheck = config.getBoolean(ConfPaths.MOVING_PASSABLE_UNTRACKED_TELEPORT_ACTIVE);
passableUntrackedCommandCheck = config.getBoolean(ConfPaths.MOVING_PASSABLE_UNTRACKED_CMD_ACTIVE);
passableUntrackedCommandTryTeleport = config.getBoolean(ConfPaths.MOVING_PASSABLE_UNTRACKED_CMD_TRYTELEPORT);
CommandUtil.feedCommands(passableUntrackedCommandPrefixes, config, ConfPaths.MOVING_PASSABLE_UNTRACKED_CMD_PREFIXES, true);
survivalFlyCheck = config.getBoolean(ConfPaths.MOVING_SURVIVALFLY_CHECK);
// Default values are specified here because this settings aren't showed by default into the configuration file.
survivalFlyBlockingSpeed = config.getInt(ConfPaths.MOVING_SURVIVALFLY_BLOCKINGSPEED, 100);
survivalFlySneakingSpeed = config.getInt(ConfPaths.MOVING_SURVIVALFLY_SNEAKINGSPEED, 100);
@ -389,10 +324,12 @@ public class MovingConfig extends ACheckConfig {
vehicleEnforceLocation = ref.decideOptimistically(); // Currently rather enabled.
vehiclePreventDestroyOwn = config.getBoolean(ConfPaths.MOVING_VEHICLE_PREVENTDESTROYOWN);
scheduleVehicleSetBacks = config.getAlmostBoolean(ConfPaths.MOVING_VEHICLE_SCHEDULESETBACKS, AlmostBoolean.MAYBE).decide();
vehicleMorePacketsCheck = config.getBoolean(ConfPaths.MOVING_VEHICLE_MOREPACKETS_CHECK);
vehicleMorePacketsActions = config.getOptimizedActionList(ConfPaths.MOVING_VEHICLE_MOREPACKETS_ACTIONS, Permissions.MOVING_MOREPACKETS);
ref = config.getAlmostBoolean(ConfPaths.MOVING_VEHICLE_ENVELOPE_ACTIVE, AlmostBoolean.MAYBE);
vehicleEnvelopeActive = ref == AlmostBoolean.MAYBE ? ServerVersion.compareMinecraftVersion("1.9") >= 0 : ref.decide();
if (ServerVersion.compareMinecraftVersion("1.9") < 0) {
worldData.overrideCheckActivation(CheckType.MOVING_VEHICLE_ENVELOPE,
AlmostBoolean.NO, OverrideType.PERMANENT, true);
}
config.readDoubleValuesForEntityTypes(ConfPaths.MOVING_VEHICLE_ENVELOPE_HSPEEDCAP, vehicleEnvelopeHorizontalSpeedCap, 4.0, true);
vehicleEnvelopeActions = config.getOptimizedActionList(ConfPaths.MOVING_VEHICLE_ENVELOPE_ACTIONS, Permissions.MOVING_VEHICLE_ENVELOPE);
// Ignored vehicle types (ignore mostly, no checks run).
@ -420,44 +357,6 @@ public class MovingConfig extends ACheckConfig {
msgKickIllegalVehicleMove = ColorUtil.replaceColors(config.getString(ConfPaths.MOVING_MESSAGE_ILLEGALVEHICLEMOVE));
}
/* (non-Javadoc)
* @see fr.neatmonster.nocheatplus.checks.ICheckConfig#isEnabled(fr.neatmonster.nocheatplus.checks.CheckType)
*/
@Override
public final boolean isEnabled(final CheckType checkType) {
switch (checkType) {
case MOVING_NOFALL:
return noFallCheck;
case MOVING_SURVIVALFLY:
return survivalFlyCheck;
case MOVING_PASSABLE:
return passableCheck;
case MOVING_MOREPACKETS:
return morePacketsCheck;
case MOVING_VEHICLE_MOREPACKETS:
return vehicleMorePacketsCheck;
case MOVING_VEHICLE_ENVELOPE:
return vehicleEnvelopeActive;
case MOVING_CREATIVEFLY:
return creativeFlyCheck;
default:
return true;
}
}
/**
* Fetches data and config for sub checks (potentially redundant fetching).
*
* @param player
* @param fromLocation
* @return
* @deprecated Having a from location but no config/data ...
*/
@Deprecated
public ModelFlying getModelFlying(final Player player, final PlayerLocation fromLocation) {
return getModelFlying(player, fromLocation, MovingData.getData(player), MovingConfig.getConfig(player));
}
public ModelFlying getModelFlying(final Player player, final PlayerLocation fromLocation,
final MovingData data, final MovingConfig cc) {
final GameMode gameMode = player.getGameMode();

View File

@ -15,21 +15,15 @@
package fr.neatmonster.nocheatplus.checks.moving;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.Callable;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.NCPAPIProvider;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.access.ACheckData;
import fr.neatmonster.nocheatplus.checks.access.CheckDataFactory;
import fr.neatmonster.nocheatplus.checks.access.ICheckData;
import fr.neatmonster.nocheatplus.checks.access.IRemoveSubCheckData;
import fr.neatmonster.nocheatplus.checks.moving.location.setback.DefaultSetBackStorage;
import fr.neatmonster.nocheatplus.checks.moving.location.tracking.LocationTrace;
@ -47,10 +41,10 @@ import fr.neatmonster.nocheatplus.checks.moving.velocity.SimpleEntry;
import fr.neatmonster.nocheatplus.checks.moving.velocity.VelocityFlags;
import fr.neatmonster.nocheatplus.checks.workaround.WRPT;
import fr.neatmonster.nocheatplus.compat.blocks.changetracker.BlockChangeReference;
import fr.neatmonster.nocheatplus.components.data.ICanHandleTimeRunningBackwards;
import fr.neatmonster.nocheatplus.components.entity.IEntityAccessDimensions;
import fr.neatmonster.nocheatplus.components.location.IGetPosition;
import fr.neatmonster.nocheatplus.components.location.IPositionWithLook;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.utilities.CheckUtils;
import fr.neatmonster.nocheatplus.utilities.TickTask;
import fr.neatmonster.nocheatplus.utilities.ds.count.ActionAccumulator;
@ -66,84 +60,31 @@ import fr.neatmonster.nocheatplus.workaround.IWorkaroundRegistry.WorkaroundSet;
*/
public class MovingData extends ACheckData implements IRemoveSubCheckData {
public static final class MovingDataFactory implements CheckDataFactory, ICanHandleTimeRunningBackwards {
@Override
public final ICheckData getData(final Player player) {
return MovingData.getData(player);
}
@Override
public ICheckData getDataIfPresent(UUID playerId, String playerName) {
return MovingData.playersMap.get(playerName);
}
@Override
public ICheckData removeData(final String playerName) {
return MovingData.removeData(playerName);
}
@Override
public void removeAllData() {
MovingData.clear();
}
@Override
public void handleTimeRanBackwards() {
for (final MovingData data : playersMap.values()) {
data.handleTimeRanBackwards();
}
}
}
/** The factory creating data. */
public static final CheckDataFactory factory = new MovingDataFactory();
private static Map<String, MovingData> playersMap = new HashMap<String, MovingData>();
/** The map containing the data per players. */
/**
* Gets the data of a specified player.
* final CheckDataFactory factory = new CheckDataFactory(
* @param player
* the player
* @return the data
/*
* TODO: Handle world unload and other by registration (PlayerDataManager) -
* might just implement the interfaces and auto-handle at registration.
*/
public static MovingData getData(final Player player) {
// Note that the trace might be null after just calling this.
MovingData data = playersMap.get(player.getName());
if (data == null) {
data = new MovingData(MovingConfig.getConfig(player));
playersMap.put(player.getName(), data);
}
return data;
}
public static ICheckData removeData(final String playerName) {
return playersMap.remove(playerName);
}
public static void clear() {
playersMap.clear();
}
/**
* Clear data related to the given world.
* @param world The world that gets unloaded.
*/
public static void onWorldUnload(final World world) {
final String worldName = world.getName();
for (final MovingData data : playersMap.values()) {
data.onWorldUnload(worldName);
}
}
public static void onReload() {
final MovingConfig globalCc = MovingConfig.getConfig((String) null);
final int tick = TickTask.getTick();
for (final MovingData data : playersMap.values()) {
data.adjustOnReload(globalCc, tick);
}
}
// /**
// * Clear data related to the given world.
// * @param world The world that gets unloaded.
// */
// public static void onWorldUnload(final World world) {
// // TODO: Register with check (interfaces or just an event listener).
// final String worldName = world.getName();
// for (final MovingData data : playersMap.values()) {
// data.onWorldUnload(worldName);
// }
// }
//
// public static void onReload() {
// // TODO: Register with check (interfaces or just an event listener).
// final MovingConfig globalCc = MovingConfig.getConfig((String) null);
// final int tick = TickTask.getTick();
// for (final MovingData data : playersMap.values()) {
// data.adjustOnReload(globalCc, tick);
// }
// }
// Check specific.
@ -365,8 +306,10 @@ public class MovingData extends ACheckData implements IRemoveSubCheckData {
/** Task id of the vehicle set back task. */
public int vehicleSetBackTaskId = -1;
public MovingData(final MovingConfig config) {
super(config);
private final IPlayerData pData;
public MovingData(final MovingConfig config, final IPlayerData pData) {
this.pData = pData;
morePacketsFreq = new ActionFrequency(config.morePacketsEPSBuckets, 500);
morePacketsBurstFreq = new ActionFrequency(12, 5000);
@ -675,7 +618,7 @@ public class MovingData extends ACheckData implements IRemoveSubCheckData {
* @param amount
*/
public void reducePlayerMorePacketsData(final float amount) {
CheckUtils.reduce(System.currentTimeMillis(), amount, morePacketsFreq, morePacketsBurstFreq);
ActionFrequency.reduce(System.currentTimeMillis(), amount, morePacketsFreq, morePacketsBurstFreq);
}
public void clearVehicleMorePacketsData() {
@ -916,12 +859,11 @@ public class MovingData extends ACheckData implements IRemoveSubCheckData {
*/
public void addVelocity(final Player player, final MovingConfig cc,
final double vx, final double vy, final double vz, final long flags) {
final int tick = TickTask.getTick();
// TODO: Slightly odd to call this each time, might switch to a counter-strategy (move - remove).
removeInvalidVelocity(tick - cc.velocityActivationTicks);
if (debug) {
if (pData.isDebugActive(CheckType.MOVING)) {
CheckUtils.debug(player, CheckType.MOVING, "New velocity: " + vx + ", " + vy + ", " + vz);
}

View File

@ -39,6 +39,7 @@ import fr.neatmonster.nocheatplus.checks.moving.util.MovingUtil;
import fr.neatmonster.nocheatplus.compat.Bridge1_9;
import fr.neatmonster.nocheatplus.compat.BridgeMisc;
import fr.neatmonster.nocheatplus.compat.blocks.changetracker.BlockChangeTracker;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.utilities.StringUtil;
import fr.neatmonster.nocheatplus.utilities.location.PlayerLocation;
import fr.neatmonster.nocheatplus.utilities.location.TrigUtil;
@ -71,12 +72,15 @@ public class CreativeFly extends Check {
* @return
*/
public Location check(final Player player, final PlayerLocation from, final PlayerLocation to,
final MovingData data, final MovingConfig cc, final long time, final int tick,
final MovingData data, final MovingConfig cc, final IPlayerData pData,
final long time, final int tick,
final boolean useBlockChangeTracker) {
// Reset tags, just in case.
tags.clear();
final boolean debug = pData.isDebugActive(type);
// Some edge data for this move.
final GameMode gameMode = player.getGameMode();
final PlayerMoveData thisMove = data.playerMoves.getCurrentMove();
@ -197,7 +201,7 @@ public class CreativeFly extends Check {
final double result = Math.max(0.0, resultH) + Math.max(0.0, resultV);
if (data.debug) {
if (debug) {
outpuDebugMove(player, hDistance, limitH, yDistance, limitV, model, tags, data);
}
@ -228,7 +232,7 @@ public class CreativeFly extends Check {
// Maximum height check (silent set back).
if (to.getY() > maximumHeight) {
setBack = data.getSetBack(to);
if (data.debug) {
if (debug) {
debug(player, "Maximum height exceeded, silent set-back.");
}
}
@ -244,7 +248,7 @@ public class CreativeFly extends Check {
if (setBack.getY() > maximumHeight) {
// Correct the y position.
setBack.setY(getCorrectedHeight(maximumHeight, setBack.getWorld()));
if (data.debug) {
if (debug) {
debug(player, "Maximum height exceeded by set back, correct to: " + setBack.getY());
}
}

View File

@ -27,6 +27,7 @@ import fr.neatmonster.nocheatplus.checks.ViolationData;
import fr.neatmonster.nocheatplus.checks.moving.MovingConfig;
import fr.neatmonster.nocheatplus.checks.moving.MovingData;
import fr.neatmonster.nocheatplus.checks.net.NetStatic;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.utilities.StringUtil;
import fr.neatmonster.nocheatplus.utilities.location.PlayerLocation;
@ -62,9 +63,11 @@ public class MorePackets extends Check {
* @return
*/
public Location check(final Player player, final PlayerLocation from, final PlayerLocation to,
final boolean allowSetSetBack, final MovingData data, final MovingConfig cc) {
final boolean allowSetSetBack, final MovingData data, final MovingConfig cc,
final IPlayerData pData) {
// Take time once, first:
final long time = System.currentTimeMillis();
final boolean debug = pData.isDebugActive(type);
// if (from.isSamePos(to)) {
// // Ignore moves with "just look" for now.
@ -94,7 +97,7 @@ public class MorePackets extends Check {
// Violation handling.
final ViolationData vd = new ViolationData(this, player, data.morePacketsVL, violation, cc.morePacketsActions);
if (data.debug || vd.needsParameters()) {
if (debug || vd.needsParameters()) {
vd.setParameter(ParameterName.PACKETS, Integer.toString(new Double(violation).intValue()));
vd.setParameter(ParameterName.TAGS, StringUtil.join(tags, "+"));
}
@ -107,7 +110,7 @@ public class MorePackets extends Check {
// Update the set back location. (CHANGED to only update, if not a violation.)
// (Might update whenever newTo == null)
data.setMorePacketsSetBack(from);
if (data.debug) {
if (debug) {
debug(player, "Update set back (morepackets) to from.");
}
}

View File

@ -29,9 +29,7 @@ import fr.neatmonster.nocheatplus.checks.moving.magic.Magic;
import fr.neatmonster.nocheatplus.checks.moving.model.LocationData;
import fr.neatmonster.nocheatplus.checks.moving.model.PlayerMoveData;
import fr.neatmonster.nocheatplus.compat.BridgeHealth;
import fr.neatmonster.nocheatplus.hooks.NCPExemptionManager;
import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.players.PlayerData;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.utilities.location.PlayerLocation;
/**
@ -71,7 +69,8 @@ public class NoFall extends Check {
* Double.NEGATIVE_INFINITY.
*/
private void handleOnGround(final Player player, final double y, final double previousSetBackY,
final boolean reallyOnGround, final MovingData data, final MovingConfig cc) {
final boolean reallyOnGround, final MovingData data, final MovingConfig cc,
final IPlayerData pData) {
// Damage to be dealt.
final float fallDist = (float) getApplicableFallHeight(player, y, previousSetBackY, data);
final double maxD = getDamage(fallDist);
@ -85,7 +84,7 @@ public class NoFall extends Check {
}
else {
// TODO: more effects like sounds, maybe use custom event with violation added.
if (data.debug) {
if (pData.isDebugActive(type)) {
debug(player, "NoFall deal damage" + (reallyOnGround ? "" : "violation") + ": " + maxD);
}
// TODO: might not be necessary: if (mcPlayer.invulnerableTicks <= 0) [no damage event for resetting]
@ -209,8 +208,9 @@ public class NoFall extends Check {
*/
public void check(final Player player, final PlayerLocation pFrom, final PlayerLocation pTo,
final double previousSetBackY,
final MovingData data, final MovingConfig cc) {
final MovingData data, final MovingConfig cc, final IPlayerData pData) {
final boolean debug = pData.isDebugActive(type);
final PlayerMoveData thisMove = data.playerMoves.getCurrentMove();
final LocationData from = thisMove.from;
final LocationData to = thisMove.to;
@ -260,7 +260,7 @@ public class NoFall extends Check {
}
else if (fromOnGround || !toOnGround && thisMove.touchedGround) {
// Check if to deal damage (fall back damage check).
touchDown(player, minY, previousSetBackY, data, cc); // Includes the current y-distance on descend!
touchDown(player, minY, previousSetBackY, data, cc, pData); // Includes the current y-distance on descend!
// Ensure very big/strange moves don't yield violations.
if (toY - fromY <= -Magic.FALL_DAMAGE_DIST) {
data.noFallSkipAirCheck = true;
@ -276,7 +276,7 @@ public class NoFall extends Check {
// In this case the player has traveled further: add the difference.
data.noFallFallDistance -= yDiff;
}
touchDown(player, minY, previousSetBackY, data, cc);
touchDown(player, minY, previousSetBackY, data, cc, pData);
}
else {
// Ensure fall distance is correct, or "anyway"?
@ -301,7 +301,7 @@ public class NoFall extends Check {
else if (cc.noFallAntiCriticals && (toReset || toOnGround || (fromReset || fromOnGround || thisMove.touchedGround) && yDiff >= 0)) {
final double max = Math.max(data.noFallFallDistance, mcFallDistance);
if (max > 0.0 && max < 0.75) { // (Ensure this does not conflict with deal-damage set to false.)
if (data.debug) {
if (debug) {
debug(player, "NoFall: Reset fall distance (anticriticals): mc=" + mcFallDistance +" / nf=" + data.noFallFallDistance);
}
if (data.noFallFallDistance > 0) {
@ -313,7 +313,7 @@ public class NoFall extends Check {
}
}
if (data.debug) {
if (debug) {
debug(player, "NoFall: mc=" + mcFallDistance +" / nf=" + data.noFallFallDistance + (oldNFDist < data.noFallFallDistance ? " (+" + (data.noFallFallDistance - oldNFDist) + ")" : "") + " | ymax=" + data.noFallMaxY);
}
@ -331,9 +331,9 @@ public class NoFall extends Check {
* @param cc
*/
private void touchDown(final Player player, final double minY, final double previousSetBackY,
final MovingData data, final MovingConfig cc) {
final MovingData data, final MovingConfig cc, IPlayerData pData) {
if (cc.noFallDealDamage) {
handleOnGround(player, minY, previousSetBackY, true, data, cc);
handleOnGround(player, minY, previousSetBackY, true, data, cc, pData);
}
else {
adjustFallDistance(player, minY, true, data, cc);
@ -359,15 +359,16 @@ public class NoFall extends Check {
* Quit or kick: adjust fall distance if necessary.
* @param player
*/
public void onLeave(final Player player) {
final MovingData data = MovingData.getData(player);
public void onLeave(final Player player, final MovingData data,
final IPlayerData pData) {
final float fallDistance = player.getFallDistance();
// TODO: Might also detect too high mc fall dist.
if (data.noFallFallDistance > fallDistance) {
final double playerY = player.getLocation(useLoc).getY();
useLoc.setWorld(null);
if (player.isFlying() || player.getGameMode() == GameMode.CREATIVE
|| player.getAllowFlight() && MovingConfig.getConfig(player).noFallSkipAllowFlight) {
|| player.getAllowFlight()
&& pData.getGenericInstance(MovingConfig.class).noFallSkipAllowFlight) {
// Forestall potential issues with flying plugins.
player.setFallDistance(0f);
data.noFallFallDistance = 0f;
@ -387,22 +388,12 @@ public class NoFall extends Check {
* @param player
* @param data
*/
public void checkDamage(final Player player, final MovingData data, final double y) {
final MovingConfig cc = MovingConfig.getConfig(player);
public void checkDamage(final Player player, final double y,
final MovingData data, final IPlayerData pData) {
final MovingConfig cc = pData.getGenericInstance(MovingConfig.class);
// Deal damage.
handleOnGround(player, y, data.hasSetBack() ? data.getSetBackY() : Double.NEGATIVE_INFINITY,
false, data, cc);
}
/**
* Convenience method bypassing the factories.
* @param player
* @param cc
* @return
*/
public boolean isEnabled(final Player player , final MovingConfig cc, final PlayerData pData) {
return cc.noFallCheck && !NCPExemptionManager.isExempted(player, CheckType.MOVING_NOFALL)
&& !pData.hasPermission(Permissions.MOVING_NOFALL, player);
false, data, cc, pData);
}
}

View File

@ -28,6 +28,7 @@ import fr.neatmonster.nocheatplus.checks.ViolationData;
import fr.neatmonster.nocheatplus.checks.moving.MovingConfig;
import fr.neatmonster.nocheatplus.checks.moving.MovingData;
import fr.neatmonster.nocheatplus.compat.blocks.changetracker.BlockChangeTracker;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.utilities.collision.Axis;
import fr.neatmonster.nocheatplus.utilities.collision.ICollidePassable;
import fr.neatmonster.nocheatplus.utilities.collision.PassableAxisTracing;
@ -70,13 +71,20 @@ public class Passable extends Check {
blockTracker = NCPAPIProvider.getNoCheatPlusAPI().getBlockChangeTracker();
}
public Location check(final Player player, final PlayerLocation from, final PlayerLocation to,
final MovingData data, final MovingConfig cc, final int tick, final boolean useBlockChangeTracker) {
return checkActual(player, from, to, data, cc, tick, useBlockChangeTracker);
public Location check(final Player player,
final PlayerLocation from, final PlayerLocation to,
final MovingData data, final MovingConfig cc, final IPlayerData pData,
final int tick, final boolean useBlockChangeTracker) {
return checkActual(player, from, to, data, cc, pData, tick, useBlockChangeTracker);
}
private Location checkActual(final Player player, final PlayerLocation from, final PlayerLocation to,
final MovingData data, final MovingConfig cc, final int tick, final boolean useBlockChangeTracker) {
private Location checkActual(final Player player,
final PlayerLocation from, final PlayerLocation to,
final MovingData data, final MovingConfig cc, final IPlayerData pData,
final int tick, final boolean useBlockChangeTracker) {
final boolean debug = pData.isDebugActive(type);
// TODO: Distinguish feet vs. box.
// Block distances (sum, max) for from-to (not for loc!).
@ -84,9 +92,11 @@ public class Passable extends Check {
// Check default order first, then others.
rayTracing.setAxisOrder(Axis.AXIS_ORDER_YXZ);
String newTag = checkRayTracing(player, from, to, manhattan, data, cc, tick, useBlockChangeTracker);
String newTag = checkRayTracing(player, from, to, manhattan,
data, cc, debug, tick, useBlockChangeTracker);
if (newTag != null) {
newTag = checkRayTracingAlernateOrder(player, from, to, manhattan, data, cc, tick,
newTag = checkRayTracingAlernateOrder(player, from, to, manhattan,
debug, data, cc, tick,
useBlockChangeTracker, newTag);
}
// Finally handle violations.
@ -97,13 +107,16 @@ public class Passable extends Check {
}
else {
// Direct return.
return potentialViolation(player, from, to, manhattan, newTag, data, cc);
return potentialViolation(player, from, to, manhattan,
debug, newTag, data, cc);
}
}
private String checkRayTracingAlernateOrder(final Player player,
final PlayerLocation from, final PlayerLocation to, final int manhattan,
final MovingData data, final MovingConfig cc, final int tick, final boolean useBlockChangeTracker,
final PlayerLocation from, final PlayerLocation to,
final int manhattan, final boolean debug,
final MovingData data, final MovingConfig cc,
final int tick, final boolean useBlockChangeTracker,
final String previousTag) {
/*
* General assumption for now: Not all combinations have to be checked.
@ -116,16 +129,19 @@ public class Passable extends Check {
if (axis == Axis.X_AXIS || axis == Axis.Z_AXIS) {
// Test the horizontal alternative only.
rayTracing.setAxisOrder(Axis.AXIS_ORDER_YZX);
return checkRayTracing(player, from, to, manhattan, data, cc, tick, useBlockChangeTracker);
return checkRayTracing(player, from, to, manhattan, data, cc,
debug, tick, useBlockChangeTracker);
}
else if (axis == Axis.Y_AXIS) {
// Test both horizontal options, each before vertical.
rayTracing.setAxisOrder(Axis.AXIS_ORDER_XZY);
if (checkRayTracing(player, from, to, manhattan, data, cc, tick, useBlockChangeTracker) == null) {
if (checkRayTracing(player, from, to, manhattan, data, cc,
debug, tick, useBlockChangeTracker) == null) {
return null;
}
rayTracing.setAxisOrder(Axis.AXIS_ORDER_ZXY);
return checkRayTracing(player, from, to, manhattan, data, cc, tick, useBlockChangeTracker);
return checkRayTracing(player, from, to, manhattan, data, cc,
debug, tick, useBlockChangeTracker);
}
else {
return previousTag; // In case nothing could be done.
@ -134,7 +150,8 @@ public class Passable extends Check {
private String checkRayTracing(final Player player,
final PlayerLocation from, final PlayerLocation to, final int manhattan,
final MovingData data, final MovingConfig cc, final int tick, final boolean useBlockChangeTracker) {
final MovingData data, final MovingConfig cc, final boolean debug,
final int tick, final boolean useBlockChangeTracker) {
String tags = null;
// NOTE: axis order is set externally.
setNormalMargins(rayTracing, from);
@ -153,7 +170,7 @@ public class Passable extends Check {
else if (rayTracing.getStepsDone() >= rayTracing.getMaxSteps()) {
tags = "raytracing_maxsteps_";
}
if (data.debug) {
if (debug) {
debugExtraCollisionDetails(player, rayTracing, "std");
}
rayTracing.cleanup();
@ -182,22 +199,25 @@ public class Passable extends Check {
* @return
*/
private Location potentialViolation(final Player player,
final PlayerLocation from, final PlayerLocation to, final int manhattan,
final PlayerLocation from, final PlayerLocation to,
final int manhattan, final boolean debug,
String tags, final MovingData data, final MovingConfig cc) {
// TODO: Might need the workaround for fences.
return actualViolation(player, from, to, tags, data, cc);
return actualViolation(player, from, to, tags, debug, data, cc);
}
private Location actualViolation(final Player player, final PlayerLocation from, final PlayerLocation to,
final String tags, final MovingData data, final MovingConfig cc) {
private Location actualViolation(final Player player,
final PlayerLocation from, final PlayerLocation to,
final String tags, final boolean debug,
final MovingData data, final MovingConfig cc) {
Location setBackLoc = null; // Alternative to from.getLocation().
// Prefer the set back location from the data.
if (data.hasSetBack()) {
setBackLoc = data.getSetBack(to);
if (data.debug) {
if (debug) {
debug(player, "Using set back location for passable.");
}
}
@ -205,7 +225,7 @@ public class Passable extends Check {
// Return the reset position.
data.passableVL += 1d;
final ViolationData vd = new ViolationData(this, player, data.passableVL, 1, cc.passableActions);
if (data.debug || vd.needsParameters()) {
if (debug || vd.needsParameters()) {
vd.setParameter(ParameterName.LOCATION_FROM, String.format(Locale.US, "%.2f, %.2f, %.2f", from.getX(), from.getY(), from.getZ()));
vd.setParameter(ParameterName.LOCATION_TO, String.format(Locale.US, "%.2f, %.2f, %.2f", to.getX(), to.getY(), to.getZ()));
vd.setParameter(ParameterName.DISTANCE, String.format(Locale.US, "%.2f", TrigUtil.distance(from, to)));
@ -221,7 +241,7 @@ public class Passable extends Check {
newTo = LocUtil.clone(setBackLoc);
} else {
newTo = from.getLocation();
if (data.debug) {
if (debug) {
debug(player, "Using from location for passable.");
}
}

View File

@ -49,7 +49,7 @@ import fr.neatmonster.nocheatplus.components.modifier.IAttributeAccess;
import fr.neatmonster.nocheatplus.components.registry.event.IGenericInstanceHandle;
import fr.neatmonster.nocheatplus.logging.Streams;
import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.players.PlayerData;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.utilities.CheckUtils;
import fr.neatmonster.nocheatplus.utilities.StringUtil;
import fr.neatmonster.nocheatplus.utilities.ds.count.ActionAccumulator;
@ -117,12 +117,14 @@ public class SurvivalFly extends Check {
* @param useBlockChangeTracker
* @return
*/
public Location check(final Player player, final PlayerLocation from, final PlayerLocation to,
public Location check(final Player player,
final PlayerLocation from, final PlayerLocation to,
final int multiMoveCount,
final MovingData data, final MovingConfig cc, final PlayerData pData,
final MovingData data, final MovingConfig cc, final IPlayerData pData,
final int tick, final long now, final boolean useBlockChangeTracker) {
tags.clear();
if (data.debug) {
final boolean debug = pData.isDebugActive(type);
if (debug) {
justUsedWorkarounds.clear();
data.ws.setJustUsedIds(justUsedWorkarounds);
}
@ -255,7 +257,7 @@ public class SurvivalFly extends Check {
&& TrigUtil.isSamePosAndLook(thisMove.from, lastMove.to)) {
// Ground somehow appeared out of thin air (block place).
data.setSetBack(from);
if (data.debug) {
if (debug) {
debug(player, "Adjust set back on move: from is now on ground.");
}
}
@ -436,7 +438,7 @@ public class SurvivalFly extends Check {
vDistanceAboveLimit = res[1];
if (res[0] == Double.MIN_VALUE && res[1] == Double.MIN_VALUE) {
// Silent set back.
if (data.debug) {
if (debug) {
tags.add("silentsbcobweb");
outputDebug(player, to, data, cc, hDistance, hAllowedDistance, hFreedom,
yDistance, vAllowedDistance, fromOnGround, resetFrom, toOnGround, resetTo, thisMove);
@ -486,7 +488,7 @@ public class SurvivalFly extends Check {
// Debug output.
final int tagsLength;
if (data.debug) {
if (debug) {
outputDebug(player, to, data, cc, hDistance, hAllowedDistance, hFreedom,
yDistance, vAllowedDistance, fromOnGround, resetFrom, toOnGround, resetTo, thisMove);
tagsLength = tags.size();
@ -660,7 +662,7 @@ public class SurvivalFly extends Check {
// Update unused velocity tracking.
// TODO: Hide and seek with API.
// TODO: Pull down tick / timing data (perhaps add an API object for millis + source + tick + sequence count (+ source of sequence count).
if (data.debug) {
if (debug) {
// TODO: Only update, if velocity is queued at all.
data.getVerticalVelocityTracker().updateBlockedState(tick,
// Assume blocked with being in web/water, despite not entirely correct.
@ -676,14 +678,16 @@ public class SurvivalFly extends Check {
data.lastFrictionVertical = data.nextFrictionVertical;
// Log tags added after violation handling.
if (data.debug && tags.size() > tagsLength) {
if (debug && tags.size() > tagsLength) {
logPostViolationTags(player);
}
return null;
}
private boolean toOnGroundPastStates(final PlayerLocation from, final PlayerLocation to,
final PlayerMoveData thisMove, int tick, final MovingData data, final MovingConfig cc) {
private boolean toOnGroundPastStates(
final PlayerLocation from, final PlayerLocation to,
final PlayerMoveData thisMove, int tick,
final MovingData data, final MovingConfig cc) {
// TODO: Heuristics / more / which? (too short move, typical step up moves, typical levels, ...)
if (to.isOnGroundOpportune(cc.yOnGround, 0L, blockChangeTracker, data.blockChangeRef, tick)) {
tags.add("pastground_to");
@ -782,7 +786,8 @@ public class SurvivalFly extends Check {
* @param data
* @param cc
*/
private void setNextFriction(final PlayerMoveData thisMove, final MovingData data, final MovingConfig cc) {
private void setNextFriction(final PlayerMoveData thisMove,
final MovingData data, final MovingConfig cc) {
// NOTE: Other methods might still override nextFriction to 1.0 due to burst/lift-off envelope.
// TODO: Other media / medium transitions / friction by block.
final LocationData from = thisMove.from;
@ -830,7 +835,7 @@ public class SurvivalFly extends Check {
*/
private double setAllowedhDist(final Player player, final boolean sprinting,
final PlayerMoveData thisMove,
final MovingData data, final MovingConfig cc, final PlayerData pData,
final MovingData data, final MovingConfig cc, final IPlayerData pData,
final boolean checkPermissions)
{
// TODO: Optimize for double checking?
@ -1003,9 +1008,10 @@ public class SurvivalFly extends Check {
*/
private double[] vDistAir(final long now, final Player player, final PlayerLocation from,
final boolean fromOnGround, final boolean resetFrom, final PlayerLocation to,
final boolean toOnGround, final boolean resetTo, final double hDistance, final double yDistance,
final boolean toOnGround, final boolean resetTo,
final double hDistance, final double yDistance,
final int multiMoveCount, final PlayerMoveData lastMove,
final MovingData data, final MovingConfig cc, final PlayerData pData) {
final MovingData data, final MovingConfig cc, final IPlayerData pData) {
final PlayerMoveData thisMove = data.playerMoves.getCurrentMove();
// Y-distance for normal jumping, like in air.
double vAllowedDistance = 0.0;
@ -1327,7 +1333,8 @@ public class SurvivalFly extends Check {
* @param cc
* @return
*/
private double vAllowedDistanceNoData(final PlayerMoveData thisMove, final PlayerMoveData lastMove,
private double vAllowedDistanceNoData(
final PlayerMoveData thisMove, final PlayerMoveData lastMove,
final double maxJumpGain, final double jumpGainMargin,
final MovingData data, final MovingConfig cc) {
if (lastMove.valid) {
@ -1425,7 +1432,8 @@ public class SurvivalFly extends Check {
* @param tag Tag to be added in case of a violation of this sub-check.
* @return A violation value > 0.001, to be interpreted like a moving violation.
*/
private static final double verticalAccounting(final double yDistance, final ActionAccumulator acc, final ArrayList<String> tags, final String tag) {
private static final double verticalAccounting(final double yDistance,
final ActionAccumulator acc, final ArrayList<String> tags, final String tag) {
// TODO: Add air friction and do it per move anyway !?
final int count0 = acc.bucketCount(0);
if (count0 > 0) {
@ -1463,7 +1471,9 @@ public class SurvivalFly extends Check {
* @param vDistanceAboveLimit
* @return vDistanceAboveLimit
*/
private double yDirChange(final PlayerLocation from, final PlayerLocation to, final double yDistance, double vDistanceAboveLimit, final PlayerMoveData lastMove, final MovingData data) {
private double yDirChange(final PlayerLocation from, final PlayerLocation to,
final double yDistance, double vDistanceAboveLimit,
final PlayerMoveData lastMove, final MovingData data) {
// TODO: Does this account for velocity in a sufficient way?
if (yDistance > 0) {
// TODO: Clear active vertical velocity here ?
@ -1538,10 +1548,11 @@ public class SurvivalFly extends Check {
* @param skipPermChecks
* @return hAllowedDistance, hDistanceAboveLimit, hFreedom
*/
private double[] hDistAfterFailure(final Player player, final PlayerLocation from, final PlayerLocation to,
private double[] hDistAfterFailure(final Player player,
final PlayerLocation from, final PlayerLocation to,
double hAllowedDistance, double hDistanceAboveLimit, final boolean sprinting,
final PlayerMoveData thisMove, final PlayerMoveData lastMove,
final MovingData data, final MovingConfig cc, final PlayerData pData,
final MovingData data, final MovingConfig cc, final IPlayerData pData,
final boolean skipPermChecks) {
// TODO: Still not entirely sure about this checking order.
@ -1633,7 +1644,10 @@ public class SurvivalFly extends Check {
* @param data
* @return hDistanceAboveLimit
*/
private double bunnyHop(final PlayerLocation from, final PlayerLocation to, final double hAllowedDistance, double hDistanceAboveLimit, final boolean sprinting, final PlayerMoveData thisMove, final PlayerMoveData lastMove, final MovingData data, final MovingConfig cc) {
private double bunnyHop(final PlayerLocation from, final PlayerLocation to,
final double hAllowedDistance, double hDistanceAboveLimit, final boolean sprinting,
final PlayerMoveData thisMove, final PlayerMoveData lastMove,
final MovingData data, final MovingConfig cc) {
// Check "bunny fly" here, to not fall over sprint resetting on the way.
boolean allowHop = true;
boolean double_bunny = false;
@ -1819,7 +1833,9 @@ public class SurvivalFly extends Check {
* @param data
* @return vAllowedDistance, vDistanceAboveLimit
*/
private double[] vDistLiquid(final PlayerLocation from, final PlayerLocation to, final boolean toOnGround, final double yDistance, final PlayerMoveData lastMove, final MovingData data) {
private double[] vDistLiquid(final PlayerLocation from, final PlayerLocation to,
final boolean toOnGround, final double yDistance, final PlayerMoveData lastMove,
final MovingData data) {
data.sfNoLowJump = true;
// Expected envelopes.
@ -1879,7 +1895,8 @@ public class SurvivalFly extends Check {
* @param data
* @return vDistanceAboveLimit
*/
private double vDistClimbable(final Player player, final PlayerLocation from, final PlayerLocation to,
private double vDistClimbable(final Player player,
final PlayerLocation from, final PlayerLocation to,
final boolean fromOnGround, final boolean toOnGround,
final PlayerMoveData thisMove, final PlayerMoveData lastMove,
final double yDistance, final MovingData data) {
@ -1951,7 +1968,9 @@ public class SurvivalFly extends Check {
* @param cc
* @return vAllowedDistance, vDistanceAboveLimit
*/
private double[] vDistWeb(final Player player, final PlayerMoveData thisMove, final boolean toOnGround, final double hDistanceAboveLimit, final long now, final MovingData data, final MovingConfig cc) {
private double[] vDistWeb(final Player player, final PlayerMoveData thisMove,
final boolean toOnGround, final double hDistanceAboveLimit, final long now,
final MovingData data, final MovingConfig cc) {
final double yDistance = thisMove.yDistance;
double vAllowedDistance = 0.0;
double vDistanceAboveLimit = 0.0;
@ -2000,7 +2019,9 @@ public class SurvivalFly extends Check {
* @param cc
* @return
*/
private Location handleViolation(final long now, final double result, final Player player, final PlayerLocation from, final PlayerLocation to, final MovingData data, final MovingConfig cc)
private Location handleViolation(final long now, final double result,
final Player player, final PlayerLocation from, final PlayerLocation to,
final MovingData data, final MovingConfig cc)
{
// Increment violation level.
data.survivalFlyVL += result;
@ -2032,7 +2053,8 @@ public class SurvivalFly extends Check {
* @param cc
* @param data
*/
public final void handleHoverViolation(final Player player, final Location loc, final MovingConfig cc, final MovingData data) {
public final void handleHoverViolation(final Player player, final Location loc,
final MovingConfig cc, final MovingData data) {
data.survivalFlyVL += cc.sfHoverViolation;
// TODO: Extra options for set back / kick, like vl?
@ -2125,7 +2147,8 @@ public class SurvivalFly extends Check {
final MovingData data, final MovingConfig cc,
final double hDistance, final double hAllowedDistance, final double hFreedom,
final double yDistance, final double vAllowedDistance,
final boolean fromOnGround, final boolean resetFrom, final boolean toOnGround, final boolean resetTo,
final boolean fromOnGround, final boolean resetFrom,
final boolean toOnGround, final boolean resetTo,
final PlayerMoveData thisMove) {
// TODO: Show player name once (!)
final PlayerMoveData lastMove = data.playerMoves.getFirstPastMove();

View File

@ -14,15 +14,15 @@
*/
package fr.neatmonster.nocheatplus.checks.moving.player;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.moving.MovingConfig;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.moving.MovingConfig;
import fr.neatmonster.nocheatplus.checks.moving.MovingData;
import fr.neatmonster.nocheatplus.checks.moving.velocity.SimpleAxisVelocity;
import fr.neatmonster.nocheatplus.checks.moving.velocity.UnusedTracker;
import fr.neatmonster.nocheatplus.logging.debug.DebugUtil;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.utilities.CheckUtils;
public class UnusedVelocity {
@ -35,8 +35,13 @@ public class UnusedVelocity {
* @param player
* @return If the player has failed the check, whatever that means.
*/
public static boolean checkUnusedVelocity(final Player player, final CheckType checkType) {
return checkUnusedVelocity(player, checkType, MovingData.getData(player), MovingConfig.getConfig(player));
public static boolean checkUnusedVelocity(final Player player,
final CheckType checkType, final IPlayerData pData) {
return checkUnusedVelocity(
player, checkType,
pData.getGenericInstance(MovingData.class),
pData.getGenericInstance(MovingConfig.class)
);
}
@ -48,7 +53,8 @@ public class UnusedVelocity {
* @param cc
* @return If the player has failed the check, whatever that means.
*/
public static boolean checkUnusedVelocity(final Player player, final CheckType checkType, final MovingData data, final MovingConfig cc) {
public static boolean checkUnusedVelocity(final Player player,
final CheckType checkType, final MovingData data, final MovingConfig cc) {
boolean violation = false;
final SimpleAxisVelocity verVel = data.getVerticalVelocityTracker();
violation |= quickCheckDirection(player, verVel.unusedTrackerPos, checkType, "vert/pos", data, cc);

View File

@ -39,11 +39,9 @@ import fr.neatmonster.nocheatplus.compat.Bridge1_9;
import fr.neatmonster.nocheatplus.compat.BridgeMisc;
import fr.neatmonster.nocheatplus.compat.MCAccess;
import fr.neatmonster.nocheatplus.components.debug.IDebugPlayer;
import fr.neatmonster.nocheatplus.hooks.NCPExemptionManager;
import fr.neatmonster.nocheatplus.logging.StaticLog;
import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.players.DataManager;
import fr.neatmonster.nocheatplus.players.PlayerData;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.utilities.CheckUtils;
import fr.neatmonster.nocheatplus.utilities.location.LocUtil;
import fr.neatmonster.nocheatplus.utilities.location.PlayerLocation;
@ -77,17 +75,13 @@ public class MovingUtil {
* @return
*/
public static final boolean shouldCheckSurvivalFly(final Player player, final PlayerLocation fromLocation,
final MovingData data, final MovingConfig cc, final PlayerData pData) {
final MovingData data, final MovingConfig cc, final IPlayerData pData) {
final GameMode gameMode = player.getGameMode();
/*
* TODO: Model rare to check conditions (elytra, ...) on base of one
* pre-check and a method to delegate to. Reuse method(s) with
* MovingConfig.
*/
return cc.survivalFlyCheck && gameMode != BridgeMisc.GAME_MODE_SPECTATOR
// (Full activation check - use permission caching for performance rather.)
return pData.isCheckActive(CheckType.MOVING_SURVIVALFLY, player)
&& gameMode != BridgeMisc.GAME_MODE_SPECTATOR
&& (cc.ignoreCreative || gameMode != GameMode.CREATIVE) && !player.isFlying()
&& (cc.ignoreAllowFlight || !player.getAllowFlight())
&& !NCPExemptionManager.isExempted(player, CheckType.MOVING_SURVIVALFLY)
&& (
!Bridge1_9.isGlidingWithElytra(player)
|| !isGlidingWithElytraValid(player, fromLocation, data, cc)
@ -96,7 +90,7 @@ public class MovingUtil {
Double.isInfinite(Bridge1_9.getLevitationAmplifier(player))
|| fromLocation.isInLiquid()
)
&& !pData.hasPermission(Permissions.MOVING_SURVIVALFLY, player);
;
}
/**
@ -287,10 +281,11 @@ public class MovingUtil {
* @param loc
* @return
*/
public static boolean shouldCheckUntrackedLocation(final Player player, final Location loc) {
public static boolean shouldCheckUntrackedLocation(final Player player,
final Location loc, final IPlayerData pData) {
return !TrigUtil.isSamePos(loc, loc.getWorld().getSpawnLocation())
&& !BlockProperties.isPassable(loc)
&& CheckType.MOVING_PASSABLE.isEnabled(player);
&& pData.isCheckActive(CheckType.MOVING_PASSABLE, player);
}
/**
@ -321,7 +316,8 @@ public class MovingUtil {
// TODO: Exempt other warps -> HASH based exemption (expire by time, keep high count)?
if (TrigUtil.isSamePos(loc, refLoc) && (entity instanceof Player)) {
final Player other = (Player) entity;
final MovingData otherData = MovingData.getData(other);
final IPlayerData otherPData = DataManager.getPlayerData(other);
final MovingData otherData = otherPData.getGenericInstance(MovingData.class);
final PlayerMoveData otherLastMove = otherData.playerMoves.getFirstPastMove();
if (!otherLastMove.toIsValid) {
// Data might have been removed.
@ -365,8 +361,10 @@ public class MovingUtil {
* @param data
* @return
*/
public static double getRealisticFallDistance(final Player player, final double fromY, final double toY, final MovingData data) {
if (CheckType.MOVING_NOFALL.isEnabled(player)) { // Not optimal
public static double getRealisticFallDistance(final Player player,
final double fromY, final double toY,
final MovingData data, final IPlayerData pData) {
if (pData.isCheckActive(CheckType.MOVING_NOFALL, player)) {
// (NoFall will not be checked, if this method is called.)
if (data.noFallMaxY >= fromY ) {
return Math.max(0.0, data.noFallMaxY - toY);
@ -387,7 +385,8 @@ public class MovingUtil {
* @param from
* @param data
*/
public static void checkSetBack(final Player player, final PlayerLocation from, final MovingData data, final IDebugPlayer idp) {
public static void checkSetBack(final Player player, final PlayerLocation from,
final MovingData data, final IPlayerData pData, final IDebugPlayer idp) {
if (!data.hasSetBack()) {
data.setSetBack(from);
}
@ -396,7 +395,7 @@ public class MovingUtil {
(from.isOnGround() || from.isResetCond())) {
// TODO: Move most to a method?
// TODO: Is a margin needed for from.isOnGround()? [bukkitapionly]
if (data.debug) {
if (pData.isDebugActive(CheckType.MOVING)) {
// TODO: Should this be info?
idp.debug(player, "Adjust set back after join/respawn: " + from.getLocation());
}
@ -446,8 +445,9 @@ public class MovingUtil {
* @param data
* @param cc
*/
public static void ensureChunksLoaded(final Player player, final Location from, final Location to, final PlayerMoveData lastMove,
final String tag, final MovingData data, final MovingConfig cc) {
public static void ensureChunksLoaded(final Player player,
final Location from, final Location to, final PlayerMoveData lastMove,
final String tag, final MovingConfig cc, final IPlayerData pData) {
// (Worlds must be equal. Ensured in player move handling.)
final double x0 = from.getX();
final double z0 = from.getZ();
@ -489,7 +489,7 @@ public class MovingUtil {
if (loadTo) {
loaded += MapUtil.ensureChunksLoaded(to.getWorld(), x1, z1, margin);
}
if (loaded > 0 && data.debug) {
if (loaded > 0 && pData.isDebugActive(CheckType.MOVING)) {
StaticLog.logInfo("Player " + tag + ": Loaded " + loaded + " chunk" + (loaded == 1 ? "" : "s") + " for the world " + from.getWorld().getName() + " for player: " + player.getName());
}
}
@ -505,8 +505,10 @@ public class MovingUtil {
* @param data
* @param cc
*/
public static void ensureChunksLoaded(final Player player, final Location loc, final String tag,
final MovingData data, final MovingConfig cc) {
public static void ensureChunksLoaded(final Player player,
final Location loc, final String tag,
final MovingData data, final MovingConfig cc,
final IPlayerData pData) {
final PlayerMoveData lastMove = data.playerMoves.getFirstPastMove();
final double x0 = loc.getX();
final double z0 = loc.getZ();
@ -524,7 +526,7 @@ public class MovingUtil {
}
}
int loaded = MapUtil.ensureChunksLoaded(loc.getWorld(), loc.getX(), loc.getZ(), Magic.CHUNK_LOAD_MARGIN_MIN);
if (loaded > 0 && data.debug) {
if (loaded > 0 && pData.isDebugActive(CheckType.MOVING)) {
StaticLog.logInfo("Player " + tag + ": Loaded " + loaded + " chunk" + (loaded == 1 ? "" : "s") + " for the world " + loc.getWorld().getName() + " for player: " + player.getName());
}
}
@ -537,7 +539,8 @@ public class MovingUtil {
* @return
*/
public static boolean hasScheduledPlayerSetBack(final Player player) {
return hasScheduledPlayerSetBack(player.getUniqueId(), MovingData.getData(player));
return hasScheduledPlayerSetBack(player.getUniqueId(),
DataManager.getGenericInstance(player, MovingData.class));
}
/**
@ -548,8 +551,12 @@ public class MovingUtil {
* @return
*/
public static boolean hasScheduledPlayerSetBack(final UUID playerId, final MovingData data) {
final PlayerData pd = DataManager.getPlayerData(playerId);
return pd != null && data.hasTeleported() && pd.isPlayerSetBackScheduled();
return data.hasTeleported() && isPlayersetBackScheduled(playerId);
}
private static boolean isPlayersetBackScheduled(final UUID playerId) {
final IPlayerData pd = DataManager.getPlayerData(playerId);
return pd != null && pd.isPlayerSetBackScheduled();
}
/**
@ -558,10 +565,12 @@ public class MovingUtil {
* @param debugMessagePrefix
* @return True, if the teleport has been successful.
*/
public static boolean processStoredSetBack(final Player player, final String debugMessagePrefix) {
final MovingData data = MovingData.getData(player);
public static boolean processStoredSetBack(final Player player,
final String debugMessagePrefix, final IPlayerData pData) {
final MovingData data = pData.getGenericInstance(MovingData.class);
final boolean debug = pData.isDebugActive(CheckType.MOVING);
if (!data.hasTeleported()) {
if (data.debug) {
if (debug) {
CheckUtils.debug(player, CheckType.MOVING, debugMessagePrefix + "No stored location available.");
}
return false;
@ -571,7 +580,7 @@ public class MovingUtil {
final Location loc = player.getLocation(useLoc);
if (data.isTeleportedPosition(loc)) {
// Skip redundant teleport.
if (data.debug) {
if (debug) {
CheckUtils.debug(player, CheckType.MOVING, debugMessagePrefix + "Skip teleport, player is there, already.");
}
data.resetTeleported(); // Not necessary to keep.
@ -582,7 +591,7 @@ public class MovingUtil {
// (player is somewhere else.)
// Post-1.9 packet level workaround.
final MovingConfig cc = MovingConfig.getConfig(player);
final MovingConfig cc = pData.getGenericInstance(MovingConfig.class);
// TODO: Consider to skip checking for packet level, if not available (plus optimize access).
// TODO: Consider a config flag, so this can be turned off (set back method).
final PlayerSetBackMethod method = cc.playerSetBackMethod;
@ -605,9 +614,9 @@ public class MovingUtil {
*/
// (CANCEL + UPDATE_FROM mean a certain teleport to the set back, still could be repeated tp.)
// TODO: Better method, full sync reference?
final CountableLocation cl = ((NetData) CheckType.NET.getDataFactory().getData(player)).teleportQueue.getLastAck();
final CountableLocation cl = pData.getGenericInstance(NetData.class).teleportQueue.getLastAck();
if (data.isTeleportedPosition(cl)) {
if (data.debug) {
if (debug) {
CheckUtils.debug(player, CheckType.MOVING, debugMessagePrefix + "Skip teleport, having received an ACK for the teleport on packet level. Player is at: " + LocUtil.simpleFormat(loc));
}
// Keep teleported in data. Subject to debug logs and/or discussion.
@ -623,7 +632,7 @@ public class MovingUtil {
return true;
}
else {
if (data .debug) {
if (debug) {
CheckUtils.debug(player, CheckType.MOVING, "Player set back on tick: Teleport failed.");
}
return false;

View File

@ -57,13 +57,14 @@ import fr.neatmonster.nocheatplus.components.registry.event.IHandle;
import fr.neatmonster.nocheatplus.logging.StaticLog;
import fr.neatmonster.nocheatplus.logging.Streams;
import fr.neatmonster.nocheatplus.players.DataManager;
import fr.neatmonster.nocheatplus.players.PlayerData;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.utilities.CheckUtils;
import fr.neatmonster.nocheatplus.utilities.StringUtil;
import fr.neatmonster.nocheatplus.utilities.entity.PassengerUtil;
import fr.neatmonster.nocheatplus.utilities.location.LocUtil;
import fr.neatmonster.nocheatplus.utilities.location.RichBoundsLocation;
import fr.neatmonster.nocheatplus.utilities.map.BlockProperties;
import fr.neatmonster.nocheatplus.worlds.IWorldDataManager;
/**
* Aggregate vehicle checks (moving, a player is somewhere above in the
@ -85,6 +86,8 @@ public class VehicleChecks extends CheckListener {
/** The instance of NoCheatPlus. */
private final Plugin plugin = Bukkit.getPluginManager().getPlugin("NoCheatPlus"); // TODO
private final IWorldDataManager worldDataManager = NCPAPIProvider.getNoCheatPlusAPI().getWorldDataManager();
private final Set<EntityType> normalVehicles = new HashSet<EntityType>();
/** Temporary use, reset world to null afterwards, avoid nesting. */
@ -146,10 +149,11 @@ public class VehicleChecks extends CheckListener {
return;
}
final EntityType vehicleType = vehicle.getType();
final MovingData data = MovingData.getData(player);
final IPlayerData pData = DataManager.getPlayerData(player);
final MovingData data = pData.getGenericInstance(MovingData.class);
final Location from = event.getFrom();
final Location to = event.getTo();
if (data.debug) {
if (pData.isDebugActive(checkType)) {
outputDebugVehicleMoveEvent(player, from, to);
}
if (from == null) {
@ -178,11 +182,14 @@ public class VehicleChecks extends CheckListener {
// TODO: Ignore or continue?
}
// Process as move.
debug(player, "VehicleMoveEvent: legacy handling, potential issue.");
final boolean debug = pData.isDebugActive(checkType);
if (debug) {
debug(player, "VehicleMoveEvent: legacy handling, potential issue.");
}
// TODO: Actually here consistency with past position tracking should be tested.
// TODO: Abstraction creation before calling checkVehicleMove, compare/align with onVehicleUpdate.
checkVehicleMove(vehicle, vehicleType, from, to, player, false, data);
checkVehicleMove(vehicle, vehicleType, from, to, player, false, data, pData, debug);
}
private void outputDebugVehicleMoveEvent(final Player player, final Location from, final Location to) {
@ -201,12 +208,14 @@ public class VehicleChecks extends CheckListener {
* @param to
* @param data
*/
public Location onPlayerMoveVehicle(final Player player, final Location from, final Location to, final MovingData data) {
public Location onPlayerMoveVehicle(final Player player,
final Location from, final Location to,
final MovingData data, final IPlayerData pData) {
// Workaround for pigs and other (1.5.x and before)!
// Note that with 1.6 not even PlayerMove fires for horses and pigs.
// (isInsideVehicle is the faster check without object creation, do re-check though, if it changes to only check for Vehicle instances.)
final Entity vehicle = passengerUtil.getLastNonPlayerVehicle(player);
if (data.debug) {
if (pData.isDebugActive(checkType)) {
debug(player, "onPlayerMoveVehicle: vehicle: " + vehicle);
}
data.wasInVehicle = true;
@ -225,14 +234,15 @@ public class VehicleChecks extends CheckListener {
final EntityType vehicleType = vehicle.getType();
if (!normalVehicles.contains(vehicleType)) {
// Treat like VehicleUpdateEvent.
onVehicleUpdate(vehicle, vehicleType, player, true, data);
onVehicleUpdate(vehicle, vehicleType, player, true,
data, pData, pData.isDebugActive(checkType));
return null;
}
else {
final Location vLoc = vehicle.getLocation();
data.vehicleConsistency = MoveConsistency.getConsistency(from, to, vLoc);
// TODO: Consider TeleportUtil.forceMount or similar.
final MovingConfig cc = MovingConfig.getConfig(player);
final MovingConfig cc = pData.getGenericInstance(MovingConfig.class);
if (data.vehicleConsistency == MoveConsistency.INCONSISTENT) {
if (cc.vehicleEnforceLocation) {
// checks.moving.vehicle.enforcelocation
@ -258,7 +268,7 @@ public class VehicleChecks extends CheckListener {
* @param event
*/
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
public void b(final VehicleUpdateEvent event) {
public void onVehicleUpdate(final VehicleUpdateEvent event) {
// TODO: VehicleUpdateEvent. How to track teleporting of the vehicle?
// TODO: Track just left vehicle/entity positions otherwise (on tick + vehicle update)?
// TODO: No problem: (?) update 'authorized state' if no player passenger.
@ -267,7 +277,7 @@ public class VehicleChecks extends CheckListener {
if (!normalVehicles.contains(vehicleType)) {
// A little extra sweep to check for debug flags.
normalVehicles.add(vehicleType);
if (MovingConfig.getConfig(vehicle.getWorld().getName()).debug) {
if (worldDataManager.getWorldData(vehicle.getWorld()).isDebugActive(checkType)) {
debug(null, "VehicleUpdateEvent fired for: " + vehicleType);
}
}
@ -285,14 +295,16 @@ public class VehicleChecks extends CheckListener {
onPlayerVehicleLeave(player, vehicle);
return;
}
final MovingData data = MovingData.getData(player);
final IPlayerData pData = DataManager.getPlayerData(player);
final MovingData data = pData.getGenericInstance(MovingData.class);
//final MovingConfig cc = MovingConfig.getConfig(player);
if (data.debug) {
final boolean debug = pData.isDebugActive(checkType);
if (debug) {
final Location loc = vehicle.getLocation(useLoc1);
debug(player, "VehicleUpdateEvent: " + vehicleType + " " + loc);
useLoc1.setWorld(null);
}
onVehicleUpdate(vehicle, vehicleType, player, false, data);
onVehicleUpdate(vehicle, vehicleType, player, false, data, pData, debug);
}
/**
@ -309,19 +321,20 @@ public class VehicleChecks extends CheckListener {
* @param fake
* True, if this is the real VehicleUpdateEvent, false if it's
* the PlayerMoveEvent (or other).
* @param pData
*/
private void onVehicleUpdate(final Entity vehicle, final EntityType vehicleType, final Player player, final boolean fake,
final MovingData data) {
final MovingData data, final IPlayerData pData, final boolean debug) {
// TODO: (private or public?)
// TODO: Might pass last position for reference.
if (data.debug) {
if (debug) {
if (lastPosLook != null) {
// Retrieve last pos.
lastPosLook.getHandle().getPositionAndLook(vehicle, usePos1);
debug(player, "Last position is reported as: " + LocUtil.simpleFormat(usePos1));
}
}
checkVehicleMove(vehicle, vehicleType, null, null, player, true, data);
checkVehicleMove(vehicle, vehicleType, null, null, player, true, data, pData, debug);
}
/**
@ -337,13 +350,14 @@ public class VehicleChecks extends CheckListener {
* @param player
* @param fake
* @param data
* @param pData2
* @param debug
*/
private void checkVehicleMove(final Entity vehicle, final EntityType vehicleType,
final Location from, final Location to, final Player player, final boolean fake,
final MovingData data) {
final MovingData data, final IPlayerData pData, boolean debug) {
// TODO: Detect teleportation and similar.
final PlayerData pData = DataManager.getPlayerData(player);
final MovingConfig cc = MovingConfig.getConfig(player);
final MovingConfig cc = pData.getGenericInstance(MovingConfig.class);
// Exclude certain vehicle types.
if (cc.ignoredVehicles.contains(vehicleType)) {
// 100% legit.
@ -360,9 +374,9 @@ public class VehicleChecks extends CheckListener {
// Determine the best location to use as past move.
// TODO: Could also check the set backs for plausible entries, however that would lead to a violation by default. Could use an indicator.
final Location refLoc = from == null ? vehicleLocation : from;
MovingUtil.ensureChunksLoaded(player, refLoc, "vehicle move (no past move)", data, cc);
MovingUtil.ensureChunksLoaded(player, refLoc, "vehicle move (no past move)", data, cc, pData);
aux.resetVehiclePositions(vehicle, refLoc, data, cc);
if (data.debug) {
if (pData.isDebugActive(checkType)) {
// TODO: Might warn instead.
debug(player, "Missing past move data, set to: " + firstPastMove.from);
}
@ -391,12 +405,13 @@ public class VehicleChecks extends CheckListener {
recoverVehicleSetBack(player, vehicle, vehicleLocation, moveInfo, data, cc);
}
NCPAPIProvider.getNoCheatPlusAPI().getLogManager().warning(Streams.STATUS, CheckUtils.getLogMessagePrefix(player, CheckType.MOVING_VEHICLE) + "Illegal coordinates on checkVehicleMove: from: " + from + " , to: " + to);
setBack(player, vehicle, newTo, data, cc);
setBack(player, vehicle, newTo, data, cc, pData);
aux.returnVehicleMoveInfo(moveInfo);
return;
}
// Ensure chunks are loaded.
MovingUtil.ensureChunksLoaded(player, useFrom, useTo, firstPastMove, "vehicle move", data, cc);
MovingUtil.ensureChunksLoaded(player, useFrom, useTo, firstPastMove,
"vehicle move", cc, pData);
// Initialize currentMove.
final VehicleMoveData thisMove = data.vehicleMoves.getCurrentMove();
thisMove.set(moveInfo.from, moveInfo.to);
@ -480,8 +495,9 @@ public class VehicleChecks extends CheckListener {
final Location vehicleLocation, final World world,
final VehicleMoveInfo moveInfo, final VehicleMoveData thisMove, final VehicleMoveData firstPastMove,
final Player player, final boolean fake,
final MovingData data, final MovingConfig cc, final PlayerData pData) {
final MovingData data, final MovingConfig cc, final IPlayerData pData) {
// TODO: (private or public?)
final boolean debug = pData.isDebugActive(checkType);
data.joinOrRespawn = false;
data.vehicleConsistency = MoveConsistency.getConsistency(thisMove, player.getLocation(useLoc1));
@ -506,7 +522,7 @@ public class VehicleChecks extends CheckListener {
data.clearNoFallData();
}
if (data.debug) {
if (debug) {
// Log move.
outputDebugVehicleMove(player, vehicle, thisMove, fake);
}
@ -515,19 +531,19 @@ public class VehicleChecks extends CheckListener {
// Ensure a common set back for now.
if (!data.vehicleSetBacks.isDefaultEntryValid()) {
ensureSetBack(player, thisMove, data);
ensureSetBack(player, thisMove, data, pData);
}
// Moving envelope check(s).
// TODO: Use set back storage for testing if this is appropriate (use SetBackEntry instead, remove Location retrieval then?).
if ((newTo == null || data.vehicleSetBacks.getSafeMediumEntry().isValidAndOlderThan(newTo))
&& vehicleEnvelope.isEnabled(player, cc, pData)) {
&& pData.isCheckActive(CheckType.MOVING_VEHICLE_ENVELOPE, player)) {
// Skip if this is the first move after set back, with to=set back.
if (data.timeSinceSetBack == 0 || thisMove.to.hashCode() == data.lastSetBackHash) {
// TODO: This is a hot fix, to prevent a set back loop. Depends on having only the morepackets set back for vehicles.
// TODO: Perhaps might want to add || !data.equalsAnyVehicleSetBack(to)
thisMove.specialCondition = true;
if (data.debug) {
if (debug) {
debug(player, "Skip envelope check on first move after set back acknowledging the set back with an odd starting point (from).");
}
}
@ -535,7 +551,8 @@ public class VehicleChecks extends CheckListener {
// Set up basic details about what/how to check.
vehicleEnvelope.prepareCheckDetails(vehicle, moveInfo, thisMove);
// Check.
final SetBackEntry tempNewTo = vehicleEnvelope.check(player, vehicle, thisMove, fake, data, cc);
final SetBackEntry tempNewTo = vehicleEnvelope.check(player, vehicle,
thisMove, fake, data, cc, pData);
if (tempNewTo != null) {
newTo = tempNewTo;
}
@ -545,8 +562,9 @@ public class VehicleChecks extends CheckListener {
// More packets: Sort this in last, to avoid setting the set back early. Always check to adjust set back, for now.
// TODO: Still always update the frequency part?
if ((newTo == null || data.vehicleSetBacks.getMidTermEntry().isValidAndOlderThan(newTo))) {
if (vehicleMorePackets.isEnabled(player, cc, pData)) {
final SetBackEntry tempNewTo = vehicleMorePackets.check(player, thisMove, newTo, data, cc);
if (pData.isCheckActive(CheckType.MOVING_VEHICLE_MOREPACKETS, player)) {
final SetBackEntry tempNewTo = vehicleMorePackets.check(player, thisMove, newTo,
data, cc, pData);
if (tempNewTo != null) {
newTo = tempNewTo;
}
@ -571,7 +589,7 @@ public class VehicleChecks extends CheckListener {
data.vehicleMoves.finishCurrentMove();
}
else {
setBack(player, vehicle, newTo, data, cc);
setBack(player, vehicle, newTo, data, cc, pData);
}
useLoc1.setWorld(null);
}
@ -581,7 +599,7 @@ public class VehicleChecks extends CheckListener {
for (final Entity passenger : passengers) {
if ((passenger instanceof Player) && !player.equals(passenger)) {
final Player otherPlayer = (Player) passenger;
final MovingData otherData = MovingData.getData(otherPlayer);
final MovingData otherData = DataManager.getGenericInstance(otherPlayer, MovingData.class);
otherData.resetVehiclePositions(moveInfo.to);
// TODO: Reset all precisely to what there is or this or what not.
otherData.vehicleSetBacks.resetAllLazily(data.vehicleSetBacks.getOldestValidEntry());
@ -599,7 +617,8 @@ public class VehicleChecks extends CheckListener {
* @param thisMove
* @param data
*/
private void ensureSetBack(final Player player, final VehicleMoveData thisMove, final MovingData data) {
private void ensureSetBack(final Player player, final VehicleMoveData thisMove,
final MovingData data, final IPlayerData pData) {
final IGetLocationWithLook ensureLoc;
if (!data.vehicleSetBacks.isAnyEntryValid()) {
ensureLoc = thisMove.from;
@ -608,20 +627,23 @@ public class VehicleChecks extends CheckListener {
ensureLoc = data.vehicleSetBacks.getOldestValidEntry();
}
data.vehicleSetBacks.setDefaultEntry(ensureLoc);
if (data.debug) {
if (pData.isDebugActive(checkType)) {
debug(player, "Ensure vehicle set back: " + ensureLoc);
}
// if (data.vehicleSetBackTaskId != -1) {
// // TODO: This is likely the wrong thing to do!
// Bukkit.getScheduler().cancelTask(data.vehicleSetBackTaskId);
// data.vehicleSetBackTaskId = -1;
// if (data.debug) {
// if (debug) {
// debug(player, "Cancel set back task on ensureSetBack.");
// }
// }
}
private void setBack(final Player player, final Entity vehicle, final SetBackEntry newTo, final MovingData data, final MovingConfig cc) {
private void setBack(final Player player, final Entity vehicle,
final SetBackEntry newTo, final MovingData data,
final MovingConfig cc, final IPlayerData pData) {
final boolean debug = pData.isDebugActive(checkType);
// TODO: Generic set back manager, preventing all sorts of stuff that might be attempted or just happen before the task is running?
if (data.vehicleSetBackTaskId == -1) {
// Schedule a delayed task to teleport back the vehicle with the player.
@ -632,20 +654,20 @@ public class VehicleChecks extends CheckListener {
// TODO: Prevent vehicle data resetting due to dismount/mount/teleport.
// TODO: Force fall type of set back?
// (Future: Dismount penalty does not need extra handling, both are teleported anyway.)
if (data.debug) {
if (debug) {
debug(player, "Will set back to: " + newTo);
}
boolean scheduleSetBack = cc.scheduleVehicleSetBacks;
// Schedule as task, if set so.
if (scheduleSetBack) {
aux.resetVehiclePositions(vehicle, LocUtil.set(useLoc2, vehicle.getWorld(), newTo), data, cc); // Heavy-ish, though.
data.vehicleSetBackTaskId = Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new VehicleSetBackTask(vehicle, player, newTo.getLocation(vehicle.getWorld()), data.debug));
data.vehicleSetBackTaskId = Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new VehicleSetBackTask(vehicle, player, newTo.getLocation(vehicle.getWorld()), debug));
if (data.vehicleSetBackTaskId == -1) {
NCPAPIProvider.getNoCheatPlusAPI().getLogManager().warning(Streams.STATUS, "Failed to schedule vehicle set back task. Player: " + player.getName() + " , set back: " + newTo);
scheduleSetBack = false; // Force direct teleport as a fall-back measure.
}
else if (data.debug) {
else if (debug) {
debug(player, "Vehicle set back task id: " + data.vehicleSetBackTaskId);
}
}
@ -658,14 +680,15 @@ public class VehicleChecks extends CheckListener {
* resetting and updating the set back (if needed) is done there
* (hack, subject to current review).
*/
if (data.debug) {
if (debug) {
debug(player, "Attempt to set the player back directly.");
}
passengerUtil.teleportWithPassengers(vehicle, player, newTo.getLocation(vehicle.getWorld()), data.debug);
passengerUtil.teleportWithPassengers(vehicle, player,
newTo.getLocation(vehicle.getWorld()), debug, pData);
}
}
else if (data.debug) {
else if (debug) {
// TODO: Reset positions.
data.vehicleMoves.invalidate();
debug(player, "Vehicle set back task already scheduled, skip this time.");
@ -692,21 +715,23 @@ public class VehicleChecks extends CheckListener {
* @return True, if an event is to be cancelled.
*/
public boolean onPlayerVehicleEnter(final Player player, final Entity vehicle) {
final MovingData data = MovingData.getData(player);
final IPlayerData pData = DataManager.getPlayerData(player);
final boolean debug = pData.isDebugActive(checkType);
final MovingData data = pData.getGenericInstance(MovingData.class);
if (!data.isVehicleSetBack && MovingUtil.hasScheduledPlayerSetBack(player.getUniqueId(), data)) {
if (data.debug) {
if (debug) {
debug(player, "Vehicle enter: prevent, due to a scheduled set back.");
}
return true;
}
if (data.debug) {
if (debug) {
debug(player, "Vehicle enter: first vehicle: " + vehicle.getClass().getName());
}
// Check for nested vehicles.
final Entity lastVehicle = passengerUtil.getLastNonPlayerVehicle(vehicle, true);
if (lastVehicle == null) {
data.clearVehicleData();
if (data.debug) {
if (debug) {
debugNestedVehicleEnter(player);
}
return false;
@ -714,14 +739,14 @@ public class VehicleChecks extends CheckListener {
else if (!lastVehicle.equals(vehicle)) {
// Nested vehicles.
// TODO: Should in general skip checking these? Set backs don't yet work with these anyway (either... or ...).
if (data.debug) {
if (debug) {
debug(player, "Vehicle enter: last of nested vehicles: " + lastVehicle.getClass().getName());
}
dataOnVehicleEnter(player, lastVehicle, data);
dataOnVehicleEnter(player, lastVehicle, data, pData);
}
else {
// Proceed normally.
dataOnVehicleEnter(player, vehicle, data);
dataOnVehicleEnter(player, vehicle, data, pData);
}
return false;
}
@ -745,9 +770,10 @@ public class VehicleChecks extends CheckListener {
* @param player
* @param vehicle
*/
private void dataOnVehicleEnter(final Player player, final Entity vehicle, final MovingData data) {
private void dataOnVehicleEnter(final Player player, final Entity vehicle,
final MovingData data, final IPlayerData pData) {
// Adjust data.
final MovingConfig cc = MovingConfig.getConfig(player);
final MovingConfig cc = pData.getGenericInstance(MovingConfig.class);
data.joinOrRespawn = false;
data.removeAllVelocity();
// Event should have a vehicle, in case check this last.
@ -764,7 +790,7 @@ public class VehicleChecks extends CheckListener {
data.vehicleSetBacks.resetAll(vLoc);
}
aux.resetVehiclePositions(vehicle, vLoc, data, cc);
if (data.debug) {
if (pData.isDebugActive(checkType)) {
debug(player, "Vehicle enter: " + vehicle.getType() + " , player: " + useLoc2 + " c=" + data.vehicleConsistency);
}
useLoc1.setWorld(null);
@ -778,8 +804,9 @@ public class VehicleChecks extends CheckListener {
* @param data
* @param cc
*/
public void onVehicleLeaveMiss(final Player player, final MovingData data, final MovingConfig cc) {
if (data.debug) {
public void onVehicleLeaveMiss(final Player player,
final MovingData data, final MovingConfig cc, final IPlayerData pData) {
if (pData.isDebugActive(checkType)) {
StaticLog.logWarning("VehicleExitEvent missing for: " + player.getName());
}
onPlayerVehicleLeave(player, null);
@ -808,11 +835,11 @@ public class VehicleChecks extends CheckListener {
final Entity attacker = event.getAttacker();
if (attacker instanceof Player && passengerUtil.isPassenger(attacker, event.getVehicle())) {
final Player player = (Player) attacker;
final MovingConfig cc = MovingConfig.getConfig(player);
final IPlayerData pData = DataManager.getPlayerData(player);
final MovingConfig cc = pData.getGenericInstance(MovingConfig.class);
if (cc.vehiclePreventDestroyOwn) {
final PlayerData pData = DataManager.getPlayerData(player);
if (CheckUtils.isEnabled(CheckType.MOVING_SURVIVALFLY, player, cc, pData)
|| CheckUtils.isEnabled(CheckType.MOVING_CREATIVEFLY, player, cc, pData)) {
if (pData.isCheckActive(CheckType.MOVING_SURVIVALFLY, player)
|| pData.isCheckActive(CheckType.MOVING_CREATIVEFLY, player)) {
}
event.setCancelled(true);
// TODO: This message must be configurable.
@ -836,7 +863,9 @@ public class VehicleChecks extends CheckListener {
* @param vehicle May be null in case of "not possible to determine".
*/
private void onPlayerVehicleLeave(final Player player, final Entity vehicle) {
final MovingData data = MovingData.getData(player);
final IPlayerData pData = DataManager.getPlayerData(player);
final MovingData data = pData.getGenericInstance(MovingData.class);
final boolean debug = pData.isDebugActive(checkType);
data.wasInVehicle = false;
data.joinOrRespawn = false;
// if (data.vehicleSetBackTaskId != -1) {
@ -845,7 +874,7 @@ public class VehicleChecks extends CheckListener {
// return;
// }
final MovingConfig cc = MovingConfig.getConfig(player);
final MovingConfig cc = pData.getGenericInstance(MovingConfig.class);
// TODO: Loc can be inconsistent, determine which to use !
final Location pLoc = player.getLocation(useLoc1);
Location loc = pLoc; // The location to use as set back.
@ -875,7 +904,7 @@ public class VehicleChecks extends CheckListener {
}
}
}
if (data.debug) {
if (debug) {
debug(player, "Vehicle leave: " + vehicle.getType() + "@" + pLoc.distance(vLoc));
}
}
@ -885,7 +914,7 @@ public class VehicleChecks extends CheckListener {
loc.setY(Location.locToBlock(loc.getY()) + 1.25);
}
if (data.debug) {
if (debug) {
debug(player, "Vehicle leave: " + pLoc.toString() + (pLoc.equals(loc) ? "" : " / player at: " + pLoc.toString()));
}
aux.resetPositionsAndMediumProperties(player, loc, data, cc);

View File

@ -36,6 +36,7 @@ import fr.neatmonster.nocheatplus.checks.moving.model.PlayerMoveData;
import fr.neatmonster.nocheatplus.checks.moving.model.VehicleMoveData;
import fr.neatmonster.nocheatplus.checks.moving.model.VehicleMoveInfo;
import fr.neatmonster.nocheatplus.checks.workaround.WRPT;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.utilities.ReflectionUtil;
import fr.neatmonster.nocheatplus.utilities.StringUtil;
@ -103,16 +104,21 @@ public class VehicleEnvelope extends Check {
bestHorse = clazz == null ? ReflectionUtil.getClass("org.bukkit.entity.Horse") : clazz;
}
public SetBackEntry check(final Player player, final Entity vehicle, final VehicleMoveData thisMove, final boolean isFake, final MovingData data, final MovingConfig cc) {
public SetBackEntry check(final Player player, final Entity vehicle,
final VehicleMoveData thisMove, final boolean isFake,
final MovingData data, final MovingConfig cc,
final IPlayerData pData) {
final boolean debug = pData.isDebugActive(type);
// Delegate to a sub-check.
tags.clear();
tags.add("entity." + vehicle.getType());
if (data.debug) {
if (debug) {
debugDetails.clear();
data.ws.setJustUsedIds(debugDetails); // Add just used workaround ids to this list directly, for now.
}
final boolean violation = checkEntity(player, vehicle, thisMove, isFake, data, cc);
if (data.debug && !debugDetails.isEmpty()) {
final boolean violation = checkEntity(player, vehicle, thisMove, isFake,
data, cc, debug);
if (debug && !debugDetails.isEmpty()) {
debugDetails(player);
debugDetails.clear();
}
@ -157,9 +163,12 @@ public class VehicleEnvelope extends Check {
}
}
private boolean checkEntity(final Player player, final Entity vehicle, final VehicleMoveData thisMove, final boolean isFake, final MovingData data, final MovingConfig cc) {
private boolean checkEntity(final Player player, final Entity vehicle,
final VehicleMoveData thisMove, final boolean isFake,
final MovingData data, final MovingConfig cc,
final boolean debug) {
boolean violation = false;
if (data.debug) {
if (debug) {
debugDetails.add("inair: " + data.sfJumpPhase);
}
@ -179,7 +188,7 @@ public class VehicleEnvelope extends Check {
// TODO: Get extended liquid specs (allow confine to certain flags, here: water). Contains info if water is only flowing down, surface properties (non liquid blocks?), still water.
if (thisMove.from.inWeb) {
// TODO: Check anything?
if (data.debug) {
if (debug) {
debugDetails.add("");
}
// if (thisMove.yDistance > 0.0) {
@ -205,7 +214,7 @@ public class VehicleEnvelope extends Check {
}
else if (thisMove.from.inWater && thisMove.to.inWater) {
// Default in-medium move.
if (data.debug) {
if (debug) {
debugDetails.add("water-water");
}
// TODO: Should still cover extreme moves here.
@ -229,27 +238,27 @@ public class VehicleEnvelope extends Check {
}
if (thisMove.from.onIce && thisMove.to.onIce) {
// Default on-ice move.
if (data.debug) {
if (debug) {
debugDetails.add("ice-ice");
}
// TODO: Should still cover extreme moves here.
}
else {
// (TODO: actually a default on-ground move.)
if (data.debug) {
if (debug) {
debugDetails.add("ground-ground");
}
}
}
else if (checkDetails.inAir) {
// In-air move.
if (checkInAir(thisMove, data)) {
if (checkInAir(thisMove, data, debug)) {
violation = true;
}
}
else {
// Some transition to probably handle.
if (data.debug) {
if (debug) {
debugDetails.add("?-?");
}
// TODO: Lift off speed etc.
@ -371,11 +380,12 @@ public class VehicleEnvelope extends Check {
* @param data
* @return
*/
private boolean checkInAir(final VehicleMoveData thisMove, final MovingData data) {
private boolean checkInAir(final VehicleMoveData thisMove, final MovingData data,
final boolean debug) {
// TODO: Distinguish sfJumpPhase and inAirDescendCount (after reaching the highest point).
if (data.debug) {
if (debug) {
debugDetails.add("air-air");
}
@ -422,7 +432,7 @@ public class VehicleEnvelope extends Check {
violation = false;
checkDetails.checkDescendMuch = checkDetails.checkAscendMuch = false; // (Full envelope has been checked.)
}
if (data.debug) {
if (debug) {
debugDetails.add("maxDescend: " + maxDescend);
}
}

View File

@ -24,6 +24,7 @@ import fr.neatmonster.nocheatplus.checks.moving.MovingConfig;
import fr.neatmonster.nocheatplus.checks.moving.MovingData;
import fr.neatmonster.nocheatplus.checks.moving.location.setback.SetBackEntry;
import fr.neatmonster.nocheatplus.checks.moving.model.VehicleMoveData;
import fr.neatmonster.nocheatplus.players.IPlayerData;
/**
* This check does the exact same thing as the MorePacket check but this one works for players inside vehicles.
@ -58,7 +59,8 @@ public class VehicleMorePackets extends Check {
* @return the location
*/
public SetBackEntry check(final Player player, final VehicleMoveData thisMove,
final SetBackEntry setBack, final MovingData data, final MovingConfig cc) {
final SetBackEntry setBack, final MovingData data, final MovingConfig cc,
final IPlayerData pData) {
// Take time once, first:
final long time = System.currentTimeMillis();
final boolean allowSetSetBack = setBack == null && data.vehicleSetBackTaskId == -1;
@ -74,6 +76,9 @@ public class VehicleMorePackets extends Check {
return data.vehicleSetBacks.getValidMidTermEntry();
}
final boolean debug = pData.isDebugActive(type);
// Player used up buffer, they fail the check.
if (data.vehicleMorePacketsBuffer < 0) {
@ -83,7 +88,7 @@ public class VehicleMorePackets extends Check {
// Execute whatever actions are associated with this check and the violation level and find out if we should
// cancel the event.
final ViolationData vd = new ViolationData(this, player, data.vehicleMorePacketsVL, -data.vehicleMorePacketsBuffer, cc.vehicleMorePacketsActions);
if (data.debug || vd.needsParameters()) {
if (debug || vd.needsParameters()) {
vd.setParameter(ParameterName.PACKETS, Integer.toString(-data.vehicleMorePacketsBuffer));
}
if (executeActions(vd).willCancel()){
@ -114,11 +119,12 @@ public class VehicleMorePackets extends Check {
// Set the new set back location.
if (allowSetSetBack && newTo == null) {
data.vehicleSetBacks.setMidTermEntry(thisMove.from);
if (data.debug) {
if (debug) {
debug(player, "Update vehicle morepackets set back: " + thisMove.from);
}
}
} else if (data.vehicleMorePacketsLastTime > time) {
}
else if (data.vehicleMorePacketsLastTime > time) {
// Security check, maybe system time changed.
data.vehicleMorePacketsLastTime = time;
}

View File

@ -21,6 +21,8 @@ import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.NCPAPIProvider;
import fr.neatmonster.nocheatplus.checks.moving.MovingData;
import fr.neatmonster.nocheatplus.logging.StaticLog;
import fr.neatmonster.nocheatplus.players.DataManager;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.utilities.entity.PassengerUtil;
/**
@ -57,11 +59,12 @@ public class VehicleSetBackTask implements Runnable{
@Override
public void run() {
final MovingData data = MovingData.getData(player);
final IPlayerData pData = DataManager.getPlayerData(player);
final MovingData data = pData.getGenericInstance(MovingData.class);
data.vehicleSetBackTaskId = -1;
try{
NCPAPIProvider.getNoCheatPlusAPI().getGenericInstance(PassengerUtil.class).teleportWithPassengers(
vehicle, player, location, debug, passengers, true);
vehicle, player, location, debug, passengers, true, pData);
}
catch(Throwable t){
StaticLog.logSevere(t);

View File

@ -20,6 +20,7 @@ import fr.neatmonster.nocheatplus.actions.ParameterName;
import fr.neatmonster.nocheatplus.checks.Check;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.ViolationData;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.utilities.TickTask;
public class AttackFrequency extends Check {
@ -28,7 +29,8 @@ public class AttackFrequency extends Check {
super(CheckType.NET_ATTACKFREQUENCY);
}
public boolean check(final Player player, final long time, final NetData data, final NetConfig cc) {
public boolean check(final Player player, final long time,
final NetData data, final NetConfig cc, final IPlayerData pData) {
// Update frequency.
data.attackFrequencySeconds.add(time, 1f);
double maxVL = 0.0;
@ -84,7 +86,7 @@ public class AttackFrequency extends Check {
if (maxVL > 0.0) {
// Trigger a violation.
final ViolationData vd = new ViolationData(this, player, maxVL, 1.0, cc.attackFrequencyActions);
if (data.debug || vd.needsParameters()) {
if (pData.isDebugActive(type) || vd.needsParameters()) {
vd.setParameter(ParameterName.PACKETS, Integer.toString((int) sum));
vd.setParameter(ParameterName.LIMIT, Integer.toString((int) maxLimit));
vd.setParameter(ParameterName.TAGS, tags);

View File

@ -19,8 +19,7 @@ import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.checks.Check;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.net.model.DataPacketFlying;
import fr.neatmonster.nocheatplus.players.PlayerData;
import fr.neatmonster.nocheatplus.utilities.CheckUtils;
import fr.neatmonster.nocheatplus.players.IPlayerData;
/**
* Check frequency of (pos/look/) flying packets, disregarding packet content.
@ -48,11 +47,10 @@ public class FlyingFrequency extends Check {
* @return
*/
public boolean check(final Player player, final DataPacketFlying packetData, final long time,
final NetData data, final NetConfig cc, final PlayerData pData) {
final NetData data, final NetConfig cc, final IPlayerData pData) {
data.flyingFrequencyAll.add(time, 1f);
final float allScore = data.flyingFrequencyAll.score(1f);
if (allScore / cc.flyingFrequencySeconds > cc.flyingFrequencyPPS
&& !CheckUtils.hasBypass(CheckType.NET_FLYINGFREQUENCY, player, pData)
if (allScore / cc.flyingFrequencySeconds > cc.flyingFrequencyPPS
&& executeActions(player, allScore / cc.flyingFrequencySeconds - cc.flyingFrequencyPPS, 1.0 / cc.flyingFrequencySeconds, cc.flyingFrequencyActions).willCancel()) {
return true;
} else {

View File

@ -14,11 +14,9 @@
*/
package fr.neatmonster.nocheatplus.checks.net;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.net.model.DataPacketFlying;
import fr.neatmonster.nocheatplus.components.registry.event.IHandle;
import fr.neatmonster.nocheatplus.players.IPlayerData;
/**
* Convenience for providing several checks with a lazy-init handle for fetching
@ -32,7 +30,7 @@ import fr.neatmonster.nocheatplus.components.registry.event.IHandle;
*/
public class FlyingQueueHandle implements IHandle<DataPacketFlying[]> {
private final Player player;
private final IPlayerData pData;
private DataPacketFlying[] queue;
/**
* Convenience flag for keeping track amongst multiple checks, which all get
@ -40,14 +38,15 @@ public class FlyingQueueHandle implements IHandle<DataPacketFlying[]> {
*/
private boolean currentLocationValid = true;
public FlyingQueueHandle(Player player) {
this.player = player;
public FlyingQueueHandle(IPlayerData pData) {
// TODO: PlayerData ?
this.pData = pData;
}
@Override
public DataPacketFlying[] getHandle() {
if (queue == null) {
queue = ((NetData) CheckType.NET.getDataFactory().getData(player)).copyFlyingQueue();
queue = pData.getGenericInstance(NetData.class).copyFlyingQueue();
}
return queue;
}

View File

@ -18,8 +18,7 @@ import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.checks.Check;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.players.PlayerData;
import fr.neatmonster.nocheatplus.utilities.CheckUtils;
import fr.neatmonster.nocheatplus.players.IPlayerData;
public class KeepAliveFrequency extends Check {
@ -36,10 +35,10 @@ public class KeepAliveFrequency extends Check {
* @return If to cancel.
*/
public boolean check(final Player player, final long time, final NetData data, final NetConfig cc,
final PlayerData pData) {
final IPlayerData pData) {
data.keepAliveFreq.add(time, 1f);
final float first = data.keepAliveFreq.bucketScore(0);
if (first > 1f && !CheckUtils.hasBypass(CheckType.NET_KEEPALIVEFREQUENCY, player, pData)) {
if (first > 1f) {
// Trigger a violation.
final double vl = Math.max(first - 1f, data.keepAliveFreq.score(1f) - data.keepAliveFreq.numberOfBuckets());
if (executeActions(player, vl, 1.0, cc.keepAliveFrequencyActions).willCancel()) {

View File

@ -17,12 +17,15 @@ package fr.neatmonster.nocheatplus.checks.net;
import fr.neatmonster.nocheatplus.actions.ActionList;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.access.ACheckConfig;
import fr.neatmonster.nocheatplus.compat.AlmostBoolean;
import fr.neatmonster.nocheatplus.compat.versions.ServerVersion;
import fr.neatmonster.nocheatplus.components.config.value.OverrideType;
import fr.neatmonster.nocheatplus.config.ConfPaths;
import fr.neatmonster.nocheatplus.config.ConfigFile;
import fr.neatmonster.nocheatplus.config.ConfigManager;
import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.permissions.RegisteredPermission;
import fr.neatmonster.nocheatplus.worlds.IWorldData;
/**
* Configuration for the net checks (fast version, sparse).
@ -47,7 +50,6 @@ public class NetConfig extends ACheckConfig {
// Instance
/////////////
public final boolean attackFrequencyActive;
public final float attackFrequencyLimitSecondsHalf;
public final float attackFrequencyLimitSecondsOne;
public final float attackFrequencyLimitSecondsTwo;
@ -55,7 +57,6 @@ public class NetConfig extends ACheckConfig {
public final float attackFrequencyLimitSecondsEight;
public final ActionList attackFrequencyActions;
public final boolean flyingFrequencyActive;
public final int flyingFrequencySeconds;
public final double flyingFrequencyPPS;
public final ActionList flyingFrequencyActions;
@ -63,27 +64,24 @@ public class NetConfig extends ACheckConfig {
public final int flyingFrequencyRedundantSeconds;
public final ActionList flyingFrequencyRedundantActions;
public final boolean keepAliveFrequencyActive;
public final ActionList keepAliveFrequencyActions;
public final boolean packetFrequencyActive;
public final float packetFrequencyPacketsPerSecond;
public final int packetFrequencySeconds;
public final ActionList packetFrequencyActions;
public final boolean soundDistanceActive;
/** Maximum distance for lightning effects (squared). */
public final double soundDistanceSq;
public final boolean supersededFlyingCancelWaiting;
public NetConfig(final ConfigFile config) {
public NetConfig(final IWorldData worldData) {
// TODO: These permissions should have default policies.
super(config, ConfPaths.NET);
super(worldData);
final ConfigFile config = worldData.getRawConfiguration();
final ConfigFile globalConfig = ConfigManager.getConfigFile();
attackFrequencyActive = config.getBoolean(ConfPaths.NET_ATTACKFREQUENCY_ACTIVE);
attackFrequencyLimitSecondsHalf = config.getInt(ConfPaths.NET_ATTACKFREQUENCY_SECONDS_HALF);
attackFrequencyLimitSecondsOne = config.getInt(ConfPaths.NET_ATTACKFREQUENCY_SECONDS_ONE);
attackFrequencyLimitSecondsTwo = config.getInt(ConfPaths.NET_ATTACKFREQUENCY_SECONDS_TWO);
@ -91,7 +89,6 @@ public class NetConfig extends ACheckConfig {
attackFrequencyLimitSecondsEight = config.getInt(ConfPaths.NET_ATTACKFREQUENCY_SECONDS_EIGHT);
attackFrequencyActions = config.getOptimizedActionList(ConfPaths.NET_ATTACKFREQUENCY_ACTIONS, Permissions.NET_ATTACKFREQUENCY);
flyingFrequencyActive = config.getBoolean(ConfPaths.NET_FLYINGFREQUENCY_ACTIVE);
flyingFrequencySeconds = Math.max(1, globalConfig.getInt(ConfPaths.NET_FLYINGFREQUENCY_SECONDS));
flyingFrequencyPPS = Math.max(1.0, globalConfig.getDouble(ConfPaths.NET_FLYINGFREQUENCY_PACKETSPERSECOND));
flyingFrequencyActions = config.getOptimizedActionList(ConfPaths.NET_FLYINGFREQUENCY_ACTIONS, Permissions.NET_FLYINGFREQUENCY);
@ -100,15 +97,17 @@ 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);
packetFrequencyActive = config.getAlmostBoolean(ConfPaths.NET_PACKETFREQUENCY_ACTIVE, ServerVersion.compareMinecraftVersion("1.9") < 0, false);
if (ServerVersion.compareMinecraftVersion("1.9") >= 0) {
// TODO: Disable packet frequency or activate 'pessimistically'.
worldData.overrideCheckActivation(CheckType.NET_PACKETFREQUENCY,
AlmostBoolean.NO, OverrideType.PERMANENT, true);
}
packetFrequencyPacketsPerSecond = config.getInt(ConfPaths.NET_PACKETFREQUENCY_PPS);
packetFrequencySeconds = config.getInt(ConfPaths.NET_PACKETFREQUENCY_SECONDS);
packetFrequencyActions = config.getOptimizedActionList(ConfPaths.NET_PACKETFREQUENCY_ACTIONS, Permissions.NET_PACKETFREQUENCY);
soundDistanceActive = config.getBoolean(ConfPaths.NET_SOUNDDISTANCE_ACTIVE);
double dist = config.getDouble(ConfPaths.NET_SOUNDDISTANCE_MAXDISTANCE);
soundDistanceSq = dist * dist;
@ -116,22 +115,4 @@ public class NetConfig extends ACheckConfig {
}
@Override
public boolean isEnabled(final CheckType checkType) {
switch(checkType) {
case NET_ATTACKFREQUENCY:
return attackFrequencyActive;
case NET_FLYINGFREQUENCY:
return flyingFrequencyActive;
case NET_PACKETFREQUENCY:
return packetFrequencyActive;
case NET_SOUNDDISTANCE:
return soundDistanceActive;
case NET_KEEPALIVEFREQUENCY:
return keepAliveFrequencyActive;
default:
return true;
}
}
}

View File

@ -1,49 +0,0 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package fr.neatmonster.nocheatplus.checks.net;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.checks.access.CheckConfigFactory;
import fr.neatmonster.nocheatplus.config.ConfigFile;
import fr.neatmonster.nocheatplus.config.WorldConfigCache;
/**
* Copy-on-write per-world configuration cache.
* @author asofold
*
*/
public class NetConfigCache extends WorldConfigCache<NetConfig> implements CheckConfigFactory {
public NetConfigCache() {
super(true);
}
@Override
protected NetConfig newConfig(String key, ConfigFile configFile) {
return new NetConfig(configFile);
}
@Override
public NetConfig getConfig(final Player player) {
return getConfig(player.getWorld());
}
@Override
public void removeAllConfigs() {
clearAllConfigs();
}
}

View File

@ -92,7 +92,6 @@ public class NetData extends ACheckData {
public final ActionFrequency packetFrequency;
public NetData(final NetConfig config) {
super(config);
flyingFrequencyAll = new ActionFrequency(config.flyingFrequencySeconds, 1000L);
flyingFrequencyRedundantFreq = new ActionFrequency(config.flyingFrequencyRedundantSeconds, 1000L);
if (config.packetFrequencySeconds <= 2) {

View File

@ -1,74 +0,0 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package fr.neatmonster.nocheatplus.checks.net;
import java.util.Iterator;
import java.util.UUID;
import java.util.Map.Entry;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.access.CheckDataFactory;
import fr.neatmonster.nocheatplus.checks.access.ICheckData;
import fr.neatmonster.nocheatplus.components.data.ICanHandleTimeRunningBackwards;
import fr.neatmonster.nocheatplus.utilities.ds.map.HashMapLOW;
/**
* Factory for NetData.
* @author asofold
*
*/
public class NetDataFactory implements CheckDataFactory, ICanHandleTimeRunningBackwards {
private final HashMapLOW<String, NetData> dataMap = new HashMapLOW<String, NetData>(35);
@Override
public void removeAllData() {
dataMap.clear();
}
@Override
public NetData getData(Player player) {
NetData data = dataMap.get(player.getName());
if (data != null) {
return data;
} else {
data = new NetData((NetConfig) CheckType.NET.getConfigFactory().getConfig(player));
dataMap.put(player.getName(), data);
return data;
}
}
@Override
public ICheckData getDataIfPresent(UUID playerId, String playerName) {
return dataMap.get(playerName);
}
@Override
public NetData removeData(String playerName) {
return dataMap.remove(playerName);
}
@Override
public void handleTimeRanBackwards() {
final Iterator<Entry<String, NetData>> it = dataMap.iterator();
while (it.hasNext()) {
final Entry<String, NetData> entry = it.next();
entry.getValue().handleSystemTimeRanBackwards();
}
}
}

View File

@ -16,10 +16,6 @@ package fr.neatmonster.nocheatplus.checks.net;
import java.util.List;
import org.bukkit.World;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.checks.chat.ChatData;
import fr.neatmonster.nocheatplus.utilities.TickTask;
import fr.neatmonster.nocheatplus.utilities.ds.count.ActionFrequency;
@ -167,23 +163,4 @@ public class NetStatic {
return Math.max(0.0, violation);
}
/**
* Convenience: Check stored world names in case the world is null.
*
* NOTE:
* @param player
* @param configCache
* @param dataFactory
* @return
*/
public static NetConfig getWorldConfig(Player player, NetConfigCache configCache, NetDataFactory dataFactory) {
World world = null;
try {
world = player.getWorld();
}
catch (UnsupportedOperationException e) {}
// TODO: Abusing ChatData for tracking world names. Should be in PlayerData or some generic data.
return configCache.getConfig(world == null ? ChatData.getData(player).currentWorldName : world.getName());
}
}

Some files were not shown because too many files have changed in this diff Show More