A bit code cleanup and new method to remove data for no longer online

players.
This commit is contained in:
Evenprime 2011-03-30 12:50:59 +02:00
parent a9c85d231e
commit 4535efd2eb
11 changed files with 72 additions and 40 deletions

View File

@ -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.7.7 version: 0.7.7a
commands: commands:
nocheat: nocheat:

View File

@ -27,7 +27,7 @@ public class NoCheatConfiguration {
public Level ircLevel = Level.OFF; public Level ircLevel = Level.OFF;
public Level consoleLevel = Level.OFF; public Level consoleLevel = Level.OFF;
public String ircTag = ""; public String ircTag = "nocheat";
// Our log output to a file // Our log output to a file
private FileHandler fh = null; private FileHandler fh = null;
@ -37,7 +37,7 @@ public class NoCheatConfiguration {
public NoCheatConfiguration(File configurationFile, NoCheatPlugin plugin) { public NoCheatConfiguration(File configurationFile, NoCheatPlugin plugin) {
this.plugin = plugin; this.plugin = plugin;
config(configurationFile); config(configurationFile);
} }
@ -46,10 +46,11 @@ public class NoCheatConfiguration {
* @param configurationFile * @param configurationFile
*/ */
public void config(File configurationFile) { public void config(File configurationFile) {
if(!configurationFile.exists()) { if(!configurationFile.exists()) {
createStandardConfigFile(configurationFile); createStandardConfigFile(configurationFile);
} }
Configuration c = new Configuration(configurationFile); Configuration c = new Configuration(configurationFile);
c.load(); c.load();

View File

@ -26,8 +26,6 @@ public class NoCheatData {
// WORKAROUND for changed PLAYER_MOVE logic // WORKAROUND for changed PLAYER_MOVE logic
public Location movingTeleportTo = null; public Location movingTeleportTo = null;
public int legitMoves = 0;
public boolean reset = false; public boolean reset = false;
public long speedhackLastCheck = System.currentTimeMillis(); // timestamp of last check for speedhacks public long speedhackLastCheck = System.currentTimeMillis(); // timestamp of last check for speedhacks
@ -39,5 +37,5 @@ public class NoCheatData {
public Runnable airbuildRunnable = null; public Runnable airbuildRunnable = null;
NoCheatData() { } public NoCheatData() { }
} }

View File

@ -44,7 +44,7 @@ public class NoCheatPlugin extends JavaPlugin {
public final BedteleportCheck bedteleportCheck; public final BedteleportCheck bedteleportCheck;
public final SpeedhackCheck speedhackCheck; public final SpeedhackCheck speedhackCheck;
public final AirbuildCheck airbuildCheck; public final AirbuildCheck airbuildCheck;
private NoCheatConfiguration config; private NoCheatConfiguration config;
// Permissions 2.x, if available // Permissions 2.x, if available
@ -61,7 +61,7 @@ public class NoCheatPlugin extends JavaPlugin {
bedteleportCheck = new BedteleportCheck(this); bedteleportCheck = new BedteleportCheck(this);
speedhackCheck = new SpeedhackCheck(this); speedhackCheck = new SpeedhackCheck(this);
airbuildCheck = new AirbuildCheck(this); airbuildCheck = new AirbuildCheck(this);
// parse the nocheat.yml config file // parse the nocheat.yml config file
setupConfig(); setupConfig();
} }
@ -90,6 +90,22 @@ public class NoCheatPlugin extends JavaPlugin {
return data; return data;
} }
/**
* Go through the playerData HashMap and remove players that are no longer online
* from the map. This should be called in long, regular intervals (e.g. every 10 minutes)
* to keep the memory footprint of the plugin low
*/
public void cleanPlayerDataCollection() {
synchronized(playerData) {
Player[] storedPlayers = (Player[]) playerData.keySet().toArray();
for(Player p : storedPlayers) {
if(!p.isOnline()) {
playerData.remove(p);
}
}
}
}
@Override @Override
public boolean onCommand(CommandSender sender, Command command, String commandLabel, String[] args) public boolean onCommand(CommandSender sender, Command command, String commandLabel, String[] args)
@ -222,7 +238,7 @@ public class NoCheatPlugin extends JavaPlugin {
* @param message * @param message
*/ */
private void log(Level l, String message) { private void log(Level l, String message) {
if(l != null) { if(l != null && message != null) {
logToChat(l, message); logToChat(l, message);
logToIRC(l, message); logToIRC(l, message);
logToConsole(l, message); logToConsole(l, message);
@ -280,12 +296,12 @@ public class NoCheatPlugin extends JavaPlugin {
return false; return false;
} }
try { try {
if(permissions != null && permissions.has(player, permission)) if(permissions != null && permissions.has(player, permission))
return true; return true;
else if(permissions == null && player.isOp()) else if(permissions == null && player.isOp())
return true; return true;
else else
return false; return false;
} }
catch(Throwable e) { catch(Throwable e) {
log(Level.SEVERE, "Asking Permissions-Plugin if "+player.getName()+" has permission "+permission+" caused the Exception: "+e.toString() + " . Full error message recorded to log-file"); log(Level.SEVERE, "Asking Permissions-Plugin if "+player.getName()+" has permission "+permission+" caused the Exception: "+e.toString() + " . Full error message recorded to log-file");

View File

@ -55,16 +55,16 @@ public class AirbuildCheck extends Check {
data.airbuildPerSecond++; data.airbuildPerSecond++;
boolean log = false;
// which limit has been reached // which limit has been reached
for(int i = limits.length-1; i >= 0; i--) { for(int i = limits.length-1; i >= 0; i--) {
if(data.airbuildPerSecond >= limits[i]) { if(data.airbuildPerSecond >= limits[i]) {
// Only explicitly log certain "milestones" // Only explicitly log certain "milestones"
if(data.airbuildPerSecond == limits[i]) { if(data.airbuildPerSecond == limits[i]) {
log = true; action(actions[i], event, true);
}
else {
action(actions[i], event, false);
} }
action(actions[i], event, log);
break; break;
} }
} }

View File

@ -2,7 +2,11 @@ package cc.co.evenprime.bukkit.nocheat.checks;
import cc.co.evenprime.bukkit.nocheat.NoCheatPlugin; import cc.co.evenprime.bukkit.nocheat.NoCheatPlugin;
/**
*
* @author Evenprime
*
*/
public abstract class Check { public abstract class Check {
public Check(NoCheatPlugin plugin) { public Check(NoCheatPlugin plugin) {

View File

@ -30,12 +30,14 @@ public class MovingCheck extends Check {
private final double jumpHeight = 1.3D; private final double jumpHeight = 1.3D;
// How high may a player move in one event on ground // How high may a player move in one event on ground
private double stepHeight = 0.501D; private final double stepHeight = 0.501D;
// Limits // Limits
public final double moveLimits[] = { 0.0D, 0.5D, 2.0D }; public final double moveLimits[] = { 0.0D, 0.5D, 2.0D };
public final double heightLimits[] = { 0.0D, 0.5D, 2.0D }; public final double heightLimits[] = { 0.0D, 0.5D, 2.0D };
public int ticksBeforeSummary = 100;
// How should moving violations be treated? // How should moving violations be treated?
public final String actions[] = { "loglow reset", "logmed reset", "loghigh reset" }; public final String actions[] = { "loglow reset", "logmed reset", "loghigh reset" };
@ -149,13 +151,13 @@ public class MovingCheck extends Check {
return; return;
// Get the player-specific data // Get the player-specific data
NoCheatData data = plugin.getPlayerData(event.getPlayer()); final NoCheatData data = plugin.getPlayerData(event.getPlayer());
// Get the two locations of the event // Get the two locations of the event
Location to = event.getTo(); final Location to = event.getTo();
// WORKAROUND for changed PLAYER_MOVE logic // WORKAROUND for changed PLAYER_MOVE logic
Location from = data.movingTeleportTo == null ? event.getFrom() : data.movingTeleportTo; final Location from = data.movingTeleportTo == null ? event.getFrom() : data.movingTeleportTo;
data.movingTeleportTo = null; data.movingTeleportTo = null;
// Notice to myself: How world changes with e.g. command /world work: // Notice to myself: How world changes with e.g. command /world work:
@ -206,7 +208,6 @@ public class MovingCheck extends Check {
// First check the distance the player has moved horizontally // First check the distance the player has moved horizontally
// TODO: Make this check much more precise
double xDistance = from.getX()-to.getX(); double xDistance = from.getX()-to.getX();
double zDistance = from.getZ()-to.getZ(); double zDistance = from.getZ()-to.getZ();
double combined = Math.sqrt((xDistance*xDistance + zDistance*zDistance)) - 0.6D ; double combined = Math.sqrt((xDistance*xDistance + zDistance*zDistance)) - 0.6D ;
@ -246,8 +247,8 @@ public class MovingCheck extends Check {
int toValues[] = {lowerBorder(to.getX()), upperBorder(to.getX()), (int)Math.floor(to.getY()+0.5D), lowerBorder(to.getZ()), upperBorder(to.getZ()) }; int toValues[] = {lowerBorder(to.getX()), upperBorder(to.getX()), (int)Math.floor(to.getY()+0.5D), 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); final boolean onGroundFrom = playerIsOnGround(from.getWorld(), fromValues, from);
boolean onGroundTo = playerIsOnGround(to.getWorld(), toValues, to); final boolean onGroundTo = playerIsOnGround(to.getWorld(), toValues, to);
// Ignore events if the player has positive y-Velocity // Ignore events if the player has positive y-Velocity
if(event.getPlayer().getVelocity().getY() > 0.0D) { if(event.getPlayer().getVelocity().getY() > 0.0D) {
@ -326,21 +327,18 @@ public class MovingCheck extends Check {
if(vl < 0) { if(vl < 0) {
data.movingJumpPhase++; // Enter next phase of the flight data.movingJumpPhase++; // Enter next phase of the flight
// Setback point stays the same. IF we don't have one, take the "from" location as a setback point for now // Setback point stays the same. If we don't have one, take the "from" location as a setback point for now
if(data.movingSetBackPoint == null) { if(data.movingSetBackPoint == null) {
data.movingSetBackPoint = from.clone(); data.movingSetBackPoint = from.clone();
} }
} }
} }
if(vl < 0 && (onGroundFrom || onGroundTo) && data.legitMoves < 100) { if(vl >= 0) {
data.legitMoves++;
}
else if(vl >= 0) {
final Player p = event.getPlayer(); final Player p = event.getPlayer();
final NoCheatData d = data; final NoCheatData d = data;
// Setup task to display summary later
if(data.movingRunnable == null) { if(data.movingRunnable == null) {
data.movingRunnable = new Runnable() { data.movingRunnable = new Runnable() {
@ -352,8 +350,8 @@ public class MovingCheck extends Check {
} }
}; };
// Give a summary in 100 ticks ~ 5 second // Give a summary in x ticks. 20 ticks ~ 1 second
plugin.getServer().getScheduler().scheduleAsyncDelayedTask(plugin, data.movingRunnable, 100); plugin.getServer().getScheduler().scheduleAsyncDelayedTask(plugin, data.movingRunnable, ticksBeforeSummary);
} }
// If we haven't already got a setback point, make this location the new setback point // If we haven't already got a setback point, make this location the new setback point
@ -386,8 +384,8 @@ public class MovingCheck extends Check {
if(!event.isCancelled()) { if(!event.isCancelled()) {
// If it wasn't our plugin that ordered the teleport, forget (almost) all our information and start from scratch // If it wasn't our plugin that ordered the teleport, forget (almost) all our information and start from scratch
// Setback points are created automatically the next time a move event is handled // Setback points are created automatically the next time a move event is handled
data.speedhackSetBackPoint = event.getTo(); data.speedhackSetBackPoint = event.getTo().clone();
data.movingSetBackPoint = event.getTo(); data.movingSetBackPoint = event.getTo().clone();
data.speedhackEventsSinceLastCheck = 0; data.speedhackEventsSinceLastCheck = 0;
data.movingJumpPhase = 0; data.movingJumpPhase = 0;
} }
@ -479,7 +477,7 @@ public class MovingCheck extends Check {
event.setCancelled(true); event.setCancelled(true);
} }
else { else {
// Lets try it that way. Maybe now people don't "disappear" any longer // If we don't have a setback point, we'll have to use the from location
event.setFrom(from.clone()); event.setFrom(from.clone());
event.setTo(from.clone()); event.setTo(from.clone());
event.getPlayer().teleport(from.clone()); event.getPlayer().teleport(from.clone());

View File

@ -5,6 +5,11 @@ import org.bukkit.event.player.PlayerTeleportEvent;
import cc.co.evenprime.bukkit.nocheat.checks.BedteleportCheck; import cc.co.evenprime.bukkit.nocheat.checks.BedteleportCheck;
/**
*
* @author Evenprime
*
*/
public class BedteleportListener extends PlayerListener { public class BedteleportListener extends PlayerListener {
private BedteleportCheck check; private BedteleportCheck check;

View File

@ -7,7 +7,7 @@ import org.bukkit.event.player.PlayerMoveEvent;
import cc.co.evenprime.bukkit.nocheat.checks.MovingCheck; import cc.co.evenprime.bukkit.nocheat.checks.MovingCheck;
/** /**
* Handle events for all Player related events * Handle events for Player related events
* *
* @author Evenprime * @author Evenprime
*/ */

View File

@ -5,6 +5,11 @@ import org.bukkit.event.player.PlayerTeleportEvent;
import cc.co.evenprime.bukkit.nocheat.checks.MovingCheck; import cc.co.evenprime.bukkit.nocheat.checks.MovingCheck;
/**
*
* @author Evenprime
*
*/
public class MovingMonitor extends PlayerListener { public class MovingMonitor extends PlayerListener {
private MovingCheck check; private MovingCheck check;

View File

@ -5,6 +5,11 @@ import org.bukkit.event.player.PlayerMoveEvent;
import cc.co.evenprime.bukkit.nocheat.checks.SpeedhackCheck; import cc.co.evenprime.bukkit.nocheat.checks.SpeedhackCheck;
/**
*
* @author Evenprime
*
*/
public class SpeedhackListener extends PlayerListener { public class SpeedhackListener extends PlayerListener {
private SpeedhackCheck check; private SpeedhackCheck check;