diff --git a/plugin.yml b/plugin.yml index 3d3c39ea..91408479 100644 --- a/plugin.yml +++ b/plugin.yml @@ -3,7 +3,7 @@ name: NoCheat author: Evenprime main: cc.co.evenprime.bukkit.nocheat.NoCheat -version: 1.07c +version: 1.08 softdepend: [ Permissions, CraftIRC ] diff --git a/src/cc/co/evenprime/bukkit/nocheat/NoCheat.java b/src/cc/co/evenprime/bukkit/nocheat/NoCheat.java index dcdfaa7f..d016214e 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/NoCheat.java +++ b/src/cc/co/evenprime/bukkit/nocheat/NoCheat.java @@ -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\""); diff --git a/src/cc/co/evenprime/bukkit/nocheat/NoCheatData.java b/src/cc/co/evenprime/bukkit/nocheat/NoCheatData.java index b3759619..11262589 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/NoCheatData.java +++ b/src/cc/co/evenprime/bukkit/nocheat/NoCheatData.java @@ -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; diff --git a/src/cc/co/evenprime/bukkit/nocheat/checks/NukeCheck.java b/src/cc/co/evenprime/bukkit/nocheat/checks/NukeCheck.java new file mode 100644 index 00000000..7acc1c84 --- /dev/null +++ b/src/cc/co/evenprime/bukkit/nocheat/checks/NukeCheck.java @@ -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); + + + } + +} diff --git a/src/cc/co/evenprime/bukkit/nocheat/config/NoCheatConfiguration.java b/src/cc/co/evenprime/bukkit/nocheat/config/NoCheatConfiguration.java index a3d49d49..bda5a061 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/config/NoCheatConfiguration.java +++ b/src/cc/co/evenprime/bukkit/nocheat/config/NoCheatConfiguration.java @@ -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 ***/ @@ -229,6 +231,21 @@ public class NoCheatConfiguration { bogusitemsNode.add(new BooleanOption("checkops", 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 ***/ { diff --git a/src/cc/co/evenprime/bukkit/nocheat/data/NukeData.java b/src/cc/co/evenprime/bukkit/nocheat/data/NukeData.java new file mode 100644 index 00000000..77e2d441 --- /dev/null +++ b/src/cc/co/evenprime/bukkit/nocheat/data/NukeData.java @@ -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; + } +} diff --git a/src/cc/co/evenprime/bukkit/nocheat/data/PermissionData.java b/src/cc/co/evenprime/bukkit/nocheat/data/PermissionData.java index 9bc9103e..bed56e6a 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/data/PermissionData.java +++ b/src/cc/co/evenprime/bukkit/nocheat/data/PermissionData.java @@ -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) { diff --git a/src/cc/co/evenprime/bukkit/nocheat/listeners/NukeBlockListener.java b/src/cc/co/evenprime/bukkit/nocheat/listeners/NukeBlockListener.java new file mode 100644 index 00000000..7216ceae --- /dev/null +++ b/src/cc/co/evenprime/bukkit/nocheat/listeners/NukeBlockListener.java @@ -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); + } + +} diff --git a/src/cc/co/evenprime/bukkit/nocheat/wizard/gui/Explainations.java b/src/cc/co/evenprime/bukkit/nocheat/wizard/gui/Explainations.java index c9da7629..ba10054f 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/wizard/gui/Explainations.java +++ b/src/cc/co/evenprime/bukkit/nocheat/wizard/gui/Explainations.java @@ -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) {