MassiveCore - Only One Command Chain

This commit is contained in:
Olof Larsson 2016-06-14 12:35:46 +02:00
parent 915bc49751
commit 5aa6cc730d
No known key found for this signature in database
GPG Key ID: BBEF14F97DA52474
3 changed files with 194 additions and 137 deletions

View File

@ -31,6 +31,7 @@ import com.massivecraft.massivecore.command.type.Type;
import com.massivecraft.massivecore.mixin.MixinMessage;
import com.massivecraft.massivecore.mson.Mson;
import com.massivecraft.massivecore.predicate.PredicateStartsWithIgnoreCase;
import com.massivecraft.massivecore.util.MUtil;
import com.massivecraft.massivecore.util.PermissionUtil;
import com.massivecraft.massivecore.util.Txt;
@ -68,6 +69,10 @@ public class MassiveCommand implements Active, PluginIdentifiableCommand
@Override
public void setActive(boolean active)
{
// Validate
this.validateActiveAndRoot(active, null);
// Apply
if (active)
{
getAllInstances().add(this);
@ -101,6 +106,13 @@ public class MassiveCommand implements Active, PluginIdentifiableCommand
this.setActive(plugin != null);
}
public void validateActiveAndRoot(Boolean active, Boolean root)
{
if (active == null) active = this.isActive();
if (root == null) root = this.isRoot();
if (active && ! root) throw new IllegalStateException("only root commands can be active");
}
// -------------------------------------------- //
// PLUGIN IDENTIFIABLE COMMAND
// -------------------------------------------- //
@ -117,20 +129,23 @@ public class MassiveCommand implements Active, PluginIdentifiableCommand
// Due to the large amount of methods in this class we place the fields alone here in the beginning.
// Field access and other similar utility methods have their special sections below.
// === CHILDREN ===
// === HIERARCHY ===
// The children. Previously called subcommands.
protected List<MassiveCommand> children = new ArrayList<MassiveCommand>();
// The parent command.
protected MassiveCommand parent = null;
// The child commands.
protected List<MassiveCommand> children = Collections.emptyList();
// === ALIASES ===
// The different names this commands will react to
protected List<String> aliases = new ArrayList<String>();
protected List<String> aliases = new MassiveList<>();
// === PARAMETERS ===
// The command parameters.
protected List<Parameter<?>> parameters = new ArrayList<Parameter<?>>();
protected List<Parameter<?>> parameters = new MassiveList<>();
// === PREPROCESS ===
@ -154,7 +169,7 @@ public class MassiveCommand implements Active, PluginIdentifiableCommand
// === REQUIREMENTS ===
// All these requirements must be met for the command to be executable;
protected List<Requirement> requirements = new ArrayList<Requirement>();
protected List<Requirement> requirements = new MassiveList<>();
// === HELP ===
@ -173,10 +188,7 @@ public class MassiveCommand implements Active, PluginIdentifiableCommand
// === EXECUTION ===
// The raw string arguments passed upon execution. An empty list if there are none.
protected List<String> args = new ArrayList<String>();
// The chain of commands used to reach this command during execution.
protected List<MassiveCommand> chain = new ArrayList<MassiveCommand>();
protected List<String> args = new MassiveList<>();
// The index of the next arg to read.
public int nextArg = 0;
@ -191,28 +203,174 @@ public class MassiveCommand implements Active, PluginIdentifiableCommand
public boolean senderIsConsole = false;
// -------------------------------------------- //
// CHILDREN
// HIERARCHY
// -------------------------------------------- //
public List<MassiveCommand> getChildren() { return this.children; }
@SuppressWarnings("unchecked")
public <T extends MassiveCommand> T setChildren(List<MassiveCommand> children) { this.children = children; return (T) this; }
public MassiveCommand getParent() { return this.parent; }
public boolean hasParent() { return this.getParent() != null; }
public boolean isChild() { return this.hasParent(); }
public boolean isRoot() { return ! this.hasParent(); }
public boolean isParent()
{
return this.getChildren().size() > 0;
}
public List<MassiveCommand> getChildren() { return this.children; }
public boolean hasChildren() { return ! this.getChildren().isEmpty(); }
public boolean isParent() { return this.hasChildren(); }
public boolean isLeaf() { return ! this.hasChildren(); }
public List<MassiveCommand> getVisibleChildren(CommandSender watcher)
{
// Create
List<MassiveCommand> ret = new MassiveList<>();
// Fill
for (MassiveCommand child : this.getChildren())
{
if (child.isVisibleTo(watcher)) ret.add(child);
}
// Return
return ret;
}
public MassiveCommand getRoot()
{
// Create
MassiveCommand ret = this;
// Fill
while (ret.hasParent())
{
ret = ret.getParent();
}
// Return
return ret;
}
// The parents is like a stack trace.
// We start with ourselves. The root is at the end.
public List<MassiveCommand> getParents(boolean includeSelf)
{
// Create
List<MassiveCommand> ret = new MassiveList<>();
// Fill
if (includeSelf) ret.add(this);
MassiveCommand parent = this.getParent();
while (parent != null)
{
ret.add(parent);
parent = parent.getParent();
}
// Return
return ret;
}
// The chain is the parents in reversed order.
public List<MassiveCommand> getChain(boolean includeSelf)
{
List<MassiveCommand> ret = this.getParents(includeSelf);
Collections.reverse(ret);
return ret;
}
public void removeParent()
{
// NoChange
if (!this.hasParent()) return;
// Apply
MassiveCommand parent = this.getParent();
parent.removeChild(this);
this.parent = null;
}
public void setParent(MassiveCommand parent)
{
// NoChange
if (MUtil.equals(this.getParent(), parent)) return;
// Remove
this.removeParent();
// NoSet
if (parent == null) return;
// Validate
this.validateActiveAndRoot(null, false);
// Apply
this.parent = parent;
parent.addChild(this);
}
@SuppressWarnings("unchecked")
public <T extends MassiveCommand> T addChild(MassiveCommand child)
{
// NoChange
if (this.getChildren().indexOf(child) != -1) return (T) this;
// Apply
return this.addChild(child, this.getChildren().size());
}
public <T extends MassiveCommand> T addChildAfter(MassiveCommand child, MassiveCommand after)
{
int index = this.getChildren().indexOf(after);
if (index == -1)
{
index = this.getChildren().size();
}
else
{
index++;
}
return this.addChild(child, index);
}
public int replaceChild(MassiveCommand child, MassiveCommand replaced)
{
int index = this.removeChild(replaced);
if (index < 0) return index;
this.addChild(child, index);
return index;
}
public int removeChild(MassiveCommand child)
{
List<MassiveCommand> children = new MassiveList<>(this.getChildren());
int index = children.indexOf(child);
if (index == -1) return -1;
children.remove(index);
this.children = Collections.unmodifiableList(children);
child.removeParent();
return index;
}
@SuppressWarnings("unchecked")
public <T extends MassiveCommand> T addChild(MassiveCommand child, int index)
{
if (!this.hasChildren() && !(child instanceof MassiveCommandHelp))
{
this.getHelpCommand();
index++;
}
List<MassiveCommand> children = new MassiveList<>(this.getChildren());
children.add(index, child);
this.children = Collections.unmodifiableList(children);
child.setParent(this);
return (T) this;
}
public MassiveCommandHelp getHelpCommand()
{
if ( ! this.hasChildren()) this.addChild(new MassiveCommandHelp(), 0);
List<MassiveCommand> children = this.getChildren();
return (MassiveCommandHelp) children.get(0);
}
// -------------------------------------------- //
// CHILDREN > GET
// -------------------------------------------- //
@ -321,58 +479,6 @@ public class MassiveCommand implements Active, PluginIdentifiableCommand
return 3; // If it were 8 characters or more, we end up here. Because many characters allow for more typos.
}
// -------------------------------------------- //
// CHILDREN > ADD & REMOVE
// -------------------------------------------- //
public <T extends MassiveCommand> T addChild(MassiveCommand child)
{
return this.addChild(child, this.children.size());
}
public <T extends MassiveCommand> T addChildAfter(MassiveCommand child, MassiveCommand after)
{
int index = this.children.indexOf(after);
if (index == -1)
{
index = this.children.size();
}
else
{
index++;
}
return this.addChild(child, index);
}
public int removeChild(MassiveCommand child)
{
int index = this.children.indexOf(child);
this.children.remove(index);
return index;
}
public int replaceChild(MassiveCommand child, MassiveCommand replaced)
{
int index = this.removeChild(replaced);
if (index < 0) return index;
this.addChild(child, index);
return index;
}
@SuppressWarnings("unchecked")
public <T extends MassiveCommand> T addChild(MassiveCommand child, int index)
{
if (this.children.isEmpty() && ! (child instanceof MassiveCommandHelp))
{
this.children.add(0, new MassiveCommandHelp());
index++;
}
child.addToChain(this);
this.children.add(index, child);
return (T) this;
}
// -------------------------------------------- //
// ALIASES
// -------------------------------------------- //
@ -789,47 +895,15 @@ public class MassiveCommand implements Active, PluginIdentifiableCommand
public List<String> getArgs() { return this.args; }
public void setArgs(List<String> args) { this.args = args; }
public List<MassiveCommand> getChain() { return new MassiveList<>(this.chain); }
public void setChain(List<MassiveCommand> chain) { this.chain = new MassiveList<>(chain); }
// Adds command to tree structure
public void addToChain(MassiveCommand command)
{
this.chain.add(0, command);
List<MassiveCommand> children = this.getChildren();
for (MassiveCommand child : children)
{
child.addToChain(command);
}
}
public MassiveCommand getParent()
{
List<MassiveCommand> chain = this.getChain();
if (chain == null) return null;
if (chain.isEmpty()) return null;
return chain.get(chain.size()-1);
}
public boolean hasParent()
{
return this.getParent() != null;
}
// -------------------------------------------- //
// EXECUTOR
// -------------------------------------------- //
public void execute(CommandSender sender, List<String> args, List<MassiveCommand> chain)
public void execute(CommandSender sender, List<String> args)
{
try
{
// Update Chain
this.setChain(chain);
// Sender Field - Setup
this.senderFieldsOuter(sender);
@ -852,9 +926,7 @@ public class MassiveCommand implements Active, PluginIdentifiableCommand
{
MassiveCommand child = matches.entrySet().iterator().next().getValue();
args.remove(0);
List<MassiveCommand> childChain = new MassiveList<>(chain);
childChain.add(this);
child.execute(sender, args, childChain);
child.execute(sender, args);
}
// Crap!
else
@ -883,11 +955,11 @@ public class MassiveCommand implements Active, PluginIdentifiableCommand
// Message: "/f ally ..."
for (MassiveCommand suggestion : suggestions)
{
MixinMessage.get().messageOne(sender, suggestion.getTemplate(suggestion.getChain(), false, false, sender));
MixinMessage.get().messageOne(sender, suggestion.getTemplate(false, false, sender));
}
// Message: "Use /Y to see all commands."
MixinMessage.get().messageOne(sender, Lang.COMMAND_CHILD_HELP.replaceAll(Lang.COMMAND_REPLACEMENT, this.getTemplate(chain, false, false, sender)).command(this));
MixinMessage.get().messageOne(sender, Lang.COMMAND_CHILD_HELP.replaceAll(Lang.COMMAND_REPLACEMENT, this.getTemplate(false, false, sender)).command(this));
}
// NOTE: This return statement will jump to the finally block.
@ -936,19 +1008,11 @@ public class MassiveCommand implements Active, PluginIdentifiableCommand
}
public void execute(CommandSender sender, List<String> args)
{
execute(sender, args, new ArrayList<MassiveCommand>());
}
// This is where the command action is performed.
public void perform() throws MassiveException
{
// Per default we just act as the help command!
List<MassiveCommand> chain = this.getChain();
chain.add(this);
MassiveCommandHelp.get().execute(this.sender, this.getArgs(), chain);
// Per default we just run the help command!
this.getHelpCommand().execute(this.sender, this.getArgs());
}
// -------------------------------------------- //
@ -995,14 +1059,13 @@ public class MassiveCommand implements Active, PluginIdentifiableCommand
public static final Mson TEMPLATE_CORE = Mson.mson("/").color(ChatColor.AQUA);
public Mson getTemplate(List<MassiveCommand> chain, boolean addDesc, boolean onlyFirstAlias, CommandSender sender)
public Mson getTemplate(boolean addDesc, boolean onlyFirstAlias, CommandSender sender)
{
// Create Ret
Mson ret = TEMPLATE_CORE;
// Get chain
List<MassiveCommand> commands = new ArrayList<MassiveCommand>(chain);
commands.add(this);
// Get commands
List<MassiveCommand> commands = this.getChain(true);
// Add commands
boolean first = true;
@ -1073,19 +1136,14 @@ public class MassiveCommand implements Active, PluginIdentifiableCommand
return ret;
}
public Mson getTemplate(List<MassiveCommand> chain, boolean addDesc, boolean onlyFirstAlias)
public Mson getTemplate(boolean addDesc, boolean onlyFirstAlias)
{
return getTemplate(chain, addDesc, onlyFirstAlias, sender);
}
public Mson getTemplate(List<MassiveCommand> chain, boolean addDesc)
{
return getTemplate(chain, addDesc, false);
return getTemplate( addDesc, onlyFirstAlias, sender);
}
public Mson getTemplate(boolean addDesc)
{
return getTemplate(this.getChain(), addDesc);
return getTemplate(addDesc, false);
}
public Mson getTemplate()
@ -1111,7 +1169,7 @@ public class MassiveCommand implements Active, PluginIdentifiableCommand
ret.append('/');
// Then parent commands
for (MassiveCommand parent : this.getChain())
for (MassiveCommand parent : this.getChain(false))
{
// Append parent
ret.append(parent.getAliases().get(0));
@ -1119,6 +1177,7 @@ public class MassiveCommand implements Active, PluginIdentifiableCommand
// Append space
ret.append(' ');
}
// Then ourself
ret.append(this.getAliases().get(0));

View File

@ -1,6 +1,5 @@
package com.massivecraft.massivecore.command;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.ChatColor;
@ -8,6 +7,7 @@ import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.massivecraft.massivecore.MassiveException;
import com.massivecraft.massivecore.collections.MassiveList;
import com.massivecraft.massivecore.mson.Mson;
import com.massivecraft.massivecore.util.Txt;
@ -46,7 +46,7 @@ public class MassiveCommandHelp extends MassiveCommand
MassiveCommand parent = this.getParent();
// Create Lines
List<Mson> lines = new ArrayList<Mson>();
List<Mson> lines = new MassiveList<>();
for (Object helpline : parent.getHelp())
{
lines.add(mson(Mson.parse("<a># "), helpline).color(ChatColor.YELLOW));
@ -55,7 +55,7 @@ public class MassiveCommandHelp extends MassiveCommand
for (MassiveCommand child : parent.getChildren())
{
if ( ! child.isVisibleTo(sender)) continue;
lines.add(child.getTemplate(this.getChain(), true, true, sender));
lines.add(child.getTemplate(true, true, sender));
}
// Send Lines

View File

@ -80,9 +80,7 @@ public class CommandEditAbstract<O, V> extends MassiveCommand
{
// ... skip directly to it.
CommandEditShow<?, ?> cmd = (CommandEditShow<?, ?>) children.get(0);
List<MassiveCommand> chain = this.getChain();
chain.add(this);
cmd.execute(this.sender, this.args, chain);
cmd.execute(this.sender, this.args);
}
else
{