mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2025-01-02 22:07:50 +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
|
||||
// Then set up the event listeners
|
||||
eventManagers.add(new MovingCheckListener(this));
|
||||
eventManagers.add(new WorkaroundsListener(this));
|
||||
eventManagers.add(new WorkaroundsListener());
|
||||
eventManagers.add(new ChatCheckListener(this));
|
||||
eventManagers.add(new BlockBreakCheckListener(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.data.Statistics.Id;
|
||||
|
||||
/**
|
||||
* The abstract Check class, providing some basic functionality
|
||||
*
|
||||
*/
|
||||
public abstract class Check {
|
||||
|
||||
private final String name;
|
||||
@ -41,13 +45,18 @@ public abstract class Check {
|
||||
|
||||
boolean special = false;
|
||||
|
||||
// Get the to be executed actions
|
||||
Action[] actions = actionList.getActions(violationLevel);
|
||||
|
||||
final long time = System.currentTimeMillis() / 1000L;
|
||||
|
||||
// The configuration will be needed too
|
||||
final ConfigurationCacheStore cc = player.getConfigurationStore();
|
||||
|
||||
for(Action ac : actions) {
|
||||
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)) {
|
||||
executeLogAction((LogAction) ac, this, player, cc);
|
||||
} else if(ac instanceof SpecialAction) {
|
||||
@ -79,6 +88,7 @@ public abstract class Check {
|
||||
if(!cc.logging.active)
|
||||
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()));
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,8 @@ import cc.co.evenprime.bukkit.nocheat.NoCheatPlayer;
|
||||
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 {
|
||||
@ -85,10 +86,11 @@ public class CheckUtil {
|
||||
|
||||
// All fences are solid - fences are treated specially due
|
||||
// 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 ONGROUND = 256;
|
||||
|
||||
// Until I can think of a better way to determine if a block is solid or
|
||||
// not, this is what I'll do
|
||||
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.BREAD);
|
||||
foods.add(Material.COOKED_BEEF);
|
||||
@ -202,7 +206,7 @@ public class CheckUtil {
|
||||
|
||||
final int lowerX = lowerBorder(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 upperZ = upperBorder(location.z);
|
||||
|
||||
|
@ -8,7 +8,6 @@ import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
import org.bukkit.event.player.PlayerToggleSprintEvent;
|
||||
import cc.co.evenprime.bukkit.nocheat.EventManager;
|
||||
import cc.co.evenprime.bukkit.nocheat.NoCheat;
|
||||
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 {
|
||||
|
||||
//private final NoCheat plugin;
|
||||
|
||||
public WorkaroundsListener(NoCheat plugin) {
|
||||
|
||||
//this.plugin = plugin;
|
||||
}
|
||||
public WorkaroundsListener() {}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void playerMove(final PlayerMoveEvent event) {
|
||||
@ -39,12 +33,14 @@ public class WorkaroundsListener implements Listener, EventManager {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
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()) {
|
||||
event.setCancelled(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getActiveChecks(ConfigurationCacheStore cc) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
@ -19,23 +19,29 @@ public class FlyingCheck extends MovingCheck {
|
||||
super(plugin, "moving.flying");
|
||||
}
|
||||
|
||||
// Determined by trial and error, the flying movement speed of the creative
|
||||
// mode
|
||||
private static final double creativeSpeed = 0.60D;
|
||||
|
||||
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 from = data.from;
|
||||
final PreciseLocation to = data.to;
|
||||
|
||||
// If we have no setback, define one now
|
||||
if(!setBack.isSet()) {
|
||||
setBack.set(from);
|
||||
}
|
||||
|
||||
// Used to store the location where the player gets teleported to
|
||||
PreciseLocation newToLocation = null;
|
||||
|
||||
// Before doing anything, do a basic height check
|
||||
// This is silent for now, will log messages later
|
||||
// probably
|
||||
// Before doing anything, do a basic height check to determine if
|
||||
// players are flying too high
|
||||
if(to.y - data.vertFreedom > ccmoving.flyingHeightLimit) {
|
||||
newToLocation = new PreciseLocation();
|
||||
newToLocation.set(setBack);
|
||||
@ -43,33 +49,36 @@ public class FlyingCheck extends MovingCheck {
|
||||
return newToLocation;
|
||||
}
|
||||
|
||||
final double yDistance = to.y - from.y;
|
||||
|
||||
// Calculate some distances
|
||||
final double yDistance = to.y - from.y;
|
||||
final double xDistance = to.x - from.x;
|
||||
final double zDistance = to.z - from.z;
|
||||
|
||||
// How far did the player move horizontally
|
||||
final double horizontalDistance = Math.sqrt((xDistance * xDistance + zDistance * zDistance));
|
||||
|
||||
double resultHoriz = 0;
|
||||
double resultVert = 0;
|
||||
double result = 0;
|
||||
|
||||
// In case of creative gamemode, give at least 0.60 speed limit
|
||||
// horizontal
|
||||
// In case of creative game mode give at least 0.60 speed limit horizontal
|
||||
double speedLimitHorizontal = player.isCreative() ? Math.max(creativeSpeed, ccmoving.flyingSpeedLimitHorizontal) : ccmoving.flyingSpeedLimitHorizontal;
|
||||
|
||||
// If the player is affected by potion of swiftness
|
||||
speedLimitHorizontal *= player.getSpeedAmplifier();
|
||||
|
||||
// Finally, determine how far the player went beyond the set limits
|
||||
resultHoriz = Math.max(0.0D, horizontalDistance - data.horizFreedom - speedLimitHorizontal);
|
||||
|
||||
boolean sprinting = player.isSprinting();
|
||||
|
||||
data.bunnyhopdelay--;
|
||||
|
||||
// Did he go too far?
|
||||
if(resultHoriz > 0 && sprinting) {
|
||||
|
||||
// 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) {
|
||||
data.bunnyhopdelay = 9;
|
||||
resultHoriz = 0;
|
||||
@ -78,6 +87,9 @@ public class FlyingCheck extends MovingCheck {
|
||||
|
||||
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();
|
||||
if(jumpAmplifier > data.lastJumpAmplifier) {
|
||||
data.lastJumpAmplifier = jumpAmplifier;
|
||||
@ -89,14 +101,15 @@ public class FlyingCheck extends MovingCheck {
|
||||
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;
|
||||
|
||||
result = resultHoriz + resultVert;
|
||||
|
||||
// The player went to far, either horizontal or vertical
|
||||
if(result > 0) {
|
||||
|
||||
// Increment violation counter
|
||||
// Increment violation counter and statistics
|
||||
data.runflyVL += result;
|
||||
if(resultHoriz > 0) {
|
||||
incrementStatistics(player, Id.MOV_RUNNING, resultHoriz);
|
||||
@ -106,6 +119,8 @@ public class FlyingCheck extends MovingCheck {
|
||||
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);
|
||||
|
||||
// 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;
|
||||
|
||||
// Some other cleanup 'n' stuff
|
||||
// If the player did not get cancelled, define a new setback point
|
||||
if(newToLocation == null) {
|
||||
setBack.set(to);
|
||||
}
|
||||
@ -125,10 +140,11 @@ public class FlyingCheck extends MovingCheck {
|
||||
return newToLocation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParameter(ParameterName wildcard, NoCheatPlayer player) {
|
||||
|
||||
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
|
||||
return super.getParameter(wildcard, player);
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ import cc.co.evenprime.bukkit.nocheat.data.Statistics.Id;
|
||||
*/
|
||||
public class MorePacketsCheck extends MovingCheck {
|
||||
|
||||
// 20 would be for perfect internet connections, 22 is good enough
|
||||
private final static int packetsPerTimeframe = 22;
|
||||
|
||||
public MorePacketsCheck(NoCheat plugin) {
|
||||
@ -55,6 +56,8 @@ public class MorePacketsCheck extends MovingCheck {
|
||||
|
||||
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);
|
||||
|
||||
if(cancel)
|
||||
@ -100,9 +103,9 @@ public class MorePacketsCheck extends MovingCheck {
|
||||
public String getParameter(ParameterName wildcard, NoCheatPlayer player) {
|
||||
|
||||
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)
|
||||
return String.format(Locale.US, "%d", (int) getData(player.getDataStore()).packets);
|
||||
return String.format(Locale.US, "%d", (int) getData(player).packets);
|
||||
else
|
||||
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.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 {
|
||||
|
||||
private static final String id = "moving";
|
||||
@ -21,21 +25,29 @@ public abstract class MovingCheck extends Check {
|
||||
public String getParameter(ParameterName wildcard, NoCheatPlayer player) {
|
||||
|
||||
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);
|
||||
} else if(wildcard == ParameterName.MOVEDISTANCE) {
|
||||
PreciseLocation from = getData(player.getDataStore()).from;
|
||||
PreciseLocation to = getData(player.getDataStore()).to;
|
||||
PreciseLocation from = getData(player).from;
|
||||
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);
|
||||
} 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);
|
||||
} else
|
||||
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);
|
||||
if(data == null) {
|
||||
data = new MovingData();
|
||||
@ -44,6 +56,17 @@ public abstract class MovingCheck extends Check {
|
||||
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) {
|
||||
MovingConfig config = cache.get(id);
|
||||
if(config == null) {
|
||||
|
@ -24,10 +24,8 @@ import cc.co.evenprime.bukkit.nocheat.config.Permissions;
|
||||
import cc.co.evenprime.bukkit.nocheat.data.PreciseLocation;
|
||||
|
||||
/**
|
||||
* The only place that listens to and modifies player_move events if necessary
|
||||
*
|
||||
* Get the event, decide which checks should work on it and in what order,
|
||||
* evaluate the check results and decide what to
|
||||
* Central location to listen to events that are
|
||||
* relevant for the moving checks
|
||||
*
|
||||
*/
|
||||
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
|
||||
* there
|
||||
*
|
||||
* @param event
|
||||
* @param event The BlockPlaceEvent
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void blockPlace(final BlockPlaceEvent event) {
|
||||
@ -66,7 +64,7 @@ public class MovingCheckListener implements Listener, EventManager {
|
||||
return;
|
||||
|
||||
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
|
||||
// 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
|
||||
final MovingData data = MovingCheck.getData(player.getDataStore());
|
||||
final MovingData data = MovingCheck.getData(player);
|
||||
|
||||
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
|
||||
* 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)
|
||||
public void teleport(final PlayerTeleportEvent event) {
|
||||
|
||||
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
|
||||
// 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
|
||||
* 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)
|
||||
public void worldChange(final PlayerChangedWorldEvent event) {
|
||||
// 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.clearRunFlyData();
|
||||
data.clearMorePacketsData();
|
||||
@ -162,7 +161,7 @@ public class MovingCheckListener implements Listener, EventManager {
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
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.clearRunFlyData();
|
||||
}
|
||||
@ -175,7 +174,7 @@ public class MovingCheckListener implements Listener, EventManager {
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
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.clearRunFlyData();
|
||||
}
|
||||
@ -184,22 +183,26 @@ public class MovingCheckListener implements Listener, EventManager {
|
||||
* When a player moves, he will be checked for various
|
||||
* suspicious behaviour.
|
||||
*
|
||||
* @param event
|
||||
* @param event The PlayerMoveEvent
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void move(final PlayerMoveEvent event) {
|
||||
|
||||
// Don't care for vehicles
|
||||
if(event.isCancelled() || event.getPlayer().isInsideVehicle())
|
||||
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) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
final NoCheatPlayer player = plugin.getPlayer(event.getPlayer());
|
||||
|
||||
final MovingConfig cc = MovingCheck.getConfig(player.getConfigurationStore());
|
||||
final MovingData data = MovingCheck.getData(player.getDataStore());
|
||||
final MovingConfig cc = MovingCheck.getConfig(player);
|
||||
final MovingData data = MovingCheck.getData(player);
|
||||
|
||||
// Advance various counters and values that change per movement
|
||||
// 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());
|
||||
final Location to = event.getTo();
|
||||
data.to.set(to);
|
||||
|
||||
|
||||
|
||||
|
||||
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?
|
||||
if(newTo != null) {
|
||||
// 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()));
|
||||
|
||||
// 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
|
||||
* 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)
|
||||
public void velocity(final PlayerVelocityEvent event) {
|
||||
if(event.isCancelled())
|
||||
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();
|
||||
|
||||
|
@ -9,45 +9,61 @@ import cc.co.evenprime.bukkit.nocheat.data.Statistics.Id;
|
||||
*/
|
||||
public class MovingData implements DataItem {
|
||||
|
||||
// Keep track of the violation levels of the checks
|
||||
public double runflyVL;
|
||||
public double nofallVL;
|
||||
public double morePacketsVL;
|
||||
|
||||
// Count how long a player is in the air
|
||||
public int jumpPhase;
|
||||
|
||||
// Remember how big the players last JumpAmplifier (potion effect) was
|
||||
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;
|
||||
|
||||
// Where should a player be teleported back to when failing the check
|
||||
public final PreciseLocation runflySetBackPoint = new PreciseLocation();
|
||||
|
||||
// Some values for estimating movement freedom
|
||||
public double vertFreedom;
|
||||
public double vertVelocity;
|
||||
public int vertVelocityCounter;
|
||||
public double horizFreedom;
|
||||
public int horizVelocityCounter;
|
||||
|
||||
public float fallDistance;
|
||||
public float lastAddedFallDistance;
|
||||
|
||||
public double horizontalBuffer;
|
||||
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 int packets;
|
||||
public int morePacketsBuffer = 50;
|
||||
|
||||
// Where to teleport the player that fails the "morepackets" check
|
||||
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();
|
||||
|
||||
// For logging and convenience, make copies of the events locations
|
||||
public final PreciseLocation from = 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 toOnOrInGround;
|
||||
|
||||
public Id statisticCategory = Id.MOV_RUNNING;
|
||||
|
||||
public int packets;
|
||||
|
||||
public void clearRunFlyData() {
|
||||
runflySetBackPoint.reset();
|
||||
jumpPhase = 0;
|
||||
|
@ -41,6 +41,9 @@ public class NoFallCheck extends MovingCheck {
|
||||
data.fallDistance = player.getPlayer().getFallDistance();
|
||||
data.nofallVL += 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);
|
||||
if(cancel) {
|
||||
player.dealFallDamage();
|
||||
@ -64,6 +67,8 @@ public class NoFallCheck extends MovingCheck {
|
||||
data.nofallVL += 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);
|
||||
|
||||
// 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
|
||||
data.nofallVL *= 0.99D;
|
||||
data.nofallVL *= 0.95D;
|
||||
|
||||
return;
|
||||
}
|
||||
@ -115,9 +120,9 @@ public class NoFallCheck extends MovingCheck {
|
||||
public String getParameter(ParameterName wildcard, NoCheatPlayer player) {
|
||||
|
||||
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)
|
||||
return String.format(Locale.US, "%.2f", getData(player.getDataStore()).fallDistance);
|
||||
return String.format(Locale.US, "%.2f", getData(player).fallDistance);
|
||||
else
|
||||
return super.getParameter(wildcard, player);
|
||||
}
|
||||
|
@ -72,8 +72,8 @@ public class RunningCheck extends MovingCheck {
|
||||
// Slowly reduce the level with each event
|
||||
data.runflyVL *= 0.95;
|
||||
|
||||
// Did the player move in unexpected ways?
|
||||
if(result > 0) {
|
||||
|
||||
// Increment violation counter
|
||||
data.runflyVL += result;
|
||||
|
||||
@ -92,15 +92,24 @@ public class RunningCheck extends MovingCheck {
|
||||
|
||||
}
|
||||
} 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)) {
|
||||
// Yes, if the player moved down "into" the ground or into liquid
|
||||
setBack.set(to);
|
||||
setBack.y = Math.ceil(setBack.y);
|
||||
data.jumpPhase = 0;
|
||||
} 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.y = Math.floor(setBack.y);
|
||||
data.jumpPhase = 0;
|
||||
} else if(fromOnGround || fromInGround || toOnGround || toInGround) {
|
||||
// The player at least touched the ground somehow
|
||||
data.jumpPhase = 0;
|
||||
}
|
||||
}
|
||||
@ -134,7 +143,7 @@ public class RunningCheck extends MovingCheck {
|
||||
|
||||
Id statisticsCategory = null;
|
||||
|
||||
// Player on ice?
|
||||
// Player on ice? Give him higher max speed
|
||||
Block b = player.getPlayer().getLocation().getBlock();
|
||||
if(b.getType() == Material.ICE || b.getRelative(0, -1, 0).getType() == Material.ICE) {
|
||||
data.onIce = 20;
|
||||
@ -208,6 +217,7 @@ public class RunningCheck extends MovingCheck {
|
||||
// How much higher did the player move than expected??
|
||||
double distanceAboveLimit = 0.0D;
|
||||
|
||||
// Potion effect "Jump"
|
||||
double jumpAmplifier = player.getJumpAmplifier();
|
||||
if(jumpAmplifier > data.lastJumpAmplifier) {
|
||||
data.lastJumpAmplifier = jumpAmplifier;
|
||||
@ -239,9 +249,9 @@ public class RunningCheck extends MovingCheck {
|
||||
|
||||
if(wildcard == ParameterName.CHECK)
|
||||
// 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)
|
||||
return String.format(Locale.US, "%d", (int) getData(player.getDataStore()).runflyVL);
|
||||
return String.format(Locale.US, "%d", (int) getData(player).runflyVL);
|
||||
else
|
||||
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.config.Permissions;
|
||||
|
||||
/**
|
||||
* Handle all NoCheat related commands in a common place
|
||||
*/
|
||||
public class CommandHandler {
|
||||
|
||||
private final List<Permission> perms;
|
||||
|
||||
|
||||
public CommandHandler(NoCheat plugin) {
|
||||
// Make a copy to allow sorting
|
||||
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>() {
|
||||
|
||||
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) {
|
||||
|
||||
boolean result = false;
|
||||
// Not our command
|
||||
// Not our command, how did it get here?
|
||||
if(!command.getName().equalsIgnoreCase("nocheat") || args.length == 0) {
|
||||
result = false;
|
||||
} 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) {
|
||||
// performance command was used
|
||||
// playerinfo command was used
|
||||
result = handlePlayerInfoCommand(plugin, sender, args);
|
||||
}
|
||||
|
||||
@ -117,9 +131,8 @@ public class CommandHandler {
|
||||
sender.sendMessage("[NoCheat] Reloading configuration");
|
||||
plugin.reloadConfiguration();
|
||||
sender.sendMessage("[NoCheat] Configuration reloaded");
|
||||
}
|
||||
else {
|
||||
sender.sendMessage("You lack the "+Permissions.ADMIN_RELOAD+ " permission to use 'reload'");
|
||||
} else {
|
||||
sender.sendMessage("You lack the " + Permissions.ADMIN_RELOAD + " permission to use 'reload'");
|
||||
}
|
||||
|
||||
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.SpecialAction;
|
||||
|
||||
/**
|
||||
* Helps with creating Actions out of text string definitions
|
||||
*
|
||||
*/
|
||||
public class ActionFactory {
|
||||
|
||||
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
|
||||
* Making everything final static prevents accidentially modifying any
|
||||
* of these
|
||||
*
|
||||
*/
|
||||
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.config.ConfigurationCacheStore;
|
||||
|
||||
/**
|
||||
* Prints the list of active checks per world on startup, if requested
|
||||
*
|
||||
*/
|
||||
public class ActiveCheckPrinter {
|
||||
|
||||
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 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 {
|
||||
|
||||
private int ingameseconds = 1;
|
||||
|
Loading…
Reference in New Issue
Block a user