Experimental "nuke" protection

This commit is contained in:
Evenprime 2011-07-08 20:14:54 +02:00
parent 8729400be5
commit 67c8ca13d1
9 changed files with 210 additions and 6 deletions

View File

@ -3,7 +3,7 @@ name: NoCheat
author: Evenprime
main: cc.co.evenprime.bukkit.nocheat.NoCheat
version: 1.07c
version: 1.08
softdepend: [ Permissions, CraftIRC ]

View File

@ -19,6 +19,7 @@ import cc.co.evenprime.bukkit.nocheat.actions.CustomAction;
import cc.co.evenprime.bukkit.nocheat.checks.AirbuildCheck;
import cc.co.evenprime.bukkit.nocheat.checks.BogusitemsCheck;
import cc.co.evenprime.bukkit.nocheat.checks.Check;
import cc.co.evenprime.bukkit.nocheat.checks.NukeCheck;
import cc.co.evenprime.bukkit.nocheat.checks.MovingCheck;
import cc.co.evenprime.bukkit.nocheat.checks.SpeedhackCheck;
import cc.co.evenprime.bukkit.nocheat.config.NoCheatConfiguration;
@ -68,6 +69,7 @@ public class NoCheat extends JavaPlugin implements CommandSender {
private Level ircLevel;
private Level consoleLevel;
private String ircTag;
private NukeCheck instantmineCheck;
public NoCheat() {
@ -137,9 +139,10 @@ public class NoCheat extends JavaPlugin implements CommandSender {
speedhackCheck = new SpeedhackCheck(this, config);
airbuildCheck = new AirbuildCheck(this, config);
bogusitemsCheck = new BogusitemsCheck(this, config);
instantmineCheck = new NukeCheck(this, config);
// just for convenience
checks = new Check[] { movingCheck, speedhackCheck, airbuildCheck, bogusitemsCheck };
checks = new Check[] { movingCheck, speedhackCheck, airbuildCheck, bogusitemsCheck, instantmineCheck };
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\"");

View File

@ -8,6 +8,7 @@ import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import cc.co.evenprime.bukkit.nocheat.data.AirbuildData;
import cc.co.evenprime.bukkit.nocheat.data.NukeData;
import cc.co.evenprime.bukkit.nocheat.data.MovingData;
import cc.co.evenprime.bukkit.nocheat.data.PermissionData;
import cc.co.evenprime.bukkit.nocheat.data.SpeedhackData;
@ -28,6 +29,7 @@ public class NoCheatData {
public AirbuildData airbuild;
public PermissionData permission;
public NukeData nuke;

View File

@ -0,0 +1,119 @@
package cc.co.evenprime.bukkit.nocheat.checks;
import java.util.Locale;
import java.util.logging.Level;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.event.Event;
import org.bukkit.event.Listener;
import org.bukkit.event.Event.Priority;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockDamageEvent;
import org.bukkit.plugin.PluginManager;
import org.bukkit.util.Vector;
import cc.co.evenprime.bukkit.nocheat.ConfigurationException;
import cc.co.evenprime.bukkit.nocheat.NoCheat;
import cc.co.evenprime.bukkit.nocheat.config.NoCheatConfiguration;
import cc.co.evenprime.bukkit.nocheat.data.NukeData;
import cc.co.evenprime.bukkit.nocheat.data.PermissionData;
import cc.co.evenprime.bukkit.nocheat.listeners.NukeBlockListener;
public class NukeCheck extends Check {
private String kickMessage;
private String logMessage;
public NukeCheck(NoCheat plugin, NoCheatConfiguration config) {
super(plugin, "nuke", PermissionData.PERMISSION_NUKE, config);
}
@Override
protected void configure(NoCheatConfiguration config) {
try {
kickMessage = config.getStringValue("nuke.kickmessage");
logMessage = config.getStringValue("nuke.logmessage").
replace("[player]", "%1$s");
setActive(config.getBooleanValue("active.nuke"));
} catch (ConfigurationException e) {
setActive(false);
e.printStackTrace();
}
}
public void check(BlockBreakEvent event) {
if(skipCheck(event.getPlayer())) {
return;
}
NukeData data = NukeData.get(event.getPlayer());
Block block = event.getBlock();
Location eyes = event.getPlayer().getEyeLocation();
Vector direction = eyes.getDirection();
double x1 = (double)block.getX() - eyes.getX();
double y1 = (double)block.getY() - eyes.getY();
double z1 = (double)block.getZ() - eyes.getZ();
double x2 = x1 + 1;
double y2 = y1 + 1;
double z2 = z1 + 1;
double factor = 1 + direction.distance(new Vector(x1 + 0.5, y1 + 0.5, z1 + 0.5));
double errorMargin = 1.2 / factor;
if(factor * direction.getX() >= x1 - errorMargin && factor * direction.getY() >= y1 - errorMargin && factor * direction.getZ() >= z1 - errorMargin &&
factor * direction.getX() <= x2 + errorMargin && factor * direction.getY() <= y2 + errorMargin && factor * direction.getZ() <= z2 + errorMargin) {
if(data.counter > 0) {
data.counter--;
}
}
else {
data.counter++;
event.setCancelled(true);
if(data.counter > 20) {
String log = String.format(Locale.US, logMessage, event.getPlayer().getName());
plugin.log(Level.SEVERE, log);
event.getPlayer().kickPlayer(kickMessage);
data.counter = 0; // Reset to prevent problems on next login
}
}
}
public void check(BlockDamageEvent event) {
}
@Override
protected void registerListeners() {
PluginManager pm = Bukkit.getServer().getPluginManager();
Listener blockListener = new NukeBlockListener(this);
// Register listeners for moving check
pm.registerEvent(Event.Type.BLOCK_BREAK, blockListener, Priority.Lowest, plugin);
pm.registerEvent(Event.Type.BLOCK_DAMAGE, blockListener, Priority.Monitor, plugin);
}
}

View File

@ -104,6 +104,8 @@ public class NoCheatConfiguration {
SimpleYaml.getBoolean("active.airbuild", false, yamlContent)));
activeNode.add(new BooleanOption("bogusitems",
SimpleYaml.getBoolean("active.bogusitems", false, yamlContent)));
activeNode.add(new BooleanOption("nuke",
SimpleYaml.getBoolean("active.nuke", false, yamlContent)));
}
/*** SPEEDHACK section ***/
@ -230,6 +232,21 @@ public class NoCheatConfiguration {
SimpleYaml.getBoolean("bogusitems.checkops", false, yamlContent)));
}
/*** NUKE section ***/
{
ParentOption nukeNode = new ParentOption("nuke", false);
root.add(nukeNode);
nukeNode.add(new BooleanOption("checkops",
SimpleYaml.getBoolean("nuke.checkops", false, yamlContent)));
nukeNode.add(new LongStringOption("logmessage",
SimpleYaml.getString("nuke.logmessage", "Nuke: [player] tried to nuke the world", yamlContent)));
nukeNode.add(new LongStringOption("kickmessage",
SimpleYaml.getString("nuke.kickmessage", "No nuking allowed", yamlContent)));
}
/*** CUSTOMACTIONS section ***/
{
ParentOption customActionsNode = new ParentOption("customactions", true);

View File

@ -0,0 +1,21 @@
package cc.co.evenprime.bukkit.nocheat.data;
import org.bukkit.entity.Player;
import cc.co.evenprime.bukkit.nocheat.NoCheatData;
public class NukeData {
public int counter = 0;
public static NukeData get(Player p) {
NoCheatData data = NoCheatData.getPlayerData(p);
if(data.nuke == null) {
data.nuke = new NukeData();
}
return data.nuke;
}
}

View File

@ -6,10 +6,10 @@ import cc.co.evenprime.bukkit.nocheat.NoCheatData;
public class PermissionData {
public long lastUpdate[] = new long[10];
public boolean cache[] = new boolean[10];
public long lastUpdate[] = new long[11];
public boolean cache[] = new boolean[11];
public static final String[] permissionNames = new String[10];
public static final String[] permissionNames = new String[11];
public static final int PERMISSION_MOVING = 0;
public static final int PERMISSION_FLYING = 1;
@ -21,6 +21,7 @@ public class PermissionData {
public static final int PERMISSION_ITEMDUPE = 7;
public static final int PERMISSION_FAKESNEAK = 8;
public static final int PERMISSION_FASTSWIM = 9;
public static final int PERMISSION_NUKE = 10;
static {
permissionNames[PERMISSION_AIRBUILD] = "nocheat.airbuild";
@ -33,6 +34,7 @@ public class PermissionData {
permissionNames[PERMISSION_ITEMDUPE] = "nocheat.itemdupe";
permissionNames[PERMISSION_FAKESNEAK] = "nocheat.fakesneak";
permissionNames[PERMISSION_FASTSWIM] = "nocheat.fastswim";
permissionNames[PERMISSION_NUKE] = "nocheat.nuke";
}
public static PermissionData get(Player p) {

View File

@ -0,0 +1,30 @@
package cc.co.evenprime.bukkit.nocheat.listeners;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockDamageEvent;
import org.bukkit.event.block.BlockListener;
import cc.co.evenprime.bukkit.nocheat.checks.NukeCheck;
public class NukeBlockListener extends BlockListener {
private NukeCheck check;
public NukeBlockListener(NukeCheck check) {
this.check = check;
}
@Override
public void onBlockDamage(BlockDamageEvent event) {
//System.out.println("Damage "+ event.getInstaBreak() + " " + event.getItemInHand() + " " + event.getBlock());
check.check(event);
}
@Override
public void onBlockBreak(BlockBreakEvent event) {
//System.out.println("Break "+ event.getPlayer() + " " + event.getBlock());
check.check(event);
}
}

View File

@ -32,6 +32,10 @@ public class Explainations {
"If one of your plugins intentionally produces such bogus items, you should not activate this (or you'll likely lose them).\n" +
"By default OPs are not checked (can be changed in the 'bogusitems' section).\n" +
"(Permissions plugin): Only players that don't have the permission 'nocheat.bogusitems' will be checked.");
set("active.nuke", "If activated, players will no longer be allowed to destroy blocks that are not in front of them.\n" +
"Because this is done by most 'nuke' hack-clients, it is easy to prevent (for now). If a player tries destroying\n" +
"blocks that are outside his field of sight, he'll get kicked from the server.\n" +
"This is only a temporary solution (and will probably not hold for long), but it's better than nothing, I guess...");
set("logging.filename", "Determines where the various messages by NoCheat are stored at, if logging to file is activated.");
set("logging.logtofile", "Determine what severeness messages need to have to be printed to the logfile.\n" +
@ -172,6 +176,12 @@ public class Explainations {
set("bedteleport.checkops", "Also check players with OP-status, unless there is another reason\n" +
"to not check them, e.g. they got the relevant permission from a Permissions plugin.");
set("nuke.logmessage", "The message that appears in your logs if somebody gets kicked for trying to nuke\n" +
"the server map");
set("nuke.kickmessage", "The message that is shown to players that get kicked for nuking");
set("nuke.checkops", "Also check players with OP-status, unless there is another reason\n" +
"to not check them, e.g. they got the relevant permission from a Permissions plugin.");
}
private static void set(String id, String text) {