Added support for blocking subcommands. Resolves #357, Resolves #365 and Resolves #334

This commit is contained in:
JeromSar 2015-01-19 22:51:02 +01:00 committed by Jerom van der Sar
parent e699ad1663
commit af1dd2e9ff
6 changed files with 112 additions and 131 deletions

View File

@ -1,3 +1,3 @@
#Build Number for ANT. Do not edit! #Build Number for ANT. Do not edit!
#Thu Jan 15 15:34:13 CET 2015 #Sun Feb 15 19:11:50 CET 2015
build.number=967 build.number=975

View File

@ -113,18 +113,19 @@ blocked_commands:
- 's:b:/tellraw:_' - 's:b:/tellraw:_'
- 's:b:/forestgen:_' - 's:b:/forestgen:_'
- 's:b:/setidletimeout:_' - 's:b:/setidletimeout:_'
- 's:b:/mail sendall:_'
- 's:b:/eco reset:_'
# Superadmin commands - Auto-eject # Superadmin commands - Auto-eject
- 's:a:/stop' - 's:a:/stop:_'
- 's:a:/reload' - 's:a:/reload:_'
- 's:a:/save-all' - 's:a:/save-all:_'
- 's:a:/save-on' - 's:a:/save-on:_'
- 's:a:/save-off' - 's:a:/save-off:_'
- 's:a:/clearhistory' - 's:a:/clearhistory:_'
- 's:a:/mat'
# Spigot commands # Spigot commands
- 's:a:/restart' - 's:a:/restart:_'
- 's:b:/setblock:_' - 's:b:/setblock:_'
# Automatically wipe dropped objects # Automatically wipe dropped objects

View File

@ -64,7 +64,7 @@ public class Command_tfm extends TFM_Command
TotalFreedomMod.buildDate, TotalFreedomMod.buildDate,
TotalFreedomMod.buildCreator), ChatColor.GOLD); TotalFreedomMod.buildCreator), ChatColor.GOLD);
playerMsg("Running on " + TFM_ConfigEntry.SERVER_NAME.getString() + ".", ChatColor.GOLD); playerMsg("Running on " + TFM_ConfigEntry.SERVER_NAME.getString() + ".", ChatColor.GOLD);
playerMsg("Created by Madgeek1450 and DarthSalamon.", ChatColor.GOLD); playerMsg("Created by Madgeek1450 and Prozza.", ChatColor.GOLD);
playerMsg("Visit " + ChatColor.AQUA + "http://totalfreedom.me/" + ChatColor.GREEN + " for more information.", ChatColor.GREEN); playerMsg("Visit " + ChatColor.AQUA + "http://totalfreedom.me/" + ChatColor.GREEN + " for more information.", ChatColor.GREEN);
return true; return true;

View File

@ -3,10 +3,9 @@ package me.StevenLawson.TotalFreedomMod;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import me.StevenLawson.TotalFreedomMod.Commands.TFM_CommandLoader; import me.StevenLawson.TotalFreedomMod.Commands.TFM_CommandLoader;
import me.StevenLawson.TotalFreedomMod.Config.TFM_ConfigEntry; import me.StevenLawson.TotalFreedomMod.Config.TFM_ConfigEntry;
import org.apache.commons.lang3.StringUtils;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandMap; import org.bukkit.command.CommandMap;
@ -15,12 +14,10 @@ import org.bukkit.entity.Player;
public class TFM_CommandBlocker public class TFM_CommandBlocker
{ {
public static final Pattern COMMAND_PATTERN;
private static final Map<String, CommandBlockerEntry> BLOCKED_COMMANDS; private static final Map<String, CommandBlockerEntry> BLOCKED_COMMANDS;
static static
{ {
COMMAND_PATTERN = Pattern.compile("^/?(\\S+)");
BLOCKED_COMMANDS = new HashMap<String, CommandBlockerEntry>(); BLOCKED_COMMANDS = new HashMap<String, CommandBlockerEntry>();
} }
@ -29,7 +26,7 @@ public class TFM_CommandBlocker
throw new AssertionError(); throw new AssertionError();
} }
public static final void load() public static void load()
{ {
BLOCKED_COMMANDS.clear(); BLOCKED_COMMANDS.clear();
@ -47,68 +44,54 @@ public class TFM_CommandBlocker
final String[] parts = rawEntry.split(":"); final String[] parts = rawEntry.split(":");
if (parts.length < 3 || parts.length > 4) if (parts.length < 3 || parts.length > 4)
{ {
TFM_Log.warning("Invalid command blocker entry: " + rawEntry);
continue; continue;
} }
final CommandBlockerRank rank = CommandBlockerRank.fromToken(parts[0]); final CommandBlockerRank rank = CommandBlockerRank.fromToken(parts[0]);
if (rank == null)
{
continue;
}
final CommandBlockerAction action = CommandBlockerAction.fromToken(parts[1]); final CommandBlockerAction action = CommandBlockerAction.fromToken(parts[1]);
if (action == null) String commandName = parts[2].toLowerCase().substring(1);
final String message = (parts.length > 3 ? parts[3] : null);
if (rank == null || action == null || commandName == null || commandName.isEmpty())
{ {
TFM_Log.warning("Invalid command blocker entry: " + rawEntry);
continue; continue;
} }
String command = parts[2]; final String[] commandParts = commandName.split(" ");
if (command == null || command.isEmpty()) String subCommand = null;
if (commandParts.length > 1)
{ {
continue; commandName = commandParts[0];
subCommand = StringUtils.join(commandParts, " ", 1, commandParts.length).trim().toLowerCase();
} }
final Matcher matcher = COMMAND_PATTERN.matcher(command);
if (matcher.find()) final Command command = commandMap.getCommand(commandName);
// Obtain command from alias
if (command == null)
{ {
command = matcher.group(1); TFM_Log.info("Blocking unknown command: /" + commandName);
if (command == null)
{
continue;
}
else
{
command = command.toLowerCase().trim();
}
} }
else else
{ {
commandName = command.getName().toLowerCase();
}
if (BLOCKED_COMMANDS.containsKey(commandName))
{
TFM_Log.warning("Not blocking: /" + commandName + " - Duplicate entry exists!");
continue; continue;
} }
String message = null; final CommandBlockerEntry blockedCommandEntry = new CommandBlockerEntry(rank, action, commandName, subCommand, message);
if (parts.length == 4) BLOCKED_COMMANDS.put(blockedCommandEntry.getCommand(), blockedCommandEntry);
if (command != null)
{ {
message = parts[3]; for (String alias : command.getAliases())
}
final CommandBlockerEntry blockedCommandEntry = new CommandBlockerEntry(rank, action, command, message);
final Command bukkitCommand = commandMap.getCommand(command);
if (bukkitCommand == null)
{
//TFM_Log.info("Blocking unknown command: " + blockedCommandEntry.getCommand());
BLOCKED_COMMANDS.put(blockedCommandEntry.getCommand(), blockedCommandEntry);
}
else
{
blockedCommandEntry.setCommand(bukkitCommand.getName().toLowerCase());
//TFM_Log.info("Blocking command: " + blockedCommandEntry.getCommand());
BLOCKED_COMMANDS.put(blockedCommandEntry.getCommand(), blockedCommandEntry);
for (String alias : bukkitCommand.getAliases())
{ {
//TFM_Log.info("Blocking alias: " + alias.toLowerCase() + " of " + blockedCommandEntry.getCommand());
BLOCKED_COMMANDS.put(alias.toLowerCase(), blockedCommandEntry); BLOCKED_COMMANDS.put(alias.toLowerCase(), blockedCommandEntry);
} }
} }
@ -129,49 +112,50 @@ public class TFM_CommandBlocker
return false; return false;
} }
final Matcher matcher = COMMAND_PATTERN.matcher(command);
if (matcher.find())
{
command = matcher.group(1);
if (command == null)
{
return false;
}
else
{
command = command.toLowerCase().trim();
}
}
else
{
return false;
}
if (command.contains(":")) if (command.contains(":"))
{ {
TFM_Util.playerMsg(sender, "Plugin-specific commands are disabled."); TFM_Util.playerMsg(sender, "Plugin-specific commands are disabled.");
return true; return true;
} }
final String[] commandParts = command.split(" ");
String subCommand = null;
if (commandParts.length > 1)
{
command = commandParts[0].substring(1);
subCommand = StringUtils.join(commandParts, " ", 1, commandParts.length).toLowerCase();
}
final CommandBlockerEntry entry = BLOCKED_COMMANDS.get(command); final CommandBlockerEntry entry = BLOCKED_COMMANDS.get(command);
if (entry != null) if (entry == null)
{ {
if (!entry.getRank().hasPermission(sender)) return false;
{ }
if (doAction)
{
entry.doActions(sender);
}
return true; if (entry.getSubCommand() != null)
{
if (subCommand == null || !subCommand.startsWith(entry.getSubCommand()))
{
return false;
} }
} }
return false; if (entry.getRank().hasPermission(sender))
{
return false;
}
if (doAction)
{
entry.doActions(sender);
}
return true;
} }
private static enum CommandBlockerRank public static enum CommandBlockerRank
{ {
ANYONE("a", 0), ANYONE("a", 0),
OP("o", 1), OP("o", 1),
@ -179,6 +163,7 @@ public class TFM_CommandBlocker
TELNET("t", 3), TELNET("t", 3),
SENIOR("c", 4), SENIOR("c", 4),
NOBODY("n", 5); NOBODY("n", 5);
//
private final String token; private final String token;
private final int level; private final int level;
@ -195,10 +180,10 @@ public class TFM_CommandBlocker
public boolean hasPermission(CommandSender sender) public boolean hasPermission(CommandSender sender)
{ {
return getSenderRank(sender).level >= this.level; return fromSender(sender).level >= this.level;
} }
public static CommandBlockerRank getSenderRank(CommandSender sender) public static CommandBlockerRank fromSender(CommandSender sender)
{ {
if (!TFM_AdminList.isSuperAdmin(sender)) if (!TFM_AdminList.isSuperAdmin(sender))
{ {
@ -209,20 +194,18 @@ public class TFM_CommandBlocker
return ANYONE; return ANYONE;
} }
else
if (TFM_AdminList.isSeniorAdmin(sender))
{ {
if (TFM_AdminList.isSeniorAdmin(sender)) return SENIOR;
{
return SENIOR;
}
if (!(sender instanceof Player))
{
return TELNET;
}
return SUPER;
} }
if (!(sender instanceof Player))
{
return TELNET;
}
return SUPER;
} }
public static CommandBlockerRank fromToken(String token) public static CommandBlockerRank fromToken(String token)
@ -238,7 +221,7 @@ public class TFM_CommandBlocker
} }
} }
private static enum CommandBlockerAction public static enum CommandBlockerAction
{ {
BLOCK("b"), BLOCK("b"),
BLOCK_AND_EJECT("a"), BLOCK_AND_EJECT("a"),
@ -268,19 +251,26 @@ public class TFM_CommandBlocker
} }
} }
private static class CommandBlockerEntry public static class CommandBlockerEntry
{ {
private final CommandBlockerRank rank; private final CommandBlockerRank rank;
private final CommandBlockerAction action; private final CommandBlockerAction action;
private String command; private final String command;
private final String subCommand;
private final String message; private final String message;
private CommandBlockerEntry(CommandBlockerRank rank, CommandBlockerAction action, String command, String message) private CommandBlockerEntry(CommandBlockerRank rank, CommandBlockerAction action, String command, String message)
{
this(rank, action, command, null, message);
}
private CommandBlockerEntry(CommandBlockerRank rank, CommandBlockerAction action, String command, String subCommand, String message)
{ {
this.rank = rank; this.rank = rank;
this.action = action; this.action = action;
this.command = command; this.command = command;
this.message = message; this.subCommand = (subCommand == null ? null : subCommand.toLowerCase().trim());
this.message = (message == null || message.equals("_") ? "That command is blocked." : message);
} }
public CommandBlockerAction getAction() public CommandBlockerAction getAction()
@ -293,6 +283,11 @@ public class TFM_CommandBlocker
return this.command; return this.command;
} }
public String getSubCommand()
{
return this.subCommand;
}
public String getMessage() public String getMessage()
{ {
return this.message; return this.message;
@ -303,37 +298,22 @@ public class TFM_CommandBlocker
return this.rank; return this.rank;
} }
public void setCommand(String command)
{
this.command = command;
}
private void doActions(CommandSender sender) private void doActions(CommandSender sender)
{ {
if (this.action == CommandBlockerAction.BLOCK_AND_EJECT && sender instanceof Player) if (action == CommandBlockerAction.BLOCK_AND_EJECT && sender instanceof Player)
{ {
TFM_Util.autoEject((Player) sender, "You used a prohibited command: " + this.command); TFM_Util.autoEject((Player) sender, "You used a prohibited command: " + command);
TFM_Util.bcastMsg(sender.getName() + " was automatically kicked for using harmful commands.", ChatColor.RED); TFM_Util.bcastMsg(sender.getName() + " was automatically kicked for using harmful commands.", ChatColor.RED);
return;
} }
else
if (action == CommandBlockerAction.BLOCK_UNKNOWN)
{ {
String response; TFM_Util.playerMsg(sender, "Unknown command. Type \"help\" for help.", ChatColor.RESET);
return;
if (this.action == CommandBlockerAction.BLOCK_UNKNOWN)
{
response = "Unknown command. Type \"help\" for help.";
}
else if (this.message == null || "_".equals(this.message))
{
response = ChatColor.GRAY + "That command is blocked.";
}
else
{
response = ChatColor.GRAY + TFM_Util.colorize(this.message);
}
sender.sendMessage(response);
} }
TFM_Util.playerMsg(sender, TFM_Util.colorize(message));
} }
} }
} }

View File

@ -33,7 +33,7 @@ public class TFM_Log
// Level.WARNING: // Level.WARNING:
public static void warning(String message) public static void warning(String message)
{ {
info(message, false); warning(message, false);
} }
public static void warning(String message, Boolean raw) public static void warning(String message, Boolean raw)
@ -49,7 +49,7 @@ public class TFM_Log
// Level.SEVERE: // Level.SEVERE:
public static void severe(String message) public static void severe(String message)
{ {
info(message, false); severe(message, false);
} }
public static void severe(String message, Boolean raw) public static void severe(String message, Boolean raw)

View File

@ -67,7 +67,7 @@ public class TFM_Util
private static final Map<String, Integer> ejectTracker = new HashMap<String, Integer>(); private static final Map<String, Integer> ejectTracker = new HashMap<String, Integer>();
public static final Map<String, EntityType> mobtypes = new HashMap<String, EntityType>(); public static final Map<String, EntityType> mobtypes = new HashMap<String, EntityType>();
// See https://github.com/TotalFreedom/License - None of the listed names may be removed. // See https://github.com/TotalFreedom/License - None of the listed names may be removed.
public static final List<String> DEVELOPERS = Arrays.asList("Madgeek1450", "DarthSalamon", "AcidicCyanide", "wild1145", "WickedGamingUK"); public static final List<String> DEVELOPERS = Arrays.asList("Madgeek1450", "Prozza", "DarthSalmon", "AcidicCyanide", "Wild1145", "WickedGamingUK");
private static final Random RANDOM = new Random(); private static final Random RANDOM = new Random();
public static String DATE_STORAGE_FORMAT = "EEE, d MMM yyyy HH:mm:ss Z"; public static String DATE_STORAGE_FORMAT = "EEE, d MMM yyyy HH:mm:ss Z";
public static final Map<String, ChatColor> CHAT_COLOR_NAMES = new HashMap<String, ChatColor>(); public static final Map<String, ChatColor> CHAT_COLOR_NAMES = new HashMap<String, ChatColor>();