Rewritten commandManager

This commit is contained in:
Eric Stokes 2011-07-09 07:52:20 -06:00
parent 8f56347572
commit fc9aa456da
5 changed files with 269 additions and 97 deletions

View File

@ -2,6 +2,7 @@ package com.onarandombox.MultiverseCore;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
@ -83,12 +84,12 @@ public class MultiverseCore extends JavaPlugin {
public void onEnable() {
// Output a little snippet to show it's enabled.
this.log(Level.INFO, "- Version " + this.getDescription().getVersion() + " Enabled - By " + getAuthors());
// Setup all the Events the plugin needs to Monitor.
this.registerEvents();
// Setup Permissions, we'll do an initial check for the Permissions plugin then fall back on isOP().
this.ph = new MVPermissions(this);
this.bank = this.banker.loadEconPlugin();
// Setup the command manager
this.commandManager = new CommandManager(this);
@ -118,7 +119,7 @@ public class MultiverseCore extends JavaPlugin {
pm.registerEvent(Event.Type.PLAYER_KICK, this.playerListener, Priority.Highest, this);
pm.registerEvent(Event.Type.PLAYER_RESPAWN, this.playerListener, Priority.Normal, this);
pm.registerEvent(Event.Type.PLAYER_CHAT, this.playerListener, Priority.Normal, this);
pm.registerEvent(Event.Type.ENTITY_REGAIN_HEALTH, this.entityListener, Priority.Normal, this);
pm.registerEvent(Event.Type.ENTITY_DAMAGE, this.entityListener, Priority.Normal, this); // To Allow/Disallow PVP as well as EnableHealth.
pm.registerEvent(Event.Type.CREATURE_SPAWN, this.entityListener, Priority.Normal, this); // To prevent all or certain animals/monsters from spawning.
@ -168,22 +169,22 @@ public class MultiverseCore extends JavaPlugin {
*/
private void registerCommands() {
// Page 1
this.commandManager.addCommand(new HelpCommand(this));
this.commandManager.addCommand(new CoordCommand(this));
this.commandManager.addCommand(new TeleportCommand(this));
this.commandManager.addCommand(new ListCommand(this));
this.commandManager.addCommand(new WhoCommand(this));
this.commandManager.addCommand(new SetSpawnCommand(this));
this.commandManager.addCommand(new CreateCommand(this));
this.commandManager.addCommand(new ImportCommand(this));
this.commandManager.addCommand(new SpawnCommand(this));
this.commandManager.addCommand(new RemoveCommand(this));
this.commandManager.addCommand(new DeleteCommand(this));
this.commandManager.addCommand(new UnloadCommand(this));
this.commandManager.addCommand(new ConfirmCommand(this));
this.commandManager.addCommand(new InfoCommand(this));
this.commandManager.addCommand(new ReloadCommand(this));
// this.commandManager.addCommand(new HelpCommand(this));
// this.commandManager.addCommand(new CoordCommand(this));
// this.commandManager.addCommand(new TeleportCommand(this));
// this.commandManager.addCommand(new ListCommand(this));
// this.commandManager.addCommand(new WhoCommand(this));
// this.commandManager.addCommand(new SetSpawnCommand(this));
// this.commandManager.addCommand(new CreateCommand(this));
// this.commandManager.addCommand(new ImportCommand(this));
// this.commandManager.addCommand(new SpawnCommand(this));
// this.commandManager.addCommand(new RemoveCommand(this));
// this.commandManager.addCommand(new DeleteCommand(this));
// this.commandManager.addCommand(new UnloadCommand(this));
// this.commandManager.addCommand(new ConfirmCommand(this));
// this.commandManager.addCommand(new InfoCommand(this));
// this.commandManager.addCommand(new ReloadCommand(this));
this.commandManager.addCommand(new ModifyAddCommand(this));
this.commandManager.addCommand(new ModifySetCommand(this));
this.commandManager.addCommand(new ModifyRemoveCommand(this));
@ -238,7 +239,7 @@ public class MultiverseCore extends JavaPlugin {
}
/**
*
*
* @return
*/
private int loadDefaultWorlds() {
@ -262,9 +263,9 @@ public class MultiverseCore extends JavaPlugin {
/**
* Add a new World to the Multiverse Setup.
*
*
* Isn't there a prettier way to do this??!!?!?!
*
*
* @param name World Name
* @param environment Environment Type
*/
@ -347,7 +348,7 @@ public class MultiverseCore extends JavaPlugin {
/**
* Remove the world from the Multiverse list
*
*
* @param name The name of the world to remove
* @return True if success, false if failure.
*/
@ -361,7 +362,7 @@ public class MultiverseCore extends JavaPlugin {
/**
* Remove the world from the Multiverse list and from the config
*
*
* @param name The name of the world to remove
* @return True if success, false if failure.
*/
@ -374,7 +375,7 @@ public class MultiverseCore extends JavaPlugin {
/**
* Remove the world from the Multiverse list, from the config and deletes the folder
*
*
* @param name The name of the world to remove
* @return True if success, false if failure.
*/
@ -389,7 +390,7 @@ public class MultiverseCore extends JavaPlugin {
/**
* Delete a folder Courtesy of: lithium3141
*
*
* @param file The folder to delete
* @return true if success
*/
@ -420,7 +421,7 @@ public class MultiverseCore extends JavaPlugin {
/**
* Grab the players session if one exists, otherwise create a session then return it.
*
*
* @param player
* @return
*/
@ -435,7 +436,7 @@ public class MultiverseCore extends JavaPlugin {
/**
* Grab and return the Teleport class.
*
*
* @return
*/
public MVTeleport getTeleporter() {
@ -462,12 +463,18 @@ public class MultiverseCore extends JavaPlugin {
sender.sendMessage("This plugin is Disabled!");
return true;
}
return this.commandManager.dispatch(sender, command, commandLabel, args);
System.out.print("Command executed!");
System.out.print(command.getName());
System.out.print(Arrays.toString(args));
ArrayList<String> allArgs = new ArrayList<String>(Arrays.asList(args));
allArgs.add(0, command.getName());
return this.commandManager.dispatch(sender, allArgs);
// return this.commandManager.dispatch(sender, command, commandLabel, args);
}
/**
* Print messages to the server Log as well as to our DebugLog. 'debugLog' is used to seperate Heroes information from the Servers Log Output.
*
*
* @param level
* @param msg
*/
@ -478,7 +485,7 @@ public class MultiverseCore extends JavaPlugin {
/**
* Print messages to the Debug Log, if the servers in Debug Mode then we also wan't to print the messages to the standard Server Console.
*
*
* @param level
* @param msg
*/
@ -491,7 +498,7 @@ public class MultiverseCore extends JavaPlugin {
/**
* Parse the Authors Array into a readable String with ',' and 'and'.
*
*
* @return
*/
private String getAuthors() {
@ -522,7 +529,7 @@ public class MultiverseCore extends JavaPlugin {
/**
* This code should get moved somewhere more appropriate, but for now, it's here.
*
*
* @param env
* @return
*/

View File

@ -1,6 +1,7 @@
package com.onarandombox.MultiverseCore.command;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.bukkit.command.CommandSender;
@ -8,7 +9,7 @@ import org.bukkit.command.CommandSender;
import com.onarandombox.MultiverseCore.MultiverseCore;
public abstract class BaseCommand {
protected MultiverseCore plugin;
protected String name;
protected String description;
@ -18,16 +19,17 @@ public abstract class BaseCommand {
protected int minArgs;
protected int maxArgs;
protected List<String> identifiers;
public final String IN_GAME_COMMAND_MSG = "This command needs to be used as a Player in game.";
public BaseCommand(MultiverseCore plugin) {
this.identifiers = new ArrayList<String>();
this.plugin = plugin;
}
public abstract void execute(CommandSender sender, String[] args);
@Deprecated
public boolean validate(String name, String[] parsedArgs, StringBuilder identifier) {
String match = this.matchIdentifier(name, parsedArgs);
if (match != null) {
@ -42,9 +44,18 @@ public abstract class BaseCommand {
}
return false;
}
public boolean validate(ArrayList<String> args) {
int argsLength = args.size();
if ((argsLength == -1 || argsLength >= this.minArgs) && (this.maxArgs == -1 || argsLength <= this.maxArgs)) {
return true;
}
return false;
}
@Deprecated
public String matchIdentifier(String input, String[] args) {
String argsString = this.getArgsString(args);
String lower = input.toLowerCase() + argsString;
int index = -1;
@ -55,14 +66,58 @@ public abstract class BaseCommand {
index = i;
}
}
if (index != -1) {
return this.identifiers.get(index);
} else {
return null;
}
}
public String getIdentifier(ArrayList<String> allArgs) {
// Combines our args to a space seperated string
String argsString = this.getArgsString(allArgs);
for (String s : this.identifiers) {
String identifier = s.toLowerCase();
if (argsString.matches(identifier + "(\\s+.*|\\s*)")) {
return identifier;
}
}
return null;
}
public ArrayList<String> removeIdentifierArgs(ArrayList<String> allArgs, String identifier) {
int identifierLength = identifier.split(" ").length;
for (int i = 0; i < identifierLength; i++) {
// Since we're pulling from the front, always remove the first element
allArgs.remove(0);
}
return allArgs;
}
protected String[] removeRedundantArgs(String[] args, String command) {
System.out.print("Attempting to remove redundant args:");
System.out.print(Arrays.toString(args));
System.out.print(command);
String[] cmdSplit = command.split(" ");
// Start at cmdSplit[1], because 0 is the command name
int match = 0;
int i = 0;
while (i + 1 < cmdSplit.length && i < args.length && cmdSplit[i + 1].equalsIgnoreCase(args[i])) {
System.out.print("Found a match!");
match = i + 1;
i++;
}
ArrayList<String> newArgs = new ArrayList<String>();
for (int j = match; j < args.length; j++) {
newArgs.add(args[j]);
}
String[] mynewArr = {};
return newArgs.toArray(mynewArr);
}
@Deprecated
private String getArgsString(String[] args) {
String returnString = "";
for (String s : args) {
@ -70,33 +125,40 @@ public abstract class BaseCommand {
}
return returnString;
}
private String getArgsString(ArrayList<String> args) {
String returnString = "";
for (String s : args) {
returnString += s + " ";
}
return returnString.substring(0, returnString.length() - 1);
}
public List<String> getIdentifiers() {
return this.identifiers;
}
public void setIdentifiers(List<String> identifiers) {
this.identifiers = identifiers;
}
public String getName() {
return this.name;
}
public String getDescription() {
return this.description;
}
public String getUsage() {
return this.usage;
}
public boolean isOpRequired() {
return this.requiresOp;
}
public String getPermission() {
return this.permission;
}
}

View File

@ -9,8 +9,11 @@
package com.onarandombox.MultiverseCore.command;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
@ -19,43 +22,88 @@ import org.bukkit.command.CommandSender;
import com.onarandombox.MultiverseCore.MultiverseCore;
public class CommandManager {
protected List<BaseCommand> commands;
private MultiverseCore plugin;
// List to hold commands that require approval
public List<QueuedCommand> queuedCommands = new ArrayList<QueuedCommand>();
public CommandManager(MultiverseCore plugin) {
this.commands = new ArrayList<BaseCommand>();
this.plugin = plugin;
}
public boolean dispatch(CommandSender sender, ArrayList<String> allArgs) {
ArrayList<String> parsedArgs = parseAllQuotedStrings(allArgs);
String identifier = null;
Iterator<BaseCommand> iterator = this.commands.iterator();
BaseCommand foundCommand = null;
// This loop is pretty neat. It goes until either the iterator has no more
// Or until we find an identifier. When we do, we no longer iterate, and the
// value left in "foundCommand" is the command we found!
while (iterator.hasNext() && identifier == null) {
foundCommand = iterator.next();
identifier = foundCommand.getIdentifier(parsedArgs);
if (identifier != null) {
// This method, removeIdentifierArgs mutates parsedArgs
foundCommand.removeIdentifierArgs(parsedArgs, identifier);
validateAndRunCommand(sender, parsedArgs, foundCommand);
}
}
return true;
}
private void validateAndRunCommand(CommandSender sender, ArrayList<String> parsedArgs, BaseCommand foundCommand) {
if (foundCommand.validate(parsedArgs)) {
if (this.plugin.ph.hasPermission(sender, foundCommand.getPermission(), foundCommand.isOpRequired())) {
foundCommand.execute(sender, parsedArgs.toArray(new String[parsedArgs.size()]));
} else {
sender.sendMessage("You do not have permission to use this command. (" + foundCommand.getPermission() + ")");
}
} else {
sender.sendMessage(ChatColor.AQUA + "Command: " + ChatColor.WHITE + foundCommand.getName());
sender.sendMessage(ChatColor.AQUA + "Description: " + ChatColor.WHITE + foundCommand.getDescription());
sender.sendMessage(ChatColor.AQUA + "Usage: " + ChatColor.WHITE + foundCommand.getUsage());
}
}
@Deprecated
public boolean dispatch(CommandSender sender, Command command, String label, String[] args) {
BaseCommand match = null;
String[] trimmedArgs = null;
StringBuilder identifier = new StringBuilder();
String[] finalArgs = null;
for (BaseCommand cmd : this.commands) {
StringBuilder tmpIdentifier = new StringBuilder();
String[] tmpArgs = parseAllQuotedStrings(args);
System.out.print("Before Args");
System.out.print(Arrays.toString(tmpArgs));
if (match == null) {
match = cmd.matchIdentifier(label, tmpArgs) == null ? null : cmd;
// If we have a valid match, then we want to remove any extraneous words.
// For example: /mvmodiy add is the name of a command, we want the command
// to never see the "add"
if (match != null) {
finalArgs = cmd.removeRedundantArgs(tmpArgs, cmd.matchIdentifier(label, tmpArgs));
}
}
System.out.print("After Args");
System.out.print(Arrays.toString(tmpArgs));
if (match != null && cmd.validate(label, tmpArgs, tmpIdentifier) && tmpIdentifier.length() > identifier.length()) {
identifier = tmpIdentifier;
trimmedArgs = tmpArgs;
}
}
if (match != null) {
if (this.plugin.ph.hasPermission(sender, match.getPermission(), match.isOpRequired())) {
if (trimmedArgs != null) {
match.execute(sender, trimmedArgs);
if (finalArgs != null) {
match.execute(sender, finalArgs);
} else {
sender.sendMessage(ChatColor.AQUA + "Command: " + ChatColor.WHITE + match.getName());
sender.sendMessage(ChatColor.AQUA + "Description: " + ChatColor.WHITE + match.getDescription());
@ -67,36 +115,37 @@ public class CommandManager {
}
return true;
}
public void addCommand(BaseCommand command) {
this.commands.add(command);
}
public void removeCommand(BaseCommand command) {
this.commands.remove(command);
}
@Deprecated
public List<BaseCommand> getCommands() {
return this.commands;
}
public List<BaseCommand> getCommands(CommandSender sender) {
ArrayList<BaseCommand> playerCommands = new ArrayList<BaseCommand>();
for(BaseCommand c : this.commands) {
if(this.plugin.ph.hasPermission(sender, c.permission, c.isOpRequired())) {
for (BaseCommand c : this.commands) {
if (this.plugin.ph.hasPermission(sender, c.permission, c.isOpRequired())) {
playerCommands.add(c);
}
}
return playerCommands;
}
/**
* Combines all quoted strings
*
* @param args
* @return
*/
@Deprecated
private String[] parseAllQuotedStrings(String[] args) {
// TODO: Allow '
ArrayList<String> newArgs = new ArrayList<String>();
@ -104,7 +153,7 @@ public class CommandManager {
// we could have: "Fish dog" the man bear pig "lives today" and maybe "even tomorrow" or "the" next day
int start = -1;
for (int i = 0; i < args.length; i++) {
// If we aren't looking for an end quote, and the first part of a string is a quote
if (start == -1 && args[i].substring(0, 1).equals("\"")) {
start = i;
@ -126,10 +175,10 @@ public class CommandManager {
// ... then we want to close that quote and make that one arg.
newArgs.add(parseQuotedString(args, start, args.length));
}
return newArgs.toArray(new String[newArgs.size()]);
}
/**
* Takes a string array and returns a combined string, excluding the stop position, including the start
*
@ -138,6 +187,7 @@ public class CommandManager {
* @param stop
* @return
*/
@Deprecated
private String parseQuotedString(String[] args, int start, int stop) {
String returnVal = args[start];
for (int i = start + 1; i < stop; i++) {
@ -145,8 +195,62 @@ public class CommandManager {
}
return returnVal.replace("\"", "");
}
/**
* Combines all quoted strings
*
* @param args
* @return
*/
private ArrayList<String> parseAllQuotedStrings(ArrayList<String> args) {
// TODO: Allow '
ArrayList<String> newArgs = new ArrayList<String>();
// Iterate through all command params:
// we could have: "Fish dog" the man bear pig "lives today" and maybe "even tomorrow" or "the" next day
int start = -1;
for (int i = 0; i < args.size(); i++) {
// If we aren't looking for an end quote, and the first part of a string is a quote
if (start == -1 && args.get(i).substring(0, 1).equals("\"")) {
start = i;
}
// Have to keep this seperate for one word quoted strings like: "fish"
if (start != -1 && args.get(i).substring(args.get(i).length() - 1, args.get(i).length()).equals("\"")) {
// Now we've found the second part of a string, let's parse the quoted one out
// Make sure it's i+1, we still want I included
newArgs.add(parseQuotedString(args, start, i + 1));
// Reset the start to look for more!
start = -1;
} else if (start == -1) {
// This is a word that is NOT enclosed in any quotes, so just add it
newArgs.add(args.get(i));
}
}
// If the string was ended but had an open quote...
if (start != -1) {
// ... then we want to close that quote and make that one arg.
newArgs.add(parseQuotedString(args, start, args.size()));
}
return newArgs;
}
/**
* Takes a string array and returns a combined string, excluding the stop position, including the start
*
* @param args
* @param start
* @param stop
* @return
*/
private String parseQuotedString(ArrayList<String> args, int start, int stop) {
String returnVal = args.get(start);
for (int i = start + 1; i < stop; i++) {
returnVal += " " + args.get(i);
}
return returnVal.replace("\"", "");
}
/**
* Returns the given flag value
*
@ -167,7 +271,7 @@ public class CommandManager {
}
return null;
}
/**
*
*/
@ -179,7 +283,7 @@ public class CommandManager {
sender.sendMessage("please type: " + ChatColor.GREEN + "/mvconfirm");
sender.sendMessage(ChatColor.GREEN + "/mvconfirm" + ChatColor.WHITE + " will only be available for 10 seconds.");
}
/**
* Tries to fire off the command
*
@ -200,7 +304,7 @@ public class CommandManager {
}
return false;
}
/**
* Cancels(invalidates) a command that has been requested. This is called when a user types something other than 'yes' or when they try to queue a second command Queuing a second command will delete the first command entirely.
*

View File

@ -8,67 +8,65 @@ import com.onarandombox.MultiverseCore.MVWorld;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.command.BaseCommand;
// This will contain all the properties that support the ADD/REMOVE
// Anything not in here will only support the SET action
public class ModifyAddCommand extends BaseCommand {
public ModifyAddCommand(MultiverseCore plugin) {
super(plugin);
this.name = "Modify a World (Add a value)";
this.description = "Modify various aspects of worlds. See the help wiki for how to use this command properly. If you do not include a world, the current world will be used";
this.usage = "/mvmodify " + ChatColor.GREEN + "ADD {VALUE} {PROPERTY}" + ChatColor.GOLD + " [WORLD] ";
this.minArgs = 3;
this.maxArgs = 4;
this.minArgs = 2;
this.maxArgs = 3;
this.identifiers.add("mvmodify add");
this.permission = "multiverse.world.modify";
this.requiresOp = true;
}
@Override
public void execute(CommandSender sender, String[] args) {
// We NEED a world from the command line
Player p = null;
if (!(sender instanceof Player)) {
if (sender instanceof Player) {
p = (Player) sender;
}
if (args.length == 3 && p == null) {
sender.sendMessage("From the command line, WORLD is required.");
if (args.length == 2 && p == null) {
sender.sendMessage(ChatColor.RED + "From the command line, WORLD is required.");
sender.sendMessage(this.description);
sender.sendMessage(this.usage);
sender.sendMessage("Nothing changed.");
return;
}
MVWorld world;
String value = args[1];
String property = args[2];
if (args.length == 3) {
String value = args[0];
String property = args[1];
if (args.length == 2) {
world = this.plugin.getMVWorld(p.getWorld().getName());
} else {
world = this.plugin.getMVWorld(args[3]);
world = this.plugin.getMVWorld(args[2]);
}
if (world == null) {
sender.sendMessage("That world does not exist!");
return;
}
if (!ModifyCommand.validateAction(Action.Add, property)) {
sender.sendMessage("Sorry, you can't ADD to " + property);
sender.sendMessage("Please visit our wiki for more information: URLGOESHERE FERNFERRET DON'T FORGET IT!");
return;
}
if (world.addToList(property, value)) {
sender.sendMessage(value + " was added to " + property);
} else {
sender.sendMessage(value + " could not be added to " + property);
}
}
}

View File

@ -43,6 +43,7 @@ public class ModifyCommand extends BaseCommand {
// ModifySetCommand
// ModifyClearCommand
}
protected static boolean validateAction(Action action, String property) {
if (action == Action.Set) {
try {