Skip to content

Commit

Permalink
Put commands on feet.
Browse files Browse the repository at this point in the history
* Add a new base class for better sub-command handling also for
tab-completion (AbstractCommand).
* Alter package structure slightly, to group command-classes by purpose.
* Some renaming.
  • Loading branch information
asofold committed Jun 11, 2013
1 parent 888c7d9 commit 8ea5ecc
Show file tree
Hide file tree
Showing 22 changed files with 325 additions and 220 deletions.
@@ -0,0 +1,156 @@
package fr.neatmonster.nocheatplus.command;


import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;

/**
* Base command class, featuring some features.<br>
* Taken from the Archer plugin (@asofold), extended by aliases.
* @author mc_dev
*
*/
public abstract class AbstractCommand<A> implements TabExecutor{

public static final List<String> noTabChoices = Collections.unmodifiableList(new LinkedList<String>());

/**
* Convenience method: join with a space in between.
* @param args
* @param startIndex
* @return
*/
public static String join(String[] args, int startIndex){
return join(args, startIndex, " ");
}

/**
* Convenience method.
* @param args
* @param startIndex
* @return
*/
public static String join(String[] args, int startIndex, String sep){
final StringBuilder b = new StringBuilder(100);
if (startIndex < args.length) b.append(args[startIndex]);
for (int i = startIndex + 1; i < args.length; i++){
b.append(sep);
b.append(args[i]);
}
return b.toString();
}

////////////////
// Not static.
////////////////

protected final A access;
public final String label;
/** Permission necessary to use this command. May be null. */
public final String permission;
/** Sub commands for delegation. */
protected final Map<String, AbstractCommand<?>> subCommands = new LinkedHashMap<String, AbstractCommand<?>>();
/** The index in args to check for sub-commands. -1 stands for default, either parent + 1 or 0 */
protected int subCommandIndex = -1;
/** Aliases for the command label. */
protected final String[] aliases;

/**
*
* @param access
* @param label Lower-case.
* @param permission
*/
public AbstractCommand(A access, String label, String permission){
this(access, label, permission, null);
}

/**
*
* @param access
* @param label Lower-case.
* @param permission May be null (no permission necessary).
* @param aliases May be null (no aliases). If given, the aliases only take effect for tab completion and selection of sub commands. Lower-case.
*/
public AbstractCommand(A access, String label, String permission, String[] aliases){
this.access = access;
this.label = label;
this.permission = permission;
this.aliases = aliases;
}

public void addSubCommands(AbstractCommand<?>... commands){
for (AbstractCommand<?> subCommand : commands ){
subCommands.put(subCommand.label, subCommand);
if (subCommand.subCommandIndex == -1){
subCommand.subCommandIndex = Math.max(0, this.subCommandIndex) + 1;
}
if (subCommand.aliases != null){
for (final String alias : subCommand.aliases){
if (!subCommands.containsKey(alias)){
subCommands.put(alias, subCommand);
}
}
}
}
}

@Override
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args)
{
final Set<String> choices = new LinkedHashSet<String>(subCommands.size());
int len = args.length;
// Attempt to delegate.
int subCommandIndex = Math.max(0, this.subCommandIndex);
if (len == subCommandIndex || len == subCommandIndex + 1){
String arg = len == subCommandIndex ? "" : args[subCommandIndex].trim().toLowerCase();
for (AbstractCommand<?> cmd : subCommands.values()){
if (cmd.label.startsWith(arg) && (cmd.permission == null || sender.hasPermission(cmd.permission))){
// Only completes the label (!).
choices.add(cmd.label);
}
}
}
else if (len > subCommandIndex + 1){
String arg = args[subCommandIndex].trim().toLowerCase();
AbstractCommand<?> subCommand = subCommands.get(arg);
if (subCommand != null && (subCommand.permission == null || sender.hasPermission(subCommand.permission))){
return subCommand.onTabComplete(sender, command, alias, args);
}
}
// No tab completion by default.
if (choices.isEmpty()) return noTabChoices;
else return new LinkedList<String>(choices);
}

@Override
public boolean onCommand(CommandSender sender, Command command, String alias, String[] args)
{
int len = args.length;
int subCommandIndex = Math.max(0, this.subCommandIndex);
if (len > subCommandIndex){
String arg = args[subCommandIndex].trim().toLowerCase();
AbstractCommand<?> subCommand = subCommands.get(arg);
if (subCommand != null){
if (subCommand.permission != null && !sender.hasPermission(subCommand.permission)){
sender.sendMessage(ChatColor.DARK_RED + "You don't have permission.");
return true;
}
return subCommand.onCommand(sender, command, alias, args);
}
}
// Usage.
return false;
}

}
@@ -0,0 +1,26 @@
package fr.neatmonster.nocheatplus.command;

import org.bukkit.ChatColor;
import org.bukkit.plugin.java.JavaPlugin;


/**
* Just an interface for sub commands, for future use.
* @author mc_dev
*
*/
public abstract class BaseCommand extends AbstractCommand<JavaPlugin>{


/** The prefix of every message sent by NoCheatPlus. */
public static final String TAG = ChatColor.RED + "NCP: " + ChatColor.WHITE;

public BaseCommand(JavaPlugin plugin, String label, String permission){
this(plugin, label, permission, null);
}

public BaseCommand(JavaPlugin access, String label, String permission, String[] aliases){
super(access, label, permission, aliases);
}

}

This file was deleted.

0 comments on commit 8ea5ecc

Please sign in to comment.