mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2024-10-06 10:27:26 +02:00
Ignore vehicles and movement with positive Y-Velocity in Speedhack
check + reset speedhack event counter in case of teleports + version bump
This commit is contained in:
parent
74e39bc99e
commit
d93438db24
@ -3,7 +3,7 @@ name: NoCheatPlugin
|
||||
author: Evenprime
|
||||
|
||||
main: cc.co.evenprime.bukkit.nocheat.NoCheatPlugin
|
||||
version: 0.7.4a
|
||||
version: 0.7.5
|
||||
|
||||
commands:
|
||||
nocheat:
|
||||
|
@ -76,17 +76,17 @@ public class NoCheatConfiguration {
|
||||
ircLevel = stringToLevel(c.getString("logging.logtoirc"));
|
||||
ircTag = c.getString("logging.logtoirctag", "nocheat");
|
||||
|
||||
plugin.speedhackCheck.limitLow = c.getInt("speedhack.limits.low", plugin.speedhackCheck.limitLow);
|
||||
plugin.speedhackCheck.limitMed = c.getInt("speedhack.limits.med", plugin.speedhackCheck.limitMed);
|
||||
plugin.speedhackCheck.limitHigh = c.getInt("speedhack.limits.high", plugin.speedhackCheck.limitHigh);
|
||||
plugin.speedhackCheck.limits[0] = c.getInt("speedhack.limits.low", plugin.speedhackCheck.limits[0]);
|
||||
plugin.speedhackCheck.limits[1] = c.getInt("speedhack.limits.med", plugin.speedhackCheck.limits[1]);
|
||||
plugin.speedhackCheck.limits[2] = c.getInt("speedhack.limits.high", plugin.speedhackCheck.limits[2]);
|
||||
|
||||
plugin.movingCheck.actions[0] = c.getString("moving.action.low", plugin.movingCheck.actions[0]);
|
||||
plugin.movingCheck.actions[1] = c.getString("moving.action.med", plugin.movingCheck.actions[1]);
|
||||
plugin.movingCheck.actions[2] = c.getString("moving.action.high", plugin.movingCheck.actions[2]);
|
||||
|
||||
plugin.speedhackCheck.actionLow = c.getString("speedhack.action.low", plugin.speedhackCheck.actionLow);
|
||||
plugin.speedhackCheck.actionMed = c.getString("speedhack.action.med", plugin.speedhackCheck.actionMed);
|
||||
plugin.speedhackCheck.actionHigh = c.getString("speedhack.action.high", plugin.speedhackCheck.actionHigh);
|
||||
plugin.speedhackCheck.actions[0] = c.getString("speedhack.action.low", plugin.speedhackCheck.actions[0]);
|
||||
plugin.speedhackCheck.actions[1] = c.getString("speedhack.action.med", plugin.speedhackCheck.actions[1]);
|
||||
plugin.speedhackCheck.actions[2] = c.getString("speedhack.action.high", plugin.speedhackCheck.actions[2]);
|
||||
|
||||
plugin.airbuildCheck.limits[0] = c.getInt("airbuild.limits.low", plugin.airbuildCheck.limits[0]);
|
||||
plugin.airbuildCheck.limits[1] = c.getInt("airbuild.limits.med", plugin.airbuildCheck.limits[1]);
|
||||
@ -146,14 +146,14 @@ public class NoCheatConfiguration {
|
||||
w.write("# Speedhack specific options"); w.newLine();
|
||||
w.write("speedhack:"); w.newLine();
|
||||
w.write(" limits:"); w.newLine();
|
||||
w.write(" low: "+plugin.speedhackCheck.limitLow); w.newLine();
|
||||
w.write(" med: "+plugin.speedhackCheck.limitMed); w.newLine();
|
||||
w.write(" high: "+plugin.speedhackCheck.limitHigh); w.newLine();
|
||||
w.write(" low: "+plugin.speedhackCheck.limits[0]); w.newLine();
|
||||
w.write(" med: "+plugin.speedhackCheck.limits[1]); w.newLine();
|
||||
w.write(" high: "+plugin.speedhackCheck.limits[2]); w.newLine();
|
||||
w.write("# Speedhack Action, one or more of 'loglow logmed loghigh reset'"); w.newLine();
|
||||
w.write(" action:"); w.newLine();
|
||||
w.write(" low: "+plugin.speedhackCheck.actionLow); w.newLine();
|
||||
w.write(" med: "+plugin.speedhackCheck.actionMed); w.newLine();
|
||||
w.write(" high: "+plugin.speedhackCheck.actionHigh); w.newLine();
|
||||
w.write(" low: "+plugin.speedhackCheck.actions[0]); w.newLine();
|
||||
w.write(" med: "+plugin.speedhackCheck.actions[1]); w.newLine();
|
||||
w.write(" high: "+plugin.speedhackCheck.actions[2]); w.newLine();
|
||||
w.write("# Moving specific options") ; w.newLine();
|
||||
w.write("moving:"); w.newLine();
|
||||
w.write("# Moving Action, one or more of 'loglow logmed loghigh reset'"); w.newLine();
|
||||
|
@ -16,12 +16,15 @@ public class NoCheatData {
|
||||
*/
|
||||
|
||||
public int movingJumpPhase = 0; // current jumpingPhase
|
||||
public long movingLastViolationTime = 0;
|
||||
public int movingViolationsInARow[] = { 0, 0, 0 };
|
||||
public World movingLastWorld = null;
|
||||
public int movingHorizFreeMoves = 4;
|
||||
public Location movingSetBackPoint = null;
|
||||
public Location movingLocation = null;
|
||||
public Runnable movingRunnable = null;
|
||||
|
||||
public int legitMoves = 0;
|
||||
|
||||
public boolean reset = false;
|
||||
|
||||
public long speedhackLastCheck = System.currentTimeMillis(); // timestamp of last check for speedhacks
|
||||
|
@ -49,8 +49,8 @@ public class AirbuildCheck extends Check {
|
||||
}
|
||||
};
|
||||
|
||||
// Give a summary in 50 ticks ~ 1 second
|
||||
plugin.getServer().getScheduler().scheduleAsyncDelayedTask(plugin, data.airbuildRunnable, 50);
|
||||
// Give a summary in 20 ticks ~ 1 second
|
||||
plugin.getServer().getScheduler().scheduleAsyncDelayedTask(plugin, data.airbuildRunnable, 20);
|
||||
}
|
||||
|
||||
data.airbuildPerSecond++;
|
||||
|
@ -3,6 +3,7 @@ package cc.co.evenprime.bukkit.nocheat.checks;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.NoCheatData;
|
||||
@ -190,12 +191,6 @@ public class MovingCheck extends Check {
|
||||
return;
|
||||
}
|
||||
|
||||
// The server believes the player should be moving up, so we ignore this event
|
||||
if(event.getPlayer().getVelocity().getY() >= 0) {
|
||||
data.movingSetBackPoint = null;
|
||||
data.speedhackSetBackPoint = null;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// The actual movingCheck starts here
|
||||
@ -215,20 +210,20 @@ public class MovingCheck extends Check {
|
||||
return; // players are allowed to "teleport" into a bed over short distances
|
||||
}
|
||||
|
||||
int vlx = -1;
|
||||
int vl = -1;
|
||||
|
||||
// How far are we off?
|
||||
if(combined > moveLimits[2]) {
|
||||
vlx = max(vlx, 2);
|
||||
vl = max(vl, 2);
|
||||
}
|
||||
else if(combined > moveLimits[1]) {
|
||||
vlx = max(vlx, 1);
|
||||
vl = max(vl, 1);
|
||||
}
|
||||
else if(combined > moveLimits[0]) {
|
||||
if(data.movingHorizFreeMoves > 0) {
|
||||
data.movingHorizFreeMoves--;
|
||||
}
|
||||
else vlx = max(vlx, 0);
|
||||
else vl = max(vl, 0);
|
||||
}
|
||||
else{
|
||||
data.movingHorizFreeMoves = 4;
|
||||
@ -243,6 +238,13 @@ public class MovingCheck extends Check {
|
||||
boolean onGroundFrom = playerIsOnGround(from.getWorld(), fromValues, from);
|
||||
boolean onGroundTo = playerIsOnGround(to.getWorld(), toValues, to);
|
||||
|
||||
// Ignore events if the player has positive y-Velocity
|
||||
if(event.getPlayer().getVelocity().getY() > 0.0D) {
|
||||
data.movingSetBackPoint = from.clone();
|
||||
data.movingJumpPhase = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle 4 distinct cases: Walk, Jump, Land, Fly
|
||||
|
||||
// Walk
|
||||
@ -251,9 +253,9 @@ public class MovingCheck extends Check {
|
||||
double limit = stepHeight;
|
||||
double distance = to.getY() - from.getY();
|
||||
|
||||
vlx = max(vlx, heightLimitCheck(limit, distance));
|
||||
vl = max(vl, heightLimitCheck(limit, distance));
|
||||
|
||||
if(vlx < 0)
|
||||
if(vl < 0)
|
||||
{
|
||||
// reset jumping
|
||||
data.movingJumpPhase = 0;
|
||||
@ -267,9 +269,9 @@ public class MovingCheck extends Check {
|
||||
double distance = to.getY() - from.getY();
|
||||
|
||||
// Check if player isn't jumping too high
|
||||
vlx = max(vlx, heightLimitCheck(limit, distance));
|
||||
vl = max(vl, heightLimitCheck(limit, distance));
|
||||
|
||||
if(vlx < 0) {
|
||||
if(vl < 0) {
|
||||
// Setup next phase of the jump
|
||||
data.movingJumpPhase = 1;
|
||||
data.movingSetBackPoint = from.clone();
|
||||
@ -289,9 +291,9 @@ public class MovingCheck extends Check {
|
||||
double distance = to.getY() - l.getY();
|
||||
|
||||
// Check if player isn't jumping too high
|
||||
vlx = max(vlx, heightLimitCheck(limit, distance));
|
||||
vl = max(vl, heightLimitCheck(limit, distance));
|
||||
|
||||
if(vlx < 0) {
|
||||
if(vl < 0) {
|
||||
data.movingJumpPhase = 0; // He is on ground now, so reset the jump
|
||||
data.movingSetBackPoint = to.clone();
|
||||
}
|
||||
@ -309,9 +311,9 @@ public class MovingCheck extends Check {
|
||||
double distance = to.getY() - l.getY();
|
||||
|
||||
// Check if player isn't jumping too high
|
||||
vlx = max(vlx, heightLimitCheck(limit, distance));
|
||||
vl = max(vl, heightLimitCheck(limit, distance));
|
||||
|
||||
if(vlx < 0) {
|
||||
if(vl < 0) {
|
||||
data.movingJumpPhase++; // Enter next phase of the flight
|
||||
// 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) {
|
||||
@ -320,12 +322,28 @@ public class MovingCheck extends Check {
|
||||
}
|
||||
}
|
||||
|
||||
if(vlx < 0 && (onGroundFrom || onGroundTo)) {
|
||||
legitimateMove(data, event);
|
||||
if(vl < 0 && (onGroundFrom || onGroundTo) && data.legitMoves < 100) {
|
||||
data.legitMoves++;
|
||||
}
|
||||
else if(vlx >= 0) {
|
||||
else if(vl >= 0) {
|
||||
|
||||
data.movingLastViolationTime = System.currentTimeMillis();
|
||||
final Player p = event.getPlayer();
|
||||
final NoCheatData d = data;
|
||||
|
||||
if(data.movingRunnable == null) {
|
||||
data.movingRunnable = new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
summary(p, d);
|
||||
// deleting its own reference
|
||||
d.movingRunnable = null;
|
||||
}
|
||||
};
|
||||
|
||||
// Give a summary in 100 ticks ~ 5 second
|
||||
plugin.getServer().getScheduler().scheduleAsyncDelayedTask(plugin, data.movingRunnable, 100);
|
||||
}
|
||||
|
||||
// If we haven't already got a setback point, make this location the new setback point
|
||||
if(data.movingSetBackPoint == null) {
|
||||
@ -336,28 +354,10 @@ public class MovingCheck extends Check {
|
||||
boolean log = true;
|
||||
|
||||
// Find out with what actions to treat the violation(s)
|
||||
if(vlx == 0) {
|
||||
if(data.movingViolationsInARow[0] > 0) log = false;
|
||||
data.movingViolationsInARow[0]++;
|
||||
action = actions[0];
|
||||
|
||||
// after a set number of minor violations a normal violation gets thrown
|
||||
if(data.movingViolationsInARow[0] % 40 == 0) {
|
||||
vlx = 1;
|
||||
log = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(vlx == 1) {
|
||||
if(data.movingViolationsInARow[1] > 0) log = false;
|
||||
data.movingViolationsInARow[1]++;
|
||||
action = actions[1];
|
||||
}
|
||||
|
||||
if(vlx == 2) {
|
||||
if(data.movingViolationsInARow[2] > 0) log = false;
|
||||
data.movingViolationsInARow[2]++;
|
||||
action = actions[2];
|
||||
if(vl >= 0) {
|
||||
if(data.movingViolationsInARow[vl] > 0) log = false; // only log the first violation of that level
|
||||
data.movingViolationsInARow[vl]++;
|
||||
action = actions[vl];
|
||||
}
|
||||
|
||||
action(event, action, log);
|
||||
@ -372,8 +372,9 @@ public class MovingCheck extends Check {
|
||||
}
|
||||
else {
|
||||
if(!event.isCancelled()) {
|
||||
// If it wasn't our plugin that ordered the teleport, forget all our information and start from scratch at the new location
|
||||
// If it wasn't our plugin that ordered the teleport, forget (almost) all our information and start from scratch at the new location
|
||||
data.speedhackSetBackPoint = event.getTo().clone();
|
||||
data.speedhackEventsSinceLastCheck = 0;
|
||||
data.movingSetBackPoint = event.getTo().clone();
|
||||
data.movingJumpPhase = 0;
|
||||
}
|
||||
@ -399,31 +400,19 @@ public class MovingCheck extends Check {
|
||||
}
|
||||
}
|
||||
|
||||
private void summary(Player p, NoCheatData data) {
|
||||
String action;
|
||||
// Give a summary (to the highest violation level that occured)
|
||||
if(data.movingViolationsInARow[2] > 0) action = actions[2];
|
||||
else if(data.movingViolationsInARow[1] > 0) action = actions[1];
|
||||
else if(data.movingViolationsInARow[0] > 0) action = actions[0];
|
||||
else action = "";
|
||||
|
||||
plugin.logAction(action, "Moving summary of last ~5 seconds: "+p.getName() + " total Violations: ("+ data.movingViolationsInARow[0] + "," + data.movingViolationsInARow[1] + "," + data.movingViolationsInARow[2] + ")");
|
||||
|
||||
protected void legitimateMove(NoCheatData data, PlayerMoveEvent event) {
|
||||
|
||||
// Give some logging about violations if the player hasn't done any for at least two seconds
|
||||
if(data.movingLastViolationTime != 0 && data.movingLastViolationTime + 2000L < System.currentTimeMillis()) {
|
||||
|
||||
data.movingLastViolationTime = 0;
|
||||
|
||||
// Give some additional logs about now ending violations
|
||||
if(data.movingViolationsInARow[2] > 0) {
|
||||
plugin.logAction(actions[2], "Moving violation ended: "+event.getPlayer().getName() + " total Events: "+ data.movingViolationsInARow[2]);
|
||||
data.movingViolationsInARow[2] = 0;
|
||||
}
|
||||
if(data.movingViolationsInARow[1] > 0) {
|
||||
plugin.logAction(actions[1], "Moving violation ended: "+event.getPlayer().getName()+ " total Events: "+ data.movingViolationsInARow[1]);
|
||||
data.movingViolationsInARow[1] = 0;
|
||||
}
|
||||
if(data.movingViolationsInARow[0] > 0) {
|
||||
plugin.logAction(actions[0], "Moving violation ended: "+event.getPlayer().getName()+ " total Events: "+ data.movingViolationsInARow[0]);
|
||||
data.movingViolationsInARow[0] = 0;
|
||||
}
|
||||
|
||||
data.movingViolationsInARow[0] = 0;
|
||||
}
|
||||
data.movingViolationsInARow[2] = 0;
|
||||
data.movingViolationsInARow[1] = 0;
|
||||
data.movingViolationsInARow[0] = 0;
|
||||
}
|
||||
|
||||
private int heightLimitCheck(double limit, double value) {
|
||||
|
@ -23,14 +23,10 @@ public class SpeedhackCheck extends Check {
|
||||
private static final int violationsLimit = 3;
|
||||
|
||||
// Limits for the speedhack check
|
||||
public int limitLow = 30;
|
||||
public int limitMed = 45;
|
||||
public int limitHigh = 60;
|
||||
public int limits[] = { 30, 45, 60 };
|
||||
|
||||
// How should speedhack violations be treated?
|
||||
public String actionLow = "loglow reset";
|
||||
public String actionMed = "logmed reset";
|
||||
public String actionHigh = "loghigh reset";
|
||||
public String actions[] = { "loglow reset", "logmed reset", "loghigh reset" };
|
||||
|
||||
public void check(PlayerMoveEvent event) {
|
||||
|
||||
@ -41,6 +37,16 @@ public class SpeedhackCheck extends Check {
|
||||
// Get the player-specific data
|
||||
NoCheatData data = plugin.getPlayerData(event.getPlayer());
|
||||
|
||||
// Ignore events if the player has positive y-Velocity (these can be the cause of event spam between server and client)
|
||||
if(event.getPlayer().getVelocity().getY() > 0.0D) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ignore events of players in vehicles (these can be the cause of event spam between server and client)
|
||||
if(event.getPlayer().isInsideVehicle()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the time of the server
|
||||
long time = System.currentTimeMillis();
|
||||
|
||||
@ -50,14 +56,14 @@ public class SpeedhackCheck extends Check {
|
||||
// TODO: Needs some better handling for server lag
|
||||
String action = null;
|
||||
|
||||
int low = (int)((limitLow * (time - data.speedhackLastCheck)) / interval);
|
||||
int med = (int)((limitMed * (time - data.speedhackLastCheck)) / interval);
|
||||
int high = (int)((limitHigh * (time - data.speedhackLastCheck)) / interval);
|
||||
int low = (int)((limits[0] * (time - data.speedhackLastCheck)) / interval);
|
||||
int med = (int)((limits[1] * (time - data.speedhackLastCheck)) / interval);
|
||||
int high = (int)((limits[2] * (time - data.speedhackLastCheck)) / interval);
|
||||
|
||||
|
||||
if(data.speedhackEventsSinceLastCheck > high) action = actionLow;
|
||||
else if(data.speedhackEventsSinceLastCheck > med) action = actionMed;
|
||||
else if(data.speedhackEventsSinceLastCheck > low) action = actionHigh;
|
||||
if(data.speedhackEventsSinceLastCheck > high) action = actions[2];
|
||||
else if(data.speedhackEventsSinceLastCheck > med) action = actions[1];
|
||||
else if(data.speedhackEventsSinceLastCheck > low) action = actions[0];
|
||||
|
||||
if(action == null) {
|
||||
data.speedhackSetBackPoint = event.getFrom().clone();
|
||||
@ -89,7 +95,7 @@ public class SpeedhackCheck extends Check {
|
||||
if(actions == null) return;
|
||||
// LOGGING IF NEEDED
|
||||
if(actions.contains("log")) {
|
||||
plugin.logAction(actions, event.getPlayer().getName()+" sent "+ data.speedhackEventsSinceLastCheck + " move events, but only "+limitLow+ " were allowed. Speedhack?");
|
||||
plugin.logAction(actions, event.getPlayer().getName()+" sent "+ data.speedhackEventsSinceLastCheck + " move events, but only "+limits[0]+ " were allowed. Speedhack?");
|
||||
}
|
||||
// RESET IF NEEDED
|
||||
if(actions.contains("reset")) {
|
||||
|
Loading…
Reference in New Issue
Block a user