mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2025-01-04 23:07:44 +01:00
And even more comments
This commit is contained in:
parent
2aedcd7515
commit
f830defb5f
@ -86,7 +86,7 @@ public class NoCheat extends JavaPlugin implements Listener {
|
|||||||
eventManagers = new ArrayList<EventManager>(8); // Big enough
|
eventManagers = new ArrayList<EventManager>(8); // Big enough
|
||||||
// Then set up the event listeners
|
// Then set up the event listeners
|
||||||
eventManagers.add(new MovingCheckListener(this));
|
eventManagers.add(new MovingCheckListener(this));
|
||||||
eventManagers.add(new WorkaroundsListener(this));
|
eventManagers.add(new WorkaroundsListener());
|
||||||
eventManagers.add(new ChatCheckListener(this));
|
eventManagers.add(new ChatCheckListener(this));
|
||||||
eventManagers.add(new BlockBreakCheckListener(this));
|
eventManagers.add(new BlockBreakCheckListener(this));
|
||||||
eventManagers.add(new BlockPlaceCheckListener(this));
|
eventManagers.add(new BlockPlaceCheckListener(this));
|
||||||
|
@ -17,6 +17,10 @@ import cc.co.evenprime.bukkit.nocheat.actions.types.SpecialAction;
|
|||||||
import cc.co.evenprime.bukkit.nocheat.config.ConfigurationCacheStore;
|
import cc.co.evenprime.bukkit.nocheat.config.ConfigurationCacheStore;
|
||||||
import cc.co.evenprime.bukkit.nocheat.data.Statistics.Id;
|
import cc.co.evenprime.bukkit.nocheat.data.Statistics.Id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The abstract Check class, providing some basic functionality
|
||||||
|
*
|
||||||
|
*/
|
||||||
public abstract class Check {
|
public abstract class Check {
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
@ -41,13 +45,18 @@ public abstract class Check {
|
|||||||
|
|
||||||
boolean special = false;
|
boolean special = false;
|
||||||
|
|
||||||
|
// Get the to be executed actions
|
||||||
Action[] actions = actionList.getActions(violationLevel);
|
Action[] actions = actionList.getActions(violationLevel);
|
||||||
|
|
||||||
final long time = System.currentTimeMillis() / 1000L;
|
final long time = System.currentTimeMillis() / 1000L;
|
||||||
|
|
||||||
|
// The configuration will be needed too
|
||||||
final ConfigurationCacheStore cc = player.getConfigurationStore();
|
final ConfigurationCacheStore cc = player.getConfigurationStore();
|
||||||
|
|
||||||
for(Action ac : actions) {
|
for(Action ac : actions) {
|
||||||
if(player.getExecutionHistory().executeAction(groupId, ac, time)) {
|
if(player.getExecutionHistory().executeAction(groupId, ac, time)) {
|
||||||
|
// The executionHistory said it really is time to execute the
|
||||||
|
// action, find out what it is and do what is needed
|
||||||
if(ac instanceof LogAction && !player.hasPermission(actionList.permissionSilent)) {
|
if(ac instanceof LogAction && !player.hasPermission(actionList.permissionSilent)) {
|
||||||
executeLogAction((LogAction) ac, this, player, cc);
|
executeLogAction((LogAction) ac, this, player, cc);
|
||||||
} else if(ac instanceof SpecialAction) {
|
} else if(ac instanceof SpecialAction) {
|
||||||
@ -79,6 +88,7 @@ public abstract class Check {
|
|||||||
if(!cc.logging.active)
|
if(!cc.logging.active)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Fire one of our custom "Log" Events
|
||||||
Bukkit.getServer().getPluginManager().callEvent(new NoCheatLogEvent(cc.logging.prefix, l.getLogMessage(player, check), cc.logging.toConsole && l.toConsole(), cc.logging.toChat && l.toChat(), cc.logging.toFile && l.toFile()));
|
Bukkit.getServer().getPluginManager().callEvent(new NoCheatLogEvent(cc.logging.prefix, l.getLogMessage(player, check), cc.logging.toConsole && l.toConsole(), cc.logging.toChat && l.toChat(), cc.logging.toFile && l.toFile()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,8 @@ import cc.co.evenprime.bukkit.nocheat.NoCheatPlayer;
|
|||||||
import cc.co.evenprime.bukkit.nocheat.data.PreciseLocation;
|
import cc.co.evenprime.bukkit.nocheat.data.PreciseLocation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Some stuff that's used by different checks
|
* Some stuff that's used by different checks or just too complex to keep
|
||||||
|
* in other places
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class CheckUtil {
|
public class CheckUtil {
|
||||||
@ -85,10 +86,11 @@ public class CheckUtil {
|
|||||||
|
|
||||||
// All fences are solid - fences are treated specially due
|
// All fences are solid - fences are treated specially due
|
||||||
// to being 1.5 blocks high
|
// to being 1.5 blocks high
|
||||||
private static final int FENCE = 16 | SOLID | NONSOLID; // 0x00010010
|
private static final int FENCE = 16 | SOLID | NONSOLID; // 0x00010011
|
||||||
|
|
||||||
private static final int INGROUND = 128;
|
private static final int INGROUND = 128;
|
||||||
private static final int ONGROUND = 256;
|
private static final int ONGROUND = 256;
|
||||||
|
|
||||||
// Until I can think of a better way to determine if a block is solid or
|
// Until I can think of a better way to determine if a block is solid or
|
||||||
// not, this is what I'll do
|
// not, this is what I'll do
|
||||||
private static final int types[];
|
private static final int types[];
|
||||||
@ -168,6 +170,8 @@ public class CheckUtil {
|
|||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// We need to know what is considered food for the instanteat check
|
||||||
foods.add(Material.APPLE);
|
foods.add(Material.APPLE);
|
||||||
foods.add(Material.BREAD);
|
foods.add(Material.BREAD);
|
||||||
foods.add(Material.COOKED_BEEF);
|
foods.add(Material.COOKED_BEEF);
|
||||||
@ -202,7 +206,7 @@ public class CheckUtil {
|
|||||||
|
|
||||||
final int lowerX = lowerBorder(location.x);
|
final int lowerX = lowerBorder(location.x);
|
||||||
final int upperX = upperBorder(location.x);
|
final int upperX = upperBorder(location.x);
|
||||||
final int Y = (int) Math.floor(location.y);
|
final int Y = (int) location.y;
|
||||||
final int lowerZ = lowerBorder(location.z);
|
final int lowerZ = lowerBorder(location.z);
|
||||||
final int upperZ = upperBorder(location.z);
|
final int upperZ = upperBorder(location.z);
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@ import org.bukkit.event.Listener;
|
|||||||
import org.bukkit.event.player.PlayerMoveEvent;
|
import org.bukkit.event.player.PlayerMoveEvent;
|
||||||
import org.bukkit.event.player.PlayerToggleSprintEvent;
|
import org.bukkit.event.player.PlayerToggleSprintEvent;
|
||||||
import cc.co.evenprime.bukkit.nocheat.EventManager;
|
import cc.co.evenprime.bukkit.nocheat.EventManager;
|
||||||
import cc.co.evenprime.bukkit.nocheat.NoCheat;
|
|
||||||
import cc.co.evenprime.bukkit.nocheat.config.ConfigurationCacheStore;
|
import cc.co.evenprime.bukkit.nocheat.config.ConfigurationCacheStore;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -18,12 +17,7 @@ import cc.co.evenprime.bukkit.nocheat.config.ConfigurationCacheStore;
|
|||||||
*/
|
*/
|
||||||
public class WorkaroundsListener implements Listener, EventManager {
|
public class WorkaroundsListener implements Listener, EventManager {
|
||||||
|
|
||||||
//private final NoCheat plugin;
|
public WorkaroundsListener() {}
|
||||||
|
|
||||||
public WorkaroundsListener(NoCheat plugin) {
|
|
||||||
|
|
||||||
//this.plugin = plugin;
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST)
|
@EventHandler(priority = EventPriority.HIGHEST)
|
||||||
public void playerMove(final PlayerMoveEvent event) {
|
public void playerMove(final PlayerMoveEvent event) {
|
||||||
@ -39,12 +33,14 @@ public class WorkaroundsListener implements Listener, EventManager {
|
|||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST)
|
@EventHandler(priority = EventPriority.HIGHEST)
|
||||||
public void toggleSprint(final PlayerToggleSprintEvent event) {
|
public void toggleSprint(final PlayerToggleSprintEvent event) {
|
||||||
|
// Some plugins cancel "sprinting", which makes no sense at all because
|
||||||
|
// it doesn't stop people from sprinting and rewards them by reducing
|
||||||
|
// their hunger bar as if they were walking instead of sprinting
|
||||||
if(event.isCancelled() && event.isSprinting()) {
|
if(event.isCancelled() && event.isSprinting()) {
|
||||||
event.setCancelled(false);
|
event.setCancelled(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> getActiveChecks(ConfigurationCacheStore cc) {
|
public List<String> getActiveChecks(ConfigurationCacheStore cc) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
@ -19,23 +19,29 @@ public class FlyingCheck extends MovingCheck {
|
|||||||
super(plugin, "moving.flying");
|
super(plugin, "moving.flying");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Determined by trial and error, the flying movement speed of the creative
|
||||||
|
// mode
|
||||||
private static final double creativeSpeed = 0.60D;
|
private static final double creativeSpeed = 0.60D;
|
||||||
|
|
||||||
public PreciseLocation check(NoCheatPlayer player, MovingData data, MovingConfig ccmoving) {
|
public PreciseLocation check(NoCheatPlayer player, MovingData data, MovingConfig ccmoving) {
|
||||||
|
|
||||||
|
// The setBack is the location that players may get teleported to when
|
||||||
|
// they fail the check
|
||||||
final PreciseLocation setBack = data.runflySetBackPoint;
|
final PreciseLocation setBack = data.runflySetBackPoint;
|
||||||
|
|
||||||
final PreciseLocation from = data.from;
|
final PreciseLocation from = data.from;
|
||||||
final PreciseLocation to = data.to;
|
final PreciseLocation to = data.to;
|
||||||
|
|
||||||
|
// If we have no setback, define one now
|
||||||
if(!setBack.isSet()) {
|
if(!setBack.isSet()) {
|
||||||
setBack.set(from);
|
setBack.set(from);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Used to store the location where the player gets teleported to
|
||||||
PreciseLocation newToLocation = null;
|
PreciseLocation newToLocation = null;
|
||||||
|
|
||||||
// Before doing anything, do a basic height check
|
// Before doing anything, do a basic height check to determine if
|
||||||
// This is silent for now, will log messages later
|
// players are flying too high
|
||||||
// probably
|
|
||||||
if(to.y - data.vertFreedom > ccmoving.flyingHeightLimit) {
|
if(to.y - data.vertFreedom > ccmoving.flyingHeightLimit) {
|
||||||
newToLocation = new PreciseLocation();
|
newToLocation = new PreciseLocation();
|
||||||
newToLocation.set(setBack);
|
newToLocation.set(setBack);
|
||||||
@ -43,33 +49,36 @@ public class FlyingCheck extends MovingCheck {
|
|||||||
return newToLocation;
|
return newToLocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
final double yDistance = to.y - from.y;
|
|
||||||
|
|
||||||
// Calculate some distances
|
// Calculate some distances
|
||||||
|
final double yDistance = to.y - from.y;
|
||||||
final double xDistance = to.x - from.x;
|
final double xDistance = to.x - from.x;
|
||||||
final double zDistance = to.z - from.z;
|
final double zDistance = to.z - from.z;
|
||||||
|
|
||||||
|
// How far did the player move horizontally
|
||||||
final double horizontalDistance = Math.sqrt((xDistance * xDistance + zDistance * zDistance));
|
final double horizontalDistance = Math.sqrt((xDistance * xDistance + zDistance * zDistance));
|
||||||
|
|
||||||
double resultHoriz = 0;
|
double resultHoriz = 0;
|
||||||
double resultVert = 0;
|
double resultVert = 0;
|
||||||
double result = 0;
|
double result = 0;
|
||||||
|
|
||||||
// In case of creative gamemode, give at least 0.60 speed limit
|
// In case of creative game mode give at least 0.60 speed limit horizontal
|
||||||
// horizontal
|
|
||||||
double speedLimitHorizontal = player.isCreative() ? Math.max(creativeSpeed, ccmoving.flyingSpeedLimitHorizontal) : ccmoving.flyingSpeedLimitHorizontal;
|
double speedLimitHorizontal = player.isCreative() ? Math.max(creativeSpeed, ccmoving.flyingSpeedLimitHorizontal) : ccmoving.flyingSpeedLimitHorizontal;
|
||||||
|
|
||||||
|
// If the player is affected by potion of swiftness
|
||||||
speedLimitHorizontal *= player.getSpeedAmplifier();
|
speedLimitHorizontal *= player.getSpeedAmplifier();
|
||||||
|
|
||||||
|
// Finally, determine how far the player went beyond the set limits
|
||||||
resultHoriz = Math.max(0.0D, horizontalDistance - data.horizFreedom - speedLimitHorizontal);
|
resultHoriz = Math.max(0.0D, horizontalDistance - data.horizFreedom - speedLimitHorizontal);
|
||||||
|
|
||||||
boolean sprinting = player.isSprinting();
|
boolean sprinting = player.isSprinting();
|
||||||
|
|
||||||
data.bunnyhopdelay--;
|
data.bunnyhopdelay--;
|
||||||
|
|
||||||
// Did he go too far?
|
|
||||||
if(resultHoriz > 0 && sprinting) {
|
if(resultHoriz > 0 && sprinting) {
|
||||||
|
|
||||||
// Try to treat it as a the "bunnyhop" problem
|
// Try to treat it as a the "bunnyhop" problem
|
||||||
|
// The bunnyhop problem is that landing and immediatly jumping
|
||||||
|
// again leads to a player moving almost twice as far in that step
|
||||||
if(data.bunnyhopdelay <= 0 && resultHoriz < 0.4D) {
|
if(data.bunnyhopdelay <= 0 && resultHoriz < 0.4D) {
|
||||||
data.bunnyhopdelay = 9;
|
data.bunnyhopdelay = 9;
|
||||||
resultHoriz = 0;
|
resultHoriz = 0;
|
||||||
@ -78,6 +87,9 @@ public class FlyingCheck extends MovingCheck {
|
|||||||
|
|
||||||
resultHoriz *= 100;
|
resultHoriz *= 100;
|
||||||
|
|
||||||
|
// Is the player affected by the "jumping" potion
|
||||||
|
// This is really just a very, very crude estimation and far from
|
||||||
|
// reality
|
||||||
double jumpAmplifier = player.getJumpAmplifier();
|
double jumpAmplifier = player.getJumpAmplifier();
|
||||||
if(jumpAmplifier > data.lastJumpAmplifier) {
|
if(jumpAmplifier > data.lastJumpAmplifier) {
|
||||||
data.lastJumpAmplifier = jumpAmplifier;
|
data.lastJumpAmplifier = jumpAmplifier;
|
||||||
@ -89,14 +101,15 @@ public class FlyingCheck extends MovingCheck {
|
|||||||
data.lastJumpAmplifier--;
|
data.lastJumpAmplifier--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// super simple, just check distance compared to max distance
|
// super simple, just check distance compared to max distance vertical
|
||||||
resultVert = Math.max(0.0D, yDistance - data.vertFreedom - speedLimitVertical) * 100;
|
resultVert = Math.max(0.0D, yDistance - data.vertFreedom - speedLimitVertical) * 100;
|
||||||
|
|
||||||
result = resultHoriz + resultVert;
|
result = resultHoriz + resultVert;
|
||||||
|
|
||||||
|
// The player went to far, either horizontal or vertical
|
||||||
if(result > 0) {
|
if(result > 0) {
|
||||||
|
|
||||||
// Increment violation counter
|
// Increment violation counter and statistics
|
||||||
data.runflyVL += result;
|
data.runflyVL += result;
|
||||||
if(resultHoriz > 0) {
|
if(resultHoriz > 0) {
|
||||||
incrementStatistics(player, Id.MOV_RUNNING, resultHoriz);
|
incrementStatistics(player, Id.MOV_RUNNING, resultHoriz);
|
||||||
@ -106,6 +119,8 @@ public class FlyingCheck extends MovingCheck {
|
|||||||
incrementStatistics(player, Id.MOV_FLYING, resultVert);
|
incrementStatistics(player, Id.MOV_FLYING, resultVert);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Execute whatever actions are associated with this check and the
|
||||||
|
// violation level and find out if we should cancel the event
|
||||||
boolean cancel = executeActions(player, ccmoving.flyingActions, data.runflyVL);
|
boolean cancel = executeActions(player, ccmoving.flyingActions, data.runflyVL);
|
||||||
|
|
||||||
// Was one of the actions a cancel? Then really do it
|
// Was one of the actions a cancel? Then really do it
|
||||||
@ -114,10 +129,10 @@ public class FlyingCheck extends MovingCheck {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Slowly reduce the level with each event
|
// Slowly reduce the violation level with each event
|
||||||
data.runflyVL *= 0.97;
|
data.runflyVL *= 0.97;
|
||||||
|
|
||||||
// Some other cleanup 'n' stuff
|
// If the player did not get cancelled, define a new setback point
|
||||||
if(newToLocation == null) {
|
if(newToLocation == null) {
|
||||||
setBack.set(to);
|
setBack.set(to);
|
||||||
}
|
}
|
||||||
@ -125,10 +140,11 @@ public class FlyingCheck extends MovingCheck {
|
|||||||
return newToLocation;
|
return newToLocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getParameter(ParameterName wildcard, NoCheatPlayer player) {
|
public String getParameter(ParameterName wildcard, NoCheatPlayer player) {
|
||||||
|
|
||||||
if(wildcard == ParameterName.VIOLATIONS)
|
if(wildcard == ParameterName.VIOLATIONS)
|
||||||
return String.format(Locale.US, "%d", (int) getData(player.getDataStore()).runflyVL);
|
return String.format(Locale.US, "%d", (int) getData(player).runflyVL);
|
||||||
else
|
else
|
||||||
return super.getParameter(wildcard, player);
|
return super.getParameter(wildcard, player);
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ import cc.co.evenprime.bukkit.nocheat.data.Statistics.Id;
|
|||||||
*/
|
*/
|
||||||
public class MorePacketsCheck extends MovingCheck {
|
public class MorePacketsCheck extends MovingCheck {
|
||||||
|
|
||||||
|
// 20 would be for perfect internet connections, 22 is good enough
|
||||||
private final static int packetsPerTimeframe = 22;
|
private final static int packetsPerTimeframe = 22;
|
||||||
|
|
||||||
public MorePacketsCheck(NoCheat plugin) {
|
public MorePacketsCheck(NoCheat plugin) {
|
||||||
@ -55,6 +56,8 @@ public class MorePacketsCheck extends MovingCheck {
|
|||||||
|
|
||||||
data.packets = -data.morePacketsBuffer;
|
data.packets = -data.morePacketsBuffer;
|
||||||
|
|
||||||
|
// Execute whatever actions are associated with this check and the
|
||||||
|
// violation level and find out if we should cancel the event
|
||||||
final boolean cancel = executeActions(player, cc.morePacketsActions, data.morePacketsVL);
|
final boolean cancel = executeActions(player, cc.morePacketsActions, data.morePacketsVL);
|
||||||
|
|
||||||
if(cancel)
|
if(cancel)
|
||||||
@ -100,9 +103,9 @@ public class MorePacketsCheck extends MovingCheck {
|
|||||||
public String getParameter(ParameterName wildcard, NoCheatPlayer player) {
|
public String getParameter(ParameterName wildcard, NoCheatPlayer player) {
|
||||||
|
|
||||||
if(wildcard == ParameterName.VIOLATIONS)
|
if(wildcard == ParameterName.VIOLATIONS)
|
||||||
return String.format(Locale.US, "%d", (int) getData(player.getDataStore()).morePacketsVL);
|
return String.format(Locale.US, "%d", (int) getData(player).morePacketsVL);
|
||||||
else if(wildcard == ParameterName.PACKETS)
|
else if(wildcard == ParameterName.PACKETS)
|
||||||
return String.format(Locale.US, "%d", (int) getData(player.getDataStore()).packets);
|
return String.format(Locale.US, "%d", (int) getData(player).packets);
|
||||||
else
|
else
|
||||||
return super.getParameter(wildcard, player);
|
return super.getParameter(wildcard, player);
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,10 @@ import cc.co.evenprime.bukkit.nocheat.config.ConfigurationCacheStore;
|
|||||||
import cc.co.evenprime.bukkit.nocheat.data.DataStore;
|
import cc.co.evenprime.bukkit.nocheat.data.DataStore;
|
||||||
import cc.co.evenprime.bukkit.nocheat.data.PreciseLocation;
|
import cc.co.evenprime.bukkit.nocheat.data.PreciseLocation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract base class for Moving checks, provides some convenience
|
||||||
|
* methods for access to data and config that's relevant to this checktype
|
||||||
|
*/
|
||||||
public abstract class MovingCheck extends Check {
|
public abstract class MovingCheck extends Check {
|
||||||
|
|
||||||
private static final String id = "moving";
|
private static final String id = "moving";
|
||||||
@ -21,21 +25,29 @@ public abstract class MovingCheck extends Check {
|
|||||||
public String getParameter(ParameterName wildcard, NoCheatPlayer player) {
|
public String getParameter(ParameterName wildcard, NoCheatPlayer player) {
|
||||||
|
|
||||||
if(wildcard == ParameterName.LOCATION) {
|
if(wildcard == ParameterName.LOCATION) {
|
||||||
PreciseLocation from = getData(player.getDataStore()).from;
|
PreciseLocation from = getData(player).from;
|
||||||
return String.format(Locale.US, "%.2f,%.2f,%.2f", from.x, from.y, from.z);
|
return String.format(Locale.US, "%.2f,%.2f,%.2f", from.x, from.y, from.z);
|
||||||
} else if(wildcard == ParameterName.MOVEDISTANCE) {
|
} else if(wildcard == ParameterName.MOVEDISTANCE) {
|
||||||
PreciseLocation from = getData(player.getDataStore()).from;
|
PreciseLocation from = getData(player).from;
|
||||||
PreciseLocation to = getData(player.getDataStore()).to;
|
PreciseLocation to = getData(player).to;
|
||||||
return String.format(Locale.US, "%.2f,%.2f,%.2f", to.x - from.x, to.y - from.y, to.z - from.z);
|
return String.format(Locale.US, "%.2f,%.2f,%.2f", to.x - from.x, to.y - from.y, to.z - from.z);
|
||||||
} else if(wildcard == ParameterName.LOCATION_TO) {
|
} else if(wildcard == ParameterName.LOCATION_TO) {
|
||||||
PreciseLocation to = getData(player.getDataStore()).to;
|
PreciseLocation to = getData(player).to;
|
||||||
return String.format(Locale.US, "%.2f,%.2f,%.2f", to.x, to.y, to.z);
|
return String.format(Locale.US, "%.2f,%.2f,%.2f", to.x, to.y, to.z);
|
||||||
} else
|
} else
|
||||||
return super.getParameter(wildcard, player);
|
return super.getParameter(wildcard, player);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MovingData getData(DataStore base) {
|
/**
|
||||||
|
* Get the "MovingData" object that belongs to the player. Will ensure
|
||||||
|
* that such a object exists and if not, create one
|
||||||
|
*
|
||||||
|
* @param player
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static MovingData getData(NoCheatPlayer player) {
|
||||||
|
DataStore base = player.getDataStore();
|
||||||
MovingData data = base.get(id);
|
MovingData data = base.get(id);
|
||||||
if(data == null) {
|
if(data == null) {
|
||||||
data = new MovingData();
|
data = new MovingData();
|
||||||
@ -44,6 +56,17 @@ public abstract class MovingCheck extends Check {
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the MovingConfig object that belongs to the world that the player
|
||||||
|
* currently resides in.
|
||||||
|
*
|
||||||
|
* @param player
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static MovingConfig getConfig(NoCheatPlayer player) {
|
||||||
|
return getConfig(player.getConfigurationStore());
|
||||||
|
}
|
||||||
|
|
||||||
public static MovingConfig getConfig(ConfigurationCacheStore cache) {
|
public static MovingConfig getConfig(ConfigurationCacheStore cache) {
|
||||||
MovingConfig config = cache.get(id);
|
MovingConfig config = cache.get(id);
|
||||||
if(config == null) {
|
if(config == null) {
|
||||||
|
@ -24,10 +24,8 @@ import cc.co.evenprime.bukkit.nocheat.config.Permissions;
|
|||||||
import cc.co.evenprime.bukkit.nocheat.data.PreciseLocation;
|
import cc.co.evenprime.bukkit.nocheat.data.PreciseLocation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The only place that listens to and modifies player_move events if necessary
|
* Central location to listen to events that are
|
||||||
*
|
* relevant for the moving checks
|
||||||
* Get the event, decide which checks should work on it and in what order,
|
|
||||||
* evaluate the check results and decide what to
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class MovingCheckListener implements Listener, EventManager {
|
public class MovingCheckListener implements Listener, EventManager {
|
||||||
@ -56,7 +54,7 @@ public class MovingCheckListener implements Listener, EventManager {
|
|||||||
* was already on top of that block and should be allowed to stay
|
* was already on top of that block and should be allowed to stay
|
||||||
* there
|
* there
|
||||||
*
|
*
|
||||||
* @param event
|
* @param event The BlockPlaceEvent
|
||||||
*/
|
*/
|
||||||
@EventHandler(priority = EventPriority.MONITOR)
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
public void blockPlace(final BlockPlaceEvent event) {
|
public void blockPlace(final BlockPlaceEvent event) {
|
||||||
@ -66,7 +64,7 @@ public class MovingCheckListener implements Listener, EventManager {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
final NoCheatPlayer player = plugin.getPlayer(event.getPlayer());
|
final NoCheatPlayer player = plugin.getPlayer(event.getPlayer());
|
||||||
final MovingConfig config = MovingCheck.getConfig(player.getConfigurationStore());
|
final MovingConfig config = MovingCheck.getConfig(player);
|
||||||
|
|
||||||
// If the player is allowed to fly anyway, the workaround is not needed
|
// If the player is allowed to fly anyway, the workaround is not needed
|
||||||
// It's kind of expensive (looking up block types) therefore it makes
|
// It's kind of expensive (looking up block types) therefore it makes
|
||||||
@ -76,7 +74,7 @@ public class MovingCheckListener implements Listener, EventManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the player-specific stored data that applies here
|
// Get the player-specific stored data that applies here
|
||||||
final MovingData data = MovingCheck.getData(player.getDataStore());
|
final MovingData data = MovingCheck.getData(player);
|
||||||
|
|
||||||
final Block block = event.getBlockPlaced();
|
final Block block = event.getBlockPlaced();
|
||||||
|
|
||||||
@ -109,15 +107,15 @@ public class MovingCheckListener implements Listener, EventManager {
|
|||||||
* it was NoCheat or another plugin. If it was NoCheat, the target
|
* it was NoCheat or another plugin. If it was NoCheat, the target
|
||||||
* location should match the "data.teleportTo" value.
|
* location should match the "data.teleportTo" value.
|
||||||
*
|
*
|
||||||
* On teleports, reset some movement related data
|
* On teleports, reset some movement related data that gets invalid
|
||||||
*
|
*
|
||||||
* @param event
|
* @param event The PlayerTeleportEvent
|
||||||
*/
|
*/
|
||||||
@EventHandler(priority = EventPriority.HIGHEST)
|
@EventHandler(priority = EventPriority.HIGHEST)
|
||||||
public void teleport(final PlayerTeleportEvent event) {
|
public void teleport(final PlayerTeleportEvent event) {
|
||||||
|
|
||||||
NoCheatPlayer player = plugin.getPlayer(event.getPlayer());
|
NoCheatPlayer player = plugin.getPlayer(event.getPlayer());
|
||||||
final MovingData data = MovingCheck.getData(player.getDataStore());
|
final MovingData data = MovingCheck.getData(player);
|
||||||
|
|
||||||
// If it was a teleport initialized by NoCheat, do it anyway
|
// If it was a teleport initialized by NoCheat, do it anyway
|
||||||
// even if another plugin said "no"
|
// even if another plugin said "no"
|
||||||
@ -141,14 +139,15 @@ public class MovingCheckListener implements Listener, EventManager {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Just for security, if a player switches between worlds, reset the
|
* Just for security, if a player switches between worlds, reset the
|
||||||
* runfly and morepackets checks.
|
* runfly and morepackets checks data, because it is definitely invalid
|
||||||
|
* now
|
||||||
*
|
*
|
||||||
* @param event
|
* @param event The PlayerChangedWorldEvent
|
||||||
*/
|
*/
|
||||||
@EventHandler(priority = EventPriority.MONITOR)
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
public void worldChange(final PlayerChangedWorldEvent event) {
|
public void worldChange(final PlayerChangedWorldEvent event) {
|
||||||
// Maybe this helps with people teleporting through multiverse portals having problems?
|
// Maybe this helps with people teleporting through multiverse portals having problems?
|
||||||
final MovingData data = MovingCheck.getData(plugin.getPlayer(event.getPlayer()).getDataStore());
|
final MovingData data = MovingCheck.getData(plugin.getPlayer(event.getPlayer()));
|
||||||
data.teleportTo.reset();
|
data.teleportTo.reset();
|
||||||
data.clearRunFlyData();
|
data.clearRunFlyData();
|
||||||
data.clearMorePacketsData();
|
data.clearMorePacketsData();
|
||||||
@ -162,7 +161,7 @@ public class MovingCheckListener implements Listener, EventManager {
|
|||||||
*/
|
*/
|
||||||
@EventHandler(priority = EventPriority.MONITOR)
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
public void portal(final PlayerPortalEvent event) {
|
public void portal(final PlayerPortalEvent event) {
|
||||||
final MovingData data = MovingCheck.getData(plugin.getPlayer(event.getPlayer()).getDataStore());
|
final MovingData data = MovingCheck.getData(plugin.getPlayer(event.getPlayer()));
|
||||||
data.clearMorePacketsData();
|
data.clearMorePacketsData();
|
||||||
data.clearRunFlyData();
|
data.clearRunFlyData();
|
||||||
}
|
}
|
||||||
@ -175,7 +174,7 @@ public class MovingCheckListener implements Listener, EventManager {
|
|||||||
*/
|
*/
|
||||||
@EventHandler(priority = EventPriority.MONITOR)
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
public void respawn(final PlayerRespawnEvent event) {
|
public void respawn(final PlayerRespawnEvent event) {
|
||||||
final MovingData data = MovingCheck.getData(plugin.getPlayer(event.getPlayer()).getDataStore());
|
final MovingData data = MovingCheck.getData(plugin.getPlayer(event.getPlayer()));
|
||||||
data.clearMorePacketsData();
|
data.clearMorePacketsData();
|
||||||
data.clearRunFlyData();
|
data.clearRunFlyData();
|
||||||
}
|
}
|
||||||
@ -184,22 +183,26 @@ public class MovingCheckListener implements Listener, EventManager {
|
|||||||
* When a player moves, he will be checked for various
|
* When a player moves, he will be checked for various
|
||||||
* suspicious behaviour.
|
* suspicious behaviour.
|
||||||
*
|
*
|
||||||
* @param event
|
* @param event The PlayerMoveEvent
|
||||||
*/
|
*/
|
||||||
@EventHandler(priority = EventPriority.LOWEST)
|
@EventHandler(priority = EventPriority.LOWEST)
|
||||||
public void move(final PlayerMoveEvent event) {
|
public void move(final PlayerMoveEvent event) {
|
||||||
|
|
||||||
|
// Don't care for vehicles
|
||||||
if(event.isCancelled() || event.getPlayer().isInsideVehicle())
|
if(event.isCancelled() || event.getPlayer().isInsideVehicle())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Don't care for movements that are very high distance or to another
|
||||||
|
// world (such that it is very likely the event data was modified by
|
||||||
|
// another plugin before we got it)
|
||||||
if(!event.getFrom().getWorld().equals(event.getTo().getWorld()) || event.getFrom().distanceSquared(event.getTo()) > 400) {
|
if(!event.getFrom().getWorld().equals(event.getTo().getWorld()) || event.getFrom().distanceSquared(event.getTo()) > 400) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final NoCheatPlayer player = plugin.getPlayer(event.getPlayer());
|
final NoCheatPlayer player = plugin.getPlayer(event.getPlayer());
|
||||||
|
|
||||||
final MovingConfig cc = MovingCheck.getConfig(player.getConfigurationStore());
|
final MovingConfig cc = MovingCheck.getConfig(player);
|
||||||
final MovingData data = MovingCheck.getData(player.getDataStore());
|
final MovingData data = MovingCheck.getData(player);
|
||||||
|
|
||||||
// Advance various counters and values that change per movement
|
// Advance various counters and values that change per movement
|
||||||
// tick. They are needed to decide on how fast a player may
|
// tick. They are needed to decide on how fast a player may
|
||||||
@ -210,9 +213,6 @@ public class MovingCheckListener implements Listener, EventManager {
|
|||||||
data.from.set(event.getFrom());
|
data.from.set(event.getFrom());
|
||||||
final Location to = event.getTo();
|
final Location to = event.getTo();
|
||||||
data.to.set(to);
|
data.to.set(to);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
PreciseLocation newTo = null;
|
PreciseLocation newTo = null;
|
||||||
|
|
||||||
@ -240,7 +240,8 @@ public class MovingCheckListener implements Listener, EventManager {
|
|||||||
// Did one of the check(s) decide we need a new "to"-location?
|
// Did one of the check(s) decide we need a new "to"-location?
|
||||||
if(newTo != null) {
|
if(newTo != null) {
|
||||||
// Compose a new location based on coordinates of "newTo" and
|
// Compose a new location based on coordinates of "newTo" and
|
||||||
// viewing direction of "event.getTo()"
|
// viewing direction of "event.getTo()" to allow the player to
|
||||||
|
// look somewhere else despite getting pulled back by NoCheat
|
||||||
event.setTo(new Location(player.getPlayer().getWorld(), newTo.x, newTo.y, newTo.z, to.getYaw(), to.getPitch()));
|
event.setTo(new Location(player.getPlayer().getWorld(), newTo.x, newTo.y, newTo.z, to.getYaw(), to.getPitch()));
|
||||||
|
|
||||||
// remember where we send the player to
|
// remember where we send the player to
|
||||||
@ -279,16 +280,16 @@ public class MovingCheckListener implements Listener, EventManager {
|
|||||||
/**
|
/**
|
||||||
* Player got a velocity packet. The server can't keep track
|
* Player got a velocity packet. The server can't keep track
|
||||||
* of actual velocity values (by design), so we have to try
|
* of actual velocity values (by design), so we have to try
|
||||||
* and do that ourselves.
|
* and do that ourselves. Very rough estimates.
|
||||||
*
|
*
|
||||||
* @param event
|
* @param event The PlayerVelocityEvent
|
||||||
*/
|
*/
|
||||||
@EventHandler(priority = EventPriority.MONITOR)
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
public void velocity(final PlayerVelocityEvent event) {
|
public void velocity(final PlayerVelocityEvent event) {
|
||||||
if(event.isCancelled())
|
if(event.isCancelled())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
final MovingData data = MovingCheck.getData(plugin.getPlayer(event.getPlayer()).getDataStore());
|
final MovingData data = MovingCheck.getData(plugin.getPlayer(event.getPlayer()));
|
||||||
|
|
||||||
final Vector v = event.getVelocity();
|
final Vector v = event.getVelocity();
|
||||||
|
|
||||||
|
@ -9,45 +9,61 @@ import cc.co.evenprime.bukkit.nocheat.data.Statistics.Id;
|
|||||||
*/
|
*/
|
||||||
public class MovingData implements DataItem {
|
public class MovingData implements DataItem {
|
||||||
|
|
||||||
|
// Keep track of the violation levels of the checks
|
||||||
public double runflyVL;
|
public double runflyVL;
|
||||||
public double nofallVL;
|
public double nofallVL;
|
||||||
public double morePacketsVL;
|
public double morePacketsVL;
|
||||||
|
|
||||||
|
// Count how long a player is in the air
|
||||||
public int jumpPhase;
|
public int jumpPhase;
|
||||||
|
|
||||||
|
// Remember how big the players last JumpAmplifier (potion effect) was
|
||||||
public double lastJumpAmplifier;
|
public double lastJumpAmplifier;
|
||||||
|
|
||||||
|
// Remember for a short time that the player was on ice and therefore
|
||||||
|
// should be allowed to move a bit faster
|
||||||
public int onIce;
|
public int onIce;
|
||||||
|
|
||||||
|
// Where should a player be teleported back to when failing the check
|
||||||
public final PreciseLocation runflySetBackPoint = new PreciseLocation();
|
public final PreciseLocation runflySetBackPoint = new PreciseLocation();
|
||||||
|
|
||||||
|
// Some values for estimating movement freedom
|
||||||
public double vertFreedom;
|
public double vertFreedom;
|
||||||
public double vertVelocity;
|
public double vertVelocity;
|
||||||
public int vertVelocityCounter;
|
public int vertVelocityCounter;
|
||||||
public double horizFreedom;
|
public double horizFreedom;
|
||||||
public int horizVelocityCounter;
|
public int horizVelocityCounter;
|
||||||
|
|
||||||
public float fallDistance;
|
|
||||||
public float lastAddedFallDistance;
|
|
||||||
|
|
||||||
public double horizontalBuffer;
|
public double horizontalBuffer;
|
||||||
public int bunnyhopdelay;
|
public int bunnyhopdelay;
|
||||||
|
|
||||||
|
// Keep track of estimated fall distance to compare to real fall distance
|
||||||
|
public float fallDistance;
|
||||||
|
public float lastAddedFallDistance;
|
||||||
|
|
||||||
|
// Keep track of when "morePackets" last time checked and how much packets
|
||||||
|
// a player sent and may send before failing the check
|
||||||
public long morePacketsLastTime;
|
public long morePacketsLastTime;
|
||||||
|
public int packets;
|
||||||
public int morePacketsBuffer = 50;
|
public int morePacketsBuffer = 50;
|
||||||
|
|
||||||
|
// Where to teleport the player that fails the "morepackets" check
|
||||||
public final PreciseLocation morePacketsSetbackPoint = new PreciseLocation();
|
public final PreciseLocation morePacketsSetbackPoint = new PreciseLocation();
|
||||||
|
|
||||||
|
// When NoCheat does teleport the player, remember the target location to
|
||||||
|
// be able to distinguish "our" teleports from teleports of others
|
||||||
public final PreciseLocation teleportTo = new PreciseLocation();
|
public final PreciseLocation teleportTo = new PreciseLocation();
|
||||||
|
|
||||||
|
// For logging and convenience, make copies of the events locations
|
||||||
public final PreciseLocation from = new PreciseLocation();
|
public final PreciseLocation from = new PreciseLocation();
|
||||||
public final PreciseLocation to = new PreciseLocation();
|
public final PreciseLocation to = new PreciseLocation();
|
||||||
|
|
||||||
|
// For convenience, remember if the locations are considered "on ground"
|
||||||
|
// by NoCheat
|
||||||
public boolean fromOnOrInGround;
|
public boolean fromOnOrInGround;
|
||||||
public boolean toOnOrInGround;
|
public boolean toOnOrInGround;
|
||||||
|
|
||||||
public Id statisticCategory = Id.MOV_RUNNING;
|
public Id statisticCategory = Id.MOV_RUNNING;
|
||||||
|
|
||||||
public int packets;
|
|
||||||
|
|
||||||
public void clearRunFlyData() {
|
public void clearRunFlyData() {
|
||||||
runflySetBackPoint.reset();
|
runflySetBackPoint.reset();
|
||||||
jumpPhase = 0;
|
jumpPhase = 0;
|
||||||
|
@ -41,6 +41,9 @@ public class NoFallCheck extends MovingCheck {
|
|||||||
data.fallDistance = player.getPlayer().getFallDistance();
|
data.fallDistance = player.getPlayer().getFallDistance();
|
||||||
data.nofallVL += data.fallDistance;
|
data.nofallVL += data.fallDistance;
|
||||||
incrementStatistics(player, Id.MOV_NOFALL, data.fallDistance);
|
incrementStatistics(player, Id.MOV_NOFALL, data.fallDistance);
|
||||||
|
|
||||||
|
// Execute whatever actions are associated with this check and the
|
||||||
|
// violation level and find out if we should cancel the event
|
||||||
final boolean cancel = executeActions(player, cc.nofallActions, data.nofallVL);
|
final boolean cancel = executeActions(player, cc.nofallActions, data.nofallVL);
|
||||||
if(cancel) {
|
if(cancel) {
|
||||||
player.dealFallDamage();
|
player.dealFallDamage();
|
||||||
@ -64,6 +67,8 @@ public class NoFallCheck extends MovingCheck {
|
|||||||
data.nofallVL += difference;
|
data.nofallVL += difference;
|
||||||
incrementStatistics(player, Id.MOV_NOFALL, difference);
|
incrementStatistics(player, Id.MOV_NOFALL, difference);
|
||||||
|
|
||||||
|
// Execute whatever actions are associated with this check and the
|
||||||
|
// violation level and find out if we should cancel the event
|
||||||
final boolean cancel = executeActions(player, cc.nofallActions, data.nofallVL);
|
final boolean cancel = executeActions(player, cc.nofallActions, data.nofallVL);
|
||||||
|
|
||||||
// If "cancelled", the fall damage gets dealt in a way that's
|
// If "cancelled", the fall damage gets dealt in a way that's
|
||||||
@ -106,7 +111,7 @@ public class NoFallCheck extends MovingCheck {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Reduce falldamage violation level
|
// Reduce falldamage violation level
|
||||||
data.nofallVL *= 0.99D;
|
data.nofallVL *= 0.95D;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -115,9 +120,9 @@ public class NoFallCheck extends MovingCheck {
|
|||||||
public String getParameter(ParameterName wildcard, NoCheatPlayer player) {
|
public String getParameter(ParameterName wildcard, NoCheatPlayer player) {
|
||||||
|
|
||||||
if(wildcard == ParameterName.VIOLATIONS)
|
if(wildcard == ParameterName.VIOLATIONS)
|
||||||
return String.format(Locale.US, "%d", (int) getData(player.getDataStore()).nofallVL);
|
return String.format(Locale.US, "%d", (int) getData(player).nofallVL);
|
||||||
else if(wildcard == ParameterName.FALLDISTANCE)
|
else if(wildcard == ParameterName.FALLDISTANCE)
|
||||||
return String.format(Locale.US, "%.2f", getData(player.getDataStore()).fallDistance);
|
return String.format(Locale.US, "%.2f", getData(player).fallDistance);
|
||||||
else
|
else
|
||||||
return super.getParameter(wildcard, player);
|
return super.getParameter(wildcard, player);
|
||||||
}
|
}
|
||||||
|
@ -72,8 +72,8 @@ public class RunningCheck extends MovingCheck {
|
|||||||
// Slowly reduce the level with each event
|
// Slowly reduce the level with each event
|
||||||
data.runflyVL *= 0.95;
|
data.runflyVL *= 0.95;
|
||||||
|
|
||||||
|
// Did the player move in unexpected ways?
|
||||||
if(result > 0) {
|
if(result > 0) {
|
||||||
|
|
||||||
// Increment violation counter
|
// Increment violation counter
|
||||||
data.runflyVL += result;
|
data.runflyVL += result;
|
||||||
|
|
||||||
@ -92,15 +92,24 @@ public class RunningCheck extends MovingCheck {
|
|||||||
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// Decide if we should create a new setBack point
|
||||||
|
// These are the result of a lot of bug reports, experience and
|
||||||
|
// trial and error
|
||||||
|
|
||||||
if((toInGround && from.y >= to.y) || CheckUtil.isLiquid(toType)) {
|
if((toInGround && from.y >= to.y) || CheckUtil.isLiquid(toType)) {
|
||||||
|
// Yes, if the player moved down "into" the ground or into liquid
|
||||||
setBack.set(to);
|
setBack.set(to);
|
||||||
setBack.y = Math.ceil(setBack.y);
|
setBack.y = Math.ceil(setBack.y);
|
||||||
data.jumpPhase = 0;
|
data.jumpPhase = 0;
|
||||||
} else if(toOnGround && (from.y >= to.y || setBack.y <= Math.floor(to.y))) {
|
} else if(toOnGround && (from.y >= to.y || setBack.y <= Math.floor(to.y))) {
|
||||||
|
// Yes, if the player moved down "onto" the ground and the new
|
||||||
|
// setback point is higher up than the old or at least at the
|
||||||
|
// same height
|
||||||
setBack.set(to);
|
setBack.set(to);
|
||||||
setBack.y = Math.floor(setBack.y);
|
setBack.y = Math.floor(setBack.y);
|
||||||
data.jumpPhase = 0;
|
data.jumpPhase = 0;
|
||||||
} else if(fromOnGround || fromInGround || toOnGround || toInGround) {
|
} else if(fromOnGround || fromInGround || toOnGround || toInGround) {
|
||||||
|
// The player at least touched the ground somehow
|
||||||
data.jumpPhase = 0;
|
data.jumpPhase = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -134,7 +143,7 @@ public class RunningCheck extends MovingCheck {
|
|||||||
|
|
||||||
Id statisticsCategory = null;
|
Id statisticsCategory = null;
|
||||||
|
|
||||||
// Player on ice?
|
// Player on ice? Give him higher max speed
|
||||||
Block b = player.getPlayer().getLocation().getBlock();
|
Block b = player.getPlayer().getLocation().getBlock();
|
||||||
if(b.getType() == Material.ICE || b.getRelative(0, -1, 0).getType() == Material.ICE) {
|
if(b.getType() == Material.ICE || b.getRelative(0, -1, 0).getType() == Material.ICE) {
|
||||||
data.onIce = 20;
|
data.onIce = 20;
|
||||||
@ -208,6 +217,7 @@ public class RunningCheck extends MovingCheck {
|
|||||||
// How much higher did the player move than expected??
|
// How much higher did the player move than expected??
|
||||||
double distanceAboveLimit = 0.0D;
|
double distanceAboveLimit = 0.0D;
|
||||||
|
|
||||||
|
// Potion effect "Jump"
|
||||||
double jumpAmplifier = player.getJumpAmplifier();
|
double jumpAmplifier = player.getJumpAmplifier();
|
||||||
if(jumpAmplifier > data.lastJumpAmplifier) {
|
if(jumpAmplifier > data.lastJumpAmplifier) {
|
||||||
data.lastJumpAmplifier = jumpAmplifier;
|
data.lastJumpAmplifier = jumpAmplifier;
|
||||||
@ -239,9 +249,9 @@ public class RunningCheck extends MovingCheck {
|
|||||||
|
|
||||||
if(wildcard == ParameterName.CHECK)
|
if(wildcard == ParameterName.CHECK)
|
||||||
// Workaround for something until I find a better way to do it
|
// Workaround for something until I find a better way to do it
|
||||||
return getData(player.getDataStore()).statisticCategory.toString();
|
return getData(player).statisticCategory.toString();
|
||||||
else if(wildcard == ParameterName.VIOLATIONS)
|
else if(wildcard == ParameterName.VIOLATIONS)
|
||||||
return String.format(Locale.US, "%d", (int) getData(player.getDataStore()).runflyVL);
|
return String.format(Locale.US, "%d", (int) getData(player).runflyVL);
|
||||||
else
|
else
|
||||||
return super.getParameter(wildcard, player);
|
return super.getParameter(wildcard, player);
|
||||||
}
|
}
|
||||||
|
@ -13,14 +13,19 @@ import org.bukkit.permissions.Permission;
|
|||||||
import cc.co.evenprime.bukkit.nocheat.NoCheat;
|
import cc.co.evenprime.bukkit.nocheat.NoCheat;
|
||||||
import cc.co.evenprime.bukkit.nocheat.config.Permissions;
|
import cc.co.evenprime.bukkit.nocheat.config.Permissions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle all NoCheat related commands in a common place
|
||||||
|
*/
|
||||||
public class CommandHandler {
|
public class CommandHandler {
|
||||||
|
|
||||||
private final List<Permission> perms;
|
private final List<Permission> perms;
|
||||||
|
|
||||||
public CommandHandler(NoCheat plugin) {
|
public CommandHandler(NoCheat plugin) {
|
||||||
// Make a copy to allow sorting
|
// Make a copy to allow sorting
|
||||||
perms = new LinkedList<Permission>(plugin.getDescription().getPermissions());
|
perms = new LinkedList<Permission>(plugin.getDescription().getPermissions());
|
||||||
|
|
||||||
|
// Sort NoCheats permission by name and parent-child relation with
|
||||||
|
// a custom sorting method
|
||||||
Collections.sort(perms, new Comparator<Permission>() {
|
Collections.sort(perms, new Comparator<Permission>() {
|
||||||
|
|
||||||
public int compare(Permission o1, Permission o2) {
|
public int compare(Permission o1, Permission o2) {
|
||||||
@ -44,10 +49,19 @@ public class CommandHandler {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle a command that is directed at NoCheat
|
||||||
|
* @param plugin
|
||||||
|
* @param sender
|
||||||
|
* @param command
|
||||||
|
* @param label
|
||||||
|
* @param args
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public boolean handleCommand(NoCheat plugin, CommandSender sender, Command command, String label, String[] args) {
|
public boolean handleCommand(NoCheat plugin, CommandSender sender, Command command, String label, String[] args) {
|
||||||
|
|
||||||
boolean result = false;
|
boolean result = false;
|
||||||
// Not our command
|
// Not our command, how did it get here?
|
||||||
if(!command.getName().equalsIgnoreCase("nocheat") || args.length == 0) {
|
if(!command.getName().equalsIgnoreCase("nocheat") || args.length == 0) {
|
||||||
result = false;
|
result = false;
|
||||||
} else if(args[0].equalsIgnoreCase("permlist") && args.length >= 2) {
|
} else if(args[0].equalsIgnoreCase("permlist") && args.length >= 2) {
|
||||||
@ -60,7 +74,7 @@ public class CommandHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
else if(args[0].equalsIgnoreCase("playerinfo") && args.length >= 2) {
|
else if(args[0].equalsIgnoreCase("playerinfo") && args.length >= 2) {
|
||||||
// performance command was used
|
// playerinfo command was used
|
||||||
result = handlePlayerInfoCommand(plugin, sender, args);
|
result = handlePlayerInfoCommand(plugin, sender, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,9 +131,8 @@ public class CommandHandler {
|
|||||||
sender.sendMessage("[NoCheat] Reloading configuration");
|
sender.sendMessage("[NoCheat] Reloading configuration");
|
||||||
plugin.reloadConfiguration();
|
plugin.reloadConfiguration();
|
||||||
sender.sendMessage("[NoCheat] Configuration reloaded");
|
sender.sendMessage("[NoCheat] Configuration reloaded");
|
||||||
}
|
} else {
|
||||||
else {
|
sender.sendMessage("You lack the " + Permissions.ADMIN_RELOAD + " permission to use 'reload'");
|
||||||
sender.sendMessage("You lack the "+Permissions.ADMIN_RELOAD+ " permission to use 'reload'");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -11,6 +11,10 @@ import cc.co.evenprime.bukkit.nocheat.actions.types.DummyAction;
|
|||||||
import cc.co.evenprime.bukkit.nocheat.actions.types.LogAction;
|
import cc.co.evenprime.bukkit.nocheat.actions.types.LogAction;
|
||||||
import cc.co.evenprime.bukkit.nocheat.actions.types.SpecialAction;
|
import cc.co.evenprime.bukkit.nocheat.actions.types.SpecialAction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helps with creating Actions out of text string definitions
|
||||||
|
*
|
||||||
|
*/
|
||||||
public class ActionFactory {
|
public class ActionFactory {
|
||||||
|
|
||||||
private static final Map<String, Object> lib = new HashMap<String, Object>();
|
private static final Map<String, Object> lib = new HashMap<String, Object>();
|
||||||
|
@ -2,6 +2,8 @@ package cc.co.evenprime.bukkit.nocheat.config;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Paths for the configuration options
|
* Paths for the configuration options
|
||||||
|
* Making everything final static prevents accidentially modifying any
|
||||||
|
* of these
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public abstract class ConfPaths {
|
public abstract class ConfPaths {
|
||||||
|
@ -6,6 +6,10 @@ import cc.co.evenprime.bukkit.nocheat.EventManager;
|
|||||||
import cc.co.evenprime.bukkit.nocheat.NoCheat;
|
import cc.co.evenprime.bukkit.nocheat.NoCheat;
|
||||||
import cc.co.evenprime.bukkit.nocheat.config.ConfigurationCacheStore;
|
import cc.co.evenprime.bukkit.nocheat.config.ConfigurationCacheStore;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints the list of active checks per world on startup, if requested
|
||||||
|
*
|
||||||
|
*/
|
||||||
public class ActiveCheckPrinter {
|
public class ActiveCheckPrinter {
|
||||||
|
|
||||||
public static void printActiveChecks(NoCheat plugin, List<EventManager> eventManagers) {
|
public static void printActiveChecks(NoCheat plugin, List<EventManager> eventManagers) {
|
||||||
|
@ -3,6 +3,12 @@ package cc.co.evenprime.bukkit.nocheat.debug;
|
|||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import cc.co.evenprime.bukkit.nocheat.NoCheat;
|
import cc.co.evenprime.bukkit.nocheat.NoCheat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A task running in the background that measures tick time vs. real time
|
||||||
|
*
|
||||||
|
* @author Evenprime
|
||||||
|
*
|
||||||
|
*/
|
||||||
public class LagMeasureTask implements Runnable {
|
public class LagMeasureTask implements Runnable {
|
||||||
|
|
||||||
private int ingameseconds = 1;
|
private int ingameseconds = 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user