From 2079e0ea66e562dfd5237bb33bb4e916d634c5a1 Mon Sep 17 00:00:00 2001 From: Steven Lawson Date: Sun, 21 Jul 2013 22:48:34 -0400 Subject: [PATCH] Added event handling for command block changes. Recoded TFM_CommandBlocker as TFM_CommandBlockerNew, will replace after evaulation. --- appinfo.properties | 6 +- buildnumber.properties | 4 +- .../Listener/TFM_PlayerListener.java | 24 +- .../Listener/TFM_ServerListener.java | 184 ++++++++++ .../TFM_CommandBlockerNew.java | 330 ++++++++++++++++++ .../TotalFreedomMod/TotalFreedomMod.java | 3 + 6 files changed, 524 insertions(+), 27 deletions(-) create mode 100644 src/me/StevenLawson/TotalFreedomMod/Listener/TFM_ServerListener.java create mode 100644 src/me/StevenLawson/TotalFreedomMod/TFM_CommandBlockerNew.java diff --git a/appinfo.properties b/appinfo.properties index d9a2cfbd..7b5eacee 100644 --- a/appinfo.properties +++ b/appinfo.properties @@ -1,6 +1,6 @@ -#Sat, 20 Jul 2013 19:28:30 -0400 +#Sun, 21 Jul 2013 22:39:51 -0400 program.VERSION=2.21 -program.BUILDNUM=320 -program.BUILDDATE=07/20/2013 07\:28 PM +program.BUILDNUM=329 +program.BUILDDATE=07/21/2013 10\:39 PM diff --git a/buildnumber.properties b/buildnumber.properties index 719dde51..64033172 100644 --- a/buildnumber.properties +++ b/buildnumber.properties @@ -1,3 +1,3 @@ #Build Number for ANT. Do not edit! -#Sat Jul 20 19:28:30 EDT 2013 -build.number=321 +#Sun Jul 21 22:39:51 EDT 2013 +build.number=330 diff --git a/src/me/StevenLawson/TotalFreedomMod/Listener/TFM_PlayerListener.java b/src/me/StevenLawson/TotalFreedomMod/Listener/TFM_PlayerListener.java index 1b1f90f6..96f8c0b6 100644 --- a/src/me/StevenLawson/TotalFreedomMod/Listener/TFM_PlayerListener.java +++ b/src/me/StevenLawson/TotalFreedomMod/Listener/TFM_PlayerListener.java @@ -6,7 +6,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map.Entry; import java.util.regex.Pattern; -import me.StevenLawson.TotalFreedomMod.TFM_CommandBlocker; +import me.StevenLawson.TotalFreedomMod.TFM_CommandBlockerNew; import me.StevenLawson.TotalFreedomMod.TFM_LandmineData; import me.StevenLawson.TotalFreedomMod.TFM_Log; import me.StevenLawson.TotalFreedomMod.TFM_PlayerData; @@ -39,8 +39,6 @@ import org.bukkit.event.player.PlayerKickEvent; import org.bukkit.event.player.PlayerLoginEvent; import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerQuitEvent; -import org.bukkit.event.server.RemoteServerCommandEvent; -import org.bukkit.event.server.ServerCommandEvent; import org.bukkit.event.server.ServerListPingEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.util.Vector; @@ -523,7 +521,7 @@ public class TFM_PlayerListener implements Listener command = command.toLowerCase().trim(); // Blocked commands - if (TFM_CommandBlocker.isCommandBlocked(command, event.getPlayer())) + if (TFM_CommandBlockerNew.getInstance().isCommandBlocked(command, event.getPlayer())) { // CommandBlocker handles messages and broadcasts event.setCancelled(true); @@ -541,24 +539,6 @@ public class TFM_PlayerListener implements Listener } } - @EventHandler(priority = EventPriority.NORMAL) - public void onRemoteServerCommand(RemoteServerCommandEvent event) - { - if (TFM_CommandBlocker.isCommandBlocked("/" + event.getCommand(), event.getSender())) - { - event.setCommand(""); - } - } - - @EventHandler(priority = EventPriority.NORMAL) - public void onServerCommand(ServerCommandEvent event) - { - if (TFM_CommandBlocker.isCommandBlocked("/" + event.getCommand(), event.getSender())) - { - event.setCommand(""); - } - } - @EventHandler(priority = EventPriority.NORMAL) public void onPlayerDropItem(PlayerDropItemEvent event) { diff --git a/src/me/StevenLawson/TotalFreedomMod/Listener/TFM_ServerListener.java b/src/me/StevenLawson/TotalFreedomMod/Listener/TFM_ServerListener.java new file mode 100644 index 00000000..4c63537b --- /dev/null +++ b/src/me/StevenLawson/TotalFreedomMod/Listener/TFM_ServerListener.java @@ -0,0 +1,184 @@ +package me.StevenLawson.TotalFreedomMod.Listener; + +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import me.StevenLawson.TotalFreedomMod.TFM_CommandBlockerNew; +import me.StevenLawson.TotalFreedomMod.TFM_SuperadminList; +import org.bukkit.ChatColor; +import org.bukkit.Server; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.server.CommandBlockSetEvent; +import org.bukkit.event.server.RemoteServerCommandEvent; +import org.bukkit.event.server.ServerCommandEvent; +import org.bukkit.permissions.Permission; +import org.bukkit.permissions.PermissionAttachment; +import org.bukkit.permissions.PermissionAttachmentInfo; +import org.bukkit.plugin.Plugin; + +public class TFM_ServerListener implements Listener +{ + // CommandBlockSetEvent does not exist in "vanilla" Bukkit/CraftBukkit. + // Comment this method out if you want to compile this without a custom CraftBukkit. + // Just make sure that enable-command-block=false in server.properties. + // -Madgeek + @EventHandler(priority = EventPriority.NORMAL) + public void onCommandBlockSet(CommandBlockSetEvent event) + { + Player player = event.getPlayer(); + String newCommandRaw = event.getNewCommand(); + + if (!TFM_SuperadminList.isSeniorAdmin(player, true)) + { + player.sendMessage(ChatColor.GRAY + "Only senior admins may set command block commands."); + event.setCancelled(true); + return; + } + + Matcher matcher = Pattern.compile("^/?(\\S+)").matcher(newCommandRaw); + if (matcher.find()) + { + String topLevelCommand = matcher.group(1); + if (topLevelCommand != null) + { + topLevelCommand = topLevelCommand.toLowerCase().trim(); + + //We need to make it look like the command is coming from the console, so keep the player's name without the Player instance via dummy: + if (TFM_CommandBlockerNew.getInstance().isCommandBlocked(topLevelCommand, new TFM_ServerListener_DummyCommandSender(player.getName()), false)) + { + player.sendMessage(ChatColor.GRAY + "That command is blocked."); + event.setCancelled(true); + } + } + } + } + + @EventHandler(priority = EventPriority.NORMAL) + public void onRemoteServerCommand(RemoteServerCommandEvent event) + { + if (TFM_CommandBlockerNew.getInstance().isCommandBlocked(event.getCommand(), event.getSender())) + { + event.setCommand(""); + } + } + + @EventHandler(priority = EventPriority.NORMAL) + public void onServerCommand(ServerCommandEvent event) + { + if (TFM_CommandBlockerNew.getInstance().isCommandBlocked(event.getCommand(), event.getSender())) + { + event.setCommand(""); + } + } + + private static class TFM_ServerListener_DummyCommandSender implements CommandSender + { + private final String senderName; + + public TFM_ServerListener_DummyCommandSender(String senderName) + { + this.senderName = senderName; + } + + @Override + public void sendMessage(String message) + { + } + + @Override + public void sendMessage(String[] messages) + { + } + + @Override + public Server getServer() + { + return null; + } + + @Override + public String getName() + { + return senderName; + } + + @Override + public boolean isPermissionSet(String name) + { + return true; + } + + @Override + public boolean isPermissionSet(Permission perm) + { + return true; + } + + @Override + public boolean hasPermission(String name) + { + return true; + } + + @Override + public boolean hasPermission(Permission perm) + { + return true; + } + + @Override + public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value) + { + return null; + } + + @Override + public PermissionAttachment addAttachment(Plugin plugin) + { + return null; + } + + @Override + public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value, int ticks) + { + return null; + } + + @Override + public PermissionAttachment addAttachment(Plugin plugin, int ticks) + { + return null; + } + + @Override + public void removeAttachment(PermissionAttachment attachment) + { + } + + @Override + public void recalculatePermissions() + { + } + + @Override + public Set getEffectivePermissions() + { + return null; + } + + @Override + public boolean isOp() + { + return true; + } + + @Override + public void setOp(boolean value) + { + } + } +} diff --git a/src/me/StevenLawson/TotalFreedomMod/TFM_CommandBlockerNew.java b/src/me/StevenLawson/TotalFreedomMod/TFM_CommandBlockerNew.java new file mode 100644 index 00000000..12c177eb --- /dev/null +++ b/src/me/StevenLawson/TotalFreedomMod/TFM_CommandBlockerNew.java @@ -0,0 +1,330 @@ +package me.StevenLawson.TotalFreedomMod; + +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import me.StevenLawson.TotalFreedomMod.Commands.TFM_CommandLoader; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandMap; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class TFM_CommandBlockerNew +{ + private Map blockedCommands = new HashMap(); + + private TFM_CommandBlockerNew() + { + parseBlockingRules(); + } + + public final void parseBlockingRules() + { + blockedCommands.clear(); + + CommandMap commandMap = TFM_CommandLoader.getInstance().getCommandMap(); + if (commandMap == null) + { + TFM_Log.severe("Error loading commandMap."); + return; + } + + for (String rawEntry : TotalFreedomMod.blockedCommands) + { + String[] parts = rawEntry.split(":"); + if (parts.length < 3 || parts.length > 4) + { + continue; + } + + CommandBlockerRank rank = CommandBlockerRank.fromToken(parts[0]); + if (rank == null) + { + continue; + } + + CommandBlockerAction action = CommandBlockerAction.fromToken(parts[1]); + if (action == null) + { + continue; + } + + String command = parts[2]; + if (command == null || command.isEmpty()) + { + continue; + } + Matcher matcher = Pattern.compile("^/?(\\S+)").matcher(command); + if (matcher.find()) + { + command = matcher.group(1); + if (command == null) + { + continue; + } + else + { + command = command.toLowerCase().trim(); + } + } + else + { + continue; + } + + String message = null; + if (parts.length == 4) + { + message = parts[3]; + } + + TFM_CommandBlocker_BlockedCommandEntry blockedCommandEntry = new TFM_CommandBlocker_BlockedCommandEntry(rank, action, command, message); + + Command bukkitCommand = commandMap.getCommand(command); + if (bukkitCommand == null) + { + //TFM_Log.info("Blocking unknown command: " + blockedCommandEntry.getCommand()); + blockedCommands.put(blockedCommandEntry.getCommand(), blockedCommandEntry); + } + else + { + blockedCommandEntry.setCommand(bukkitCommand.getName().toLowerCase()); + + //TFM_Log.info("Blocking command: " + blockedCommandEntry.getCommand()); + blockedCommands.put(blockedCommandEntry.getCommand(), blockedCommandEntry); + + for (String alias : bukkitCommand.getAliases()) + { + //TFM_Log.info("Blocking alias: " + alias.toLowerCase() + " of " + blockedCommandEntry.getCommand()); + blockedCommands.put(alias.toLowerCase(), blockedCommandEntry); + } + } + } + } + + public boolean isCommandBlocked(String command, CommandSender sender) + { + return isCommandBlocked(command, sender, true); + } + + public boolean isCommandBlocked(String command, CommandSender sender, boolean doAction) + { + if (command == null || command.isEmpty()) + { + return false; + } + + Matcher matcher = Pattern.compile("^/?(\\S+)").matcher(command); + if (matcher.find()) + { + command = matcher.group(1); + if (command == null) + { + return false; + } + else + { + command = command.toLowerCase().trim(); + } + } + else + { + return false; + } + + TFM_CommandBlocker_BlockedCommandEntry blockedCommandEntry = blockedCommands.get(command); + + if (blockedCommandEntry != null) + { + if (!blockedCommandEntry.getRank().hasPermission(sender)) + { + if (doAction) + { + doBlockedCommandAction(sender, blockedCommandEntry); + } + + return true; + } + } + + return false; + } + + private void doBlockedCommandAction(CommandSender sender, TFM_CommandBlocker_BlockedCommandEntry blockedCommandEntry) + { + CommandBlockerAction action = blockedCommandEntry.getAction(); + + if (action == CommandBlockerAction.BLOCK_AND_EJECT && sender instanceof Player) + { + TFM_Util.autoEject((Player) sender, "You used a prohibited command: " + blockedCommandEntry.getCommand()); + TFM_Util.bcastMsg(sender.getName() + " was automatically kicked for using harmful commands.", ChatColor.RED); + } + else + { + String message = blockedCommandEntry.getMessage(); + + if (action == CommandBlockerAction.BLOCK_UNKNOWN) + { + message = "Unknown command. Type \"help\" for help."; + } + else if (message == null || "_".equals(message)) + { + message = ChatColor.GRAY + "That command is blocked."; + } + else + { + message = ChatColor.GRAY + ChatColor.translateAlternateColorCodes('&', message); + } + + sender.sendMessage(message); + } + } + + private static enum CommandBlockerRank + { + ANYONE("a", 0), + OP("o", 1), + SUPER("s", 2), + TELNET("t", 3), + SENIOR("c", 4), + NOBODY("n", 5); + private final String token; + private final int level; + + private CommandBlockerRank(String token, int level) + { + this.token = token; + this.level = level; + } + + public String getToken() + { + return token; + } + + public boolean hasPermission(CommandSender sender) + { + return getSenderRank(sender).level >= this.level; + } + + public static CommandBlockerRank getSenderRank(CommandSender sender) + { + if (!TFM_SuperadminList.isUserSuperadmin(sender)) + { + if (sender.isOp()) + { + return OP; + } + + return ANYONE; + } + else + { + if (TFM_SuperadminList.isSeniorAdmin(sender)) + { + return SENIOR; + } + + if (!(sender instanceof Player)) + { + return TELNET; + } + + return SUPER; + } + } + + public static CommandBlockerRank fromToken(String token) + { + for (CommandBlockerRank rank : CommandBlockerRank.values()) + { + if (rank.getToken().equalsIgnoreCase(token)) + { + return rank; + } + } + return ANYONE; + } + } + + private enum CommandBlockerAction + { + BLOCK("b"), BLOCK_AND_EJECT("a"), BLOCK_UNKNOWN("u"); + private final String token; + + private CommandBlockerAction(String token) + { + this.token = token; + } + + public String getToken() + { + return token; + } + + public static CommandBlockerAction fromToken(String token) + { + for (CommandBlockerAction action : CommandBlockerAction.values()) + { + if (action.getToken().equalsIgnoreCase(token)) + { + return action; + } + } + return null; + } + } + + private static class TFM_CommandBlocker_BlockedCommandEntry + { + private final CommandBlockerRank rank; + private final CommandBlockerAction action; + private String command; + private final String message; + + public TFM_CommandBlocker_BlockedCommandEntry(CommandBlockerRank rank, CommandBlockerAction action, String command, String message) + { + this.rank = rank; + this.action = action; + this.command = command; + this.message = message; + } + + public CommandBlockerAction getAction() + { + return action; + } + + public String getCommand() + { + return command; + } + + public String getMessage() + { + return message; + } + + public CommandBlockerRank getRank() + { + return rank; + } + + public void setCommand(String command) + { + this.command = command; + } + } + + public static TFM_CommandBlockerNew getInstance() + { + return TFM_CommandBlockerNewHolder.INSTANCE; + } + + private static class TFM_CommandBlockerNewHolder + { + private static final TFM_CommandBlockerNew INSTANCE = new TFM_CommandBlockerNew(); + } +} diff --git a/src/me/StevenLawson/TotalFreedomMod/TotalFreedomMod.java b/src/me/StevenLawson/TotalFreedomMod/TotalFreedomMod.java index 56a8e64b..c741b63e 100644 --- a/src/me/StevenLawson/TotalFreedomMod/TotalFreedomMod.java +++ b/src/me/StevenLawson/TotalFreedomMod/TotalFreedomMod.java @@ -9,6 +9,7 @@ import me.StevenLawson.TotalFreedomMod.Commands.TFM_CommandLoader; import me.StevenLawson.TotalFreedomMod.Listener.TFM_BlockListener; import me.StevenLawson.TotalFreedomMod.Listener.TFM_EntityListener; import me.StevenLawson.TotalFreedomMod.Listener.TFM_PlayerListener; +import me.StevenLawson.TotalFreedomMod.Listener.TFM_ServerListener; import me.StevenLawson.TotalFreedomMod.Listener.TFM_WeatherListener; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.exception.ExceptionUtils; @@ -125,6 +126,7 @@ public class TotalFreedomMod extends JavaPlugin public void run() { TFM_CommandLoader.getInstance().scan(); + TFM_CommandBlockerNew.getInstance().parseBlockingRules(); } }, 20L); } @@ -357,6 +359,7 @@ public class TotalFreedomMod extends JavaPlugin pm.registerEvents(new TFM_BlockListener(), plugin); pm.registerEvents(new TFM_PlayerListener(), plugin); pm.registerEvents(new TFM_WeatherListener(), plugin); + pm.registerEvents(new TFM_ServerListener(), plugin); } private static void setAppProperties()