2011-10-08 22:03:44 +02:00
|
|
|
package com.massivecraft.factions.zcore;
|
|
|
|
|
|
|
|
import java.util.*;
|
|
|
|
import java.util.Map.Entry;
|
|
|
|
|
|
|
|
import org.bukkit.Bukkit;
|
|
|
|
import org.bukkit.command.CommandSender;
|
|
|
|
import org.bukkit.entity.Player;
|
|
|
|
|
|
|
|
import com.massivecraft.factions.zcore.MCommand;
|
|
|
|
import com.massivecraft.factions.zcore.MPlugin;
|
|
|
|
import com.massivecraft.factions.zcore.util.TextUtil;
|
|
|
|
|
|
|
|
|
|
|
|
public abstract class MCommand<T extends MPlugin>
|
|
|
|
{
|
|
|
|
public T p;
|
|
|
|
|
|
|
|
// The sub-commands to this command
|
|
|
|
public List<MCommand<?>> subCommands;
|
2011-10-10 01:21:05 +02:00
|
|
|
public void addSubCommand(MCommand<?> subCommand)
|
|
|
|
{
|
|
|
|
subCommand.commandChain.addAll(this.commandChain);
|
|
|
|
subCommand.commandChain.add(this);
|
|
|
|
this.subCommands.add(subCommand);
|
|
|
|
}
|
2011-10-08 22:03:44 +02:00
|
|
|
|
|
|
|
// The different names this commands will react to
|
|
|
|
public List<String> aliases;
|
|
|
|
public boolean allowNoSlashAccess;
|
|
|
|
|
|
|
|
// Information on the args
|
|
|
|
public List<String> requiredArgs;
|
|
|
|
public LinkedHashMap<String, String> optionalArgs;
|
|
|
|
|
2011-10-09 14:53:38 +02:00
|
|
|
// FIELD: Help Short
|
|
|
|
// This field may be left blank and will in such case be loaded from the permissions node instead.
|
|
|
|
// Thus make sure the permissions node description is an action description like "eat hamburgers" or "do admin stuff".
|
|
|
|
private String helpShort;
|
|
|
|
public void setHelpShort(String val) { this.helpShort = val; }
|
|
|
|
public String getHelpShort()
|
|
|
|
{
|
|
|
|
if (this.helpShort == null)
|
|
|
|
{
|
|
|
|
String pdesc = p.perm.getPermissionDescription(this.permission);
|
|
|
|
if (pdesc != null)
|
|
|
|
{
|
|
|
|
return pdesc;
|
|
|
|
}
|
|
|
|
return "*no short help available*";
|
|
|
|
}
|
|
|
|
return this.helpShort;
|
|
|
|
}
|
|
|
|
|
2011-10-08 22:03:44 +02:00
|
|
|
public List<String> helpLong;
|
|
|
|
public CommandVisibility visibility;
|
|
|
|
|
|
|
|
// Some information on permissions
|
|
|
|
public boolean senderMustBePlayer;
|
|
|
|
public String permission;
|
|
|
|
|
|
|
|
// Information available on execution of the command
|
|
|
|
public CommandSender sender; // Will always be set
|
2011-10-08 23:22:02 +02:00
|
|
|
public Player me; // Will only be set when the sender is a player
|
2011-10-09 14:53:38 +02:00
|
|
|
public boolean senderIsConsole;
|
2011-10-08 22:03:44 +02:00
|
|
|
public List<String> args; // Will contain the arguments, or and empty list if there are none.
|
2011-10-10 01:21:05 +02:00
|
|
|
public List<MCommand<?>> commandChain = new ArrayList<MCommand<?>>(); // The command chain used to execute this command
|
2011-10-08 22:03:44 +02:00
|
|
|
|
|
|
|
public MCommand(T p)
|
|
|
|
{
|
|
|
|
this.p = p;
|
|
|
|
|
|
|
|
this.permission = null;
|
|
|
|
|
|
|
|
this.allowNoSlashAccess = false;
|
|
|
|
|
|
|
|
this.subCommands = new ArrayList<MCommand<?>>();
|
|
|
|
this.aliases = new ArrayList<String>();
|
|
|
|
|
|
|
|
this.requiredArgs = new ArrayList<String>();
|
|
|
|
this.optionalArgs = new LinkedHashMap<String, String>();
|
|
|
|
|
2011-10-09 14:53:38 +02:00
|
|
|
this.helpShort = null;
|
2011-10-08 22:03:44 +02:00
|
|
|
this.helpLong = new ArrayList<String>();
|
|
|
|
this.visibility = CommandVisibility.VISIBLE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// The commandChain is a list of the parent command chain used to get to this command.
|
|
|
|
public void execute(CommandSender sender, List<String> args, List<MCommand<?>> commandChain)
|
|
|
|
{
|
|
|
|
// Set the execution-time specific variables
|
|
|
|
this.sender = sender;
|
|
|
|
if (sender instanceof Player)
|
|
|
|
{
|
2011-10-08 23:22:02 +02:00
|
|
|
this.me = (Player)sender;
|
2011-10-09 14:53:38 +02:00
|
|
|
this.senderIsConsole = false;
|
2011-10-08 22:03:44 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-10-08 23:22:02 +02:00
|
|
|
this.me = null;
|
2011-10-09 14:53:38 +02:00
|
|
|
this.senderIsConsole = true;
|
2011-10-08 22:03:44 +02:00
|
|
|
}
|
|
|
|
this.args = args;
|
|
|
|
this.commandChain = commandChain;
|
|
|
|
|
|
|
|
// Is there a matching sub command?
|
|
|
|
if (args.size() > 0 )
|
|
|
|
{
|
|
|
|
for (MCommand<?> subCommand: this.subCommands)
|
|
|
|
{
|
|
|
|
if (subCommand.aliases.contains(args.get(0)))
|
|
|
|
{
|
|
|
|
args.remove(0);
|
|
|
|
commandChain.add(this);
|
|
|
|
subCommand.execute(sender, args, commandChain);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-10-09 21:57:43 +02:00
|
|
|
if ( ! validCall(this.sender, this.args)) return;
|
|
|
|
|
|
|
|
if ( ! this.isEnabled()) return;
|
2011-10-08 22:03:44 +02:00
|
|
|
|
|
|
|
perform();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void execute(CommandSender sender, List<String> args)
|
|
|
|
{
|
|
|
|
execute(sender, args, new ArrayList<MCommand<?>>());
|
|
|
|
}
|
|
|
|
|
|
|
|
// This is where the command action is performed.
|
|
|
|
public abstract void perform();
|
|
|
|
|
|
|
|
|
|
|
|
// -------------------------------------------- //
|
|
|
|
// Call Validation
|
|
|
|
// -------------------------------------------- //
|
|
|
|
|
|
|
|
/**
|
|
|
|
* In this method we validate that all prerequisites to perform this command has been met.
|
|
|
|
*/
|
|
|
|
// TODO: There should be a boolean for silence
|
|
|
|
public boolean validCall(CommandSender sender, List<String> args)
|
|
|
|
{
|
|
|
|
if ( ! validSenderType(sender, true))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( ! validSenderPermissions(sender, true))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( ! validArgs(args, sender))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2011-10-09 21:57:43 +02:00
|
|
|
public boolean isEnabled()
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2011-10-08 22:03:44 +02:00
|
|
|
public boolean validSenderType(CommandSender sender, boolean informSenderIfNot)
|
|
|
|
{
|
|
|
|
if (this.senderMustBePlayer && ! (sender instanceof Player))
|
|
|
|
{
|
|
|
|
if (informSenderIfNot)
|
|
|
|
{
|
2011-10-10 13:40:24 +02:00
|
|
|
msg(Lang.commandSenderMustBePlayer);
|
2011-10-08 22:03:44 +02:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean validSenderPermissions(CommandSender sender, boolean informSenderIfNot)
|
|
|
|
{
|
|
|
|
if (this.permission == null) return true;
|
|
|
|
return p.perm.has(sender, this.permission, informSenderIfNot);
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean validArgs(List<String> args, CommandSender sender)
|
|
|
|
{
|
|
|
|
if (args.size() < this.requiredArgs.size())
|
|
|
|
{
|
|
|
|
if (sender != null)
|
|
|
|
{
|
2011-10-10 13:40:24 +02:00
|
|
|
msg(Lang.commandToFewArgs);
|
2011-10-08 22:03:44 +02:00
|
|
|
sender.sendMessage(this.getUseageTemplate());
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (args.size() > this.requiredArgs.size() + this.optionalArgs.size())
|
|
|
|
{
|
|
|
|
if (sender != null)
|
|
|
|
{
|
|
|
|
// Get the to many string slice
|
|
|
|
List<String> theToMany = args.subList(this.requiredArgs.size() + this.optionalArgs.size(), args.size());
|
2011-10-10 13:40:24 +02:00
|
|
|
msg(Lang.commandToManyArgs, TextUtil.implode(theToMany, " "));
|
2011-10-08 22:03:44 +02:00
|
|
|
sender.sendMessage(this.getUseageTemplate());
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
public boolean validArgs(List<String> args)
|
|
|
|
{
|
|
|
|
return this.validArgs(args, null);
|
|
|
|
}
|
|
|
|
|
|
|
|
// -------------------------------------------- //
|
|
|
|
// Help and Usage information
|
|
|
|
// -------------------------------------------- //
|
|
|
|
|
|
|
|
public String getUseageTemplate(List<MCommand<?>> commandChain, boolean addShortHelp)
|
|
|
|
{
|
|
|
|
StringBuilder ret = new StringBuilder();
|
2011-10-10 13:31:25 +02:00
|
|
|
ret.append(p.txt.parseTags("<c>"));
|
2011-10-08 22:03:44 +02:00
|
|
|
ret.append('/');
|
|
|
|
|
|
|
|
for (MCommand<?> mc : commandChain)
|
|
|
|
{
|
|
|
|
ret.append(TextUtil.implode(mc.aliases, ","));
|
|
|
|
ret.append(' ');
|
|
|
|
}
|
|
|
|
|
|
|
|
ret.append(TextUtil.implode(this.aliases, ","));
|
|
|
|
|
|
|
|
List<String> args = new ArrayList<String>();
|
|
|
|
|
|
|
|
for (String requiredArg : this.requiredArgs)
|
|
|
|
{
|
|
|
|
args.add("<"+requiredArg+">");
|
|
|
|
}
|
|
|
|
|
|
|
|
for (Entry<String, String> optionalArg : this.optionalArgs.entrySet())
|
|
|
|
{
|
|
|
|
String val = optionalArg.getValue();
|
|
|
|
if (val == null)
|
|
|
|
{
|
|
|
|
val = "";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
val = "="+val;
|
|
|
|
}
|
|
|
|
args.add("["+optionalArg.getKey()+val+"]");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (args.size() > 0)
|
|
|
|
{
|
2011-10-10 13:31:25 +02:00
|
|
|
ret.append(p.txt.parseTags("<p> "));
|
2011-10-08 22:03:44 +02:00
|
|
|
ret.append(TextUtil.implode(args, " "));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (addShortHelp)
|
|
|
|
{
|
2011-10-10 13:31:25 +02:00
|
|
|
ret.append(p.txt.parseTags(" <i>"));
|
2011-10-08 22:03:44 +02:00
|
|
|
ret.append(this.helpShort);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret.toString();
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getUseageTemplate(boolean addShortHelp)
|
|
|
|
{
|
|
|
|
return getUseageTemplate(this.commandChain, addShortHelp);
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getUseageTemplate()
|
|
|
|
{
|
|
|
|
return getUseageTemplate(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
// -------------------------------------------- //
|
|
|
|
// Message Sending Helpers
|
|
|
|
// -------------------------------------------- //
|
|
|
|
|
2011-10-10 13:40:24 +02:00
|
|
|
public void msg(String str, Object... args)
|
2011-10-08 22:03:44 +02:00
|
|
|
{
|
2011-10-09 14:53:38 +02:00
|
|
|
sender.sendMessage(p.txt.parse(str, args));
|
2011-10-08 22:03:44 +02:00
|
|
|
}
|
|
|
|
|
2011-10-08 23:22:02 +02:00
|
|
|
public void sendMessage(String msg)
|
2011-10-08 22:03:44 +02:00
|
|
|
{
|
2011-10-09 14:53:38 +02:00
|
|
|
sender.sendMessage(msg);
|
2011-10-08 22:03:44 +02:00
|
|
|
}
|
|
|
|
|
2011-10-09 14:53:38 +02:00
|
|
|
public void sendMessage(List<String> msgs)
|
2011-10-08 22:03:44 +02:00
|
|
|
{
|
|
|
|
for(String msg : msgs)
|
|
|
|
{
|
2011-10-09 14:53:38 +02:00
|
|
|
this.sendMessage(msg);
|
2011-10-08 22:03:44 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// -------------------------------------------- //
|
|
|
|
// Argument Readers
|
|
|
|
// -------------------------------------------- //
|
|
|
|
|
2011-10-09 20:10:19 +02:00
|
|
|
// Is set? ======================
|
2011-10-09 14:53:38 +02:00
|
|
|
public boolean argIsSet(int idx)
|
|
|
|
{
|
|
|
|
if (this.args.size() < idx+1)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2011-10-09 20:10:19 +02:00
|
|
|
// STRING ======================
|
2011-10-08 22:03:44 +02:00
|
|
|
public String argAsString(int idx, String def)
|
|
|
|
{
|
|
|
|
if (this.args.size() < idx+1)
|
|
|
|
{
|
|
|
|
return def;
|
|
|
|
}
|
|
|
|
return this.args.get(idx);
|
|
|
|
}
|
|
|
|
public String argAsString(int idx)
|
|
|
|
{
|
|
|
|
return this.argAsString(idx, null);
|
|
|
|
}
|
|
|
|
|
2011-10-09 20:10:19 +02:00
|
|
|
// INT ======================
|
2011-10-10 01:43:21 +02:00
|
|
|
public int strAsInt(String str, int def)
|
2011-10-08 22:03:44 +02:00
|
|
|
{
|
|
|
|
if (str == null) return def;
|
|
|
|
try
|
|
|
|
{
|
|
|
|
int ret = Integer.parseInt(str);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
|
|
|
return def;
|
|
|
|
}
|
|
|
|
}
|
2011-10-10 01:43:21 +02:00
|
|
|
public int argAsInt(int idx, int def)
|
|
|
|
{
|
|
|
|
return strAsInt(this.argAsString(idx), def);
|
|
|
|
}
|
2011-10-08 22:03:44 +02:00
|
|
|
public int argAsInt(int idx)
|
|
|
|
{
|
|
|
|
return this.argAsInt(idx, -1);
|
|
|
|
}
|
|
|
|
|
2011-10-09 20:10:19 +02:00
|
|
|
// Double ======================
|
2011-10-10 01:43:21 +02:00
|
|
|
public double strAsDouble(String str, double def)
|
2011-10-08 22:03:44 +02:00
|
|
|
{
|
|
|
|
if (str == null) return def;
|
|
|
|
try
|
|
|
|
{
|
|
|
|
double ret = Double.parseDouble(str);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
|
|
|
return def;
|
|
|
|
}
|
|
|
|
}
|
2011-10-10 01:43:21 +02:00
|
|
|
public double argAsDouble(int idx, double def)
|
|
|
|
{
|
|
|
|
return strAsDouble(this.argAsString(idx), def);
|
|
|
|
}
|
2011-10-08 22:03:44 +02:00
|
|
|
public double argAsDouble(int idx)
|
|
|
|
{
|
|
|
|
return this.argAsDouble(idx, -1d);
|
|
|
|
}
|
|
|
|
|
2011-10-09 20:10:19 +02:00
|
|
|
// TODO: Go through the str conversion for the other arg-readers as well.
|
|
|
|
// Boolean ======================
|
|
|
|
public Boolean strAsBool(String str)
|
2011-10-08 22:03:44 +02:00
|
|
|
{
|
|
|
|
str = str.toLowerCase();
|
|
|
|
if (str.startsWith("y") || str.startsWith("t") || str.startsWith("on") || str.startsWith("+") || str.startsWith("1"))
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2011-10-09 20:10:19 +02:00
|
|
|
public Boolean argAsBool(int idx, boolean def)
|
|
|
|
{
|
|
|
|
String str = this.argAsString(idx);
|
|
|
|
if (str == null) return def;
|
|
|
|
|
|
|
|
return strAsBool(str);
|
|
|
|
}
|
|
|
|
public Boolean argAsBool(int idx)
|
2011-10-08 22:03:44 +02:00
|
|
|
{
|
|
|
|
return this.argAsBool(idx, false);
|
|
|
|
}
|
|
|
|
|
2011-10-09 20:10:19 +02:00
|
|
|
// PLAYER ======================
|
2011-10-10 01:43:21 +02:00
|
|
|
public Player strAsPlayer(String name, Player def, boolean msg)
|
2011-10-08 22:03:44 +02:00
|
|
|
{
|
|
|
|
Player ret = def;
|
|
|
|
|
|
|
|
if (name != null)
|
|
|
|
{
|
|
|
|
Player player = Bukkit.getServer().getPlayer(name);
|
|
|
|
if (player != null)
|
|
|
|
{
|
|
|
|
ret = player;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (msg && ret == null)
|
|
|
|
{
|
2011-10-10 13:40:24 +02:00
|
|
|
this.msg("<b>No player \"<p>%s<b>\" could not be found.", name);
|
2011-10-08 22:03:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
2011-10-10 01:43:21 +02:00
|
|
|
|
|
|
|
public Player argAsPlayer(int idx, Player def, boolean msg)
|
|
|
|
{
|
|
|
|
return this.strAsPlayer(this.argAsString(idx), def, msg);
|
|
|
|
}
|
2011-10-08 22:03:44 +02:00
|
|
|
public Player argAsPlayer(int idx, Player def)
|
|
|
|
{
|
|
|
|
return this.argAsPlayer(idx, def, true);
|
|
|
|
}
|
|
|
|
public Player argAsPlayer(int idx)
|
|
|
|
{
|
|
|
|
return this.argAsPlayer(idx, null);
|
|
|
|
}
|
|
|
|
|
2011-10-09 20:10:19 +02:00
|
|
|
// BEST PLAYER MATCH ======================
|
2011-10-10 01:43:21 +02:00
|
|
|
public Player strAsBestPlayerMatch(String name, Player def, boolean msg)
|
2011-10-08 22:03:44 +02:00
|
|
|
{
|
|
|
|
Player ret = def;
|
|
|
|
|
|
|
|
if (name != null)
|
|
|
|
{
|
|
|
|
List<Player> players = Bukkit.getServer().matchPlayer(name);
|
|
|
|
if (players.size() > 0)
|
|
|
|
{
|
|
|
|
ret = players.get(0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (msg && ret == null)
|
|
|
|
{
|
2011-10-10 13:40:24 +02:00
|
|
|
this.msg("<b>No player match found for \"<p>%s<b>\".", name);
|
2011-10-08 22:03:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
2011-10-10 01:43:21 +02:00
|
|
|
public Player argAsBestPlayerMatch(int idx, Player def, boolean msg)
|
|
|
|
{
|
|
|
|
return this.strAsBestPlayerMatch(this.argAsString(idx), def, msg);
|
|
|
|
}
|
2011-10-08 22:03:44 +02:00
|
|
|
public Player argAsBestPlayerMatch(int idx, Player def)
|
|
|
|
{
|
|
|
|
return this.argAsBestPlayerMatch(idx, def, true);
|
|
|
|
}
|
|
|
|
public Player argAsBestPlayerMatch(int idx)
|
|
|
|
{
|
|
|
|
return this.argAsPlayer(idx, null);
|
|
|
|
}
|
|
|
|
}
|