diff --git a/src/com/redstoner/misc/Main.java b/src/com/redstoner/misc/Main.java index 6696363..db24596 100644 --- a/src/com/redstoner/misc/Main.java +++ b/src/com/redstoner/misc/Main.java @@ -8,6 +8,7 @@ import com.redstoner.coremods.moduleLoader.ModuleLoader; import com.redstoner.modules.adminchat.Adminchat; import com.redstoner.modules.chatgroups.Chatgroups; import com.redstoner.modules.check.Check; +import com.redstoner.modules.damnspam.DamnSpam; import com.redstoner.modules.imout.Imout; import com.redstoner.modules.lagchunks.LagChunks; import com.redstoner.modules.skullclick.SkullClick; @@ -16,7 +17,7 @@ import com.redstoner.modules.warn.Warn; /** Main class. Duh. * * @author Pepich */ -@Version(major = 1, minor = 1, revision = 4, compatible = -1) +@Version(major = 1, minor = 1, revision = 5, compatible = -1) public class Main extends JavaPlugin { public static JavaPlugin plugin; @@ -31,6 +32,7 @@ public class Main extends JavaPlugin ModuleLoader.addModule(Adminchat.class); ModuleLoader.addModule(Chatgroups.class); ModuleLoader.addModule(Check.class); + ModuleLoader.addModule(DamnSpam.class); ModuleLoader.addModule(Imout.class); ModuleLoader.addModule(LagChunks.class); ModuleLoader.addModule(SkullClick.class); diff --git a/src/com/redstoner/modules/damnspam/DamnSpam.java b/src/com/redstoner/modules/damnspam/DamnSpam.java new file mode 100644 index 0000000..72a7716 --- /dev/null +++ b/src/com/redstoner/modules/damnspam/DamnSpam.java @@ -0,0 +1,388 @@ +package com.redstoner.modules.damnspam; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; + +import com.nemez.cmdmgr.Command; +import com.redstoner.annotations.AutoRegisterListener; +import com.redstoner.annotations.Version; +import com.redstoner.misc.mysql.FolderRegistry; +import com.redstoner.modules.Module; + +@AutoRegisterListener +@Version(major = 1, minor = 0, revision = 0, compatible = 1) +public class DamnSpam implements Module, Listener +{ + private boolean enabled = false; + File configFile; + Map inputs; + boolean changingInput = false; + List acceptedInputs; + HashMap attachedBlocks; + HashMap players; + int maxTimeout = 240; + String timeoutErrorString = "&cThe timeout must be -1 or within 0 and " + maxTimeout; + + @Override + public void onEnable() + { + configFile = new File(FolderRegistry.configFolder, "DamnSpam.json"); + loadInputs(); + acceptedInputs = new ArrayList(); + Collections.addAll(acceptedInputs, Material.WOOD_BUTTON, Material.STONE_BUTTON, Material.LEVER); + attachedBlocks = new HashMap(); + attachedBlocks.put(Material.LEVER, + new int[][] {{0, 7, 8, 15}, {5, 6, 13, 14}, {4, 12}, {3, 11}, {2, 10}, {1, 9}}); + attachedBlocks.put(Material.STONE_BUTTON, + new int[][] {{0, 8}, {5, 6, 7, 13, 14, 15}, {4, 12}, {3, 11}, {2, 10}, {1, 9}}); + attachedBlocks.put(Material.WOOD_BUTTON, + new int[][] {{0, 8}, {5, 6, 7, 13, 14, 15}, {4, 12}, {3, 11}, {2, 10}, {1, 9}}); + players = new HashMap(); + enabled = true; + } + + public void loadInputs() + { + inputs = new HashMap(); + try + { + FileReader reader = new FileReader(configFile); + JSONObject json = (JSONObject) new JSONParser().parse(reader); + for (Object key : json.keySet()) + { + JSONObject inputData = (JSONObject) json.get(key); + String uuid = (String) inputData.get("creator"); + Double timeoutOn = (Double) inputData.get("timeout_on"); + Double timeoutOff = (Double) inputData.get("timeout_off"); + Double lastTime = (Double) inputData.get("last_time"); + inputs.put((String) key, new SpamInput(uuid, timeoutOff, timeoutOn, lastTime)); + } + } + catch (IOException | ParseException e) + { + e.printStackTrace(); + } + } + + @SuppressWarnings("unchecked") + public void saveInputs() + { + JSONObject json = new JSONObject(); + for (String key : inputs.keySet()) + { + JSONObject jsonInput = new JSONObject(); + SpamInput input = inputs.get(key); + jsonInput.put("creator", input.player); + jsonInput.put("timeout_on", input.timeoutOn); + jsonInput.put("timeout_off", input.timeoutOff); + jsonInput.put("last_time", input.lastTime); + json.put(key, jsonInput); + } + try + { + PrintWriter writer = new PrintWriter(configFile); + writer.write(json.toJSONString()); + writer.close(); + } + catch (FileNotFoundException e) + { + e.printStackTrace(); + } + } + + public String locationString(Location loc) + { + return loc.getWorld().getName() + ";" + loc.getBlockX() + ";" + loc.getBlockY() + ";" + loc.getBlockZ(); + } + + public boolean isAcceptableTimeout(double timeout) + { + return (timeout > 0 && timeout <= maxTimeout) || timeout == -1; + } + + public boolean canBuild(Player player, Block block) + { + BlockBreakEvent event = new BlockBreakEvent(block, player); + Bukkit.getPluginManager().callEvent(event); + return !event.isCancelled(); + } + + @Command(hook = "damnspamSingle") + public void damnspam(CommandSender sender, double seconds) + { + boolean destroyingInput = false; + seconds = (double) Math.round(seconds * 100) / 100; + if (seconds == 0) + destroyingInput = true; + else if (!isAcceptableTimeout(seconds)) + { + sender.sendMessage(ChatColor.translateAlternateColorCodes('&', + "&cThe timeout must be -1 or within 0 and " + maxTimeout)); + return; + } + sender.sendMessage( + ChatColor.translateAlternateColorCodes('&', "&aPlease click the input you would like to set.")); + setPlayer((Player) sender, destroyingInput, seconds, seconds); + } + + @Command(hook = "damnspamDouble") + public void damnspam(CommandSender sender, double secondsOff, double secondsOn) + { + boolean destroyingInput = false; + secondsOn = (double) Math.round(secondsOn * 100) / 100; + secondsOff = (double) Math.round(secondsOff * 100) / 100; + if (secondsOn == 0 && secondsOff == 0) + { + destroyingInput = true; + } + else if (!(isAcceptableTimeout(secondsOn) && isAcceptableTimeout(secondsOff))) + { + sender.sendMessage(ChatColor.translateAlternateColorCodes('&', + "&cThe timeout must be -1 or within 0 and " + maxTimeout)); + return; + } + sender.sendMessage( + ChatColor.translateAlternateColorCodes('&', "&aPlease click the input you would like to set.")); + setPlayer((Player) sender, destroyingInput, secondsOff, secondsOn); + } + + public void setPlayer(Player player, boolean destroying, double timeoutOff, double timeoutOn) + { + SpamInput input = null; + if (!destroying) + { + input = new SpamInput(player.getUniqueId().toString(), timeoutOff, timeoutOn, 0); + } + players.put(player, input); + } + + public boolean attemptInputRegister(Player player, Block block, Cancellable event) + { + if (players.containsKey(player)) + { + if (!acceptedInputs.contains(block.getType())) + { + player.sendMessage( + ChatColor.translateAlternateColorCodes('&', "&cThat block is not an acceptable input!")); + return true; + } + String typeStr = block.getType().toString().toLowerCase().replace("_", " "); + String locationStr = locationString(block.getLocation()); + changingInput = true; + boolean buildCheck = canBuild(player, block); + changingInput = false; + if (!buildCheck) + { + player.sendMessage(ChatColor.translateAlternateColorCodes('&', + "&cThere is no timeout to remove on this " + typeStr + "(by setting the timeout to 0)")); + return true; + } + SpamInput input = players.get(player); + if (input == null) + { + if (!inputs.containsKey(locationStr)) + { + player.sendMessage(ChatColor.translateAlternateColorCodes('&', + "&cThere is no timeout to remove on this " + typeStr + "(by setting the timeout to 0)")); + return true; + } + inputs.remove(locationStr); + player.sendMessage(ChatColor.translateAlternateColorCodes('&', + "&aSuccessfully removed the timeout for this " + typeStr)); + } + else + { + inputs.put(locationStr, players.get(player)); + player.sendMessage(ChatColor.translateAlternateColorCodes('&', + "&aSuccessfully set a timeout for this " + typeStr)); + } + players.remove(player); + saveInputs(); + return true; + } + return false; + } + + public void checkBlockBreak(BlockBreakEvent event, Block block) + { + if (!acceptedInputs.contains(block.getType())) + return; + String posStr = locationString(block.getLocation()); + if (!inputs.containsKey(posStr)) + return; + SpamInput input = inputs.get(posStr); + Player sender = event.getPlayer(); + String typeStr = block.getType().toString().toLowerCase().replace("_", " "); + String inputStr = (block.getLocation().equals(event.getBlock()) ? "this " + typeStr + : "the " + typeStr + " attached to that block"); + if (!sender.isSneaking()) + { + sender.sendMessage(ChatColor.translateAlternateColorCodes('&', "&cYou cannot destroy " + inputStr)); + sender.sendMessage(ChatColor.translateAlternateColorCodes('&', + "&c&nSneak&c and break or set the timeout to 0 if you want to remove it.")); + event.setCancelled(true); + return; + } + if (sender.hasPermission("damnspam.admin") || sender.getUniqueId().toString().equals(input.player)) + { + inputs.remove(posStr); + saveInputs(); + sender.sendMessage(ChatColor.translateAlternateColorCodes('&', "&aSuccesfully removed " + inputStr)); + } + else + { + sender.sendMessage( + ChatColor.translateAlternateColorCodes('&', "&cYou are not allowed to remove " + inputStr)); + event.setCancelled(true); + } + } + + @SuppressWarnings("deprecation") + public List getAttachedBlocks(Block block) + { + List blocks = new ArrayList(); + BlockFace[] directions = {BlockFace.DOWN, BlockFace.UP, BlockFace.NORTH, BlockFace.SOUTH, BlockFace.WEST, + BlockFace.EAST}; + for (int i = 0; i < directions.length; i++) + { + Block side = block.getRelative(directions[i]); + int[][] dvalues = attachedBlocks.get(side.getType()); + if (dvalues != null) + { + boolean onSide = false; + for (int val : dvalues[i]) + { + if (side.getData() == (byte) val) + { + onSide = true; + break; + } + } + if (onSide) + blocks.add(side); + } + } + return blocks; + } + + @EventHandler(priority = EventPriority.NORMAL) + public void onBreak(BlockBreakEvent event) + { + if (changingInput || event.isCancelled()) + return; + boolean register = attemptInputRegister(event.getPlayer(), event.getBlock(), event); + if (!register) + { + Block block = event.getBlock(); + checkBlockBreak(event, block); + for (Block affected : getAttachedBlocks(block)) + { + checkBlockBreak(event, affected); + } + } + } + + @SuppressWarnings("deprecation") + @EventHandler(priority = EventPriority.HIGHEST) + public void onInteract(PlayerInteractEvent event) + { + boolean register = attemptInputRegister(event.getPlayer(), event.getClickedBlock(), event); + if (!register && event.getAction().equals(Action.RIGHT_CLICK_BLOCK) && !event.isCancelled()) + { + Player sender = event.getPlayer(); + Block block = event.getClickedBlock(); + String posStr = locationString(block.getLocation()); + SpamInput data = inputs.get(posStr); + if (data != null) + { + String btype = block.getType().toString().toLowerCase().replace("_", " "); + double checktime = 0; + if (btype.equals("lever") && block.getData() < 8) + checktime = data.timeoutOff; + else + checktime = data.timeoutOn; + double timeLeft = (data.lastTime + checktime) + - ((double) Math.round((double) System.currentTimeMillis() / 10) / 100); + timeLeft = (double) Math.round(timeLeft * 100) / 100; + if (checktime == -1) + { + event.setCancelled(true); + sender.sendMessage(ChatColor.translateAlternateColorCodes('&', + "&cThis " + btype + " is locked permanently by /damnspam.")); + } + else if (timeLeft > 0) + { + event.setCancelled(true); + sender.sendMessage(ChatColor.translateAlternateColorCodes('&', "&cThis " + btype + + " has a damnspam timeout of " + checktime + ", with " + timeLeft + " left.")); + } + else + { + data.lastTime = (double) Math.round((double) System.currentTimeMillis() / 10) / 100; + } + inputs.put(posStr, data); + } + } + } + + @Override + public boolean enabled() + { + return enabled; + } + + @Override + public void onDisable() + { + enabled = false; + } + + // @noformat + @Override + public String getCommandString() + { + return "command damnspam {\n" + + " perm utils.damnspam;\n" + + " \n" + + " [double:seconds] {\n" + + " run damnspamSingle seconds;\n" + + " help Set single input cooldown for button or lever.;\n" + + " type player;\n" + + " }\n" + + " \n" + + " [double:secondsOff] [double:secondsOn] {\n" + + " run damnspamDouble secondsOff secondsOn;\n" + + " help Set input cooldown after it's been turned off and turned on (for lever only).;\n" + + " type player;\n" + + " }\n" + + "}"; + } + // @format +} diff --git a/src/com/redstoner/modules/damnspam/SpamInput.java b/src/com/redstoner/modules/damnspam/SpamInput.java new file mode 100644 index 0000000..9735dd9 --- /dev/null +++ b/src/com/redstoner/modules/damnspam/SpamInput.java @@ -0,0 +1,17 @@ +package com.redstoner.modules.damnspam; + +public class SpamInput { + + protected String player; + protected double timeoutOn; + protected double timeoutOff; + protected double lastTime; + + protected SpamInput(String player, double timeoutOff, double timeoutOn, double lastTime) { + this.player = player; + this.timeoutOff = timeoutOff; + this.timeoutOn = timeoutOn; + this.lastTime = lastTime; + } + +}