mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2025-01-20 06:21:23 +01:00
[Development] Started working on the fight checks and some little fixes.
This commit is contained in:
parent
40bf2a171a
commit
a4f16cedf0
@ -6,10 +6,8 @@ import java.util.logging.Logger;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.command.CommandException;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
import fr.neatmonster.nocheatplus.actions.Action;
|
||||
import fr.neatmonster.nocheatplus.actions.ParameterName;
|
||||
@ -36,7 +34,7 @@ import fr.neatmonster.nocheatplus.players.Permissions;
|
||||
/**
|
||||
* The Class Check.
|
||||
*/
|
||||
public abstract class Check implements Listener {
|
||||
public abstract class Check {
|
||||
protected static Map<String, ExecutionHistory> histories = new HashMap<String, ExecutionHistory>();
|
||||
|
||||
private static Logger fileLogger = null;
|
||||
@ -54,31 +52,6 @@ public abstract class Check implements Listener {
|
||||
return histories.get(player.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a player is close enough to a target, based on his eye location.
|
||||
*
|
||||
* @param player
|
||||
* the player
|
||||
* @param targetX
|
||||
* the target x
|
||||
* @param targetY
|
||||
* the target y
|
||||
* @param targetZ
|
||||
* the target z
|
||||
* @param limit
|
||||
* the limit
|
||||
* @return the result
|
||||
*/
|
||||
public static final double reachCheck(final Player player, final double targetX, final double targetY,
|
||||
final double targetZ, final double limit) {
|
||||
final Location eyes = player.getPlayer().getEyeLocation();
|
||||
|
||||
final double distance = Math.sqrt(Math.pow(eyes.getX() - targetX, 2) + Math.pow(eyes.getY() - targetY, 2)
|
||||
+ Math.pow(eyes.getZ() - targetZ, 2));
|
||||
|
||||
return Math.max(distance - limit, 0.0D);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the colors of a message.
|
||||
*
|
||||
|
@ -48,7 +48,7 @@ public class Arrivals extends Check {
|
||||
private final Map<Long, String> joins = new HashMap<Long, String>();
|
||||
|
||||
/**
|
||||
* Checks player.
|
||||
* Checks a player.
|
||||
*
|
||||
* @param player
|
||||
* the player
|
||||
|
160
src/fr/neatmonster/nocheatplus/checks/fight/Angle.java
Normal file
160
src/fr/neatmonster/nocheatplus/checks/fight/Angle.java
Normal file
@ -0,0 +1,160 @@
|
||||
package fr.neatmonster.nocheatplus.checks.fight;
|
||||
|
||||
import java.util.TreeMap;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import fr.neatmonster.nocheatplus.actions.ParameterName;
|
||||
import fr.neatmonster.nocheatplus.checks.Check;
|
||||
import fr.neatmonster.nocheatplus.checks.CheckEvent;
|
||||
import fr.neatmonster.nocheatplus.players.Permissions;
|
||||
import fr.neatmonster.nocheatplus.utilities.LagMeasureTask;
|
||||
|
||||
/*
|
||||
* MMP"""""""MM dP
|
||||
* M' .mmmm MM 88
|
||||
* M `M 88d888b. .d8888b. 88 .d8888b.
|
||||
* M MMMMM MM 88' `88 88' `88 88 88ooood8
|
||||
* M MMMMM MM 88 88 88. .88 88 88. ...
|
||||
* M MMMMM MM dP dP `8888P88 dP `88888P'
|
||||
* MMMMMMMMMMMM .88
|
||||
* d8888P
|
||||
*/
|
||||
/**
|
||||
* A check used to verify if the player isn't using a forcefield in order to attack multiple entities at the same time.
|
||||
*
|
||||
* Thanks @asofold for the original idea!
|
||||
*/
|
||||
public class Angle extends Check {
|
||||
|
||||
/**
|
||||
* The event triggered by this check.
|
||||
*/
|
||||
public class AngleEvent extends CheckEvent {
|
||||
|
||||
/**
|
||||
* Instantiates a new angle event.
|
||||
*
|
||||
* @param player
|
||||
* the player
|
||||
*/
|
||||
public AngleEvent(final Player player) {
|
||||
super(player);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks a player.
|
||||
*
|
||||
* @param player
|
||||
* the player
|
||||
* @return true, if successful
|
||||
*/
|
||||
public boolean check(final Player player) {
|
||||
final FightConfig cc = FightConfig.getConfig(player);
|
||||
final FightData data = FightData.getData(player);
|
||||
|
||||
boolean cancel = false;
|
||||
|
||||
// Remove the old locations from the map.
|
||||
for (final long time : new TreeMap<Long, Location>(data.angleHits).navigableKeySet())
|
||||
if (System.currentTimeMillis() - time > 1000L)
|
||||
data.angleHits.remove(time);
|
||||
|
||||
// Add the new location to the map.
|
||||
data.angleHits.put(System.currentTimeMillis(), player.getLocation());
|
||||
|
||||
// Declare variables.
|
||||
double deltaMove = 0D;
|
||||
long deltaTime = 0L;
|
||||
float deltaYaw = 0f;
|
||||
|
||||
// Browse the locations of the map.
|
||||
long previousTime = 0L;
|
||||
Location previousLocation = null;
|
||||
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) {
|
||||
// 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;
|
||||
}
|
||||
// Remember the current time and location.
|
||||
previousTime = time;
|
||||
previousLocation = location;
|
||||
}
|
||||
|
||||
// Let's calculate the average move.
|
||||
final double averageMove = deltaMove / (data.angleHits.size() - 1);
|
||||
|
||||
// And the average time elapsed.
|
||||
final double averageTime = deltaTime / (data.angleHits.size() - 1);
|
||||
|
||||
// And the average yaw delta.
|
||||
final double averageYaw = deltaYaw / (data.angleHits.size() - 1);
|
||||
|
||||
// Declare the variable.
|
||||
double violation = 0D;
|
||||
|
||||
// If the average move is between 0 and 0.2 block(s), add it to the violation.
|
||||
if (averageMove > 0D && averageMove < 0.2D)
|
||||
violation += 200D * (0.2D - averageMove) / 0.2D;
|
||||
|
||||
// If the average time elapsed is between 0 and 150 millisecond(s), add it to the violation.
|
||||
if (averageTime > 0L && averageTime < 150L)
|
||||
violation += 500D * (150L - averageTime) / 150L;
|
||||
|
||||
// If the average difference of yaw is superior to 50 degrees, add it to the violation.
|
||||
if (averageYaw > 50f)
|
||||
violation += 300D * (360f - averageYaw) / 360f;
|
||||
|
||||
// Transform the violation into a percentage.
|
||||
violation /= 10D;
|
||||
|
||||
// Is the violation is superior to the threshold defined in the configuration?
|
||||
if (violation > cc.angleThreshold) {
|
||||
|
||||
// Has the server lagged?
|
||||
if (!LagMeasureTask.skipCheck())
|
||||
// If it hasn't, increment the violation level.
|
||||
data.angleVL += violation;
|
||||
|
||||
// Dispatch a angle event (API).
|
||||
final AngleEvent e = new AngleEvent(player);
|
||||
Bukkit.getPluginManager().callEvent(e);
|
||||
|
||||
// Execute whatever actions are associated with this check and the violation level and find out if we should
|
||||
// cancel the event.
|
||||
cancel = !e.isCancelled() && executeActions(player, cc.angleActions, data.angleVL);
|
||||
} else
|
||||
// Reward the player by lowering his violation level.
|
||||
data.angleVL *= 0.98D;
|
||||
|
||||
return cancel;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see fr.neatmonster.nocheatplus.checks.Check#getParameter(fr.neatmonster.nocheatplus.actions.ParameterName, org.bukkit.entity.Player)
|
||||
*/
|
||||
@Override
|
||||
public String getParameter(final ParameterName wildcard, final Player player) {
|
||||
if (wildcard == ParameterName.VIOLATIONS)
|
||||
return String.valueOf(Math.round(FightData.getData(player).angleVL));
|
||||
else
|
||||
return super.getParameter(wildcard, player);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see fr.neatmonster.nocheatplus.checks.Check#isEnabled(org.bukkit.entity.Player)
|
||||
*/
|
||||
@Override
|
||||
protected boolean isEnabled(final Player player) {
|
||||
return !player.hasPermission(Permissions.FIGHT_ANGLE) && FightConfig.getConfig(player).angleCheck;
|
||||
}
|
||||
}
|
69
src/fr/neatmonster/nocheatplus/checks/fight/FightConfig.java
Normal file
69
src/fr/neatmonster/nocheatplus/checks/fight/FightConfig.java
Normal file
@ -0,0 +1,69 @@
|
||||
package fr.neatmonster.nocheatplus.checks.fight;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import fr.neatmonster.nocheatplus.actions.types.ActionList;
|
||||
import fr.neatmonster.nocheatplus.config.ConfPaths;
|
||||
import fr.neatmonster.nocheatplus.config.ConfigFile;
|
||||
import fr.neatmonster.nocheatplus.config.ConfigManager;
|
||||
import fr.neatmonster.nocheatplus.players.Permissions;
|
||||
|
||||
/*
|
||||
* MM""""""""`M oo dP dP MM'""""'YMM .8888b oo
|
||||
* MM mmmmmmmM 88 88 M' .mmm. `M 88 "
|
||||
* M' MMMM dP .d8888b. 88d888b. d8888P M MMMMMooM .d8888b. 88d888b. 88aaa dP .d8888b.
|
||||
* MM MMMMMMMM 88 88' `88 88' `88 88 M MMMMMMMM 88' `88 88' `88 88 88 88' `88
|
||||
* MM MMMMMMMM 88 88. .88 88 88 88 M. `MMM' .M 88. .88 88 88 88 88 88. .88
|
||||
* MM MMMMMMMM dP `8888P88 dP dP dP MM. .dM `88888P' dP dP dP dP `8888P88
|
||||
* MMMMMMMMMMMM .88 MMMMMMMMMMM .88
|
||||
* d8888P d8888P
|
||||
*/
|
||||
/**
|
||||
* Configurations specific for the "fight" checks. Every world gets one of these assigned to it, or if a world doesn't
|
||||
* get it's own, it will use the "global" version.
|
||||
*/
|
||||
public class FightConfig {
|
||||
|
||||
/** The map containing the configurations per world. */
|
||||
private static 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 int angleThreshold;
|
||||
public final ActionList angleActions;
|
||||
|
||||
/**
|
||||
* Instantiates a new fight configuration.
|
||||
*
|
||||
* @param data
|
||||
* the data
|
||||
*/
|
||||
public FightConfig(final ConfigFile data) {
|
||||
angleCheck = data.getBoolean(ConfPaths.FIGHT_ANGLE_CHECK);
|
||||
angleThreshold = data.getInt(ConfPaths.FIGHT_ANGLE_THRESHOLD);
|
||||
angleActions = data.getActionList(ConfPaths.FIGHT_ANGLE_ACTIONS, Permissions.FIGHT_ANGLE);
|
||||
}
|
||||
}
|
46
src/fr/neatmonster/nocheatplus/checks/fight/FightData.java
Normal file
46
src/fr/neatmonster/nocheatplus/checks/fight/FightData.java
Normal file
@ -0,0 +1,46 @@
|
||||
package fr.neatmonster.nocheatplus.checks.fight;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/*
|
||||
* MM""""""""`M oo dP dP M""""""'YMM dP
|
||||
* MM mmmmmmmM 88 88 M mmmm. `M 88
|
||||
* M' MMMM dP .d8888b. 88d888b. d8888P M MMMMM M .d8888b. d8888P .d8888b.
|
||||
* MM MMMMMMMM 88 88' `88 88' `88 88 M MMMMM M 88' `88 88 88' `88
|
||||
* MM MMMMMMMM 88 88. .88 88 88 88 M MMMM' .M 88. .88 88 88. .88
|
||||
* MM MMMMMMMM dP `8888P88 dP dP dP M .MM `88888P8 dP `88888P8
|
||||
* MMMMMMMMMMMM .88 MMMMMMMMMMM
|
||||
* d8888P
|
||||
*/
|
||||
/**
|
||||
* Player specific data for the fight checks.
|
||||
*/
|
||||
public class FightData {
|
||||
|
||||
/** The map containing the data per players. */
|
||||
private static Map<String, FightData> playersMap = new HashMap<String, FightData>();
|
||||
|
||||
/**
|
||||
* 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());
|
||||
return playersMap.get(player.getName());
|
||||
}
|
||||
|
||||
// Violation levels.
|
||||
public double angleVL;
|
||||
|
||||
// Data of the angle check.
|
||||
public TreeMap<Long, Location> angleHits = new TreeMap<Long, Location>();
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package fr.neatmonster.nocheatplus.checks.fight;
|
||||
|
||||
/*
|
||||
* MM""""""""`M oo dP dP M""MMMMMMMM oo dP
|
||||
* MM mmmmmmmM 88 88 M MMMMMMMM 88
|
||||
* M' MMMM dP .d8888b. 88d888b. d8888P M MMMMMMMM dP .d8888b. d8888P .d8888b. 88d888b. .d8888b. 88d888b.
|
||||
* MM MMMMMMMM 88 88' `88 88' `88 88 M MMMMMMMM 88 Y8ooooo. 88 88ooood8 88' `88 88ooood8 88' `88
|
||||
* MM MMMMMMMM 88 88. .88 88 88 88 M MMMMMMMM 88 88 88 88. ... 88 88 88. ... 88
|
||||
* MM MMMMMMMM dP `8888P88 dP dP dP M M dP `88888P' dP `88888P' dP dP `88888P' dP
|
||||
* MMMMMMMMMMMM .88 MMMMMMMMMMM
|
||||
* d8888P
|
||||
*/
|
||||
/**
|
||||
* Central location to listen to events that are relevant for the fight checks.
|
||||
*/
|
||||
public class FightListener {
|
||||
|
||||
}
|
@ -186,6 +186,22 @@ public abstract class ConfPaths {
|
||||
|
||||
public static final String CHAT_NOPWNAGE_ACTIONS = CHAT_NOPWNAGE + "actions";
|
||||
|
||||
/*
|
||||
* 888'Y88 ,e, 888 d8
|
||||
* 888 ,'Y " e88 888 888 ee d88
|
||||
* 888C8 888 d888 888 888 88b d88888
|
||||
* 888 " 888 Y888 888 888 888 888
|
||||
* 888 888 "88 888 888 888 888
|
||||
* , 88P
|
||||
* "8",P"
|
||||
*/
|
||||
private static final String FIGHT = CHECKS + "fight.";
|
||||
|
||||
private static final String FIGHT_ANGLE = FIGHT + "angle.";
|
||||
public static final String FIGHT_ANGLE_CHECK = FIGHT_ANGLE + "active";
|
||||
public static final String FIGHT_ANGLE_THRESHOLD = FIGHT_ANGLE + "threshold";
|
||||
public static final String FIGHT_ANGLE_ACTIONS = FIGHT_ANGLE + "actions";
|
||||
|
||||
/*
|
||||
* e e ,e,
|
||||
* d8b d8b e88 88e Y8b Y888P " 888 8e e88 888
|
||||
|
@ -62,7 +62,7 @@ public class DefaultConfig extends ConfigFile {
|
||||
set(ConfPaths.BLOCKBREAK_FASTBREAK_CHECK, true);
|
||||
set(ConfPaths.BLOCKBREAK_FASTBREAK_EXPERIMENTAL, true);
|
||||
set(ConfPaths.BLOCKBREAK_FASTBREAK_INTERVAL, 100);
|
||||
set(ConfPaths.BLOCKBREAK_FASTBREAK_ACTIONS, "cancel vl>100 log:bbfastbreak:3:5:cif cancel");
|
||||
set(ConfPaths.BLOCKBREAK_FASTBREAK_ACTIONS, "cancel vl>100 log:fastbreak:3:5:cif cancel");
|
||||
|
||||
set(ConfPaths.BLOCKBREAK_NOSWING_CHECK, true);
|
||||
set(ConfPaths.BLOCKBREAK_NOSWING_ACTIONS, "log:bbnoswing:3:2:if cancel");
|
||||
@ -83,7 +83,7 @@ public class DefaultConfig extends ConfigFile {
|
||||
set(ConfPaths.BLOCKPLACE_FASTPLACE_CHECK, true);
|
||||
set(ConfPaths.BLOCKPLACE_FASTPLACE_EXPERIMENTAL, true);
|
||||
set(ConfPaths.BLOCKPLACE_FASTPLACE_INTERVAL, 95L);
|
||||
set(ConfPaths.BLOCKPLACE_FASTPLACE_ACTIONS, "cancel vl>100 log:bpfastplace:3:5:cif cancel");
|
||||
set(ConfPaths.BLOCKPLACE_FASTPLACE_ACTIONS, "cancel vl>100 log:fastplace:3:5:cif cancel");
|
||||
|
||||
set(ConfPaths.BLOCKPLACE_REACH_CHECK, true);
|
||||
set(ConfPaths.BLOCKPLACE_REACH_ACTIONS, "cancel vl>5 log:breach:0:2:if cancel");
|
||||
@ -168,6 +168,19 @@ public class DefaultConfig extends ConfigFile {
|
||||
|
||||
set(ConfPaths.CHAT_NOPWNAGE_ACTIONS, "cancel log:nopwnage:2:5:cf cmd:ban cmd:ban-ip");
|
||||
|
||||
/*
|
||||
* 888'Y88 ,e, 888 d8
|
||||
* 888 ,'Y " e88 888 888 ee d88
|
||||
* 888C8 888 d888 888 888 88b d88888
|
||||
* 888 " 888 Y888 888 888 888 888
|
||||
* 888 888 "88 888 888 888 888
|
||||
* , 88P
|
||||
* "8",P"
|
||||
*/
|
||||
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");
|
||||
|
||||
/*
|
||||
* e e ,e,
|
||||
* d8b d8b e88 88e Y8b Y888P " 888 8e e88 888
|
||||
@ -222,14 +235,16 @@ public class DefaultConfig extends ConfigFile {
|
||||
*/
|
||||
final String start = "[player] failed [check]: ";
|
||||
final String end = ". VL [violations].";
|
||||
set(ConfPaths.STRINGS + ".angle", start + "tried to hit multiple entities at the same time" + end);
|
||||
set(ConfPaths.STRINGS + ".ban", "ban [player]");
|
||||
set(ConfPaths.STRINGS + ".ban-ip", "ban-ip [ip]");
|
||||
set(ConfPaths.STRINGS + ".bbfastbreak", start + "tried to break too much blocks" + end);
|
||||
set(ConfPaths.STRINGS + ".bbnoswing", start + "didn't swing arm" + end);
|
||||
set(ConfPaths.STRINGS + ".bdirection", start + "tried to interact with a block out of his line of sight" + end);
|
||||
set(ConfPaths.STRINGS + ".bpspeed", start + "tried to throw projectiles too quickly" + end);
|
||||
set(ConfPaths.STRINGS + ".breach", start
|
||||
+ "tried to interact with a block over distance [reachdistance] block(s)" + end);
|
||||
set(ConfPaths.STRINGS + ".fastbreak", start + "tried to break too much blocks" + end);
|
||||
set(ConfPaths.STRINGS + ".fastplace", start + "tried to place too much blocks" + end);
|
||||
set(ConfPaths.STRINGS + ".flyshort", start + "tried to move unexpectedly" + end);
|
||||
set(ConfPaths.STRINGS + ".flylong", start
|
||||
+ "tried to move from [locationfrom] to [locationto] over a distance of [distance] block(s)" + end);
|
||||
|
@ -103,6 +103,18 @@ public class Permissions {
|
||||
public static final String CHAT_COLOR = CHAT + ".color";
|
||||
public static final String CHAT_NOPWNAGE = CHAT + ".nopwnage";
|
||||
|
||||
/*
|
||||
* 888'Y88 ,e, 888 d8
|
||||
* 888 ,'Y " e88 888 888 ee d88
|
||||
* 888C8 888 d888 888 888 88b d88888
|
||||
* 888 " 888 Y888 888 888 888 888
|
||||
* 888 888 "88 888 888 888 888
|
||||
* , 88P
|
||||
* "8",P"
|
||||
*/
|
||||
private static final String FIGHT = CHECKS + ".fight";
|
||||
public static final String FIGHT_ANGLE = FIGHT + ".angle";
|
||||
|
||||
/*
|
||||
* e e ,e,
|
||||
* d8b d8b e88 88e Y8b Y888P " 888 8e e88 888
|
||||
|
Loading…
Reference in New Issue
Block a user