mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2024-09-19 10:21:27 +02: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
|
author: Evenprime
|
||||||
|
|
||||||
main: cc.co.evenprime.bukkit.nocheat.NoCheatPlugin
|
main: cc.co.evenprime.bukkit.nocheat.NoCheatPlugin
|
||||||
version: 0.6.4
|
version: 0.6.4a
|
||||||
|
|
||||||
commands:
|
commands:
|
||||||
nocheat:
|
nocheat:
|
||||||
|
@ -40,7 +40,7 @@ public class NoCheatConfiguration {
|
|||||||
public static String speedhackActionNormal = "";
|
public static String speedhackActionNormal = "";
|
||||||
public static String speedhackActionHeavy = "";
|
public static String speedhackActionHeavy = "";
|
||||||
|
|
||||||
public static int movingFreeMoves = 10;
|
public static int movingFreeMoves = 5;
|
||||||
|
|
||||||
// How should moving violations be treated?
|
// How should moving violations be treated?
|
||||||
public static String movingActionMinor = "";
|
public static String movingActionMinor = "";
|
||||||
@ -109,7 +109,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", 10);
|
movingFreeMoves = c.getInt("moving.freemoves", 5);
|
||||||
|
|
||||||
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");
|
||||||
@ -121,7 +121,7 @@ public class NoCheatConfiguration {
|
|||||||
|
|
||||||
airbuildAction = c.getString("airbuild.action", "logmed deny");
|
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 movingJumpPhase = 0; // current jumpingPhase
|
||||||
|
public int movingLegitMovesInARow = 0;
|
||||||
public int movingMinorViolationsInARow = 0;
|
public int movingMinorViolationsInARow = 0;
|
||||||
public int movingNormalViolationsInARow = 0;
|
public int movingNormalViolationsInARow = 0;
|
||||||
public int movingHeavyViolationsInARow = 0;
|
public int movingHeavyViolationsInARow = 0;
|
||||||
|
@ -29,6 +29,9 @@ public class MovingCheck {
|
|||||||
public static double movingDistanceMed = 2.0D;
|
public static double movingDistanceMed = 2.0D;
|
||||||
public static double movingDistanceHigh = 5.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
|
// Block types that may be treated specially
|
||||||
private enum BlockType {
|
private enum BlockType {
|
||||||
SOLID, NONSOLID, LADDER, LIQUID, UNKNOWN;
|
SOLID, NONSOLID, LADDER, LIQUID, UNKNOWN;
|
||||||
@ -164,60 +167,77 @@ public class MovingCheck {
|
|||||||
|
|
||||||
// pre-calculate boundary values that are needed multiple times in the following checks
|
// pre-calculate boundary values that are needed multiple times in the following checks
|
||||||
// the array each contains [lowerX, higherX, Y, lowerZ, higherZ]
|
// 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 fromValues[] = {lowerBorder(from.getX()), upperBorder(from.getX()), from.getBlockY(), lowerBorder(from.getZ()),upperBorder(from.getZ()) };
|
||||||
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 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
|
// 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(from.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
|
||||||
if(onGroundFrom && onGroundTo)
|
if(onGroundFrom && onGroundTo)
|
||||||
{
|
{
|
||||||
// reset jumping
|
|
||||||
data.movingJumpPhase = 0;
|
|
||||||
|
|
||||||
// Check if the player isn't 'walking' up unrealistically far in one step
|
// Check if the player isn't 'walking' up unrealistically far in one step
|
||||||
// Finally found out why this can happen:
|
// 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
|
// 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[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);
|
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
|
||||||
|
{
|
||||||
|
// reset jumping
|
||||||
|
data.movingJumpPhase = 0;
|
||||||
|
data.movingSetBackPoint = event.getTo().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)
|
||||||
{
|
{
|
||||||
// reset jumping
|
|
||||||
data.movingJumpPhase = 0;
|
|
||||||
|
|
||||||
// Check if player isn't jumping too high
|
// 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);
|
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 if(to.getY() <= from.getY()) {
|
else {
|
||||||
// Very special case if running over a cliff and then immediately jumping.
|
// Setup next phase of the jump
|
||||||
// Some sort of "air jump", MC allows it, so we have to do so too.
|
data.movingJumpPhase = 1;
|
||||||
|
data.movingSetBackPoint = event.getFrom().clone();
|
||||||
}
|
}
|
||||||
else data.movingJumpPhase++; // Setup next phase of the jump
|
|
||||||
}
|
}
|
||||||
// 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() < jumpingPhases[data.movingJumpPhase])) {
|
if(!(to.getY() - from.getY() < Math.max(jumpingPhases[data.movingJumpPhase], 0D))) {
|
||||||
|
|
||||||
|
double offset = (to.getY() - from.getY()) - Math.max(jumpingPhases[data.movingJumpPhase], 0D);
|
||||||
|
|
||||||
|
if(offset > 2D) vl = max(vl, Level.SEVERE);
|
||||||
|
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 {
|
||||||
|
|
||||||
|
if(!(to.getY() - from.getY() < jumpingPhases[data.movingJumpPhase]))
|
||||||
|
{
|
||||||
double offset = (to.getY() - from.getY()) - jumpingPhases[data.movingJumpPhase];
|
double offset = (to.getY() - from.getY()) - jumpingPhases[data.movingJumpPhase];
|
||||||
|
|
||||||
if(offset > 2D) vl = max(vl, Level.SEVERE);
|
if(offset > 2D) vl = max(vl, Level.SEVERE);
|
||||||
@ -225,23 +245,10 @@ public class MovingCheck {
|
|||||||
else vl = max(vl, Level.INFO);
|
else vl = max(vl, Level.INFO);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
data.movingJumpPhase = 0; // He is on ground now, so reset the jump
|
data.movingJumpPhase++; // Enter next phase of the flight
|
||||||
|
// Setback point stays the same
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 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])) {
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
data.movingJumpPhase++; // Enter next phase of the flight
|
|
||||||
}
|
|
||||||
|
|
||||||
// do a security check on the jumping phase, such that we don't get
|
// do a security check on the jumping phase, such that we don't get
|
||||||
// OutOfArrayBoundsExceptions at long air times (falling off high places)
|
// OutOfArrayBoundsExceptions at long air times (falling off high places)
|
||||||
@ -249,20 +256,19 @@ public class MovingCheck {
|
|||||||
data.movingJumpPhase = jumpingPhases.length - 1;
|
data.movingJumpPhase = jumpingPhases.length - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(vl == null) {
|
if(vl == null && (onGroundFrom || onGroundTo)) {
|
||||||
legitimateMove(data, event);
|
legitimateMove(data, event);
|
||||||
}
|
}
|
||||||
else {
|
else if(vl != null) {
|
||||||
|
|
||||||
|
data.movingLegitMovesInARow = 0;
|
||||||
|
|
||||||
String actions = null;
|
String actions = null;
|
||||||
boolean log = true;
|
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)
|
// Find out with what actions to treat the violation(s)
|
||||||
if(Level.INFO.equals(vl)) {
|
if(Level.INFO.equals(vl)) {
|
||||||
|
|
||||||
data.movingMinorViolationsInARow++;
|
data.movingMinorViolationsInARow++;
|
||||||
|
|
||||||
actions = NoCheatConfiguration.movingActionMinor;
|
actions = NoCheatConfiguration.movingActionMinor;
|
||||||
@ -323,23 +329,29 @@ public class MovingCheck {
|
|||||||
|
|
||||||
|
|
||||||
protected static void legitimateMove(NoCheatData data, PlayerMoveEvent event) {
|
protected static void legitimateMove(NoCheatData data, PlayerMoveEvent event) {
|
||||||
// Give some additional logs about now ending violations
|
|
||||||
if(data.movingHeavyViolationsInARow > 0) {
|
data.movingLegitMovesInARow++;
|
||||||
NoCheatPlugin.logAction(NoCheatConfiguration.movingActionHeavy, "Moving violation ended: "+event.getPlayer().getName() + " total Events: "+ data.movingHeavyViolationsInARow);
|
|
||||||
data.movingHeavyViolationsInARow = 0;
|
if(data.movingLegitMovesInARow > 40) {
|
||||||
}
|
|
||||||
if(data.movingNormalViolationsInARow > 0) {
|
data.movingLegitMovesInARow = 0;
|
||||||
NoCheatPlugin.logAction(NoCheatConfiguration.movingActionNormal, "Moving violation ended: "+event.getPlayer().getName()+ " total Events: "+ data.movingNormalViolationsInARow);
|
|
||||||
data.movingNormalViolationsInARow = 0;
|
// Give some additional logs about now ending violations
|
||||||
}
|
if(data.movingHeavyViolationsInARow > 0) {
|
||||||
if(data.movingMinorViolationsInARow > NoCheatConfiguration.movingFreeMoves) {
|
NoCheatPlugin.logAction(NoCheatConfiguration.movingActionHeavy, "Moving violation ended: "+event.getPlayer().getName() + " total Events: "+ data.movingHeavyViolationsInARow);
|
||||||
NoCheatPlugin.logAction(NoCheatConfiguration.movingActionMinor, "Moving violation ended: "+event.getPlayer().getName()+ " total Events: "+ data.movingMinorViolationsInARow);
|
data.movingHeavyViolationsInARow = 0;
|
||||||
|
}
|
||||||
|
if(data.movingNormalViolationsInARow > 0) {
|
||||||
|
NoCheatPlugin.logAction(NoCheatConfiguration.movingActionNormal, "Moving violation ended: "+event.getPlayer().getName()+ " total Events: "+ data.movingNormalViolationsInARow);
|
||||||
|
data.movingNormalViolationsInARow = 0;
|
||||||
|
}
|
||||||
|
if(data.movingMinorViolationsInARow > NoCheatConfiguration.movingFreeMoves) {
|
||||||
|
NoCheatPlugin.logAction(NoCheatConfiguration.movingActionMinor, "Moving violation ended: "+event.getPlayer().getName()+ " total Events: "+ data.movingMinorViolationsInARow);
|
||||||
|
data.movingMinorViolationsInARow = 0;
|
||||||
|
}
|
||||||
|
|
||||||
data.movingMinorViolationsInARow = 0;
|
data.movingMinorViolationsInARow = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
data.movingMinorViolationsInARow = 0;
|
|
||||||
|
|
||||||
data.movingSetBackPoint = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Level max(Level l1, Level l2) {
|
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
|
// 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
|
// 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.
|
// set his flying phase to something he can work with.
|
||||||
if(data.movingJumpPhase > 7) {
|
data.movingJumpPhase = 0;
|
||||||
data.movingJumpPhase = 7;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we have stored a location for the player, we put him back there
|
// If we have stored a location for the player, we put him back there
|
||||||
if(data.movingSetBackPoint != null) {
|
if(data.movingSetBackPoint != null) {
|
||||||
|
|
||||||
// Lets try it that way. Maybe now people don't "disappear" any longer
|
// Lets try it that way. Maybe now people don't "disappear" any longer
|
||||||
event.setFrom(data.movingSetBackPoint);
|
event.setFrom(data.movingSetBackPoint);
|
||||||
event.setTo(data.movingSetBackPoint);
|
event.setTo(data.movingSetBackPoint);
|
||||||
@ -443,4 +452,20 @@ public class MovingCheck {
|
|||||||
int i = (int)d;
|
int i = (int)d;
|
||||||
return d > (double)i ? i : i - 1;
|
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