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.mixin.MixinMessage;
import com.massivecraft.massivecore.mson.Mson; import com.massivecraft.massivecore.mson.Mson;
import com.massivecraft.massivecore.predicate.PredicateStartsWithIgnoreCase; import com.massivecraft.massivecore.predicate.PredicateStartsWithIgnoreCase;
import com.massivecraft.massivecore.util.MUtil;
import com.massivecraft.massivecore.util.PermissionUtil; import com.massivecraft.massivecore.util.PermissionUtil;
import com.massivecraft.massivecore.util.Txt; import com.massivecraft.massivecore.util.Txt;
@ -68,6 +69,10 @@ public class MassiveCommand implements Active, PluginIdentifiableCommand
@Override @Override
public void setActive(boolean active) public void setActive(boolean active)
{ {
// Validate
this.validateActiveAndRoot(active, null);
// Apply
if (active) if (active)
{ {
getAllInstances().add(this); getAllInstances().add(this);
@ -101,6 +106,13 @@ public class MassiveCommand implements Active, PluginIdentifiableCommand
this.setActive(plugin != null); 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 // 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. // 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. // Field access and other similar utility methods have their special sections below.
// === CHILDREN === // === HIERARCHY ===
// The children. Previously called subcommands. // The parent command.
protected List<MassiveCommand> children = new ArrayList<MassiveCommand>(); protected MassiveCommand parent = null;
// The child commands.
protected List<MassiveCommand> children = Collections.emptyList();
// === ALIASES === // === ALIASES ===
// The different names this commands will react to // The different names this commands will react to
protected List<String> aliases = new ArrayList<String>(); protected List<String> aliases = new MassiveList<>();
// === PARAMETERS === // === PARAMETERS ===
// The command parameters. // The command parameters.
protected List<Parameter<?>> parameters = new ArrayList<Parameter<?>>(); protected List<Parameter<?>> parameters = new MassiveList<>();
// === PREPROCESS === // === PREPROCESS ===
@ -154,7 +169,7 @@ public class MassiveCommand implements Active, PluginIdentifiableCommand
// === REQUIREMENTS === // === REQUIREMENTS ===
// All these requirements must be met for the command to be executable; // 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 === // === HELP ===
@ -173,10 +188,7 @@ public class MassiveCommand implements Active, PluginIdentifiableCommand
// === EXECUTION === // === EXECUTION ===
// The raw string arguments passed upon execution. An empty list if there are none. // The raw string arguments passed upon execution. An empty list if there are none.
protected List<String> args = new ArrayList<String>(); protected List<String> args = new MassiveList<>();
// The chain of commands used to reach this command during execution.
protected List<MassiveCommand> chain = new ArrayList<MassiveCommand>();
// The index of the next arg to read. // The index of the next arg to read.
public int nextArg = 0; public int nextArg = 0;
@ -191,28 +203,174 @@ public class MassiveCommand implements Active, PluginIdentifiableCommand
public boolean senderIsConsole = false; public boolean senderIsConsole = false;
// -------------------------------------------- // // -------------------------------------------- //
// CHILDREN // HIERARCHY
// -------------------------------------------- // // -------------------------------------------- //
public List<MassiveCommand> getChildren() { return this.children; } public MassiveCommand getParent() { return this.parent; }
@SuppressWarnings("unchecked") public boolean hasParent() { return this.getParent() != null; }
public <T extends MassiveCommand> T setChildren(List<MassiveCommand> children) { this.children = children; return (T) this; } public boolean isChild() { return this.hasParent(); }
public boolean isRoot() { return ! this.hasParent(); }
public boolean isParent() public List<MassiveCommand> getChildren() { return this.children; }
{ public boolean hasChildren() { return ! this.getChildren().isEmpty(); }
return this.getChildren().size() > 0; public boolean isParent() { return this.hasChildren(); }
} public boolean isLeaf() { return ! this.hasChildren(); }
public List<MassiveCommand> getVisibleChildren(CommandSender watcher) public List<MassiveCommand> getVisibleChildren(CommandSender watcher)
{ {
// Create
List<MassiveCommand> ret = new MassiveList<>(); List<MassiveCommand> ret = new MassiveList<>();
// Fill
for (MassiveCommand child : this.getChildren()) for (MassiveCommand child : this.getChildren())
{ {
if (child.isVisibleTo(watcher)) ret.add(child); if (child.isVisibleTo(watcher)) ret.add(child);
} }
// Return
return ret; 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 // 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. 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 // ALIASES
// -------------------------------------------- // // -------------------------------------------- //
@ -790,46 +896,14 @@ public class MassiveCommand implements Active, PluginIdentifiableCommand
public List<String> getArgs() { return this.args; } public List<String> getArgs() { return this.args; }
public void setArgs(List<String> args) { this.args = 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 // EXECUTOR
// -------------------------------------------- // // -------------------------------------------- //
public void execute(CommandSender sender, List<String> args, List<MassiveCommand> chain) public void execute(CommandSender sender, List<String> args)
{ {
try try
{ {
// Update Chain
this.setChain(chain);
// Sender Field - Setup // Sender Field - Setup
this.senderFieldsOuter(sender); this.senderFieldsOuter(sender);
@ -852,9 +926,7 @@ public class MassiveCommand implements Active, PluginIdentifiableCommand
{ {
MassiveCommand child = matches.entrySet().iterator().next().getValue(); MassiveCommand child = matches.entrySet().iterator().next().getValue();
args.remove(0); args.remove(0);
List<MassiveCommand> childChain = new MassiveList<>(chain); child.execute(sender, args);
childChain.add(this);
child.execute(sender, args, childChain);
} }
// Crap! // Crap!
else else
@ -883,11 +955,11 @@ public class MassiveCommand implements Active, PluginIdentifiableCommand
// Message: "/f ally ..." // Message: "/f ally ..."
for (MassiveCommand suggestion : suggestions) 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." // 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. // 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. // This is where the command action is performed.
public void perform() throws MassiveException public void perform() throws MassiveException
{ {
// Per default we just act as the help command! // Per default we just run the help command!
List<MassiveCommand> chain = this.getChain(); this.getHelpCommand().execute(this.sender, this.getArgs());
chain.add(this);
MassiveCommandHelp.get().execute(this.sender, this.getArgs(), chain);
} }
// -------------------------------------------- // // -------------------------------------------- //
@ -995,14 +1059,13 @@ public class MassiveCommand implements Active, PluginIdentifiableCommand
public static final Mson TEMPLATE_CORE = Mson.mson("/").color(ChatColor.AQUA); 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 // Create Ret
Mson ret = TEMPLATE_CORE; Mson ret = TEMPLATE_CORE;
// Get chain // Get commands
List<MassiveCommand> commands = new ArrayList<MassiveCommand>(chain); List<MassiveCommand> commands = this.getChain(true);
commands.add(this);
// Add commands // Add commands
boolean first = true; boolean first = true;
@ -1073,19 +1136,14 @@ public class MassiveCommand implements Active, PluginIdentifiableCommand
return ret; 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); return getTemplate( addDesc, onlyFirstAlias, sender);
}
public Mson getTemplate(List<MassiveCommand> chain, boolean addDesc)
{
return getTemplate(chain, addDesc, false);
} }
public Mson getTemplate(boolean addDesc) public Mson getTemplate(boolean addDesc)
{ {
return getTemplate(this.getChain(), addDesc); return getTemplate(addDesc, false);
} }
public Mson getTemplate() public Mson getTemplate()
@ -1111,7 +1169,7 @@ public class MassiveCommand implements Active, PluginIdentifiableCommand
ret.append('/'); ret.append('/');
// Then parent commands // Then parent commands
for (MassiveCommand parent : this.getChain()) for (MassiveCommand parent : this.getChain(false))
{ {
// Append parent // Append parent
ret.append(parent.getAliases().get(0)); ret.append(parent.getAliases().get(0));
@ -1119,6 +1177,7 @@ public class MassiveCommand implements Active, PluginIdentifiableCommand
// Append space // Append space
ret.append(' '); ret.append(' ');
} }
// Then ourself // Then ourself
ret.append(this.getAliases().get(0)); ret.append(this.getAliases().get(0));

View File

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

View File

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