mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2024-11-07 03:02:11 +01:00
Finally a clean solution for getting stuck on ledges + resetting
player to his last valid location on the ground instead of somewhere in midair + even less verbose logging (only show logs if the violating player made 40 legitimate moves in a row. If he keeps doing violations, just keep counting incidents).
This commit is contained in:
parent
4a09449d2c
commit
3bcb55d2b2
@ -3,7 +3,7 @@ name: NoCheatPlugin
|
||||
author: Evenprime
|
||||
|
||||
main: cc.co.evenprime.bukkit.nocheat.NoCheatPlugin
|
||||
version: 0.6.4
|
||||
version: 0.6.4a
|
||||
|
||||
commands:
|
||||
nocheat:
|
||||
|
@ -40,7 +40,7 @@ public class NoCheatConfiguration {
|
||||
public static String speedhackActionNormal = "";
|
||||
public static String speedhackActionHeavy = "";
|
||||
|
||||
public static int movingFreeMoves = 10;
|
||||
public static int movingFreeMoves = 5;
|
||||
|
||||
// How should moving violations be treated?
|
||||
public static String movingActionMinor = "";
|
||||
@ -109,7 +109,7 @@ public class NoCheatConfiguration {
|
||||
speedhackLimitMed = c.getInt("speedhack.limits.med", 45);
|
||||
speedhackLimitHigh = c.getInt("speedhack.limits.high", 60);
|
||||
|
||||
movingFreeMoves = c.getInt("moving.freemoves", 10);
|
||||
movingFreeMoves = c.getInt("moving.freemoves", 5);
|
||||
|
||||
movingActionMinor = c.getString("moving.action.low", "loglow reset");
|
||||
movingActionNormal = c.getString("moving.action.med", "logmed reset");
|
||||
@ -121,7 +121,7 @@ public class NoCheatConfiguration {
|
||||
|
||||
airbuildAction = c.getString("airbuild.action", "logmed deny");
|
||||
|
||||
if(movingFreeMoves < 10) movingFreeMoves = 10;
|
||||
if(movingFreeMoves < 5) movingFreeMoves = 5;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -15,6 +15,7 @@ public class NoCheatData {
|
||||
*/
|
||||
|
||||
public int movingJumpPhase = 0; // current jumpingPhase
|
||||
public int movingLegitMovesInARow = 0;
|
||||
public int movingMinorViolationsInARow = 0;
|
||||
public int movingNormalViolationsInARow = 0;
|
||||
public int movingHeavyViolationsInARow = 0;
|
||||
|
@ -29,6 +29,9 @@ public class MovingCheck {
|
||||
public static double movingDistanceMed = 2.0D;
|
||||
public static double movingDistanceHigh = 5.0D;
|
||||
|
||||
final static double magic = 0.30000001192092896D;
|
||||
final static double magic2 = 0.69999998807907103D;
|
||||
|
||||
// Block types that may be treated specially
|
||||
private enum BlockType {
|
||||
SOLID, NONSOLID, LADDER, LIQUID, UNKNOWN;
|
||||
@ -164,83 +167,87 @@ public class MovingCheck {
|
||||
|
||||
// pre-calculate boundary values that are needed multiple times in the following checks
|
||||
// the array each contains [lowerX, higherX, Y, lowerZ, higherZ]
|
||||
int fromValues[] = {floor_double(from.getX() - 0.3D), (int)Math.floor(from.getX() + 0.3D), from.getBlockY(), floor_double(from.getZ() - 0.3D),(int)Math.floor(from.getZ() + 0.3D) };
|
||||
int toValues[] = {floor_double(to.getX() - 0.3D), (int)Math.floor(to.getX() + 0.3D), to.getBlockY(), floor_double(to.getZ() - 0.3D), (int)Math.floor(to.getZ() + 0.3D) };
|
||||
int fromValues[] = {lowerBorder(from.getX()), upperBorder(from.getX()), from.getBlockY(), lowerBorder(from.getZ()),upperBorder(from.getZ()) };
|
||||
int toValues[] = {lowerBorder(to.getX()), upperBorder(to.getX()), to.getBlockY(), lowerBorder(to.getZ()), upperBorder(to.getZ()) };
|
||||
|
||||
// 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 onGroundTo = playerIsOnGround(from.getWorld(), toValues, to);
|
||||
|
||||
|
||||
// Both locations seem to be on solid ground or at a ladder
|
||||
if(onGroundFrom && onGroundTo)
|
||||
{
|
||||
// reset jumping
|
||||
data.movingJumpPhase = 0;
|
||||
|
||||
// Check if the player isn't 'walking' up unrealistically far in one step
|
||||
// Finally found out why this can happen:
|
||||
// If a player runs into a wall at an angle from above, 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
|
||||
// the target block
|
||||
if(!(to.getY() - from.getY() < jumpingPhases[data.movingJumpPhase])) {
|
||||
if(!(to.getY() - from.getY() < jumpingPhases[0])) {
|
||||
|
||||
double offset = (to.getY() - from.getY()) - jumpingPhases[data.movingJumpPhase];
|
||||
double offset = (to.getY() - from.getY()) - jumpingPhases[0];
|
||||
|
||||
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
|
||||
{
|
||||
// reset jumping
|
||||
data.movingJumpPhase = 0;
|
||||
data.movingSetBackPoint = event.getTo().clone();
|
||||
}
|
||||
}
|
||||
// player is starting to jump (or starting to fall down somewhere)
|
||||
else if(onGroundFrom && !onGroundTo)
|
||||
{
|
||||
// reset jumping
|
||||
data.movingJumpPhase = 0;
|
||||
|
||||
// Check if player isn't jumping too high
|
||||
if(!(to.getY() - from.getY() < jumpingPhases[data.movingJumpPhase])) {
|
||||
if(!(to.getY() - from.getY() < jumpingPhases[0])) {
|
||||
|
||||
double offset = (to.getY() - from.getY()) - jumpingPhases[data.movingJumpPhase];
|
||||
double offset = (to.getY() - from.getY()) - jumpingPhases[0];
|
||||
|
||||
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 if(to.getY() <= from.getY()) {
|
||||
// Very special case if running over a cliff and then immediately jumping.
|
||||
// Some sort of "air jump", MC allows it, so we have to do so too.
|
||||
else {
|
||||
// Setup next phase of the jump
|
||||
data.movingJumpPhase = 1;
|
||||
data.movingSetBackPoint = event.getFrom().clone();
|
||||
}
|
||||
else data.movingJumpPhase++; // Setup next phase of the jump
|
||||
}
|
||||
// player is probably landing somewhere
|
||||
else if(!onGroundFrom && onGroundTo)
|
||||
{
|
||||
// Check if player isn't landing to high (sounds weird, but has its use)
|
||||
if(!(to.getY() - from.getY() < jumpingPhases[data.movingJumpPhase])) {
|
||||
if(!(to.getY() - from.getY() < Math.max(jumpingPhases[data.movingJumpPhase], 0D))) {
|
||||
|
||||
double offset = (to.getY() - from.getY()) - jumpingPhases[data.movingJumpPhase];
|
||||
double offset = (to.getY() - from.getY()) - Math.max(jumpingPhases[data.movingJumpPhase], 0D);
|
||||
|
||||
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 {
|
||||
data.movingJumpPhase = 0; // He is on ground now, so reset the jump
|
||||
data.movingSetBackPoint = event.getTo().clone();
|
||||
}
|
||||
}
|
||||
// Player is moving through air (during jumping, falling)
|
||||
else {
|
||||
// May also be at the very edge of a platform (I seem to not be able to reliably tell if that's the case)
|
||||
if(!(to.getY() - from.getY() < jumpingPhases[data.movingJumpPhase])) {
|
||||
|
||||
if(!(to.getY() - from.getY() < jumpingPhases[data.movingJumpPhase]))
|
||||
{
|
||||
double offset = (to.getY() - from.getY()) - jumpingPhases[data.movingJumpPhase];
|
||||
|
||||
if(offset > 2D) vl = max(vl, Level.SEVERE);
|
||||
else if(offset > 1D) vl = max(vl, Level.WARNING);
|
||||
else vl = max(vl, Level.INFO);
|
||||
}
|
||||
|
||||
else {
|
||||
data.movingJumpPhase++; // Enter next phase of the flight
|
||||
// Setback point stays the same
|
||||
}
|
||||
}
|
||||
|
||||
// do a security check on the jumping phase, such that we don't get
|
||||
@ -249,20 +256,19 @@ public class MovingCheck {
|
||||
data.movingJumpPhase = jumpingPhases.length - 1;
|
||||
}
|
||||
|
||||
if(vl == null) {
|
||||
if(vl == null && (onGroundFrom || onGroundTo)) {
|
||||
legitimateMove(data, event);
|
||||
}
|
||||
else {
|
||||
else if(vl != null) {
|
||||
|
||||
data.movingLegitMovesInARow = 0;
|
||||
|
||||
String actions = null;
|
||||
boolean log = true;
|
||||
|
||||
// If it is the first violation, store the "from" location for potential later use
|
||||
if(data.movingSetBackPoint == null) {
|
||||
data.movingSetBackPoint = event.getFrom().clone();
|
||||
}
|
||||
|
||||
// Find out with what actions to treat the violation(s)
|
||||
if(Level.INFO.equals(vl)) {
|
||||
|
||||
data.movingMinorViolationsInARow++;
|
||||
|
||||
actions = NoCheatConfiguration.movingActionMinor;
|
||||
@ -323,6 +329,13 @@ public class MovingCheck {
|
||||
|
||||
|
||||
protected static void legitimateMove(NoCheatData data, PlayerMoveEvent event) {
|
||||
|
||||
data.movingLegitMovesInARow++;
|
||||
|
||||
if(data.movingLegitMovesInARow > 40) {
|
||||
|
||||
data.movingLegitMovesInARow = 0;
|
||||
|
||||
// Give some additional logs about now ending violations
|
||||
if(data.movingHeavyViolationsInARow > 0) {
|
||||
NoCheatPlugin.logAction(NoCheatConfiguration.movingActionHeavy, "Moving violation ended: "+event.getPlayer().getName() + " total Events: "+ data.movingHeavyViolationsInARow);
|
||||
@ -338,8 +351,7 @@ public class MovingCheck {
|
||||
}
|
||||
|
||||
data.movingMinorViolationsInARow = 0;
|
||||
|
||||
data.movingSetBackPoint = null;
|
||||
}
|
||||
}
|
||||
|
||||
private static Level max(Level l1, Level l2) {
|
||||
@ -361,13 +373,10 @@ public class MovingCheck {
|
||||
// Still not a perfect solution. After resetting a player his vertical momentum gets lost
|
||||
// Therefore we can't expect him to fall big distances in his next move, therefore we have to
|
||||
// set his flying phase to something he can work with.
|
||||
if(data.movingJumpPhase > 7) {
|
||||
data.movingJumpPhase = 7;
|
||||
}
|
||||
data.movingJumpPhase = 0;
|
||||
|
||||
// If we have stored a location for the player, we put him back there
|
||||
if(data.movingSetBackPoint != null) {
|
||||
|
||||
// Lets try it that way. Maybe now people don't "disappear" any longer
|
||||
event.setFrom(data.movingSetBackPoint);
|
||||
event.setTo(data.movingSetBackPoint);
|
||||
@ -443,4 +452,20 @@ public class MovingCheck {
|
||||
int i = (int)d;
|
||||
return d > (double)i ? i : i - 1;
|
||||
}
|
||||
|
||||
public static int lowerBorder(double d1) {
|
||||
double floor = Math.floor(d1);
|
||||
double d4 = (d1 - floor) - magic;
|
||||
//System.out.println(d4);
|
||||
return (int) (floor + d4);
|
||||
}
|
||||
|
||||
public static int upperBorder(double d1) {
|
||||
double floor = Math.floor(d1);
|
||||
double d4 = (d1 - floor) - magic2;
|
||||
//System.out.println(d4);
|
||||
int tmp = (int) (floor - d4);
|
||||
|
||||
return tmp < floor ? tmp + 2 : (int)floor ;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user