mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2024-11-03 01:00:20 +01:00
New movement check model + fixed logging to console
New move model works with absolute limits instead of relative limits for height checks.
This commit is contained in:
parent
c5c67c4f7f
commit
6fd8c775c5
@ -3,7 +3,7 @@ name: NoCheatPlugin
|
|||||||
author: Evenprime
|
author: Evenprime
|
||||||
|
|
||||||
main: cc.co.evenprime.bukkit.nocheat.NoCheatPlugin
|
main: cc.co.evenprime.bukkit.nocheat.NoCheatPlugin
|
||||||
version: 0.6.9
|
version: 0.6.9a
|
||||||
|
|
||||||
commands:
|
commands:
|
||||||
nocheat:
|
nocheat:
|
||||||
|
@ -4,7 +4,6 @@ import java.io.BufferedWriter;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.logging.ConsoleHandler;
|
|
||||||
import java.util.logging.FileHandler;
|
import java.util.logging.FileHandler;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
@ -20,7 +19,7 @@ import org.bukkit.util.config.Configuration;
|
|||||||
public class NoCheatConfiguration {
|
public class NoCheatConfiguration {
|
||||||
|
|
||||||
// Our personal logger
|
// Our personal logger
|
||||||
public static final String loggerName = "cc.co.evenprime.bukkit.nocheat";
|
public static final String loggerName = "cc.co.evenprime.nocheat";
|
||||||
public static final Logger logger = Logger.getLogger(loggerName);
|
public static final Logger logger = Logger.getLogger(loggerName);
|
||||||
|
|
||||||
// Which checks are active
|
// Which checks are active
|
||||||
@ -39,7 +38,7 @@ public class NoCheatConfiguration {
|
|||||||
public static String speedhackActionNormal = "";
|
public static String speedhackActionNormal = "";
|
||||||
public static String speedhackActionHeavy = "";
|
public static String speedhackActionHeavy = "";
|
||||||
|
|
||||||
public static int movingFreeMoves = 5;
|
public static int movingFreeMoves = 1;
|
||||||
|
|
||||||
// How should moving violations be treated?
|
// How should moving violations be treated?
|
||||||
public static String movingActionMinor = "";
|
public static String movingActionMinor = "";
|
||||||
@ -49,14 +48,14 @@ public class NoCheatConfiguration {
|
|||||||
// How should airbuild violations be treated?
|
// How should airbuild violations be treated?
|
||||||
public static String airbuildAction = "";
|
public static String airbuildAction = "";
|
||||||
|
|
||||||
// The log level above which players with the permission nocheat.notify will get informed about violations
|
// The log level above which information gets logged to the specified logger
|
||||||
public static Level chatLevel = Level.OFF;
|
public static Level chatLevel = Level.OFF;
|
||||||
public static Level ircLevel = Level.OFF;
|
public static Level ircLevel = Level.OFF;
|
||||||
|
public static Level consoleLevel = Level.OFF;
|
||||||
|
|
||||||
public static String ircTag = "";
|
public static String ircTag = "";
|
||||||
|
|
||||||
// Our two log outputs, the console and a file
|
// Our log output to a file
|
||||||
private static ConsoleHandler ch = null;
|
|
||||||
private static FileHandler fh = null;
|
private static FileHandler fh = null;
|
||||||
|
|
||||||
private NoCheatConfiguration() {}
|
private NoCheatConfiguration() {}
|
||||||
@ -75,16 +74,6 @@ public class NoCheatConfiguration {
|
|||||||
|
|
||||||
logger.setLevel(Level.INFO);
|
logger.setLevel(Level.INFO);
|
||||||
logger.setUseParentHandlers(false);
|
logger.setUseParentHandlers(false);
|
||||||
|
|
||||||
|
|
||||||
if(ch == null) {
|
|
||||||
ch = new ConsoleHandler();
|
|
||||||
|
|
||||||
ch.setLevel(stringToLevel(c.getString("logging.logtoconsole")));
|
|
||||||
ch.setFormatter(Logger.getLogger("Minecraft").getHandlers()[0].getFormatter());
|
|
||||||
logger.addHandler(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if(fh == null) {
|
if(fh == null) {
|
||||||
try {
|
try {
|
||||||
@ -101,6 +90,7 @@ public class NoCheatConfiguration {
|
|||||||
|
|
||||||
chatLevel = stringToLevel(c.getString("logging.logtonotify")); // deprecated, will be deleted eventually
|
chatLevel = stringToLevel(c.getString("logging.logtonotify")); // deprecated, will be deleted eventually
|
||||||
chatLevel = stringToLevel(c.getString("logging.logtochat"));
|
chatLevel = stringToLevel(c.getString("logging.logtochat"));
|
||||||
|
consoleLevel = stringToLevel(c.getString("logging.logtoconsole"));
|
||||||
|
|
||||||
ircLevel = stringToLevel(c.getString("logging.logtoirc"));
|
ircLevel = stringToLevel(c.getString("logging.logtoirc"));
|
||||||
ircTag = c.getString("logging.logtoirctag", "nocheat");
|
ircTag = c.getString("logging.logtoirctag", "nocheat");
|
||||||
@ -114,7 +104,7 @@ public class NoCheatConfiguration {
|
|||||||
speedhackLimitMed = c.getInt("speedhack.limits.med", 45);
|
speedhackLimitMed = c.getInt("speedhack.limits.med", 45);
|
||||||
speedhackLimitHigh = c.getInt("speedhack.limits.high", 60);
|
speedhackLimitHigh = c.getInt("speedhack.limits.high", 60);
|
||||||
|
|
||||||
movingFreeMoves = c.getInt("moving.freemoves", 5);
|
movingFreeMoves = c.getInt("moving.freemoves", 1);
|
||||||
|
|
||||||
movingActionMinor = c.getString("moving.action.low", "loglow reset");
|
movingActionMinor = c.getString("moving.action.low", "loglow reset");
|
||||||
movingActionNormal = c.getString("moving.action.med", "logmed reset");
|
movingActionNormal = c.getString("moving.action.med", "logmed reset");
|
||||||
@ -187,7 +177,7 @@ public class NoCheatConfiguration {
|
|||||||
w.write("# Moving specific options") ; w.newLine();
|
w.write("# Moving specific options") ; w.newLine();
|
||||||
w.write("moving:"); w.newLine();
|
w.write("moving:"); w.newLine();
|
||||||
w.write("# After how many minor violations should the plugin react (minimum 1)"); w.newLine();
|
w.write("# After how many minor violations should the plugin react (minimum 1)"); w.newLine();
|
||||||
w.write(" freemoves: 5"); w.newLine();
|
w.write(" freemoves: 1"); w.newLine();
|
||||||
w.write("# Moving Action, one or more of 'loglow logmed loghigh reset'"); w.newLine();
|
w.write("# Moving Action, one or more of 'loglow logmed loghigh reset'"); w.newLine();
|
||||||
w.write(" action:"); w.newLine();
|
w.write(" action:"); w.newLine();
|
||||||
w.write(" low: loglow reset"); w.newLine();
|
w.write(" low: loglow reset"); w.newLine();
|
||||||
|
@ -40,7 +40,8 @@ public class NoCheatPlugin extends JavaPlugin {
|
|||||||
private NoCheatEntityListener entityListener;
|
private NoCheatEntityListener entityListener;
|
||||||
|
|
||||||
// My main logger
|
// My main logger
|
||||||
private static Logger log;
|
private static Logger consoleLogger;
|
||||||
|
private static Logger fileLogger;
|
||||||
|
|
||||||
private static NoCheatPlugin p;
|
private static NoCheatPlugin p;
|
||||||
|
|
||||||
@ -139,7 +140,8 @@ public class NoCheatPlugin extends JavaPlugin {
|
|||||||
blockListener = new NoCheatBlockListener();
|
blockListener = new NoCheatBlockListener();
|
||||||
entityListener = new NoCheatEntityListener();
|
entityListener = new NoCheatEntityListener();
|
||||||
|
|
||||||
log = NoCheatConfiguration.logger;
|
fileLogger = NoCheatConfiguration.logger;
|
||||||
|
consoleLogger = Logger.getLogger("Minecraft");
|
||||||
|
|
||||||
PluginManager pm = getServer().getPluginManager();
|
PluginManager pm = getServer().getPluginManager();
|
||||||
pm.registerEvent(Event.Type.PLAYER_MOVE, playerListener, Priority.Lowest, this); // used for speedhack and moving checks
|
pm.registerEvent(Event.Type.PLAYER_MOVE, playerListener, Priority.Lowest, this); // used for speedhack and moving checks
|
||||||
@ -212,7 +214,8 @@ public class NoCheatPlugin extends JavaPlugin {
|
|||||||
if(l != null) {
|
if(l != null) {
|
||||||
logToChat(l, message);
|
logToChat(l, message);
|
||||||
logToIRC(l, message);
|
logToIRC(l, message);
|
||||||
log.log(l, message);
|
logToConsole(l, message);
|
||||||
|
fileLogger.log(l, message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,6 +235,12 @@ public class NoCheatPlugin extends JavaPlugin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void logToConsole(Level l, String message) {
|
||||||
|
if( NoCheatConfiguration.consoleLevel.intValue() <= l.intValue()) {
|
||||||
|
consoleLogger.log(l, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void logAction(String actions, String message) {
|
public static void logAction(String actions, String message) {
|
||||||
if(actions == null) return;
|
if(actions == null) return;
|
||||||
|
|
||||||
|
@ -22,7 +22,9 @@ public class MovingCheck {
|
|||||||
|
|
||||||
// previously-calculated upper bound values for jumps. Minecraft is very deterministic when it comes to jumps
|
// previously-calculated upper bound values for jumps. Minecraft is very deterministic when it comes to jumps
|
||||||
// Each entry represents the maximum gain in height per move event.
|
// Each entry represents the maximum gain in height per move event.
|
||||||
private static double jumpingPhases[] = new double[]{ 0.501D, 0.34D, 0.26D, 0.17D, 0.09D, 0.02D, 0.00D, -0.07D, -0.15D, -0.22D, -0.29D, -0.36D, -0.43D, -0.49D };
|
static final int jumpingLimit = 3;
|
||||||
|
static final double jumpingHeightLimit = 1.3D;
|
||||||
|
static double stepHeight = 0.501D;
|
||||||
|
|
||||||
// Limits for the moving check
|
// Limits for the moving check
|
||||||
public static double movingDistanceLow = 0.1D;
|
public static double movingDistanceLow = 0.1D;
|
||||||
@ -183,7 +185,7 @@ public class MovingCheck {
|
|||||||
|
|
||||||
// compare locations to the world to guess if the player is standing on the ground, a half-block or next to a ladder
|
// compare locations to the world to guess if the player is standing on the ground, a half-block or next to a ladder
|
||||||
boolean onGroundFrom = playerIsOnGround(from.getWorld(), fromValues, from);
|
boolean onGroundFrom = playerIsOnGround(from.getWorld(), fromValues, from);
|
||||||
boolean onGroundTo = playerIsOnGround(from.getWorld(), toValues, to);
|
boolean onGroundTo = playerIsOnGround(to.getWorld(), toValues, to);
|
||||||
|
|
||||||
|
|
||||||
// Both locations seem to be on solid ground or at a ladder
|
// Both locations seem to be on solid ground or at a ladder
|
||||||
@ -194,9 +196,9 @@ public class MovingCheck {
|
|||||||
// If a player runs into a wall, the game tries to
|
// If a player runs into a wall, the game tries to
|
||||||
// place him above the block he bumped into, by placing him 0.5 m above
|
// place him above the block he bumped into, by placing him 0.5 m above
|
||||||
// the target block
|
// the target block
|
||||||
if(!(to.getY() - from.getY() < jumpingPhases[0])) {
|
if(!(to.getY() - from.getY() < stepHeight)) {
|
||||||
|
|
||||||
double offset = (to.getY() - from.getY()) - jumpingPhases[0];
|
double offset = (to.getY() - from.getY()) - stepHeight;
|
||||||
|
|
||||||
if(offset > 2D) vl = max(vl, Level.SEVERE);
|
if(offset > 2D) vl = max(vl, Level.SEVERE);
|
||||||
else if(offset > 0.5D) vl = max(vl, Level.WARNING);
|
else if(offset > 0.5D) vl = max(vl, Level.WARNING);
|
||||||
@ -206,17 +208,19 @@ public class MovingCheck {
|
|||||||
{
|
{
|
||||||
// reset jumping
|
// reset jumping
|
||||||
data.movingJumpPhase = 0;
|
data.movingJumpPhase = 0;
|
||||||
data.movingSetBackPoint = event.getTo().clone();
|
data.movingSetBackPoint = from.clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// player is starting to jump (or starting to fall down somewhere)
|
// player is starting to jump (or starting to fall down somewhere)
|
||||||
else if(onGroundFrom && !onGroundTo)
|
else if(onGroundFrom && !onGroundTo)
|
||||||
{
|
{
|
||||||
// Check if player isn't jumping too high
|
// Check if player isn't jumping too high
|
||||||
if(!(to.getY() - from.getY() < jumpingPhases[0])) {
|
double limit = jumpingHeightLimit;
|
||||||
|
|
||||||
double offset = (to.getY() - from.getY()) - jumpingPhases[0];
|
if(to.getY() - from.getY() > limit) {
|
||||||
|
|
||||||
|
double offset = (to.getY() - from.getY()) - limit;
|
||||||
|
|
||||||
if(offset > 2D) vl = max(vl, Level.SEVERE);
|
if(offset > 2D) vl = max(vl, Level.SEVERE);
|
||||||
else if(offset > 0.5D) vl = max(vl, Level.WARNING);
|
else if(offset > 0.5D) vl = max(vl, Level.WARNING);
|
||||||
else vl = max(vl, Level.INFO);
|
else vl = max(vl, Level.INFO);
|
||||||
@ -224,16 +228,21 @@ public class MovingCheck {
|
|||||||
else {
|
else {
|
||||||
// Setup next phase of the jump
|
// Setup next phase of the jump
|
||||||
data.movingJumpPhase = 1;
|
data.movingJumpPhase = 1;
|
||||||
data.movingSetBackPoint = event.getFrom().clone();
|
data.movingSetBackPoint = from.clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// player is probably landing somewhere
|
// player is probably landing somewhere
|
||||||
else if(!onGroundFrom && onGroundTo)
|
else if(!onGroundFrom && onGroundTo)
|
||||||
{
|
{
|
||||||
// Check if player isn't landing to high (sounds weird, but has its use)
|
// Check if player isn't landing to high (sounds weird, but has its use)
|
||||||
if(!(to.getY() - from.getY() < Math.max(jumpingPhases[data.movingJumpPhase], 0D))) {
|
Location l = data.movingSetBackPoint;
|
||||||
|
if(l == null) { l = from; }
|
||||||
|
|
||||||
|
double limit = jumpingHeightLimit;
|
||||||
|
|
||||||
|
if(to.getY() - l.getY() > limit) {
|
||||||
|
|
||||||
double offset = (to.getY() - from.getY()) - Math.max(jumpingPhases[data.movingJumpPhase], 0D);
|
double offset = (to.getY() - l.getY()) - limit;
|
||||||
|
|
||||||
if(offset > 2D) vl = max(vl, Level.SEVERE);
|
if(offset > 2D) vl = max(vl, Level.SEVERE);
|
||||||
else if(offset > 0.5D) vl = max(vl, Level.WARNING);
|
else if(offset > 0.5D) vl = max(vl, Level.WARNING);
|
||||||
@ -241,32 +250,35 @@ public class MovingCheck {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
data.movingJumpPhase = 0; // He is on ground now, so reset the jump
|
data.movingJumpPhase = 0; // He is on ground now, so reset the jump
|
||||||
data.movingSetBackPoint = event.getTo().clone();
|
data.movingSetBackPoint = to.clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Player is moving through air (during jumping, falling)
|
// Player is moving through air (during jumping, falling)
|
||||||
else {
|
else {
|
||||||
|
// Check if player isn't landing to high (sounds weird, but has its use)
|
||||||
|
Location l = data.movingSetBackPoint;
|
||||||
|
if(l == null) { l = from; }
|
||||||
|
|
||||||
if(!(to.getY() - from.getY() < jumpingPhases[data.movingJumpPhase]))
|
// The expected fall velocity is a rough estimate - players usually accelerate by that value
|
||||||
|
double limit = (data.movingJumpPhase > jumpingLimit) ? jumpingHeightLimit - (data.movingJumpPhase-jumpingLimit) * 0.2D : jumpingHeightLimit;
|
||||||
|
|
||||||
|
if(to.getY() - l.getY() > limit)
|
||||||
{
|
{
|
||||||
double offset = (to.getY() - from.getY()) - jumpingPhases[data.movingJumpPhase];
|
double offset = (to.getY() - l.getY()) - limit;
|
||||||
|
|
||||||
if(offset > 2D) vl = max(vl, Level.SEVERE);
|
if(offset > 2D) vl = max(vl, Level.SEVERE);
|
||||||
else if(offset > 1D) vl = max(vl, Level.WARNING);
|
else if(offset > 0.5D) vl = max(vl, Level.WARNING);
|
||||||
else vl = max(vl, Level.INFO);
|
else vl = max(vl, Level.INFO);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
data.movingJumpPhase++; // Enter next phase of the flight
|
data.movingJumpPhase++; // Enter next phase of the flight
|
||||||
// Setback point stays the same
|
// Setback point stays the same. IF we don't have one, take the "from" location as a setback point for now
|
||||||
|
if(data.movingSetBackPoint == null) {
|
||||||
|
data.movingSetBackPoint = from.clone();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// do a security check on the jumping phase, such that we don't get
|
|
||||||
// OutOfArrayBoundsExceptions at long air times (falling off high places)
|
|
||||||
if(!(data.movingJumpPhase < jumpingPhases.length)) {
|
|
||||||
data.movingJumpPhase = jumpingPhases.length - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(vl == null && (onGroundFrom || onGroundTo)) {
|
if(vl == null && (onGroundFrom || onGroundTo)) {
|
||||||
legitimateMove(data, event);
|
legitimateMove(data, event);
|
||||||
}
|
}
|
||||||
@ -317,14 +329,14 @@ public class MovingCheck {
|
|||||||
data.movingHeavyViolationsInARow++;
|
data.movingHeavyViolationsInARow++;
|
||||||
actions = NoCheatConfiguration.movingActionHeavy;
|
actions = NoCheatConfiguration.movingActionHeavy;
|
||||||
}
|
}
|
||||||
|
|
||||||
action(event, actions, log);
|
action(event, actions, log);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform actions that were specified by the player
|
* Perform actions that were specified by the admin
|
||||||
* @param event
|
* @param event
|
||||||
* @param actions
|
* @param actions
|
||||||
*/
|
*/
|
||||||
@ -347,7 +359,7 @@ public class MovingCheck {
|
|||||||
protected static void legitimateMove(NoCheatData data, PlayerMoveEvent event) {
|
protected static void legitimateMove(NoCheatData data, PlayerMoveEvent event) {
|
||||||
|
|
||||||
// Give some logging about violations if the player hasn't done any for at least two seconds
|
// Give some logging about violations if the player hasn't done any for at least two seconds
|
||||||
if(data.movingLastViolationTime != 0 && data.movingLastViolationTime + 1000L > System.currentTimeMillis()) {
|
if(data.movingLastViolationTime != 0 && data.movingLastViolationTime + 2000L < System.currentTimeMillis()) {
|
||||||
|
|
||||||
data.movingLastViolationTime = 0;
|
data.movingLastViolationTime = 0;
|
||||||
|
|
||||||
@ -360,7 +372,7 @@ public class MovingCheck {
|
|||||||
NoCheatPlugin.logAction(NoCheatConfiguration.movingActionNormal, "Moving violation ended: "+event.getPlayer().getName()+ " total Events: "+ data.movingNormalViolationsInARow);
|
NoCheatPlugin.logAction(NoCheatConfiguration.movingActionNormal, "Moving violation ended: "+event.getPlayer().getName()+ " total Events: "+ data.movingNormalViolationsInARow);
|
||||||
data.movingNormalViolationsInARow = 0;
|
data.movingNormalViolationsInARow = 0;
|
||||||
}
|
}
|
||||||
if(data.movingMinorViolationsInARow > NoCheatConfiguration.movingFreeMoves +1) {
|
if(data.movingMinorViolationsInARow > NoCheatConfiguration.movingFreeMoves) {
|
||||||
NoCheatPlugin.logAction(NoCheatConfiguration.movingActionMinor, "Moving violation ended: "+event.getPlayer().getName()+ " total Events: "+ data.movingMinorViolationsInARow);
|
NoCheatPlugin.logAction(NoCheatConfiguration.movingActionMinor, "Moving violation ended: "+event.getPlayer().getName()+ " total Events: "+ data.movingMinorViolationsInARow);
|
||||||
data.movingMinorViolationsInARow = 0;
|
data.movingMinorViolationsInARow = 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user