Command Conditions and MANY other code changes for Generics <3🌮

This completes and fully enables a new feature called "Conditions"

We already had some forms of conditions built into @Flags such as
on the Player for itemheld.

However, letting end users add additional restrictions to existing context
handlers such as players is not possible without redefining the context.

That's not friendly nor scalable.

Flags will now be primarily only for controlling how to resolve a context,
and then Conditions will then be the way to validate the context and trigger
a failure if the condition is not met.

Conditions can be placed on Command Class, Methods, or individual Parameters.
This commit is contained in:
Aikar
2018-01-08 23:30:27 -05:00
parent 01f47211bb
commit 40eaa9ea07
29 changed files with 255 additions and 291 deletions
@@ -24,15 +24,20 @@
package co.aikar.commands;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.entity.living.player.Player;
@SuppressWarnings("WeakerAccess")
public class SpongeCommandCompletionContext extends CommandCompletionContext {
public class SpongeCommandCompletionContext extends CommandCompletionContext<SpongeCommandIssuer> {
SpongeCommandCompletionContext(final RegisteredCommand command, final CommandIssuer issuer, final String input, final String config, final String[] args) {
SpongeCommandCompletionContext(final RegisteredCommand command, final SpongeCommandIssuer issuer, final String input, final String config, final String[] args) {
super(command, issuer, input, config, args);
}
public CommandSource getSource() {
return this.issuer.getIssuer();
}
public Player getPlayer() {
return this.issuer.getPlayer();
}
}
@@ -24,6 +24,7 @@
package co.aikar.commands;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.entity.living.player.Player;
import java.lang.reflect.Parameter;
import java.util.List;
@@ -39,4 +40,8 @@ public class SpongeCommandExecutionContext extends CommandExecutionContext<Spong
public CommandSource getSource() {
return this.issuer.getIssuer();
}
public Player getPlayer() {
return this.issuer.getPlayer();
}
}
@@ -45,9 +45,12 @@ public class SpongeCommandIssuer implements CommandIssuer {
}
@Override
public <T> T getIssuer() {
//noinspection unchecked
return (T) this.source;
public CommandSource getIssuer() {
return this.source;
}
public Player getPlayer() {
return isPlayer() ? (Player) source : null;
}
@Override
@@ -23,7 +23,6 @@
package co.aikar.commands;
import co.aikar.commands.annotation.Conditions;
import co.aikar.commands.apachecommonslang.ApacheCommonsExceptionUtil;
import co.aikar.timings.Timing;
import co.aikar.timings.Timings;
@@ -47,9 +46,7 @@ public class SpongeCommandManager extends CommandManager<
TextColor,
SpongeMessageFormatter,
SpongeCommandExecutionContext,
SpongeCommandCompletionContext,
SpongeConditionContext,
SpongeParameterConditionContext<?>
SpongeConditionContext
> {
protected final PluginContainer plugin;
@@ -150,7 +147,7 @@ public class SpongeCommandManager extends CommandManager<
@Override
public CommandCompletionContext createCompletionContext(RegisteredCommand command, CommandIssuer sender, String input, String config, String[] args) {
return new SpongeCommandCompletionContext(command, sender, input, config, args);
return new SpongeCommandCompletionContext(command, (SpongeCommandIssuer) sender, input, config, args);
}
@Override
@@ -192,15 +189,9 @@ public class SpongeCommandManager extends CommandManager<
);
}
@Override
public SpongeConditionContext createConditionContext(CommandOperationContext context, Conditions conditions) {
return new SpongeConditionContext(context.getRegisteredCommand(), (SpongeCommandIssuer) context.getCommandIssuer(), conditions);
}
@Override
public <P> SpongeParameterConditionContext createConditionContext(CommandOperationContext context, SpongeCommandExecutionContext execContext, Conditions conditions) {
return new SpongeParameterConditionContext<P>(context.getRegisteredCommand(), (SpongeCommandIssuer) context.getCommandIssuer(), execContext, conditions);
public SpongeConditionContext createConditionContext(CommandIssuer issuer, String config) {
return new SpongeConditionContext((SpongeCommandIssuer) issuer, config);
}
}
@@ -1,9 +1,19 @@
package co.aikar.commands;
import co.aikar.commands.annotation.Conditions;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.entity.living.player.Player;
public class SpongeConditionContext extends ConditionContext <SpongeCommandIssuer> {
SpongeConditionContext(RegisteredCommand cmd, SpongeCommandIssuer issuer, Conditions condAnno) {
super(cmd, issuer, condAnno);
SpongeConditionContext(SpongeCommandIssuer issuer, String config) {
super(issuer, config);
}
public CommandSource getSource() {
return getIssuer().getIssuer();
}
public Player getPlayer() {
return getIssuer().getPlayer();
}
}
@@ -1,9 +0,0 @@
package co.aikar.commands;
import co.aikar.commands.annotation.Conditions;
public class SpongeParameterConditionContext <P> extends ParameterConditionContext<P, SpongeCommandExecutionContext, SpongeCommandIssuer> {
SpongeParameterConditionContext(RegisteredCommand cmd, SpongeCommandIssuer issuer, SpongeCommandExecutionContext execContext, Conditions conditions) {
super(cmd, issuer, execContext, conditions);
}
}