mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2025-01-31 20:01:25 +01:00
Add yawrate check to fight/combined. Adjust angle check.
This commit is contained in:
parent
5e2d4fe57f
commit
66fe28dd93
105
src/fr/neatmonster/nocheatplus/checks/combined/Combined.java
Normal file
105
src/fr/neatmonster/nocheatplus/checks/combined/Combined.java
Normal file
@ -0,0 +1,105 @@
|
||||
package fr.neatmonster.nocheatplus.checks.combined;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
|
||||
/**
|
||||
* Static access API for shared use. This is actually not really a check, but access to combined or shared data.
|
||||
* @author mc_dev
|
||||
*
|
||||
*/
|
||||
public class Combined {
|
||||
|
||||
/**
|
||||
* Check if a penalty is set by changing horizontal facing dierection too often.
|
||||
* @param player
|
||||
* @param yaw
|
||||
* @param now
|
||||
* @param worldName
|
||||
* @return
|
||||
*/
|
||||
public static final boolean checkYaw(final Player player, final float yaw, final long now, final String worldName){
|
||||
return checkYaw(player, yaw, now, worldName, CombinedData.getData(player));
|
||||
}
|
||||
|
||||
/**
|
||||
* Feed horizontal facing direction.
|
||||
* @param player
|
||||
* @param yaw
|
||||
* @param now
|
||||
* @param worldName
|
||||
*/
|
||||
public static final void feedYaw(final Player player, final float yaw, final long now, final String worldName){
|
||||
feedYaw(player, yaw, now, worldName, CombinedData.getData(player));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the yaw change data.
|
||||
* @param player
|
||||
* @param yaw
|
||||
* @param now
|
||||
* @param worldName
|
||||
* @param data
|
||||
*/
|
||||
private static final void feedYaw(final Player player, final float yaw, final long now, final String worldName, final CombinedData data) {
|
||||
// Reset on world change or timeout.
|
||||
if (now - data.lastYawTime > 999 || !worldName.equals(data.lastWorld)){
|
||||
data.lastYaw = yaw;
|
||||
data.lastYawTime = now;
|
||||
data.lastWorld = worldName;
|
||||
}
|
||||
|
||||
final float yawDiff = (yaw - data.lastYaw) % 180;
|
||||
final long elapsed = now - data.lastYawTime;
|
||||
|
||||
// Set data to current state.
|
||||
data.lastYaw = yaw;
|
||||
data.lastYawTime = now;
|
||||
|
||||
final float dAbs = Math.abs(yawDiff);
|
||||
final float dNorm = (float) dAbs / (float) (1 + elapsed);
|
||||
|
||||
data.yawFreq.add(now, dNorm);
|
||||
}
|
||||
|
||||
/**
|
||||
* This calls feedLastYaw and does nothing but set the freezing time to be used by whatever check.
|
||||
* @param player
|
||||
* @param yaw
|
||||
* @param now
|
||||
* @param worldName
|
||||
* @return
|
||||
*/
|
||||
private static final boolean checkYaw(Player player, float yaw, long now, final String worldName, final CombinedData data) {
|
||||
|
||||
feedYaw(player, yaw, now, worldName, data);
|
||||
|
||||
final CombinedConfig cc = CombinedConfig.getConfig(player);
|
||||
|
||||
// Angle diff per second
|
||||
final float total = Math.max(data.yawFreq.getScore(1f), data.yawFreq.getScore(0) * 3f);
|
||||
final float threshold = cc.lastYawRate;
|
||||
if (total > threshold){
|
||||
// Add time
|
||||
data.timeFreeze = Math.max(data.timeFreeze, now + (long) ((total - threshold) / threshold * 1000f));
|
||||
}
|
||||
return now < data.timeFreeze;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow to pass a config flag if to check or only to feed.
|
||||
* @param player
|
||||
* @param yaw
|
||||
* @param now
|
||||
* @param worldName
|
||||
* @param yawRateCheck If to actually check the yaw rate, or just feed.
|
||||
* @return
|
||||
*/
|
||||
public static final boolean checkYaw(final Player player, final float yaw, final long now, final String worldName, final boolean yawRateCheck) {
|
||||
if (yawRateCheck) return checkYaw(player, yaw, now, worldName);
|
||||
else {
|
||||
feedYaw(player, yaw, now, worldName);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -37,14 +37,20 @@ public class CombinedConfig extends ACheckConfig {
|
||||
return cc;
|
||||
}
|
||||
|
||||
/** Do mind that this flag is not used by all compinents. */
|
||||
public final boolean improbableCheck;
|
||||
public final float improbableLevel;
|
||||
public final ActionList improbableActions;
|
||||
|
||||
// Last yaw tracking
|
||||
public final float lastYawRate;
|
||||
|
||||
public CombinedConfig(final ConfigFile config) {
|
||||
improbableCheck = config.getBoolean(ConfPaths.COMBINED_IMPROBABLE_CHECK, false);
|
||||
improbableLevel = (float) config.getDouble(ConfPaths.COMBINED_IMPROBABLE_LEVEL, 300);
|
||||
improbableActions = config.getActionList(ConfPaths.COMBINED_IMPROBABLE_ACTIONS, Permissions.COMBINED_IMPROBABLE);
|
||||
|
||||
lastYawRate = config.getInt(ConfPaths.COMBINED_YAWRATE_RATE);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -46,11 +46,13 @@ public class CombinedData extends ACheckData {
|
||||
|
||||
public float lastYaw;
|
||||
public long lastYawTime;
|
||||
public final ActionFrequency yawFreq = new ActionFrequency(4, 500);
|
||||
public final ActionFrequency yawFreq = new ActionFrequency(3, 333);
|
||||
|
||||
public long timeFreeze = 0;
|
||||
|
||||
public final ActionFrequency improbableCount = new ActionFrequency(20, 3000);
|
||||
|
||||
public String lastWorld = "";
|
||||
|
||||
public CombinedData(final Player player){
|
||||
// final CombinedConfig cc = CombinedConfig.getConfig(player);
|
||||
|
@ -1,10 +1,13 @@
|
||||
package fr.neatmonster.nocheatplus.checks.combined;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
import org.bukkit.event.player.PlayerToggleSneakEvent;
|
||||
import org.bukkit.event.player.PlayerToggleSprintEvent;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -19,23 +22,26 @@ public class CombinedListener implements Listener {
|
||||
this.improbable = new Improbable();
|
||||
}
|
||||
|
||||
// @EventHandler(priority=EventPriority.LOW)
|
||||
// public void onPlayerToggleSneak(final PlayerToggleSneakEvent event){
|
||||
// // Check also in case of cancelled events.
|
||||
// if (Improbable.check(event.getPlayer(), 0.35f, System.currentTimeMillis())) event.setCancelled(true);
|
||||
// }
|
||||
//
|
||||
// @EventHandler(priority=EventPriority.LOW)
|
||||
// public void onPlayerToggleSprint(final PlayerToggleSprintEvent event){
|
||||
// // Check also in case of cancelled events.
|
||||
// if (Improbable.check(event.getPlayer(), 0.35f, System.currentTimeMillis())) event.setCancelled(true);
|
||||
// }
|
||||
@EventHandler(priority=EventPriority.LOW)
|
||||
public void onPlayerToggleSneak(final PlayerToggleSneakEvent event){
|
||||
// Check also in case of cancelled events.
|
||||
if (Improbable.check(event.getPlayer(), 0.35f, System.currentTimeMillis())) event.setCancelled(true);
|
||||
}
|
||||
|
||||
@EventHandler(priority=EventPriority.MONITOR)
|
||||
@EventHandler(priority=EventPriority.LOW)
|
||||
public void onPlayerToggleSprint(final PlayerToggleSprintEvent event){
|
||||
// Check also in case of cancelled events.
|
||||
if (Improbable.check(event.getPlayer(), 0.35f, System.currentTimeMillis())) event.setCancelled(true);
|
||||
}
|
||||
|
||||
@EventHandler(priority=EventPriority.MONITOR, ignoreCancelled = false)
|
||||
public final void onPlayerMove(final PlayerMoveEvent event){
|
||||
final Player player =event.getPlayer();
|
||||
// Experimental
|
||||
final Player player = event.getPlayer();
|
||||
// Just add the yaw to the list.
|
||||
Improbable.checkYaw(player, player.getLocation().getYaw(), System.currentTimeMillis());
|
||||
final Location loc = player.getLocation();
|
||||
final String worldName = loc.getWorld().getName();
|
||||
Combined.feedYaw(player, loc.getYaw(), System.currentTimeMillis(), worldName);
|
||||
}
|
||||
|
||||
// (possibly other types of events, but these combine with fighting).
|
||||
|
@ -26,10 +26,6 @@ public class Improbable extends Check {
|
||||
public static final boolean check(final Player player, final float weight, final long now){
|
||||
return instance.checkImprobable(player, weight, now);
|
||||
}
|
||||
|
||||
public static final boolean checkYaw(final Player player, final float yaw, final long now){
|
||||
return instance.checkLastYaw(player, yaw, now);
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
// Instance methods.
|
||||
@ -67,28 +63,5 @@ public class Improbable extends Check {
|
||||
data.improbableVL *= 0.95;
|
||||
return cancel;
|
||||
}
|
||||
|
||||
private boolean checkLastYaw(Player player, float yaw, long now) {
|
||||
if (!isEnabled(player)) return false;
|
||||
final CombinedData data = CombinedData.getData(player);
|
||||
// final CombinedConfig cc = CombinedConfig.getConfig(player);
|
||||
final float yawDiff = (yaw - data.lastYaw) % 180;
|
||||
|
||||
|
||||
// final long elapsed = now - data.lastYawTime;
|
||||
boolean cancel = false;
|
||||
|
||||
if (now < data.timeFreeze) cancel = true;
|
||||
|
||||
final float dAbs = Math.abs(yawDiff);
|
||||
data.yawFreq.add(now, (float) dAbs); // *3f / ((float) (elapsed + 1)) );
|
||||
if (dAbs > 30) data.timeFreeze = now + (long) dAbs * 3;
|
||||
// System.out.println("yawDiff " + player.getName() + ": " + yawDiff + " (" + elapsed+ ") - " + data.yawFreq.getScore(1f));
|
||||
|
||||
// Set data to current state.
|
||||
data.lastYaw = yaw;
|
||||
data.lastYawTime = now;
|
||||
return cancel;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -38,11 +38,17 @@ public class Angle extends Check {
|
||||
*
|
||||
* @param player
|
||||
* the player
|
||||
* @param worldChanged
|
||||
* @return true, if successful
|
||||
*/
|
||||
public boolean check(final Player player) {
|
||||
public boolean check(final Player player, final boolean worldChanged) {
|
||||
final FightConfig cc = FightConfig.getConfig(player);
|
||||
final FightData data = FightData.getData(player);
|
||||
|
||||
if (worldChanged){
|
||||
// TODO: clear some data.
|
||||
data.angleHits.clear();
|
||||
}
|
||||
|
||||
boolean cancel = false;
|
||||
|
||||
@ -69,13 +75,15 @@ public class Angle extends Check {
|
||||
for (final long time : data.angleHits.descendingKeySet()) {
|
||||
final Location location = data.angleHits.get(time);
|
||||
// We need a previous location to calculate deltas.
|
||||
if (previousLocation != null && location.getWorld().getName().equals(previousLocation.getWorld().getName())) {
|
||||
if (previousLocation != null){ // && location.getWorld().getName().equals(previousLocation.getWorld().getName())) {
|
||||
// (Risks exceptions on reloading).
|
||||
// Calculate the distance between the two locations.
|
||||
deltaMove += previousLocation.distanceSquared(location);
|
||||
// Calculate the time elapsed between the two hits.
|
||||
deltaTime += previousTime - time;
|
||||
// Calculate the difference of the yaw between the two locations.
|
||||
deltaYaw += (previousLocation.getYaw() - location.getYaw()) % 360f;
|
||||
final float dYaw = (previousLocation.getYaw() - location.getYaw()) % 180;
|
||||
deltaYaw += Math.abs(dYaw);
|
||||
}
|
||||
// Remember the current time and location.
|
||||
previousTime = time;
|
||||
|
@ -99,6 +99,8 @@ public class FightConfig extends ACheckConfig {
|
||||
public final boolean speedCheck;
|
||||
public final int speedLimit;
|
||||
public final ActionList speedActions;
|
||||
|
||||
public final boolean yawRateCheck;
|
||||
|
||||
/**
|
||||
* Instantiates a new fight configuration.
|
||||
@ -143,6 +145,8 @@ public class FightConfig extends ACheckConfig {
|
||||
speedCheck = data.getBoolean(ConfPaths.FIGHT_SPEED_CHECK);
|
||||
speedLimit = data.getInt(ConfPaths.FIGHT_SPEED_LIMIT);
|
||||
speedActions = data.getActionList(ConfPaths.FIGHT_SPEED_ACTIONS, Permissions.FIGHT_SPEED);
|
||||
|
||||
yawRateCheck = data.getBoolean(ConfPaths.FIGHT_YAWRATE_CHECK, true);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
@ -72,6 +72,10 @@ public class FightData extends ACheckData {
|
||||
public double speedVL;
|
||||
|
||||
public boolean skipNext;
|
||||
|
||||
// Shared
|
||||
|
||||
public String lastWorld = "";
|
||||
|
||||
// Data of the angle check.
|
||||
public TreeMap<Long, Location> angleHits = new TreeMap<Long, Location>();
|
||||
|
@ -15,6 +15,7 @@ import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason;
|
||||
import org.bukkit.event.player.PlayerAnimationEvent;
|
||||
import org.bukkit.event.player.PlayerToggleSprintEvent;
|
||||
|
||||
import fr.neatmonster.nocheatplus.checks.combined.Combined;
|
||||
import fr.neatmonster.nocheatplus.checks.combined.Improbable;
|
||||
import fr.neatmonster.nocheatplus.players.Permissions;
|
||||
|
||||
@ -98,6 +99,8 @@ public class FightListener implements Listener {
|
||||
|
||||
boolean cancelled = false;
|
||||
|
||||
final String worldName = player.getWorld().getName();
|
||||
|
||||
// Check for self hit exploits (mind that projectiles should be excluded)
|
||||
final Entity cbEntity = event.getEntity();
|
||||
if (cbEntity instanceof Player){
|
||||
@ -113,10 +116,11 @@ public class FightListener implements Listener {
|
||||
|
||||
final long now = System.currentTimeMillis();
|
||||
|
||||
final boolean worldChanged = !worldName.equals(data.lastWorld);
|
||||
|
||||
// Improbable yaw:
|
||||
if (Improbable.checkYaw(player, player.getLocation().getYaw(), now)){
|
||||
if (Combined.checkYaw(player, player.getLocation().getYaw(), now, worldName, cc.yawRateCheck)){
|
||||
cancelled = true;
|
||||
// System.out.println(player.getName() + " <- cancelled attack by yaw.");
|
||||
}
|
||||
|
||||
// Combined speed:
|
||||
@ -127,7 +131,7 @@ public class FightListener implements Listener {
|
||||
final net.minecraft.server.Entity damaged = ((CraftEntity) cbEntity).getHandle();
|
||||
|
||||
// Run through the main checks.
|
||||
if (!cancelled && angle.isEnabled(player) && angle.check(player))
|
||||
if (!cancelled && angle.isEnabled(player) && angle.check(player, worldChanged))
|
||||
cancelled = true;
|
||||
|
||||
if (!cancelled && critical.isEnabled(player) && critical.check(player))
|
||||
@ -154,6 +158,8 @@ public class FightListener implements Listener {
|
||||
// One of the checks requested the event to be cancelled, so do it.
|
||||
if (cancelled)
|
||||
event.setCancelled(cancelled);
|
||||
|
||||
data.lastWorld = worldName;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -301,6 +301,9 @@ public abstract class ConfPaths {
|
||||
|
||||
public static final String COMBINED_IMPROBABLE_ACTIONS = COMBINED_IMPROBABLE + "actions";
|
||||
|
||||
private static final String COMBINED_YAWRATE = COMBINED + "yawrate.";
|
||||
public static final String COMBINED_YAWRATE_RATE = COMBINED_YAWRATE + "rate";
|
||||
|
||||
/*
|
||||
* 888'Y88 ,e, 888 d8
|
||||
* 888 ,'Y " e88 888 888 ee d88
|
||||
@ -359,6 +362,9 @@ public abstract class ConfPaths {
|
||||
public static final String FIGHT_SPEED_CHECK = FIGHT_SPEED + "active";
|
||||
public static final String FIGHT_SPEED_LIMIT = FIGHT_SPEED + "limit";
|
||||
public static final String FIGHT_SPEED_ACTIONS = FIGHT_SPEED + "actions";
|
||||
|
||||
private static final String FIGHT_YAWRATE = FIGHT + "yawrate.";
|
||||
public static final String FIGHT_YAWRATE_CHECK = FIGHT_YAWRATE + "active";
|
||||
|
||||
/*
|
||||
* 888 d8
|
||||
|
@ -228,6 +228,8 @@ public class DefaultConfig extends ConfigFile {
|
||||
set(ConfPaths.COMBINED_IMPROBABLE_FASTBREAK_CHECK, false);
|
||||
set(ConfPaths.COMBINED_IMPROBABLE_ACTIONS, "cancel log:improbable:2:8:if");
|
||||
|
||||
set(ConfPaths.COMBINED_YAWRATE_RATE , "380");
|
||||
|
||||
/*
|
||||
* 888'Y88 ,e, 888 d8
|
||||
* 888 ,'Y " e88 888 888 ee d88
|
||||
@ -237,6 +239,8 @@ public class DefaultConfig extends ConfigFile {
|
||||
* , 88P
|
||||
* "8",P"
|
||||
*/
|
||||
set(ConfPaths.FIGHT_YAWRATE_CHECK, true);
|
||||
|
||||
set(ConfPaths.FIGHT_ANGLE_CHECK, true);
|
||||
set(ConfPaths.FIGHT_ANGLE_THRESHOLD, 50);
|
||||
set(ConfPaths.FIGHT_ANGLE_ACTIONS, "cancel vl>100 log:angle:3:5:f cancel vl>250 log:angle:0:5:cif cancel");
|
||||
|
Loading…
Reference in New Issue
Block a user