mirror of
https://github.com/aikar/commands.git
synced 2026-05-31 06:11:55 +00:00
More work on Command Conditions #58
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017 Daniel Ennis (Aikar) - MIT License
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package co.aikar.commands;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.event.server.PluginDisableEvent;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
class ACFBukkitListener implements Listener {
|
||||
private BukkitCommandManager manager;
|
||||
private final Plugin plugin;
|
||||
|
||||
public ACFBukkitListener(BukkitCommandManager manager, Plugin plugin) {
|
||||
this.manager = manager;
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPluginDisable(PluginDisableEvent event) {
|
||||
if (!(plugin.getName().equalsIgnoreCase(event.getPlugin().getName()))) {
|
||||
return;
|
||||
}
|
||||
manager.unregisterCommands();
|
||||
}
|
||||
@EventHandler
|
||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
manager.readPlayerLocale(player);
|
||||
this.plugin.getServer().getScheduler().runTaskLater(this.plugin, () -> manager.readPlayerLocale(player), 20);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerJoin(PlayerQuitEvent event) {
|
||||
manager.issuersLocale.remove(event.getPlayer().getUniqueId());
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
package co.aikar.commands;
|
||||
|
||||
import co.aikar.commands.annotation.Conditions;
|
||||
import co.aikar.commands.apachecommonslang.ApacheCommonsExceptionUtil;
|
||||
import co.aikar.timings.lib.MCTiming;
|
||||
import co.aikar.timings.lib.TimingManager;
|
||||
@@ -35,11 +36,6 @@ import org.bukkit.command.CommandMap;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.SimpleCommandMap;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.event.server.PluginDisableEvent;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -57,7 +53,16 @@ import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public class BukkitCommandManager extends CommandManager<CommandSender, BukkitCommandIssuer, ChatColor, BukkitMessageFormatter> {
|
||||
public class BukkitCommandManager extends CommandManager<
|
||||
CommandSender,
|
||||
BukkitCommandIssuer,
|
||||
ChatColor,
|
||||
BukkitMessageFormatter,
|
||||
BukkitCommandExecutionContext,
|
||||
BukkitCommandCompletionContext,
|
||||
BukkitConditionContext,
|
||||
BukkitParameterConditionContext<?>
|
||||
> {
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
protected final Plugin plugin;
|
||||
@@ -85,7 +90,7 @@ public class BukkitCommandManager extends CommandManager<CommandSender, BukkitCo
|
||||
this.formatters.put(MessageType.SYNTAX, new BukkitMessageFormatter(ChatColor.YELLOW, ChatColor.GREEN, ChatColor.WHITE));
|
||||
this.formatters.put(MessageType.INFO, new BukkitMessageFormatter(ChatColor.BLUE, ChatColor.DARK_GREEN, ChatColor.GREEN));
|
||||
this.formatters.put(MessageType.HELP, new BukkitMessageFormatter(ChatColor.AQUA, ChatColor.GREEN, ChatColor.YELLOW));
|
||||
Bukkit.getPluginManager().registerEvents(new ACFBukkitListener(plugin), plugin);
|
||||
Bukkit.getPluginManager().registerEvents(new ACFBukkitListener(this, plugin), plugin);
|
||||
getLocales(); // auto load locales
|
||||
this.localeTask = Bukkit.getScheduler().runTaskTimer(plugin, () -> {
|
||||
if (cantReadLocale) {
|
||||
@@ -246,7 +251,7 @@ public class BukkitCommandManager extends CommandManager<CommandSender, BukkitCo
|
||||
return null;
|
||||
}
|
||||
|
||||
private void readPlayerLocale(Player player) {
|
||||
void readPlayerLocale(Player player) {
|
||||
if (!player.isOnline() || cantReadLocale) {
|
||||
return;
|
||||
}
|
||||
@@ -275,33 +280,6 @@ public class BukkitCommandManager extends CommandManager<CommandSender, BukkitCo
|
||||
}
|
||||
}
|
||||
|
||||
private class ACFBukkitListener implements Listener {
|
||||
private final Plugin plugin;
|
||||
|
||||
public ACFBukkitListener(Plugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPluginDisable(PluginDisableEvent event) {
|
||||
if (!(plugin.getName().equalsIgnoreCase(event.getPlugin().getName()))) {
|
||||
return;
|
||||
}
|
||||
unregisterCommands();
|
||||
}
|
||||
@EventHandler
|
||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
readPlayerLocale(player);
|
||||
this.plugin.getServer().getScheduler().runTaskLater(this.plugin, () -> readPlayerLocale(player), 20);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerJoin(PlayerQuitEvent event) {
|
||||
issuersLocale.remove(event.getPlayer().getUniqueId());
|
||||
}
|
||||
}
|
||||
|
||||
public TimingManager getTimings() {
|
||||
return timingManager;
|
||||
}
|
||||
@@ -320,13 +298,12 @@ public class BukkitCommandManager extends CommandManager<CommandSender, BukkitCo
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R extends CommandExecutionContext> R createCommandContext(RegisteredCommand command, Parameter parameter, CommandIssuer sender, List<String> args, int i, Map<String, Object> passedArgs) {
|
||||
//noinspection unchecked
|
||||
return (R) new BukkitCommandExecutionContext(command, parameter, (BukkitCommandIssuer) sender, args, i, passedArgs);
|
||||
public BukkitCommandExecutionContext createCommandContext(RegisteredCommand command, Parameter parameter, CommandIssuer sender, List<String> args, int i, Map<String, Object> passedArgs) {
|
||||
return new BukkitCommandExecutionContext(command, parameter, (BukkitCommandIssuer) sender, args, i, passedArgs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandCompletionContext createCompletionContext(RegisteredCommand command, CommandIssuer sender, String input, String config, String[] args) {
|
||||
public BukkitCommandCompletionContext createCompletionContext(RegisteredCommand command, CommandIssuer sender, String input, String config, String[] args) {
|
||||
return new BukkitCommandCompletionContext(command, sender, input, config, args);
|
||||
}
|
||||
|
||||
@@ -335,6 +312,16 @@ public class BukkitCommandManager extends CommandManager<CommandSender, BukkitCo
|
||||
return new BukkitRegisteredCommand(command, cmdName, method, prefSubCommand);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BukkitConditionContext createConditionContext(CommandOperationContext context, Conditions conditions) {
|
||||
return new BukkitConditionContext(context.getRegisteredCommand(), (BukkitCommandIssuer) context.getCommandIssuer(), conditions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <P> BukkitParameterConditionContext createConditionContext(CommandOperationContext context, BukkitCommandExecutionContext execContext, Conditions conditions) {
|
||||
return new BukkitParameterConditionContext<P>(context.getRegisteredCommand(), (BukkitCommandIssuer) context.getCommandIssuer(), execContext, conditions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(LogLevel level, String message, Throwable throwable) {
|
||||
Level logLevel = level == LogLevel.INFO ? Level.INFO : Level.SEVERE;
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017 Daniel Ennis (Aikar) - MIT License
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package co.aikar.commands;
|
||||
|
||||
import co.aikar.commands.annotation.Conditions;
|
||||
|
||||
public class BukkitConditionContext extends ConditionContext<BukkitCommandIssuer> {
|
||||
BukkitConditionContext(RegisteredCommand cmd, BukkitCommandIssuer issuer, Conditions condAnno) {
|
||||
super(cmd, issuer, condAnno);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017 Daniel Ennis (Aikar) - MIT License
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package co.aikar.commands;
|
||||
|
||||
import co.aikar.commands.annotation.Conditions;
|
||||
|
||||
public class BukkitParameterConditionContext <P> extends ParameterConditionContext<P, BukkitCommandExecutionContext, BukkitCommandIssuer> {
|
||||
BukkitParameterConditionContext(RegisteredCommand cmd, BukkitCommandIssuer issuer, BukkitCommandExecutionContext execContext, Conditions conditions) {
|
||||
super(cmd, issuer, execContext, conditions);
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
package co.aikar.commands;
|
||||
|
||||
import co.aikar.commands.annotation.Conditions;
|
||||
import co.aikar.commands.apachecommonslang.ApacheCommonsExceptionUtil;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
@@ -36,7 +37,16 @@ import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class BungeeCommandManager extends CommandManager<CommandSender, BungeeCommandIssuer, ChatColor, BungeeMessageFormatter> {
|
||||
public class BungeeCommandManager extends CommandManager<
|
||||
CommandSender,
|
||||
BungeeCommandIssuer,
|
||||
ChatColor,
|
||||
BungeeMessageFormatter,
|
||||
BungeeCommandExecutionContext,
|
||||
BungeeCommandCompletionContext,
|
||||
BungeeConditionContext,
|
||||
BungeeParameterConditionContext<?>
|
||||
> {
|
||||
|
||||
protected final Plugin plugin;
|
||||
protected Map<String, BungeeRootCommand> registeredCommands = new HashMap<>();
|
||||
@@ -144,9 +154,8 @@ public class BungeeCommandManager extends CommandManager<CommandSender, BungeeCo
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R extends CommandExecutionContext> R createCommandContext(RegisteredCommand command, Parameter parameter, CommandIssuer sender, List<String> args, int i, Map<String, Object> passedArgs) {
|
||||
//noinspection unchecked
|
||||
return (R) new BungeeCommandExecutionContext(command, parameter, (BungeeCommandIssuer) sender, args, i, passedArgs);
|
||||
public BungeeCommandExecutionContext createCommandContext(RegisteredCommand command, Parameter parameter, CommandIssuer sender, List<String> args, int i, Map<String, Object> passedArgs) {
|
||||
return new BungeeCommandExecutionContext(command, parameter, (BungeeCommandIssuer) sender, args, i, passedArgs);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -154,6 +163,18 @@ public class BungeeCommandManager extends CommandManager<CommandSender, BungeeCo
|
||||
return new BungeeCommandCompletionContext(command, sender, input, config, args);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BungeeConditionContext createConditionContext(CommandOperationContext context, Conditions conditions) {
|
||||
return new BungeeConditionContext(context.getRegisteredCommand(), (BungeeCommandIssuer) context.getCommandIssuer(), conditions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <P> BungeeParameterConditionContext createConditionContext(CommandOperationContext context, BungeeCommandExecutionContext execContext, Conditions conditions) {
|
||||
return new BungeeParameterConditionContext<P>(context.getRegisteredCommand(), (BungeeCommandIssuer) context.getCommandIssuer(), execContext, conditions);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public RegisteredCommand createRegisteredCommand(BaseCommand command, String cmdName, Method method, String prefSubCommand) {
|
||||
return new RegisteredCommand(command, cmdName, method, prefSubCommand);
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package co.aikar.commands;
|
||||
|
||||
import co.aikar.commands.annotation.Conditions;
|
||||
|
||||
public class BungeeConditionContext extends ConditionContext <BungeeCommandIssuer> {
|
||||
BungeeConditionContext(RegisteredCommand cmd, BungeeCommandIssuer issuer, Conditions condAnno) {
|
||||
super(cmd, issuer, condAnno);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package co.aikar.commands;
|
||||
|
||||
import co.aikar.commands.annotation.Conditions;
|
||||
|
||||
public class BungeeParameterConditionContext <P> extends ParameterConditionContext<P, BungeeCommandExecutionContext, BungeeCommandIssuer> {
|
||||
BungeeParameterConditionContext(RegisteredCommand cmd, BungeeCommandIssuer issuer, BungeeCommandExecutionContext execContext, Conditions conditions) {
|
||||
super(cmd, issuer, execContext, conditions);
|
||||
}
|
||||
}
|
||||
@@ -71,7 +71,7 @@ public abstract class BaseCommand {
|
||||
private String execSubcommand;
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
private String[] origArgs;
|
||||
CommandManager<?, ?, ?, ?> manager = null;
|
||||
CommandManager<?, ?, ?, ?, ?, ?, ?, ?> manager = null;
|
||||
BaseCommand parentCommand;
|
||||
Map<String, RootCommand> registeredCommands = new HashMap<>();
|
||||
String description;
|
||||
|
||||
@@ -24,14 +24,23 @@
|
||||
package co.aikar.commands;
|
||||
|
||||
import co.aikar.commands.annotation.Conditions;
|
||||
import com.google.common.collect.HashBasedTable;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Table;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings("BooleanMethodIsAlwaysInverted") // No IDEA, you are wrong
|
||||
public class CommandConditions <M extends CommandManager, CC extends ConditionContext> {
|
||||
public class CommandConditions <
|
||||
I extends CommandIssuer,
|
||||
M extends CommandManager,
|
||||
CC extends ConditionContext,
|
||||
CEC extends CommandExecutionContext<CEC, I>,
|
||||
PCC extends ParameterConditionContext<?, CEC, I>
|
||||
> {
|
||||
M manager;
|
||||
Map<String, Condition<CC>> conditions = Maps.newHashMap();
|
||||
Table<Class<?>, String, ParameterCondition<PCC>> paramConditions = HashBasedTable.create();
|
||||
CommandConditions(M manager) {
|
||||
this.manager = manager;
|
||||
}
|
||||
@@ -40,6 +49,15 @@ public class CommandConditions <M extends CommandManager, CC extends ConditionCo
|
||||
return this.conditions.put(id.toLowerCase(), handler);
|
||||
}
|
||||
|
||||
<P> ParameterCondition addCondition(Class<P> clazz, String id, ParameterCondition<PCC> handler) {
|
||||
return this.paramConditions.put(clazz, id.toLowerCase(), handler);
|
||||
}
|
||||
|
||||
boolean validateConditions(CommandOperationContext context, CEC cec) {
|
||||
Conditions conditions = cec.getParam().getAnnotation(Conditions.class);
|
||||
return conditions == null || validateConditions(conditions, context, cec);
|
||||
}
|
||||
|
||||
boolean validateConditions(CommandOperationContext context) {
|
||||
RegisteredCommand cmd = context.getRegisteredCommand();
|
||||
Conditions conditions = cmd.method.getAnnotation(Conditions.class);
|
||||
@@ -66,7 +84,7 @@ public class CommandConditions <M extends CommandManager, CC extends ConditionCo
|
||||
return true;
|
||||
}
|
||||
//noinspection unchecked
|
||||
CC conditionContext = (CC) this.manager.createConditionContext(context);
|
||||
CC conditionContext = (CC) this.manager.createConditionContext(context, condAnno);
|
||||
String conditions = this.manager.getCommandReplacements().replace(condAnno.value());
|
||||
for (String cond : ACFPatterns.PIPE.split(conditions)) {
|
||||
String[] split = ACFPatterns.EQUALS.split(cond, 2);
|
||||
@@ -80,7 +98,40 @@ public class CommandConditions <M extends CommandManager, CC extends ConditionCo
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean validateConditions(Conditions condAnno, CommandOperationContext context, CEC execContext) {
|
||||
if (condAnno == null) {
|
||||
return true;
|
||||
}
|
||||
//noinspection unchecked
|
||||
ParameterConditionContext conditionContext = this.manager.createConditionContext(context, execContext, condAnno);
|
||||
String conditions = this.manager.getCommandReplacements().replace(condAnno.value());
|
||||
for (String cond : ACFPatterns.PIPE.split(conditions)) {
|
||||
String[] split = ACFPatterns.EQUALS.split(cond, 2);
|
||||
ParameterCondition condition;
|
||||
Class<?> cls = execContext.getParam().getClass();
|
||||
String id = split[0].toLowerCase();
|
||||
do {
|
||||
condition = this.paramConditions.get(cls, id);
|
||||
if (condition == null && cls.getSuperclass() != null && cls.getSuperclass() != Object.class) {
|
||||
cls = cls.getSuperclass();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} while (cls != null);
|
||||
|
||||
//noinspection unchecked
|
||||
if (condition != null && !condition.validateCondition(conditionContext)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
interface Condition <CC extends ConditionContext> {
|
||||
boolean validateCondition(CC context);
|
||||
}
|
||||
interface ParameterCondition <PCC extends ParameterConditionContext> {
|
||||
boolean validateCondition(PCC context);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings({"WeakerAccess", "unused"})
|
||||
public class CommandExecutionContext <T extends CommandExecutionContext, I extends CommandIssuer> {
|
||||
public class CommandExecutionContext <CEC extends CommandExecutionContext, I extends CommandIssuer> {
|
||||
private final RegisteredCommand cmd;
|
||||
private final Parameter param;
|
||||
protected final I issuer;
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
package co.aikar.commands;
|
||||
|
||||
import co.aikar.commands.annotation.Conditions;
|
||||
import co.aikar.locales.MessageKeyProvider;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
@@ -40,7 +41,16 @@ import java.util.Set;
|
||||
import java.util.Stack;
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public abstract class CommandManager <I, AI extends CommandIssuer, FT, F extends MessageFormatter<FT>> {
|
||||
public abstract class CommandManager <
|
||||
IT,
|
||||
I extends CommandIssuer,
|
||||
FT,
|
||||
MF extends MessageFormatter<FT>,
|
||||
CEC extends CommandExecutionContext<CEC, I>,
|
||||
CCC extends CommandCompletionContext,
|
||||
CC extends ConditionContext<I>,
|
||||
PCC extends ParameterConditionContext<?, CEC, I>
|
||||
> {
|
||||
|
||||
/**
|
||||
* This is a stack incase a command calls a command
|
||||
@@ -58,10 +68,10 @@ public abstract class CommandManager <I, AI extends CommandIssuer, FT, F extends
|
||||
protected ExceptionHandler defaultExceptionHandler = null;
|
||||
|
||||
protected boolean usePerIssuerLocale = false;
|
||||
protected List<IssuerLocaleChangedCallback<AI>> localeChangedCallbacks = Lists.newArrayList();
|
||||
protected List<IssuerLocaleChangedCallback<I>> localeChangedCallbacks = Lists.newArrayList();
|
||||
protected Set<Locale> supportedLanguages = Sets.newHashSet(Locales.ENGLISH, Locales.GERMAN, Locales.SPANISH, Locales.CZECH);
|
||||
protected Map<MessageType, F> formatters = new IdentityHashMap<>();
|
||||
protected F defaultFormatter;
|
||||
protected Map<MessageType, MF> formatters = new IdentityHashMap<>();
|
||||
protected MF defaultFormatter;
|
||||
protected int defaultHelpPerPage = 10;
|
||||
|
||||
private Set<String> unstableAPIs = Sets.newHashSet();
|
||||
@@ -80,31 +90,31 @@ public abstract class CommandManager <I, AI extends CommandIssuer, FT, F extends
|
||||
return context != null ? context.getCommandManager() : null;
|
||||
}
|
||||
|
||||
public F setFormat(MessageType type, F formatter) {
|
||||
public MF setFormat(MessageType type, MF formatter) {
|
||||
return formatters.put(type, formatter);
|
||||
}
|
||||
|
||||
public F getFormat(MessageType type) {
|
||||
public MF getFormat(MessageType type) {
|
||||
return formatters.getOrDefault(type, defaultFormatter);
|
||||
}
|
||||
|
||||
public void setFormat(MessageType type, FT... colors) {
|
||||
F format = getFormat(type);
|
||||
MF format = getFormat(type);
|
||||
for (int i = 0; i < colors.length; i++) {
|
||||
format.setColor(i, colors[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public void setFormat(MessageType type, int i, FT color) {
|
||||
F format = getFormat(type);
|
||||
MF format = getFormat(type);
|
||||
format.setColor(i, color);
|
||||
}
|
||||
|
||||
public F getDefaultFormatter() {
|
||||
public MF getDefaultFormatter() {
|
||||
return defaultFormatter;
|
||||
}
|
||||
|
||||
public void setDefaultFormatter(F defaultFormatter) {
|
||||
public void setDefaultFormatter(MF defaultFormatter) {
|
||||
this.defaultFormatter = defaultFormatter;
|
||||
}
|
||||
|
||||
@@ -176,7 +186,7 @@ public abstract class CommandManager <I, AI extends CommandIssuer, FT, F extends
|
||||
public abstract boolean isCommandIssuer(Class<?> type);
|
||||
|
||||
// TODO: Change this to I if we make a breaking change
|
||||
public abstract AI getCommandIssuer(Object issuer);
|
||||
public abstract I getCommandIssuer(Object issuer);
|
||||
|
||||
public abstract RootCommand createRootCommand(String cmd);
|
||||
|
||||
@@ -195,12 +205,17 @@ public abstract class CommandManager <I, AI extends CommandIssuer, FT, F extends
|
||||
usePerIssuerLocale = setting;
|
||||
return old;
|
||||
}
|
||||
public <R extends ConditionContext> R createConditionContext(CommandOperationContext context) {
|
||||
public ConditionContext createConditionContext(CommandOperationContext context, Conditions conditions) {
|
||||
//noinspection unchecked
|
||||
return (R) new ConditionContext<>(context.getRegisteredCommand(), context.getCommandIssuer());
|
||||
return new ConditionContext<>(context.getRegisteredCommand(), context.getCommandIssuer(), conditions);
|
||||
}
|
||||
|
||||
public abstract <R extends CommandExecutionContext> R createCommandContext(RegisteredCommand command, Parameter parameter, CommandIssuer sender, List<String> args, int i, Map<String, Object> passedArgs);
|
||||
public <P> ParameterConditionContext createConditionContext(CommandOperationContext context, CEC execContext, Conditions conditions) {
|
||||
//noinspection unchecked
|
||||
return new ParameterConditionContext<P, CEC, I>(context.getRegisteredCommand(), (I) context.getCommandIssuer(), execContext, conditions);
|
||||
}
|
||||
|
||||
public abstract CommandExecutionContext createCommandContext(RegisteredCommand command, Parameter parameter, CommandIssuer sender, List<String> args, int i, Map<String, Object> passedArgs);
|
||||
|
||||
public abstract CommandCompletionContext createCompletionContext(RegisteredCommand command, CommandIssuer sender, String input, String config, String[] args);
|
||||
|
||||
@@ -286,7 +301,7 @@ public abstract class CommandManager <I, AI extends CommandIssuer, FT, F extends
|
||||
return result;
|
||||
}
|
||||
|
||||
public void sendMessage(I issuerArg, MessageType type, MessageKeyProvider key, String... replacements) {
|
||||
public void sendMessage(IT issuerArg, MessageType type, MessageKeyProvider key, String... replacements) {
|
||||
sendMessage(getCommandIssuer(issuerArg), type, key, replacements);
|
||||
}
|
||||
|
||||
@@ -313,11 +328,11 @@ public abstract class CommandManager <I, AI extends CommandIssuer, FT, F extends
|
||||
return message;
|
||||
}
|
||||
|
||||
public void onLocaleChange(IssuerLocaleChangedCallback<AI> onChange) {
|
||||
public void onLocaleChange(IssuerLocaleChangedCallback<I> onChange) {
|
||||
localeChangedCallbacks.add(onChange);
|
||||
}
|
||||
|
||||
public void notifyLocaleChange(AI issuer, Locale oldLocale, Locale newLocale) {
|
||||
public void notifyLocaleChange(I issuer, Locale oldLocale, Locale newLocale) {
|
||||
localeChangedCallbacks.forEach(cb -> {
|
||||
try {
|
||||
cb.onIssuerLocaleChange(issuer, oldLocale, newLocale);
|
||||
@@ -331,11 +346,11 @@ public abstract class CommandManager <I, AI extends CommandIssuer, FT, F extends
|
||||
return getLocales().getDefaultLocale();
|
||||
}
|
||||
|
||||
CommandOperationContext<AI> createCommandOperationContext(BaseCommand command, CommandIssuer issuer, String commandLabel, String[] args, boolean isAsync) {
|
||||
CommandOperationContext<I> createCommandOperationContext(BaseCommand command, CommandIssuer issuer, String commandLabel, String[] args, boolean isAsync) {
|
||||
//noinspection unchecked
|
||||
return new CommandOperationContext<>(
|
||||
this,
|
||||
(AI) issuer,
|
||||
(I) issuer,
|
||||
command,
|
||||
commandLabel,
|
||||
args,
|
||||
|
||||
@@ -23,21 +23,42 @@
|
||||
|
||||
package co.aikar.commands;
|
||||
|
||||
import co.aikar.commands.annotation.Conditions;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class ConditionContext <I extends CommandIssuer> {
|
||||
|
||||
private final RegisteredCommand cmd;
|
||||
private final I issuer;
|
||||
private final Conditions condAnno;
|
||||
private final Map<String, String> flags;
|
||||
|
||||
ConditionContext(RegisteredCommand cmd, I issuer) {
|
||||
ConditionContext(RegisteredCommand cmd, I issuer, Conditions condAnno) {
|
||||
this.cmd = cmd;
|
||||
this.issuer = issuer;
|
||||
}
|
||||
|
||||
public RegisteredCommand getCmd() {
|
||||
return cmd;
|
||||
this.condAnno = condAnno;
|
||||
this.flags = Maps.newHashMap();
|
||||
for (String s : ACFPatterns.COMMA.split(cmd.scope.manager.getCommandReplacements().replace(condAnno.value()))) {
|
||||
String[] v = ACFPatterns.EQUALS.split(s, 2);
|
||||
this.flags.put(v[0], v.length > 1 ? v[1] : null);
|
||||
}
|
||||
}
|
||||
|
||||
public I getIssuer() {
|
||||
return issuer;
|
||||
}
|
||||
|
||||
public boolean hasFlag(String flag) {
|
||||
return flags.containsKey(flag);
|
||||
}
|
||||
|
||||
public String getFlagValue(String flag, String def) {
|
||||
return flags.getOrDefault(flag, def);
|
||||
}
|
||||
|
||||
public Integer getFlagValue(String flag, Integer def) {
|
||||
return ACFUtil.parseInt(this.flags.get(flag), def);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ public class Locales {
|
||||
public static final Locale WELSH = new Locale("cy");
|
||||
|
||||
|
||||
private final CommandManager<?, ?, ?, ?> manager;
|
||||
private final CommandManager<?, ?, ?, ?, ?, ?, ?, ?> manager;
|
||||
private final LocaleManager<CommandIssuer> localeManager;
|
||||
private final SetMultimap<String, Locale> loadedBundles = HashMultimap.create();
|
||||
|
||||
|
||||
@@ -31,18 +31,18 @@ import java.util.regex.Matcher;
|
||||
|
||||
/**
|
||||
* Handles formatting Messages and managing colors
|
||||
* @param <C> The platform specific color object
|
||||
* @param <FT> The platform specific color object
|
||||
*/
|
||||
public abstract class MessageFormatter <C> {
|
||||
public abstract class MessageFormatter <FT> {
|
||||
|
||||
private final List<C> colors = new ArrayList<>();
|
||||
private final List<FT> colors = new ArrayList<>();
|
||||
|
||||
@SafeVarargs
|
||||
public MessageFormatter(C... colors) {
|
||||
public MessageFormatter(FT... colors) {
|
||||
this.colors.addAll(Arrays.asList(colors));
|
||||
|
||||
}
|
||||
public C setColor(int index, C color) {
|
||||
public FT setColor(int index, FT color) {
|
||||
if (index > 0) {
|
||||
index--;
|
||||
} else {
|
||||
@@ -60,24 +60,24 @@ public abstract class MessageFormatter <C> {
|
||||
}
|
||||
}
|
||||
|
||||
public C getColor(int index) {
|
||||
public FT getColor(int index) {
|
||||
if (index > 0) {
|
||||
index--;
|
||||
} else {
|
||||
index = 0;
|
||||
}
|
||||
C color = colors.get(index);
|
||||
FT color = colors.get(index);
|
||||
if (color == null) {
|
||||
color = getDefaultColor();
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
public C getDefaultColor() {
|
||||
public FT getDefaultColor() {
|
||||
return getColor(1);
|
||||
}
|
||||
|
||||
abstract String format(C color, String message);
|
||||
abstract String format(FT color, String message);
|
||||
|
||||
public String format(int index, String message) {
|
||||
return format(getColor(index), message);
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017 Daniel Ennis (Aikar) - MIT License
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package co.aikar.commands;
|
||||
|
||||
import co.aikar.commands.annotation.Conditions;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ParameterConditionContext <P, CEC extends CommandExecutionContext, I extends CommandIssuer> extends ConditionContext<I> {
|
||||
|
||||
private final CEC execContext;
|
||||
|
||||
ParameterConditionContext(RegisteredCommand cmd, I issuer, CEC execContext, Conditions conditions) {
|
||||
super(cmd, issuer, conditions);
|
||||
|
||||
this.execContext = execContext;
|
||||
}
|
||||
|
||||
public boolean isLastArg() {
|
||||
return execContext.isLastArg();
|
||||
}
|
||||
|
||||
public int getNumParams() {
|
||||
return execContext.getNumParams();
|
||||
}
|
||||
|
||||
public boolean canOverridePlayerContext() {
|
||||
return execContext.canOverridePlayerContext();
|
||||
}
|
||||
|
||||
public Object getResolvedArg(String arg) {
|
||||
return execContext.getResolvedArg(arg);
|
||||
}
|
||||
|
||||
public Object getResolvedArg(Class[] classes) {
|
||||
return execContext.getResolvedArg(classes);
|
||||
}
|
||||
|
||||
public Object getResolvedArg(String key, Class[] classes) {
|
||||
return execContext.getResolvedArg(key, classes);
|
||||
}
|
||||
|
||||
public boolean isOptional() {
|
||||
return execContext.isOptional();
|
||||
}
|
||||
|
||||
public Annotation getAnnotation(Class cls) {
|
||||
return execContext.getAnnotation(cls);
|
||||
}
|
||||
|
||||
public boolean hasAnnotation(Class cls) {
|
||||
return execContext.hasAnnotation(cls);
|
||||
}
|
||||
|
||||
public List<String> getArgs() {
|
||||
return execContext.getArgs();
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
return execContext.getIndex();
|
||||
}
|
||||
|
||||
public Map<String, Object> getPassedArgs() {
|
||||
return execContext.getPassedArgs();
|
||||
}
|
||||
|
||||
public String joinArgs() {
|
||||
return execContext.joinArgs();
|
||||
}
|
||||
|
||||
public String joinArgs(String sep) {
|
||||
return execContext.joinArgs(sep);
|
||||
}
|
||||
}
|
||||
@@ -52,13 +52,13 @@ import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public class RegisteredCommand <R extends CommandExecutionContext<? extends CommandExecutionContext, ? extends CommandIssuer>> {
|
||||
public class RegisteredCommand <CEC extends CommandExecutionContext<? extends CommandExecutionContext, ? extends CommandIssuer>> {
|
||||
final BaseCommand scope;
|
||||
final String command;
|
||||
final Method method;
|
||||
final String prefSubCommand;
|
||||
final Parameter[] parameters;
|
||||
final ContextResolver<?, R>[] resolvers;
|
||||
final ContextResolver<?, CEC>[] resolvers;
|
||||
final String syntaxText;
|
||||
final String helpText;
|
||||
|
||||
@@ -67,7 +67,7 @@ public class RegisteredCommand <R extends CommandExecutionContext<? extends Comm
|
||||
final int requiredResolvers;
|
||||
final int optionalResolvers;
|
||||
final List<String> registeredSubcommands = new ArrayList<>();
|
||||
private final CommandManager<?, ?, ?, ?> manager;
|
||||
private final CommandManager<?, ?, ?, ?, ?, ?, ?, ?> manager;
|
||||
|
||||
RegisteredCommand(BaseCommand scope, String command, Method method, String prefSubCommand) {
|
||||
this.scope = scope;
|
||||
@@ -100,7 +100,7 @@ public class RegisteredCommand <R extends CommandExecutionContext<? extends Comm
|
||||
final Class<?> type = parameter.getType();
|
||||
|
||||
//noinspection unchecked
|
||||
final ContextResolver<?, R> resolver = commandContexts.getResolver(type);
|
||||
final ContextResolver<?, CEC> resolver = commandContexts.getResolver(type);
|
||||
if (resolver != null) {
|
||||
resolvers[i] = resolver;
|
||||
|
||||
@@ -129,13 +129,13 @@ public class RegisteredCommand <R extends CommandExecutionContext<? extends Comm
|
||||
this.optionalResolvers = optionalResolvers;
|
||||
}
|
||||
|
||||
private boolean isOptionalResolver(ContextResolver<?, R> resolver, Parameter parameter) {
|
||||
private boolean isOptionalResolver(ContextResolver<?, CEC> resolver, Parameter parameter) {
|
||||
return isOptionalResolver(resolver)
|
||||
|| parameter.getAnnotation(Optional.class) != null
|
||||
|| parameter.getAnnotation(Default.class) != null;
|
||||
}
|
||||
|
||||
private boolean isOptionalResolver(ContextResolver<?, R> resolver) {
|
||||
private boolean isOptionalResolver(ContextResolver<?, CEC> resolver) {
|
||||
return resolver instanceof IssuerAwareContextResolver || resolver instanceof IssuerOnlyContextResolver
|
||||
|| resolver instanceof OptionalContextResolver;
|
||||
}
|
||||
@@ -203,8 +203,9 @@ public class RegisteredCommand <R extends CommandExecutionContext<? extends Comm
|
||||
final String parameterName = parameter.getName();
|
||||
final Class<?> type = parameter.getType();
|
||||
//noinspection unchecked
|
||||
final ContextResolver<?, R> resolver = resolvers[i];
|
||||
R context = this.manager.createCommandContext(this, parameter, sender, args, i, passedArgs);
|
||||
final ContextResolver<?, CEC> resolver = resolvers[i];
|
||||
//noinspection unchecked
|
||||
CEC context = (CEC) this.manager.createCommandContext(this, parameter, sender, args, i, passedArgs);
|
||||
boolean isOptionalResolver = isOptionalResolver(resolver, parameter);
|
||||
if (!isOptionalResolver) {
|
||||
remainingRequired--;
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
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;
|
||||
@@ -40,7 +41,16 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public class SpongeCommandManager extends CommandManager<CommandSource, SpongeCommandIssuer, TextColor, SpongeMessageFormatter> {
|
||||
public class SpongeCommandManager extends CommandManager<
|
||||
CommandSource,
|
||||
SpongeCommandIssuer,
|
||||
TextColor,
|
||||
SpongeMessageFormatter,
|
||||
SpongeCommandExecutionContext,
|
||||
SpongeCommandCompletionContext,
|
||||
SpongeConditionContext,
|
||||
SpongeParameterConditionContext<?>
|
||||
> {
|
||||
|
||||
protected final PluginContainer plugin;
|
||||
protected Map<String, SpongeRootCommand> registeredCommands = new HashMap<>();
|
||||
@@ -134,9 +144,8 @@ public class SpongeCommandManager extends CommandManager<CommandSource, SpongeCo
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R extends CommandExecutionContext> R createCommandContext(RegisteredCommand command, Parameter parameter, CommandIssuer sender, List<String> args, int i, Map<String, Object> passedArgs) {
|
||||
//noinspection unchecked
|
||||
return (R) new SpongeCommandExecutionContext(command, parameter, (SpongeCommandIssuer) sender, args, i, passedArgs);
|
||||
public SpongeCommandExecutionContext createCommandContext(RegisteredCommand command, Parameter parameter, CommandIssuer sender, List<String> args, int i, Map<String, Object> passedArgs) {
|
||||
return new SpongeCommandExecutionContext(command, parameter, (SpongeCommandIssuer) sender, args, i, passedArgs);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -182,4 +191,16 @@ public class SpongeCommandManager extends CommandManager<CommandSource, SpongeCo
|
||||
isAsync
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package co.aikar.commands;
|
||||
|
||||
import co.aikar.commands.annotation.Conditions;
|
||||
|
||||
public class SpongeConditionContext extends ConditionContext <SpongeCommandIssuer> {
|
||||
SpongeConditionContext(RegisteredCommand cmd, SpongeCommandIssuer issuer, Conditions condAnno) {
|
||||
super(cmd, issuer, condAnno);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user