Fixed speedhack check and minor other stuff

This commit is contained in:
Evenprime 2011-05-17 18:12:42 +02:00
parent 1fe7aaa1ae
commit 22d73209a8
9 changed files with 79 additions and 41 deletions

View File

@ -3,7 +3,7 @@ name: NoCheat
author: Evenprime
main: cc.co.evenprime.bukkit.nocheat.NoCheat
version: 1.00a
version: 1.00b
commands:
nocheat:

View File

@ -4,7 +4,6 @@ package cc.co.evenprime.bukkit.nocheat;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
@ -31,7 +30,6 @@ import com.ensifera.animosity.craftirc.CraftIRC;
import com.nijikokun.bukkit.Permissions.Permissions;
import com.nijiko.permissions.PermissionHandler;
import org.bukkit.plugin.Plugin;
import org.bukkit.util.config.Configuration;
/**
*
@ -56,8 +54,8 @@ public class NoCheat extends JavaPlugin implements CommandSender {
private boolean exceptionWithPermissions = false;
private boolean cleanUpTaskSetup = false;
private boolean serverLagMeasureTaskSetup = false;
private int cleanUpTaskId = -1;
private int serverLagMeasureTaskSetup = -1;
private int serverTicks = 0;
private long serverLagInMilliSeconds = 0;
@ -124,6 +122,13 @@ public class NoCheat extends JavaPlugin implements CommandSender {
if(config != null)
config.cleanup();
try {
teardownCleanupTask();
teardownServerLagMeasureTask();
NoCheatData.cancelPlayerDataTasks();
}
catch(Exception e) { /* Can't do much in case of error here... */ }
Logger.getLogger("Minecraft").info( "[NoCheat] version [" + pdfFile.getVersion() + "] is disabled.");
}
@ -142,9 +147,6 @@ public class NoCheat extends JavaPlugin implements CommandSender {
// just for convenience
checks = new Check[] { movingCheck, bedteleportCheck, speedhackCheck, airbuildCheck, itemdupeCheck, bogusitemsCheck };
// parse the nocheat.yml config file
setupConfig();
if(!allowFlightSet && movingCheck.isActive()) {
Logger.getLogger("Minecraft").warning( "[NoCheat] you have set \"allow-flight=false\" in your server.properties file. That builtin anti-flying-mechanism will likely conflict with this plugin. Please consider deactivating it by setting it to \"true\"");
}
@ -164,11 +166,9 @@ public class NoCheat extends JavaPlugin implements CommandSender {
private void setupCleanupTask() {
if(cleanUpTaskSetup) return;
if(cleanUpTaskId != -1) return;
cleanUpTaskSetup = true;
Bukkit.getServer().getScheduler().scheduleAsyncRepeatingTask(this, new Runnable() {
cleanUpTaskId = Bukkit.getServer().getScheduler().scheduleAsyncRepeatingTask(this, new Runnable() {
@Override
public void run() {
@ -176,12 +176,15 @@ public class NoCheat extends JavaPlugin implements CommandSender {
}
}, 5000, 5000);
}
private void teardownCleanupTask() {
if(cleanUpTaskId != -1)
Bukkit.getServer().getScheduler().cancelTask(cleanUpTaskId);
}
private void setupServerLagMeasureTask() {
if(serverLagMeasureTaskSetup) return;
serverLagMeasureTaskSetup = true;
if(serverLagMeasureTaskSetup != -1) return;
Bukkit.getServer().getScheduler().scheduleAsyncRepeatingTask(this, new Runnable() {
@ -194,6 +197,11 @@ public class NoCheat extends JavaPlugin implements CommandSender {
}
}, 10, 10);
}
private void teardownServerLagMeasureTask() {
if(serverLagMeasureTaskSetup == -1)
Bukkit.getServer().getScheduler().cancelTask(serverLagMeasureTaskSetup);
}
/**
* Get, if available, a reference to the Permissions-plugin

View File

@ -4,6 +4,7 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import cc.co.evenprime.bukkit.nocheat.data.AirbuildData;
@ -68,5 +69,30 @@ public class NoCheatData {
}
}
}
/**
* 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 static void cancelPlayerDataTasks() {
synchronized(playerData) {
Iterator<Map.Entry<Player, NoCheatData>> it = playerData.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<Player, NoCheatData> pairs = (Map.Entry<Player, NoCheatData>)it.next();
int id;
id = pairs.getValue().airbuild != null ? pairs.getValue().airbuild.summaryTask : -1;
if(id != -1)
Bukkit.getServer().getScheduler().cancelTask(id);
id = pairs.getValue().moving != null ? pairs.getValue().moving.summaryTask : -1;
if(id != -1)
Bukkit.getServer().getScheduler().cancelTask(id);
}
}
}
}

View File

@ -48,19 +48,19 @@ public class AirbuildCheck extends Check {
final AirbuildData data = AirbuildData.get(event.getPlayer());
final Player p = event.getPlayer();
if(data.summaryTask == null) {
data.summaryTask = new Runnable() {
if(data.summaryTask == -1) {
Runnable r = new Runnable() {
@Override
public void run() {
summary(p, data);
// deleting its own reference
data.summaryTask = null;
data.summaryTask = -1;
}
};
// Give a summary in 100 ticks ~ 1 second
plugin.getServer().getScheduler().scheduleAsyncDelayedTask(plugin, data.summaryTask, 100);
data.summaryTask = plugin.getServer().getScheduler().scheduleAsyncDelayedTask(plugin, r, 100);
}
data.perFiveSeconds++;

View File

@ -355,8 +355,8 @@ public class MovingCheck extends Check {
*/
private void setupSummaryTask(final Player p, final MovingData data) {
// Setup task to display summary later
if(data.summaryTask == null) {
data.summaryTask = new Runnable() {
if(data.summaryTask == -1) {
Runnable r = new Runnable() {
@Override
public void run() {
@ -365,7 +365,7 @@ public class MovingCheck extends Check {
plugin.log(data.highestLogLevel, logString);
}
// deleting its own reference
data.summaryTask = null;
data.summaryTask = -1;
data.violationsInARow[0] = 0;
data.violationsInARow[1] = 0;
@ -374,7 +374,7 @@ public class MovingCheck extends Check {
};
// Give a summary in x ticks. 20 ticks ~ 1 second
plugin.getServer().getScheduler().scheduleAsyncDelayedTask(plugin, data.summaryTask, ticksBeforeSummary);
data.summaryTask = plugin.getServer().getScheduler().scheduleAsyncDelayedTask(plugin, r, ticksBeforeSummary);
}
}

View File

@ -49,6 +49,8 @@ public class SpeedhackCheck extends Check {
// Should we check at all?
if(skipCheck(player)) return;
// Ignore events of players in vehicles (these can be the cause of event spam between server and client)
// Ignore events if the player has positive y-Velocity (these can be the cause of event spam between server and client)
if(player.isInsideVehicle() || player.getVelocity().getY() > 0.0D) {
@ -77,8 +79,6 @@ public class SpeedhackCheck extends Check {
resetData(data, event.getFrom(), ticks);
}
else {
Action action[] = null;
final int low = (limits[0]+1) / 2;
final int med = (limits[1]+1) / 2;
final int high = (limits[2]+1) / 2;
@ -97,7 +97,7 @@ public class SpeedhackCheck extends Check {
if(data.violationsInARowTotal >= violationsLimit) {
data.violationsInARow[level]++;
action(action, event, data.violationsInARow[level], data);
action(actions[level], event, data.violationsInARow[level], data);
}
// Reset value for next check
@ -129,12 +129,12 @@ public class SpeedhackCheck extends Check {
for(Action a : actions) {
if(a.firstAfter <= violations) {
if(a.firstAfter == violations || a.repeat) {
if(a instanceof LogAction) {
String log = String.format(logMessage, event.getPlayer().getName(), data.eventsSinceLastCheck*2, limits[0]);
plugin.log(((LogAction)a).level, log);
}
else if(a instanceof CancelAction) {
if(a instanceof LogAction) {
String log = String.format(logMessage, event.getPlayer().getName(), data.eventsSinceLastCheck*2, limits[0]);
plugin.log(((LogAction)a).level, log);
}
else if(a.firstAfter == violations || a.repeat) {
if(a instanceof CancelAction) {
resetPlayer(event, data);
}
else if(a instanceof CustomAction) {

View File

@ -14,6 +14,7 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import cc.co.evenprime.bukkit.nocheat.ConfigurationException;
import cc.co.evenprime.bukkit.nocheat.LogFileFormatter;
import cc.co.evenprime.bukkit.nocheat.actions.Action;
import cc.co.evenprime.bukkit.nocheat.actions.CancelAction;
import cc.co.evenprime.bukkit.nocheat.actions.LogAction;
@ -113,7 +114,8 @@ public class NoCheatConfiguration {
root.add(speedhackNode);
speedhackNode.add(new LongStringOption("logmessage",
SimpleYaml.getString("logging.filename", "%1$s sent %2$d move events, but only %3$d were allowed. Speedhack?", yamlContent)));
SimpleYaml.getString("speedhack.logmessage", "[player] sent [events] move events, but only [limit] were allowed. Speedhack?", yamlContent).
replace("[player]", "%1$s").replace("[events]", "%2$d").replace("[limit]", "%3$d")));
/*** SPEEDHACK LIMITS section ***/
{
@ -121,11 +123,11 @@ public class NoCheatConfiguration {
speedhackNode.add(speedhackLimitsNode);
speedhackLimitsNode.add(new IntegerOption("low",
SimpleYaml.getInt("speedhack.limits.low", 30, yamlContent)));
SimpleYaml.getInt("speedhack.limits.low", 22, yamlContent)));
speedhackLimitsNode.add(new IntegerOption("med",
SimpleYaml.getInt("speedhack.limits.med", 45, yamlContent)));
SimpleYaml.getInt("speedhack.limits.med", 33, yamlContent)));
speedhackLimitsNode.add(new IntegerOption("high",
SimpleYaml.getInt("speedhack.limits.high", 60, yamlContent)));
SimpleYaml.getInt("speedhack.limits.high", 44, yamlContent)));
}
/*** SPEEDHACK ACTIONS section ***/
@ -148,9 +150,11 @@ public class NoCheatConfiguration {
root.add(movingNode);
movingNode.add(new LongStringOption("logmessage",
SimpleYaml.getString("moving.logmessage", "Moving violation: %1$s from %2$s (%4$.1f, %5$.1f, %6$.1f) to %3$s (%7$.1f, %8$.1f, %9$.1f)", yamlContent)));
SimpleYaml.getString("moving.logmessage", "Moving violation: [player] from [world] [from] to [to]", yamlContent).
replace("[player]", "%1$s").replace("[world]", "%2$s").replace("[from]", "(%4$.1f, %5$.1f, %6$.1f)").replace("[to]", "(%7$.1f, %8$.1f, %9$.1f)")));
movingNode.add(new LongStringOption("summarymessage",
SimpleYaml.getString("moving.summarymessage", "Moving summary of last ~%2$d seconds: %1$s total Violations: (%3$d,%4$d,%5$d)", yamlContent)));
SimpleYaml.getString("moving.summarymessage", "Moving summary of last ~[timeframe] seconds: [player] total Violations: [violations]", yamlContent).
replace("[timeframe]", "%2$d").replace("[player]", "%1$s").replace("[violations]", "(%3$d,%4$d,%5$d)")));
movingNode.add(new BooleanOption("allowflying",
SimpleYaml.getBoolean("moving.allowflying", false, yamlContent)));
movingNode.add(new BooleanOption("allowfakesneak",
@ -250,7 +254,7 @@ public class NoCheatConfiguration {
try {
fh = new FileHandler(getStringValue("logging.filename"), true);
fh.setLevel(getLogLevelValue("logging.logtofile"));
fh.setFormatter(Logger.getLogger("Minecraft").getHandlers()[0].getFormatter());
fh.setFormatter(new LogFileFormatter());
logger.addHandler(fh);
} catch (Exception e) {

View File

@ -6,7 +6,7 @@ import cc.co.evenprime.bukkit.nocheat.NoCheatData;
public class AirbuildData {
public int perFiveSeconds = 0;
public Runnable summaryTask = null;
public int summaryTask = -1;
public static AirbuildData get(Player p) {

View File

@ -15,7 +15,7 @@ public class MovingData {
public double vertFreedom = 0.0D;
public int vertFreedomCounter = 0;
public Location setBackPoint = null;
public Runnable summaryTask = null;
public int summaryTask = -1;
public Level highestLogLevel = null;
public double maxYVelocity = 0.0D;
public int sneakingFreedomCounter = 10;