diff --git a/docs/acf-bukkit/co/aikar/commands/BukkitCommandManager.html b/docs/acf-bukkit/co/aikar/commands/BukkitCommandManager.html index f47292ef..17ed3382 100644 --- a/docs/acf-bukkit/co/aikar/commands/BukkitCommandManager.html +++ b/docs/acf-bukkit/co/aikar/commands/BukkitCommandManager.html @@ -114,7 +114,7 @@ var activeTableTab = "activeTableTab";
public class BukkitCommandManager +public class BukkitCommandManager extends co.aikar.commands.CommandManager<org.bukkit.command.CommandSender,BukkitCommandIssuer,org.bukkit.ChatColor,BukkitMessageFormatter>
protected final org.bukkit.plugin.Plugin plugin+
protected final org.bukkit.plugin.Plugin plugin
protected Map<String,org.bukkit.command.Command> knownCommands+
protected Map<String,org.bukkit.command.Command> knownCommands
protected Map<String,BukkitRootCommand> registeredCommands+
protected Map<String,BukkitRootCommand> registeredCommands
protected BukkitCommandContexts contexts+
protected BukkitCommandContexts contexts
protected BukkitCommandCompletions completions+
protected BukkitCommandCompletions completions
protected BukkitLocales locales+
protected BukkitLocales locales
protected Map<UUID,Locale> issuersLocale+
protected Map<UUID,Locale> issuersLocale
public BukkitCommandManager(org.bukkit.plugin.Plugin plugin)+
public BukkitCommandManager(org.bukkit.plugin.Plugin plugin)
public org.bukkit.plugin.Plugin getPlugin()+
public org.bukkit.plugin.Plugin getPlugin()
public boolean isCommandIssuer(Class<?> type)+
public boolean isCommandIssuer(Class<?> type)
isCommandIssuer in class co.aikar.commands.CommandManager<org.bukkit.command.CommandSender,BukkitCommandIssuer,org.bukkit.ChatColor,BukkitMessageFormatter>public co.aikar.commands.CommandContexts<BukkitCommandExecutionContext> getCommandContexts()+
public co.aikar.commands.CommandContexts<BukkitCommandExecutionContext> getCommandContexts()
getCommandContexts in class co.aikar.commands.CommandManager<org.bukkit.command.CommandSender,BukkitCommandIssuer,org.bukkit.ChatColor,BukkitMessageFormatter>public co.aikar.commands.CommandCompletions<BukkitCommandCompletionContext> getCommandCompletions()+
public co.aikar.commands.CommandCompletions<BukkitCommandCompletionContext> getCommandCompletions()
getCommandCompletions in class co.aikar.commands.CommandManager<org.bukkit.command.CommandSender,BukkitCommandIssuer,org.bukkit.ChatColor,BukkitMessageFormatter>public BukkitLocales getLocales()+
public BukkitLocales getLocales()
getLocales in class co.aikar.commands.CommandManager<org.bukkit.command.CommandSender,BukkitCommandIssuer,org.bukkit.ChatColor,BukkitMessageFormatter>public boolean hasRegisteredCommands()+
public boolean hasRegisteredCommands()
hasRegisteredCommands in class co.aikar.commands.CommandManager<org.bukkit.command.CommandSender,BukkitCommandIssuer,org.bukkit.ChatColor,BukkitMessageFormatter>public void registerCommand(co.aikar.commands.BaseCommand command, +public void registerCommand(co.aikar.commands.BaseCommand command, boolean force)
public void registerCommand(co.aikar.commands.BaseCommand command)+
public void registerCommand(co.aikar.commands.BaseCommand command)
registerCommand in class co.aikar.commands.CommandManager<org.bukkit.command.CommandSender,BukkitCommandIssuer,org.bukkit.ChatColor,BukkitMessageFormatter>public void unregisterCommand(co.aikar.commands.BaseCommand command)+
public void unregisterCommand(co.aikar.commands.BaseCommand command)
@Deprecated -public void unregisterCommand(BukkitRootCommand command)+public void unregisterCommand(BukkitRootCommand command)
public void unregisterCommands()+
public void unregisterCommands()
public co.aikar.timings.lib.TimingManager getTimings()+
public co.aikar.timings.lib.TimingManager getTimings()
public co.aikar.commands.RootCommand createRootCommand(String cmd)+
public co.aikar.commands.RootCommand createRootCommand(String cmd)
createRootCommand in class co.aikar.commands.CommandManager<org.bukkit.command.CommandSender,BukkitCommandIssuer,org.bukkit.ChatColor,BukkitMessageFormatter>public BukkitCommandIssuer getCommandIssuer(Object issuer)+
public BukkitCommandIssuer getCommandIssuer(Object issuer)
getCommandIssuer in class co.aikar.commands.CommandManager<org.bukkit.command.CommandSender,BukkitCommandIssuer,org.bukkit.ChatColor,BukkitMessageFormatter>public <R extends co.aikar.commands.CommandExecutionContext> R createCommandContext(co.aikar.commands.RegisteredCommand command, +public <R extends co.aikar.commands.CommandExecutionContext> R createCommandContext(co.aikar.commands.RegisteredCommand command, Parameter parameter, co.aikar.commands.CommandIssuer sender, List<String> args, @@ -602,7 +602,7 @@ public void- @@ -740,7 +740,7 @@ public
createCompletionContext
-public co.aikar.commands.CommandCompletionContext createCompletionContext(co.aikar.commands.RegisteredCommand command, +public co.aikar.commands.CommandCompletionContext createCompletionContext(co.aikar.commands.RegisteredCommand command, co.aikar.commands.CommandIssuer sender, String input, String config, @@ -619,7 +619,7 @@ public void- @@ -582,7 +582,7 @@ extends
createRegisteredCommand
-public co.aikar.commands.RegisteredCommand createRegisteredCommand(co.aikar.commands.BaseCommand command, +public co.aikar.commands.RegisteredCommand createRegisteredCommand(co.aikar.commands.BaseCommand command, String cmdName, Method method, String prefSubCommand)@@ -635,7 +635,7 @@ public void- @@ -565,7 +565,7 @@ extends
log
-public void log(co.aikar.commands.LogLevel level, +public void log(co.aikar.commands.LogLevel level, String message, Throwable throwable)@@ -650,7 +650,7 @@ public void
getIssuerLocale
-public Locale getIssuerLocale(co.aikar.commands.CommandIssuer issuer)+public Locale getIssuerLocale(co.aikar.commands.CommandIssuer issuer)
- Overrides:
- diff --git a/docs/acf-bukkit/src-html/co/aikar/commands/BukkitCommandManager.html b/docs/acf-bukkit/src-html/co/aikar/commands/BukkitCommandManager.html index 2c4544db..177e782c 100644 --- a/docs/acf-bukkit/src-html/co/aikar/commands/BukkitCommandManager.html +++ b/docs/acf-bukkit/src-html/co/aikar/commands/BukkitCommandManager.html @@ -55,309 +55,314 @@ 047import java.lang.reflect.Field; 048import java.lang.reflect.Method; 049import java.lang.reflect.Parameter; -050import java.util.*; -051import java.util.logging.Level; -052import java.util.logging.Logger; -053 -054@SuppressWarnings("WeakerAccess") -055public class BukkitCommandManager extends CommandManager<CommandSender, BukkitCommandIssuer, ChatColor, BukkitMessageFormatter> { -056 -057 @SuppressWarnings("WeakerAccess") -058 protected final Plugin plugin; -059 private final CommandMap commandMap; -060 private final TimingManager timingManager; -061 private final BukkitTask localeTask; -062 protected Map<String, Command> knownCommands = new HashMap<>(); -063 protected Map<String, BukkitRootCommand> registeredCommands = new HashMap<>(); -064 protected BukkitCommandContexts contexts; -065 protected BukkitCommandCompletions completions; -066 MCTiming commandTiming; -067 protected BukkitLocales locales; -068 private boolean cantReadLocale = false; -069 protected Map<UUID, Locale> issuersLocale = Maps.newConcurrentMap(); -070 -071 @SuppressWarnings("JavaReflectionMemberAccess") -072 public BukkitCommandManager(Plugin plugin) { -073 this.plugin = plugin; -074 this.timingManager = TimingManager.of(plugin); -075 this.commandTiming = this.timingManager.of("Commands"); -076 this.commandMap = hookCommandMap(); -077 this.formatters.put(MessageType.ERROR, defaultFormatter = new BukkitMessageFormatter(ChatColor.RED, ChatColor.YELLOW, ChatColor.RED)); -078 this.formatters.put(MessageType.SYNTAX, new BukkitMessageFormatter(ChatColor.YELLOW, ChatColor.GREEN, ChatColor.WHITE)); -079 this.formatters.put(MessageType.INFO, new BukkitMessageFormatter(ChatColor.BLUE, ChatColor.DARK_GREEN, ChatColor.GREEN)); -080 this.formatters.put(MessageType.HELP, new BukkitMessageFormatter(ChatColor.AQUA, ChatColor.GREEN, ChatColor.YELLOW)); -081 Bukkit.getPluginManager().registerEvents(new ACFBukkitListener(plugin), plugin); -082 getLocales(); // auto load locales -083 this.localeTask = Bukkit.getScheduler().runTaskTimer(plugin, () -> { -084 if (cantReadLocale) { -085 return; -086 } -087 Bukkit.getOnlinePlayers().forEach(this::readPlayerLocale); -088 }, 5, 5); -089 } -090 -091 @NotNull private CommandMap hookCommandMap() { -092 CommandMap commandMap = null; -093 try { -094 Server server = Bukkit.getServer(); -095 Method getCommandMap = server.getClass().getDeclaredMethod("getCommandMap"); -096 getCommandMap.setAccessible(true); -097 commandMap = (CommandMap) getCommandMap.invoke(server); -098 if (!SimpleCommandMap.class.isAssignableFrom(commandMap.getClass())) { -099 this.log(LogLevel.ERROR, "ERROR: CommandMap has been hijacked! Offending command map is located at: " + commandMap.getClass().getName()); -100 this.log(LogLevel.ERROR, "We are going to try to hijack it back and resolve this, but you are now in dangerous territory."); -101 this.log(LogLevel.ERROR, "We can not guarantee things are going to work."); -102 Field cmField = server.getClass().getDeclaredField("commandMap"); -103 commandMap = new ProxyCommandMap(this, commandMap); -104 cmField.set(server, commandMap); -105 this.log(LogLevel.INFO, "Injected Proxy Command Map... good luck..."); -106 } -107 Field knownCommands = SimpleCommandMap.class.getDeclaredField("knownCommands"); -108 knownCommands.setAccessible(true); -109 //noinspection unchecked -110 this.knownCommands = (Map<String, Command>) knownCommands.get(commandMap); -111 } catch (Exception e) { -112 this.log(LogLevel.ERROR, "Failed to get Command Map. ACF will not function."); -113 ACFUtil.sneaky(e); -114 } -115 return commandMap; -116 } -117 -118 public Plugin getPlugin() { -119 return this.plugin; -120 } -121 -122 @Override -123 public boolean isCommandIssuer(Class<?> type) { -124 return CommandSender.class.isAssignableFrom(type); +050import java.util.HashMap; +051import java.util.List; +052import java.util.Locale; +053import java.util.Map; +054import java.util.Objects; +055import java.util.UUID; +056import java.util.logging.Level; +057import java.util.logging.Logger; +058 +059@SuppressWarnings("WeakerAccess") +060public class BukkitCommandManager extends CommandManager<CommandSender, BukkitCommandIssuer, ChatColor, BukkitMessageFormatter> { +061 +062 @SuppressWarnings("WeakerAccess") +063 protected final Plugin plugin; +064 private final CommandMap commandMap; +065 private final TimingManager timingManager; +066 private final BukkitTask localeTask; +067 protected Map<String, Command> knownCommands = new HashMap<>(); +068 protected Map<String, BukkitRootCommand> registeredCommands = new HashMap<>(); +069 protected BukkitCommandContexts contexts; +070 protected BukkitCommandCompletions completions; +071 MCTiming commandTiming; +072 protected BukkitLocales locales; +073 private boolean cantReadLocale = false; +074 protected Map<UUID, Locale> issuersLocale = Maps.newConcurrentMap(); +075 +076 @SuppressWarnings("JavaReflectionMemberAccess") +077 public BukkitCommandManager(Plugin plugin) { +078 this.plugin = plugin; +079 this.timingManager = TimingManager.of(plugin); +080 this.commandTiming = this.timingManager.of("Commands"); +081 this.commandMap = hookCommandMap(); +082 this.formatters.put(MessageType.ERROR, defaultFormatter = new BukkitMessageFormatter(ChatColor.RED, ChatColor.YELLOW, ChatColor.RED)); +083 this.formatters.put(MessageType.SYNTAX, new BukkitMessageFormatter(ChatColor.YELLOW, ChatColor.GREEN, ChatColor.WHITE)); +084 this.formatters.put(MessageType.INFO, new BukkitMessageFormatter(ChatColor.BLUE, ChatColor.DARK_GREEN, ChatColor.GREEN)); +085 this.formatters.put(MessageType.HELP, new BukkitMessageFormatter(ChatColor.AQUA, ChatColor.GREEN, ChatColor.YELLOW)); +086 Bukkit.getPluginManager().registerEvents(new ACFBukkitListener(plugin), plugin); +087 getLocales(); // auto load locales +088 this.localeTask = Bukkit.getScheduler().runTaskTimer(plugin, () -> { +089 if (cantReadLocale) { +090 return; +091 } +092 Bukkit.getOnlinePlayers().forEach(this::readPlayerLocale); +093 }, 5, 5); +094 } +095 +096 @NotNull private CommandMap hookCommandMap() { +097 CommandMap commandMap = null; +098 try { +099 Server server = Bukkit.getServer(); +100 Method getCommandMap = server.getClass().getDeclaredMethod("getCommandMap"); +101 getCommandMap.setAccessible(true); +102 commandMap = (CommandMap) getCommandMap.invoke(server); +103 if (!SimpleCommandMap.class.isAssignableFrom(commandMap.getClass())) { +104 this.log(LogLevel.ERROR, "ERROR: CommandMap has been hijacked! Offending command map is located at: " + commandMap.getClass().getName()); +105 this.log(LogLevel.ERROR, "We are going to try to hijack it back and resolve this, but you are now in dangerous territory."); +106 this.log(LogLevel.ERROR, "We can not guarantee things are going to work."); +107 Field cmField = server.getClass().getDeclaredField("commandMap"); +108 commandMap = new ProxyCommandMap(this, commandMap); +109 cmField.set(server, commandMap); +110 this.log(LogLevel.INFO, "Injected Proxy Command Map... good luck..."); +111 } +112 Field knownCommands = SimpleCommandMap.class.getDeclaredField("knownCommands"); +113 knownCommands.setAccessible(true); +114 //noinspection unchecked +115 this.knownCommands = (Map<String, Command>) knownCommands.get(commandMap); +116 } catch (Exception e) { +117 this.log(LogLevel.ERROR, "Failed to get Command Map. ACF will not function."); +118 ACFUtil.sneaky(e); +119 } +120 return commandMap; +121 } +122 +123 public Plugin getPlugin() { +124 return this.plugin; 125 } 126 127 @Override -128 public synchronized CommandContexts<BukkitCommandExecutionContext> getCommandContexts() { -129 if (this.contexts == null) { -130 this.contexts = new BukkitCommandContexts(this); -131 } -132 return contexts; -133 } -134 -135 @Override -136 public synchronized CommandCompletions<BukkitCommandCompletionContext> getCommandCompletions() { -137 if (this.completions == null) { -138 this.completions = new BukkitCommandCompletions(this); -139 } -140 return completions; -141 } -142 -143 -144 @Override -145 public BukkitLocales getLocales() { -146 if (this.locales == null) { -147 this.locales = new BukkitLocales(this); -148 this.locales.loadLanguages(); -149 } -150 return locales; -151 } -152 -153 -154 @Override -155 public boolean hasRegisteredCommands() { -156 return !registeredCommands.isEmpty(); -157 } +128 public boolean isCommandIssuer(Class<?> type) { +129 return CommandSender.class.isAssignableFrom(type); +130 } +131 +132 @Override +133 public synchronized CommandContexts<BukkitCommandExecutionContext> getCommandContexts() { +134 if (this.contexts == null) { +135 this.contexts = new BukkitCommandContexts(this); +136 } +137 return contexts; +138 } +139 +140 @Override +141 public synchronized CommandCompletions<BukkitCommandCompletionContext> getCommandCompletions() { +142 if (this.completions == null) { +143 this.completions = new BukkitCommandCompletions(this); +144 } +145 return completions; +146 } +147 +148 +149 @Override +150 public BukkitLocales getLocales() { +151 if (this.locales == null) { +152 this.locales = new BukkitLocales(this); +153 this.locales.loadLanguages(); +154 } +155 return locales; +156 } +157 158 -159 public void registerCommand(BaseCommand command, boolean force) { -160 final String plugin = this.plugin.getName().toLowerCase(); -161 command.onRegister(this); -162 for (Map.Entry<String, RootCommand> entry : command.registeredCommands.entrySet()) { -163 String commandName = entry.getKey().toLowerCase(); -164 BukkitRootCommand bukkitCommand = (BukkitRootCommand) entry.getValue(); -165 if (!bukkitCommand.isRegistered) { -166 if (force && knownCommands.containsKey(commandName)) { -167 Command oldCommand = commandMap.getCommand(commandName); -168 knownCommands.remove(commandName); -169 for (Map.Entry<String, Command> ce : knownCommands.entrySet()) { -170 String key = ce.getKey(); -171 Command value = ce.getValue(); -172 if (key.contains(":") && oldCommand.equals(value)) { -173 String[] split = ACFPatterns.COLON.split(key, 2); -174 if (split.length > 1) { -175 oldCommand.unregister(commandMap); -176 oldCommand.setLabel(split[0] + ":" + command.getName()); -177 oldCommand.register(commandMap); -178 } -179 } -180 } -181 } -182 commandMap.register(commandName, plugin, bukkitCommand); -183 } -184 bukkitCommand.isRegistered = true; -185 registeredCommands.put(commandName, bukkitCommand); -186 } -187 } -188 -189 @Override -190 public void registerCommand(BaseCommand command) { -191 registerCommand(command, false); +159 @Override +160 public boolean hasRegisteredCommands() { +161 return !registeredCommands.isEmpty(); +162 } +163 +164 public void registerCommand(BaseCommand command, boolean force) { +165 final String plugin = this.plugin.getName().toLowerCase(); +166 command.onRegister(this); +167 for (Map.Entry<String, RootCommand> entry : command.registeredCommands.entrySet()) { +168 String commandName = entry.getKey().toLowerCase(); +169 BukkitRootCommand bukkitCommand = (BukkitRootCommand) entry.getValue(); +170 if (!bukkitCommand.isRegistered) { +171 if (force && knownCommands.containsKey(commandName)) { +172 Command oldCommand = commandMap.getCommand(commandName); +173 knownCommands.remove(commandName); +174 for (Map.Entry<String, Command> ce : knownCommands.entrySet()) { +175 String key = ce.getKey(); +176 Command value = ce.getValue(); +177 if (key.contains(":") && oldCommand.equals(value)) { +178 String[] split = ACFPatterns.COLON.split(key, 2); +179 if (split.length > 1) { +180 oldCommand.unregister(commandMap); +181 oldCommand.setLabel(split[0] + ":" + command.getName()); +182 oldCommand.register(commandMap); +183 } +184 } +185 } +186 } +187 commandMap.register(commandName, plugin, bukkitCommand); +188 } +189 bukkitCommand.isRegistered = true; +190 registeredCommands.put(commandName, bukkitCommand); +191 } 192 } 193 -194 public void unregisterCommand(BaseCommand command) { -195 for (RootCommand rootcommand : command.registeredCommands.values()) { -196 BukkitRootCommand bukkitCommand = (BukkitRootCommand) rootcommand; -197 bukkitCommand.getSubCommands().values().removeAll(command.subCommands.values()); -198 if (bukkitCommand.isRegistered && bukkitCommand.getSubCommands().isEmpty()) { -199 unregisterCommand(bukkitCommand); -200 bukkitCommand.isRegistered = false; -201 } -202 } -203 } -204 -205 /** -206 * @deprecated Use unregisterCommand(BaseCommand) - this will be visibility reduced later. -207 * @param command -208 */ -209 @Deprecated -210 public void unregisterCommand(BukkitRootCommand command) { -211 final String plugin = this.plugin.getName().toLowerCase(); -212 command.unregister(commandMap); -213 String key = command.getName(); -214 Command registered = knownCommands.get(key); -215 if (command.equals(registered)) { -216 knownCommands.remove(key); -217 } -218 knownCommands.remove(plugin + ":" + key); -219 } -220 -221 public void unregisterCommands() { -222 for (Map.Entry<String, BukkitRootCommand> entry : registeredCommands.entrySet()) { -223 unregisterCommand(entry.getValue()); -224 } -225 this.registeredCommands.clear(); -226 } -227 -228 -229 private Field getEntityField(Player player) throws NoSuchFieldException { -230 Class cls = player.getClass(); -231 while (cls != Object.class) { -232 if (cls.getName().endsWith("CraftEntity")) { -233 Field field = cls.getDeclaredField("entity"); -234 field.setAccessible(true); -235 return field; -236 } -237 cls = cls.getSuperclass(); -238 } -239 return null; -240 } -241 -242 private void readPlayerLocale(Player player) { -243 if (!player.isOnline() || cantReadLocale) { -244 return; -245 } -246 try { -247 Field entityField = getEntityField(player); -248 if (entityField == null) { -249 return; -250 } -251 Object nmsPlayer = entityField.get(player); -252 if (nmsPlayer != null) { -253 Field localeField = nmsPlayer.getClass().getField("locale"); -254 Object localeString = localeField.get(nmsPlayer); -255 if (localeString != null && localeString instanceof String) { -256 String[] split = ACFPatterns.UNDERSCORE.split((String) localeString); -257 Locale locale = split.length > 1 ? new Locale(split[0], split[1]) : new Locale(split[0]); -258 Locale prev = issuersLocale.put(player.getUniqueId(), locale); -259 if (!Objects.equals(locale, prev)) { -260 this.notifyLocaleChange(getCommandIssuer(player), prev, locale); -261 } -262 } -263 } -264 } catch (Exception e) { -265 cantReadLocale = true; -266 this.localeTask.cancel(); -267 this.log(LogLevel.INFO, "Can't read players locale, you will be unable to automatically detect players language. Only Bukkit 1.7+ is supported for this.", e); -268 } -269 } -270 -271 private class ACFBukkitListener implements Listener { -272 private final Plugin plugin; -273 -274 public ACFBukkitListener(Plugin plugin) { -275 this.plugin = plugin; -276 } -277 -278 @EventHandler -279 public void onPluginDisable(PluginDisableEvent event) { -280 if (!(plugin.getName().equalsIgnoreCase(event.getPlugin().getName()))) { -281 return; -282 } -283 unregisterCommands(); -284 } -285 @EventHandler -286 public void onPlayerJoin(PlayerJoinEvent event) { -287 Player player = event.getPlayer(); -288 readPlayerLocale(player); -289 this.plugin.getServer().getScheduler().runTaskLater(this.plugin, () -> readPlayerLocale(player), 20); -290 } -291 -292 @EventHandler -293 public void onPlayerJoin(PlayerQuitEvent event) { -294 issuersLocale.remove(event.getPlayer().getUniqueId()); +194 @Override +195 public void registerCommand(BaseCommand command) { +196 registerCommand(command, false); +197 } +198 +199 public void unregisterCommand(BaseCommand command) { +200 for (RootCommand rootcommand : command.registeredCommands.values()) { +201 BukkitRootCommand bukkitCommand = (BukkitRootCommand) rootcommand; +202 bukkitCommand.getSubCommands().values().removeAll(command.subCommands.values()); +203 if (bukkitCommand.isRegistered && bukkitCommand.getSubCommands().isEmpty()) { +204 unregisterCommand(bukkitCommand); +205 bukkitCommand.isRegistered = false; +206 } +207 } +208 } +209 +210 /** +211 * @deprecated Use unregisterCommand(BaseCommand) - this will be visibility reduced later. +212 * @param command +213 */ +214 @Deprecated +215 public void unregisterCommand(BukkitRootCommand command) { +216 final String plugin = this.plugin.getName().toLowerCase(); +217 command.unregister(commandMap); +218 String key = command.getName(); +219 Command registered = knownCommands.get(key); +220 if (command.equals(registered)) { +221 knownCommands.remove(key); +222 } +223 knownCommands.remove(plugin + ":" + key); +224 } +225 +226 public void unregisterCommands() { +227 for (Map.Entry<String, BukkitRootCommand> entry : registeredCommands.entrySet()) { +228 unregisterCommand(entry.getValue()); +229 } +230 this.registeredCommands.clear(); +231 } +232 +233 +234 private Field getEntityField(Player player) throws NoSuchFieldException { +235 Class cls = player.getClass(); +236 while (cls != Object.class) { +237 if (cls.getName().endsWith("CraftEntity")) { +238 Field field = cls.getDeclaredField("entity"); +239 field.setAccessible(true); +240 return field; +241 } +242 cls = cls.getSuperclass(); +243 } +244 return null; +245 } +246 +247 private void readPlayerLocale(Player player) { +248 if (!player.isOnline() || cantReadLocale) { +249 return; +250 } +251 try { +252 Field entityField = getEntityField(player); +253 if (entityField == null) { +254 return; +255 } +256 Object nmsPlayer = entityField.get(player); +257 if (nmsPlayer != null) { +258 Field localeField = nmsPlayer.getClass().getField("locale"); +259 Object localeString = localeField.get(nmsPlayer); +260 if (localeString != null && localeString instanceof String) { +261 String[] split = ACFPatterns.UNDERSCORE.split((String) localeString); +262 Locale locale = split.length > 1 ? new Locale(split[0], split[1]) : new Locale(split[0]); +263 Locale prev = issuersLocale.put(player.getUniqueId(), locale); +264 if (!Objects.equals(locale, prev)) { +265 this.notifyLocaleChange(getCommandIssuer(player), prev, locale); +266 } +267 } +268 } +269 } catch (Exception e) { +270 cantReadLocale = true; +271 this.localeTask.cancel(); +272 this.log(LogLevel.INFO, "Can't read players locale, you will be unable to automatically detect players language. Only Bukkit 1.7+ is supported for this.", e); +273 } +274 } +275 +276 private class ACFBukkitListener implements Listener { +277 private final Plugin plugin; +278 +279 public ACFBukkitListener(Plugin plugin) { +280 this.plugin = plugin; +281 } +282 +283 @EventHandler +284 public void onPluginDisable(PluginDisableEvent event) { +285 if (!(plugin.getName().equalsIgnoreCase(event.getPlugin().getName()))) { +286 return; +287 } +288 unregisterCommands(); +289 } +290 @EventHandler +291 public void onPlayerJoin(PlayerJoinEvent event) { +292 Player player = event.getPlayer(); +293 readPlayerLocale(player); +294 this.plugin.getServer().getScheduler().runTaskLater(this.plugin, () -> readPlayerLocale(player), 20); 295 } -296 } -297 -298 public TimingManager getTimings() { -299 return timingManager; -300 } -301 -302 @Override -303 public RootCommand createRootCommand(String cmd) { -304 return new BukkitRootCommand(this, cmd); +296 +297 @EventHandler +298 public void onPlayerJoin(PlayerQuitEvent event) { +299 issuersLocale.remove(event.getPlayer().getUniqueId()); +300 } +301 } +302 +303 public TimingManager getTimings() { +304 return timingManager; 305 } 306 307 @Override -308 public BukkitCommandIssuer getCommandIssuer(Object issuer) { -309 if (!(issuer instanceof CommandSender)) { -310 throw new IllegalArgumentException(issuer.getClass().getName() + " is not a Command Issuer."); -311 } -312 return new BukkitCommandIssuer(this, (CommandSender) issuer); -313 } -314 -315 @Override -316 public <R extends CommandExecutionContext> R createCommandContext(RegisteredCommand command, Parameter parameter, CommandIssuer sender, List<String> args, int i, Map<String, Object> passedArgs) { -317 //noinspection unchecked -318 return (R) new BukkitCommandExecutionContext(command, parameter, (BukkitCommandIssuer) sender, args, i, passedArgs); -319 } -320 -321 @Override -322 public CommandCompletionContext createCompletionContext(RegisteredCommand command, CommandIssuer sender, String input, String config, String[] args) { -323 return new BukkitCommandCompletionContext(command, sender, input, config, args); +308 public RootCommand createRootCommand(String cmd) { +309 return new BukkitRootCommand(this, cmd); +310 } +311 +312 @Override +313 public BukkitCommandIssuer getCommandIssuer(Object issuer) { +314 if (!(issuer instanceof CommandSender)) { +315 throw new IllegalArgumentException(issuer.getClass().getName() + " is not a Command Issuer."); +316 } +317 return new BukkitCommandIssuer(this, (CommandSender) issuer); +318 } +319 +320 @Override +321 public <R extends CommandExecutionContext> R createCommandContext(RegisteredCommand command, Parameter parameter, CommandIssuer sender, List<String> args, int i, Map<String, Object> passedArgs) { +322 //noinspection unchecked +323 return (R) new BukkitCommandExecutionContext(command, parameter, (BukkitCommandIssuer) sender, args, i, passedArgs); 324 } 325 326 @Override -327 public RegisteredCommand createRegisteredCommand(BaseCommand command, String cmdName, Method method, String prefSubCommand) { -328 return new BukkitRegisteredCommand(command, cmdName, method, prefSubCommand); +327 public CommandCompletionContext createCompletionContext(RegisteredCommand command, CommandIssuer sender, String input, String config, String[] args) { +328 return new BukkitCommandCompletionContext(command, sender, input, config, args); 329 } 330 331 @Override -332 public void log(LogLevel level, String message, Throwable throwable) { -333 Logger logger = this.plugin.getLogger(); -334 Level logLevel = level == LogLevel.INFO ? Level.INFO : Level.SEVERE; -335 logger.log(logLevel, LogLevel.LOG_PREFIX + message); -336 if (throwable != null) { -337 for (String line : ACFPatterns.NEWLINE.split(ApacheCommonsExceptionUtil.getFullStackTrace(throwable))) { -338 logger.log(logLevel, LogLevel.LOG_PREFIX + line); -339 } -340 } -341 } -342 -343 @Override -344 public Locale getIssuerLocale(CommandIssuer issuer) { -345 UUID uniqueId = ((Player) issuer.getIssuer()).getUniqueId(); -346 Locale locale = issuersLocale.get(uniqueId); -347 if (locale != null) { -348 return locale; -349 } -350 return super.getIssuerLocale(issuer); -351 } -352} +332 public RegisteredCommand createRegisteredCommand(BaseCommand command, String cmdName, Method method, String prefSubCommand) { +333 return new BukkitRegisteredCommand(command, cmdName, method, prefSubCommand); +334 } +335 +336 @Override +337 public void log(LogLevel level, String message, Throwable throwable) { +338 Logger logger = this.plugin.getLogger(); +339 Level logLevel = level == LogLevel.INFO ? Level.INFO : Level.SEVERE; +340 logger.log(logLevel, LogLevel.LOG_PREFIX + message); +341 if (throwable != null) { +342 for (String line : ACFPatterns.NEWLINE.split(ApacheCommonsExceptionUtil.getFullStackTrace(throwable))) { +343 logger.log(logLevel, LogLevel.LOG_PREFIX + line); +344 } +345 } +346 } +347 +348 @Override +349 public Locale getIssuerLocale(CommandIssuer issuer) { +350 UUID uniqueId = ((Player) issuer.getIssuer()).getUniqueId(); +351 Locale locale = issuersLocale.get(uniqueId); +352 if (locale != null) { +353 return locale; +354 } +355 return super.getIssuerLocale(issuer); +356 } +357} diff --git a/docs/acf-core/co/aikar/commands/CommandManager.html b/docs/acf-core/co/aikar/commands/CommandManager.html index 6e9f1791..298c9096 100644 --- a/docs/acf-core/co/aikar/commands/CommandManager.html +++ b/docs/acf-core/co/aikar/commands/CommandManager.html @@ -109,7 +109,7 @@ var activeTableTab = "activeTableTab";
getIssuerLocalein classco.aikar.commands.CommandManager<org.bukkit.command.CommandSender,BukkitCommandIssuer,org.bukkit.ChatColor,BukkitMessageFormatter>- @@ -485,7 +485,7 @@ extends
-public abstract class CommandManager<I,AI extends CommandIssuer,FT,F extends MessageFormatter<FT>> +public abstract class CommandManager<I,AI extends CommandIssuer,FT,F extends MessageFormatter<FT>> extends Object- @@ -494,7 +494,7 @@ extends
rootCommands
-protected Map<String,co.aikar.commands.RootCommand> rootCommands+protected Map<String,co.aikar.commands.RootCommand> rootCommands- @@ -503,7 +503,7 @@ extends
replacements
-protected final CommandReplacements replacements+protected final CommandReplacements replacements- @@ -512,7 +512,7 @@ extends
defaultExceptionHandler
-protected ExceptionHandler defaultExceptionHandler+protected ExceptionHandler defaultExceptionHandler- @@ -521,7 +521,7 @@ extends
localeChangedCallbacks
-protected List<IssuerLocaleChangedCallback<AI extends CommandIssuer>> localeChangedCallbacks+protected List<IssuerLocaleChangedCallback<AI extends CommandIssuer>> localeChangedCallbacks- @@ -530,7 +530,7 @@ extends
supportedLanguages
-protected Set<Locale> supportedLanguages+protected Set<Locale> supportedLanguages- @@ -539,7 +539,7 @@ extends
formatters
-protected Map<MessageType,F extends MessageFormatter<FT>> formatters+protected Map<MessageType,F extends MessageFormatter<FT>> formatters- @@ -548,7 +548,7 @@ extends
defaultFormatter
-protected F extends MessageFormatter<FT> defaultFormatter+protected F extends MessageFormatter<FT> defaultFormatterdefaultHelpPerPage
-protected int defaultHelpPerPage+protected int defaultHelpPerPageCommandManager
-public CommandManager()+public CommandManager()- @@ -591,7 +591,7 @@ extends
getCurrentCommandOperationContext
-public static CommandOperationContext getCurrentCommandOperationContext()+public static CommandOperationContext getCurrentCommandOperationContext()- @@ -600,7 +600,7 @@ extends
getCurrentCommandIssuer
-public static CommandIssuer getCurrentCommandIssuer()+public static CommandIssuer getCurrentCommandIssuer()- @@ -611,7 +611,7 @@ extends
getCurrentCommandManager
-public static CommandManager getCurrentCommandManager()+public static CommandManager getCurrentCommandManager()- @@ -621,7 +621,7 @@ extends
setFormat
-public F setFormat(MessageType type, +public F setFormat(MessageType type, F formatter)- @@ -632,7 +632,7 @@ extends
getFormat
-public F getFormat(MessageType type)+public F getFormat(MessageType type)- @@ -644,7 +644,7 @@ extends
setFormat
-public void setFormat(MessageType type, +public void setFormat(MessageType type, FT... colors)- @@ -655,7 +655,7 @@ extends
setFormat
-public void setFormat(MessageType type, +public void setFormat(MessageType type, int i, FT color)- @@ -666,7 +666,7 @@ extends
getDefaultFormatter
-public F getDefaultFormatter()+public F getDefaultFormatter()- @@ -675,7 +675,7 @@ extends
setDefaultFormatter
-public void setDefaultFormatter(F defaultFormatter)+public void setDefaultFormatter(F defaultFormatter)getCommandContexts
-public abstract CommandContexts<?> getCommandContexts()+public abstract CommandContexts<?> getCommandContexts()Gets the command contexts manager
- Returns:
@@ -689,7 +689,7 @@ extends- @@ -716,7 +716,7 @@ public
getCommandCompletions
-public abstract CommandCompletions<?> getCommandCompletions()+public abstract CommandCompletions<?> getCommandCompletions()Gets the command completions managergenerateCommandHelp
@Deprecated -public CommandHelp generateCommandHelp(CommandIssuer issuer, +public CommandHelp generateCommandHelp(CommandIssuer issuer, @NotNull @NotNull String command)Deprecated. Unstable API@@ -729,7 +729,7 @@ publicgenerateCommandHelp
@Deprecated -public CommandHelp generateCommandHelp()+public CommandHelp generateCommandHelp()Deprecated. Unstable APIgenerateCommandHelp
@Deprecated -public CommandHelp generateCommandHelp(CommandIssuer issuer, +public CommandHelp generateCommandHelp(CommandIssuer issuer, co.aikar.commands.RootCommand rootCommand)Deprecated. Unstable API
@Deprecated -public int getDefaultHelpPerPage()+public int getDefaultHelpPerPage()
@Deprecated -public void setDefaultHelpPerPage(int defaultHelpPerPage)+public void setDefaultHelpPerPage(int defaultHelpPerPage)
public abstract void registerCommand(BaseCommand command)+
public abstract void registerCommand(BaseCommand command)
public abstract boolean hasRegisteredCommands()+
public abstract boolean hasRegisteredCommands()
public abstract boolean isCommandIssuer(Class<?> type)+
public abstract boolean isCommandIssuer(Class<?> type)
public abstract AI getCommandIssuer(Object issuer)+
public abstract AI getCommandIssuer(Object issuer)
public abstract co.aikar.commands.RootCommand createRootCommand(String cmd)+
public abstract co.aikar.commands.RootCommand createRootCommand(String cmd)
public abstract Locales getLocales()+
public abstract Locales getLocales()
public abstract <R extends CommandExecutionContext> R createCommandContext(RegisteredCommand command, +public abstract <R extends CommandExecutionContext> R createCommandContext(RegisteredCommand command, Parameter parameter, CommandIssuer sender, List<String> args, @@ -850,7 +850,7 @@ public voidcreateCompletionContext
-public abstract CommandCompletionContext createCompletionContext(RegisteredCommand command, +public abstract CommandCompletionContext createCompletionContext(RegisteredCommand command, CommandIssuer sender, String input, String config, @@ -863,7 +863,7 @@ public void- @@ -874,7 +874,7 @@ public void
log
-public abstract void log(co.aikar.commands.LogLevel level, +public abstract void log(co.aikar.commands.LogLevel level, String message, Throwable throwable)- @@ -884,7 +884,7 @@ public void
log
-public void log(co.aikar.commands.LogLevel level, +public void log(co.aikar.commands.LogLevel level, String message)getCommandReplacements
-public CommandReplacements getCommandReplacements()+public CommandReplacements getCommandReplacements()Lets you add custom string replacements that can be applied to annotation values, to reduce duplication/repetition of common values such as permission nodes and command prefixes. @@ -903,7 +903,7 @@ public void- @@ -913,7 +913,7 @@ public void
hasPermission
-public boolean hasPermission(CommandIssuer issuer, +public boolean hasPermission(CommandIssuer issuer, String permission)- @@ -922,7 +922,7 @@ public void
obtainRootCommand
-public co.aikar.commands.RootCommand obtainRootCommand(String cmd)+public co.aikar.commands.RootCommand obtainRootCommand(String cmd)createRegisteredCommand
-public RegisteredCommand createRegisteredCommand(BaseCommand command, +public RegisteredCommand createRegisteredCommand(BaseCommand command, String cmdName, Method method, String prefSubCommand)@@ -934,7 +934,7 @@ public voidsetDefaultExceptionHandler
-public void setDefaultExceptionHandler(ExceptionHandler exceptionHandler)+public void setDefaultExceptionHandler(ExceptionHandler exceptionHandler)Sets the defaultExceptionHandlerthat is called when an exception occurs while executing a command, if the command doesn't have it's own exception handler registered.
- Parameters:
@@ -948,7 +948,7 @@ public voidgetDefaultExceptionHandler
-public ExceptionHandler getDefaultExceptionHandler()+public ExceptionHandler getDefaultExceptionHandler()Gets the current default exception handler, might be null.
- Returns:
@@ -962,7 +962,7 @@ public voidhandleUncaughtException
-protected boolean handleUncaughtException(BaseCommand scope, +protected boolean handleUncaughtException(BaseCommand scope, RegisteredCommand registeredCommand, CommandIssuer sender, List<String> args, @@ -977,7 +977,7 @@ public voidsendMessage
-public void sendMessage(I issuerArg, +public void sendMessage(I issuerArg, MessageType type, co.aikar.locales.MessageKeyProvider key, String... replacements)@@ -989,7 +989,7 @@ public voidsendMessage
-public void sendMessage(CommandIssuer issuer, +public void sendMessage(CommandIssuer issuer, MessageType type, co.aikar.locales.MessageKeyProvider key, String... replacements)@@ -1001,7 +1001,7 @@ public voidformatMessage
-public String formatMessage(CommandIssuer issuer, +public String formatMessage(CommandIssuer issuer, MessageType type, co.aikar.locales.MessageKeyProvider key, String... replacements)@@ -1013,7 +1013,7 @@ public void- @@ -1024,7 +1024,7 @@ public void
onLocaleChange
-public void onLocaleChange(IssuerLocaleChangedCallback<AI> onChange)+public void onLocaleChange(IssuerLocaleChangedCallback<AI> onChange)- @@ -1035,7 +1035,7 @@ public void
notifyLocaleChange
-public void notifyLocaleChange(AI issuer, +public void notifyLocaleChange(AI issuer, Locale oldLocale, Locale newLocale)- @@ -1044,7 +1044,7 @@ public void
getIssuerLocale
-public Locale getIssuerLocale(CommandIssuer issuer)+public Locale getIssuerLocale(CommandIssuer issuer)- diff --git a/docs/acf-core/src-html/co/aikar/commands/CommandManager.html b/docs/acf-core/src-html/co/aikar/commands/CommandManager.html index e6b8dfda..45097e79 100644 --- a/docs/acf-core/src-html/co/aikar/commands/CommandManager.html +++ b/docs/acf-core/src-html/co/aikar/commands/CommandManager.html @@ -33,323 +33,327 @@ 025 026import co.aikar.locales.MessageKeyProvider; 027import com.google.common.collect.Lists; -028import com.google.common.collect.Maps; -029import com.google.common.collect.Sets; -030import org.jetbrains.annotations.NotNull; -031 -032import java.lang.reflect.Method; -033import java.lang.reflect.Parameter; -034import java.util.*; -035import java.util.function.BiConsumer; -036 -037@SuppressWarnings("WeakerAccess") -038public abstract class CommandManager <I, AI extends CommandIssuer, FT, F extends MessageFormatter<FT>> { -039 -040 /** -041 * This is a stack incase a command calls a command -042 */ -043 static ThreadLocal<Stack<CommandOperationContext>> commandOperationContext = ThreadLocal.withInitial(() -> { -044 return new Stack<CommandOperationContext>() { -045 @Override -046 public synchronized CommandOperationContext peek() { -047 return super.size() == 0 ? null : super.peek(); -048 } -049 }; -050 }); -051 protected Map<String, RootCommand> rootCommands = new HashMap<>(); -052 protected final CommandReplacements replacements = new CommandReplacements(this); -053 protected ExceptionHandler defaultExceptionHandler = null; -054 -055 -056 protected List<IssuerLocaleChangedCallback<AI>> localeChangedCallbacks = Lists.newArrayList(); -057 protected Set<Locale> supportedLanguages = Sets.newHashSet(Locales.ENGLISH, Locales.GERMAN, Locales.SPANISH, Locales.CZECH); -058 protected Map<MessageType, F> formatters = new IdentityHashMap<>(); -059 protected F defaultFormatter; -060 protected int defaultHelpPerPage = 10; -061 -062 private Set<String> unstableAPIs = Sets.newHashSet(); -063 -064 public static CommandOperationContext getCurrentCommandOperationContext() { -065 return commandOperationContext.get().peek(); -066 } +028import com.google.common.collect.Sets; +029import org.jetbrains.annotations.NotNull; +030 +031import java.lang.reflect.Method; +032import java.lang.reflect.Parameter; +033import java.util.HashMap; +034import java.util.IdentityHashMap; +035import java.util.List; +036import java.util.Locale; +037import java.util.Map; +038import java.util.Set; +039import java.util.Stack; +040 +041@SuppressWarnings("WeakerAccess") +042public abstract class CommandManager <I, AI extends CommandIssuer, FT, F extends MessageFormatter<FT>> { +043 +044 /** +045 * This is a stack incase a command calls a command +046 */ +047 static ThreadLocal<Stack<CommandOperationContext>> commandOperationContext = ThreadLocal.withInitial(() -> { +048 return new Stack<CommandOperationContext>() { +049 @Override +050 public synchronized CommandOperationContext peek() { +051 return super.size() == 0 ? null : super.peek(); +052 } +053 }; +054 }); +055 protected Map<String, RootCommand> rootCommands = new HashMap<>(); +056 protected final CommandReplacements replacements = new CommandReplacements(this); +057 protected ExceptionHandler defaultExceptionHandler = null; +058 +059 +060 protected List<IssuerLocaleChangedCallback<AI>> localeChangedCallbacks = Lists.newArrayList(); +061 protected Set<Locale> supportedLanguages = Sets.newHashSet(Locales.ENGLISH, Locales.GERMAN, Locales.SPANISH, Locales.CZECH); +062 protected Map<MessageType, F> formatters = new IdentityHashMap<>(); +063 protected F defaultFormatter; +064 protected int defaultHelpPerPage = 10; +065 +066 private Set<String> unstableAPIs = Sets.newHashSet(); 067 -068 public static CommandIssuer getCurrentCommandIssuer() { -069 CommandOperationContext context = commandOperationContext.get().peek(); -070 return context != null ? context.getCommandIssuer() : null; -071 } -072 -073 public static CommandManager getCurrentCommandManager() { -074 CommandOperationContext context = commandOperationContext.get().peek(); -075 return context != null ? context.getCommandManager() : null; -076 } -077 -078 public F setFormat(MessageType type, F formatter) { -079 return formatters.put(type, formatter); +068 public static CommandOperationContext getCurrentCommandOperationContext() { +069 return commandOperationContext.get().peek(); +070 } +071 +072 public static CommandIssuer getCurrentCommandIssuer() { +073 CommandOperationContext context = commandOperationContext.get().peek(); +074 return context != null ? context.getCommandIssuer() : null; +075 } +076 +077 public static CommandManager getCurrentCommandManager() { +078 CommandOperationContext context = commandOperationContext.get().peek(); +079 return context != null ? context.getCommandManager() : null; 080 } 081 -082 public F getFormat(MessageType type) { -083 return formatters.getOrDefault(type, defaultFormatter); +082 public F setFormat(MessageType type, F formatter) { +083 return formatters.put(type, formatter); 084 } 085 -086 public void setFormat(MessageType type, FT... colors) { -087 F format = getFormat(type); -088 for (int i = 0; i < colors.length; i++) { -089 format.setColor(i, colors[i]); -090 } -091 } -092 -093 public void setFormat(MessageType type, int i, FT color) { -094 F format = getFormat(type); -095 format.setColor(i, color); -096 } -097 -098 public F getDefaultFormatter() { -099 return defaultFormatter; +086 public F getFormat(MessageType type) { +087 return formatters.getOrDefault(type, defaultFormatter); +088 } +089 +090 public void setFormat(MessageType type, FT... colors) { +091 F format = getFormat(type); +092 for (int i = 0; i < colors.length; i++) { +093 format.setColor(i, colors[i]); +094 } +095 } +096 +097 public void setFormat(MessageType type, int i, FT color) { +098 F format = getFormat(type); +099 format.setColor(i, color); 100 } 101 -102 public void setDefaultFormatter(F defaultFormatter) { -103 this.defaultFormatter = defaultFormatter; +102 public F getDefaultFormatter() { +103 return defaultFormatter; 104 } 105 -106 /** -107 * Gets the command contexts manager -108 * @return Command Contexts -109 */ -110 public abstract CommandContexts<?> getCommandContexts(); -111 -112 /** -113 * Gets the command completions manager -114 * @return Command Completions -115 */ -116 public abstract CommandCompletions<?> getCommandCompletions(); -117 -118 /** @deprecated Unstable API */ @Deprecated @UnstableAPI -119 public CommandHelp generateCommandHelp(@NotNull String command) { -120 verifyUnstableAPI("help"); -121 CommandOperationContext context = getCurrentCommandOperationContext(); -122 if (context == null) { -123 throw new IllegalStateException("This method can only be called as part of a command execution."); -124 } -125 return generateCommandHelp(context.getCommandIssuer(), command); -126 } -127 -128 /** @deprecated Unstable API */ @Deprecated @UnstableAPI -129 public CommandHelp generateCommandHelp(CommandIssuer issuer, @NotNull String command) { -130 verifyUnstableAPI("help"); -131 return generateCommandHelp(issuer, obtainRootCommand(ACFPatterns.SPACE.split(command, 2)[0])); -132 } -133 -134 /** @deprecated Unstable API */ @Deprecated @UnstableAPI -135 public CommandHelp generateCommandHelp() { -136 verifyUnstableAPI("help"); -137 CommandOperationContext context = getCurrentCommandOperationContext(); -138 if (context == null) { -139 throw new IllegalStateException("This method can only be called as part of a command execution."); -140 } -141 String commandLabel = context.getCommandLabel(); -142 return generateCommandHelp(context.getCommandIssuer(), this.obtainRootCommand(commandLabel)); -143 } -144 -145 /** @deprecated Unstable API */ @Deprecated @UnstableAPI -146 public CommandHelp generateCommandHelp(CommandIssuer issuer, RootCommand rootCommand) { -147 verifyUnstableAPI("help"); -148 return new CommandHelp(this, rootCommand, issuer); -149 } -150 -151 /** @deprecated Unstable API */ @Deprecated @UnstableAPI -152 public int getDefaultHelpPerPage() { -153 verifyUnstableAPI("help"); -154 return defaultHelpPerPage; -155 } -156 -157 /** @deprecated Unstable API */ @Deprecated @UnstableAPI -158 public void setDefaultHelpPerPage(int defaultHelpPerPage) { -159 verifyUnstableAPI("help"); -160 this.defaultHelpPerPage = defaultHelpPerPage; -161 } -162 -163 /** -164 * Registers a command with ACF -165 * -166 * @param command The command to register -167 * @return boolean -168 */ -169 public abstract void registerCommand(BaseCommand command); -170 public abstract boolean hasRegisteredCommands(); -171 public abstract boolean isCommandIssuer(Class<?> type); -172 -173 // TODO: Change this to I if we make a breaking change -174 public abstract AI getCommandIssuer(Object issuer); -175 -176 public abstract RootCommand createRootCommand(String cmd); -177 -178 /** -179 * Returns a Locales Manager to add and modify language tables for your commands. -180 * @return -181 */ -182 public abstract Locales getLocales(); -183 -184 public abstract <R extends CommandExecutionContext> R createCommandContext(RegisteredCommand command, Parameter parameter, CommandIssuer sender, List<String> args, int i, Map<String, Object> passedArgs); -185 -186 public abstract CommandCompletionContext createCompletionContext(RegisteredCommand command, CommandIssuer sender, String input, String config, String[] args); +106 public void setDefaultFormatter(F defaultFormatter) { +107 this.defaultFormatter = defaultFormatter; +108 } +109 +110 /** +111 * Gets the command contexts manager +112 * @return Command Contexts +113 */ +114 public abstract CommandContexts<?> getCommandContexts(); +115 +116 /** +117 * Gets the command completions manager +118 * @return Command Completions +119 */ +120 public abstract CommandCompletions<?> getCommandCompletions(); +121 +122 /** @deprecated Unstable API */ @Deprecated @UnstableAPI +123 public CommandHelp generateCommandHelp(@NotNull String command) { +124 verifyUnstableAPI("help"); +125 CommandOperationContext context = getCurrentCommandOperationContext(); +126 if (context == null) { +127 throw new IllegalStateException("This method can only be called as part of a command execution."); +128 } +129 return generateCommandHelp(context.getCommandIssuer(), command); +130 } +131 +132 /** @deprecated Unstable API */ @Deprecated @UnstableAPI +133 public CommandHelp generateCommandHelp(CommandIssuer issuer, @NotNull String command) { +134 verifyUnstableAPI("help"); +135 return generateCommandHelp(issuer, obtainRootCommand(ACFPatterns.SPACE.split(command, 2)[0])); +136 } +137 +138 /** @deprecated Unstable API */ @Deprecated @UnstableAPI +139 public CommandHelp generateCommandHelp() { +140 verifyUnstableAPI("help"); +141 CommandOperationContext context = getCurrentCommandOperationContext(); +142 if (context == null) { +143 throw new IllegalStateException("This method can only be called as part of a command execution."); +144 } +145 String commandLabel = context.getCommandLabel(); +146 return generateCommandHelp(context.getCommandIssuer(), this.obtainRootCommand(commandLabel)); +147 } +148 +149 /** @deprecated Unstable API */ @Deprecated @UnstableAPI +150 public CommandHelp generateCommandHelp(CommandIssuer issuer, RootCommand rootCommand) { +151 verifyUnstableAPI("help"); +152 return new CommandHelp(this, rootCommand, issuer); +153 } +154 +155 /** @deprecated Unstable API */ @Deprecated @UnstableAPI +156 public int getDefaultHelpPerPage() { +157 verifyUnstableAPI("help"); +158 return defaultHelpPerPage; +159 } +160 +161 /** @deprecated Unstable API */ @Deprecated @UnstableAPI +162 public void setDefaultHelpPerPage(int defaultHelpPerPage) { +163 verifyUnstableAPI("help"); +164 this.defaultHelpPerPage = defaultHelpPerPage; +165 } +166 +167 /** +168 * Registers a command with ACF +169 * +170 * @param command The command to register +171 * @return boolean +172 */ +173 public abstract void registerCommand(BaseCommand command); +174 public abstract boolean hasRegisteredCommands(); +175 public abstract boolean isCommandIssuer(Class<?> type); +176 +177 // TODO: Change this to I if we make a breaking change +178 public abstract AI getCommandIssuer(Object issuer); +179 +180 public abstract RootCommand createRootCommand(String cmd); +181 +182 /** +183 * Returns a Locales Manager to add and modify language tables for your commands. +184 * @return +185 */ +186 public abstract Locales getLocales(); 187 -188 public abstract void log(final LogLevel level, final String message, final Throwable throwable); +188 public abstract <R extends CommandExecutionContext> R createCommandContext(RegisteredCommand command, Parameter parameter, CommandIssuer sender, List<String> args, int i, Map<String, Object> passedArgs); 189 -190 public void log(final LogLevel level, final String message) { -191 log(level, message, null); -192 } +190 public abstract CommandCompletionContext createCompletionContext(RegisteredCommand command, CommandIssuer sender, String input, String config, String[] args); +191 +192 public abstract void log(final LogLevel level, final String message, final Throwable throwable); 193 -194 /** -195 * Lets you add custom string replacements that can be applied to annotation values, -196 * to reduce duplication/repetition of common values such as permission nodes and command prefixes. -197 * -198 * Any replacement registered starts with a % -199 * -200 * So for ex @CommandPermission("%staff") -201 * @return Replacements Manager -202 */ -203 public CommandReplacements getCommandReplacements() { -204 return replacements; -205 } -206 -207 public boolean hasPermission(CommandIssuer issuer, String permission) { -208 if (permission == null || permission.isEmpty()) { -209 return true; -210 } -211 for (String perm : ACFPatterns.COMMA.split(permission)) { -212 if (!perm.isEmpty() && !issuer.hasPermission(perm)) { -213 return false; -214 } -215 } -216 return true; -217 } -218 -219 public synchronized RootCommand obtainRootCommand(String cmd) { -220 return rootCommands.computeIfAbsent(cmd.toLowerCase(), this::createRootCommand); +194 public void log(final LogLevel level, final String message) { +195 log(level, message, null); +196 } +197 +198 /** +199 * Lets you add custom string replacements that can be applied to annotation values, +200 * to reduce duplication/repetition of common values such as permission nodes and command prefixes. +201 * +202 * Any replacement registered starts with a % +203 * +204 * So for ex @CommandPermission("%staff") +205 * @return Replacements Manager +206 */ +207 public CommandReplacements getCommandReplacements() { +208 return replacements; +209 } +210 +211 public boolean hasPermission(CommandIssuer issuer, String permission) { +212 if (permission == null || permission.isEmpty()) { +213 return true; +214 } +215 for (String perm : ACFPatterns.COMMA.split(permission)) { +216 if (!perm.isEmpty() && !issuer.hasPermission(perm)) { +217 return false; +218 } +219 } +220 return true; 221 } 222 -223 public RegisteredCommand createRegisteredCommand(BaseCommand command, String cmdName, Method method, String prefSubCommand) { -224 return new RegisteredCommand(command, cmdName, method, prefSubCommand); +223 public synchronized RootCommand obtainRootCommand(String cmd) { +224 return rootCommands.computeIfAbsent(cmd.toLowerCase(), this::createRootCommand); 225 } 226 -227 /** -228 * Sets the default {@link ExceptionHandler} that is called when an exception occurs while executing a command, if the command doesn't have it's own exception handler registered. -229 * -230 * @param exceptionHandler the handler that should handle uncaught exceptions -231 */ -232 public void setDefaultExceptionHandler(ExceptionHandler exceptionHandler) { -233 defaultExceptionHandler = exceptionHandler; -234 } -235 -236 /** -237 * Gets the current default exception handler, might be null. -238 * -239 * @return the default exception handler -240 */ -241 public ExceptionHandler getDefaultExceptionHandler() { -242 return defaultExceptionHandler; -243 } -244 -245 protected boolean handleUncaughtException(BaseCommand scope, RegisteredCommand registeredCommand, CommandIssuer sender, List<String> args, Throwable t) { -246 boolean result = false; -247 if (scope.getExceptionHandler() != null) { -248 result = scope.getExceptionHandler().execute(scope, registeredCommand, sender, args, t); -249 } else if (defaultExceptionHandler != null) { -250 result = defaultExceptionHandler.execute(scope, registeredCommand, sender, args, t); -251 } -252 return result; -253 } -254 -255 public void sendMessage(I issuerArg, MessageType type, MessageKeyProvider key, String... replacements) { -256 sendMessage(getCommandIssuer(issuerArg), type, key, replacements); +227 public RegisteredCommand createRegisteredCommand(BaseCommand command, String cmdName, Method method, String prefSubCommand) { +228 return new RegisteredCommand(command, cmdName, method, prefSubCommand); +229 } +230 +231 /** +232 * Sets the default {@link ExceptionHandler} that is called when an exception occurs while executing a command, if the command doesn't have it's own exception handler registered. +233 * +234 * @param exceptionHandler the handler that should handle uncaught exceptions +235 */ +236 public void setDefaultExceptionHandler(ExceptionHandler exceptionHandler) { +237 defaultExceptionHandler = exceptionHandler; +238 } +239 +240 /** +241 * Gets the current default exception handler, might be null. +242 * +243 * @return the default exception handler +244 */ +245 public ExceptionHandler getDefaultExceptionHandler() { +246 return defaultExceptionHandler; +247 } +248 +249 protected boolean handleUncaughtException(BaseCommand scope, RegisteredCommand registeredCommand, CommandIssuer sender, List<String> args, Throwable t) { +250 boolean result = false; +251 if (scope.getExceptionHandler() != null) { +252 result = scope.getExceptionHandler().execute(scope, registeredCommand, sender, args, t); +253 } else if (defaultExceptionHandler != null) { +254 result = defaultExceptionHandler.execute(scope, registeredCommand, sender, args, t); +255 } +256 return result; 257 } 258 -259 public void sendMessage(CommandIssuer issuer, MessageType type, MessageKeyProvider key, String... replacements) { -260 String message = formatMessage(issuer, type, key, replacements); -261 -262 for (String msg : ACFPatterns.NEWLINE.split(message)) { -263 issuer.sendMessageInternal(ACFUtil.rtrim(msg)); -264 } -265 } -266 -267 public String formatMessage(CommandIssuer issuer, MessageType type, MessageKeyProvider key, String... replacements) { -268 String message = getLocales().getMessage(issuer, key.getMessageKey()); -269 if (replacements.length > 0) { -270 message = ACFUtil.replaceStrings(message, replacements); -271 } -272 -273 message = getCommandReplacements().replace(message); -274 -275 MessageFormatter formatter = formatters.getOrDefault(type, defaultFormatter); -276 if (formatter != null) { -277 message = formatter.format(message); -278 } -279 return message; -280 } -281 -282 public void onLocaleChange(IssuerLocaleChangedCallback<AI> onChange) { -283 localeChangedCallbacks.add(onChange); +259 public void sendMessage(I issuerArg, MessageType type, MessageKeyProvider key, String... replacements) { +260 sendMessage(getCommandIssuer(issuerArg), type, key, replacements); +261 } +262 +263 public void sendMessage(CommandIssuer issuer, MessageType type, MessageKeyProvider key, String... replacements) { +264 String message = formatMessage(issuer, type, key, replacements); +265 +266 for (String msg : ACFPatterns.NEWLINE.split(message)) { +267 issuer.sendMessageInternal(ACFUtil.rtrim(msg)); +268 } +269 } +270 +271 public String formatMessage(CommandIssuer issuer, MessageType type, MessageKeyProvider key, String... replacements) { +272 String message = getLocales().getMessage(issuer, key.getMessageKey()); +273 if (replacements.length > 0) { +274 message = ACFUtil.replaceStrings(message, replacements); +275 } +276 +277 message = getCommandReplacements().replace(message); +278 +279 MessageFormatter formatter = formatters.getOrDefault(type, defaultFormatter); +280 if (formatter != null) { +281 message = formatter.format(message); +282 } +283 return message; 284 } 285 -286 public void notifyLocaleChange(AI issuer, Locale oldLocale, Locale newLocale) { -287 localeChangedCallbacks.forEach(cb -> { -288 try { -289 cb.onIssuerLocaleChange(issuer, oldLocale, newLocale); -290 } catch (Exception e) { -291 this.log(LogLevel.ERROR, "Error in notifyLocaleChange", e); -292 } -293 }); -294 } -295 -296 public Locale getIssuerLocale(CommandIssuer issuer) { -297 return getLocales().getDefaultLocale(); +286 public void onLocaleChange(IssuerLocaleChangedCallback<AI> onChange) { +287 localeChangedCallbacks.add(onChange); +288 } +289 +290 public void notifyLocaleChange(AI issuer, Locale oldLocale, Locale newLocale) { +291 localeChangedCallbacks.forEach(cb -> { +292 try { +293 cb.onIssuerLocaleChange(issuer, oldLocale, newLocale); +294 } catch (Exception e) { +295 this.log(LogLevel.ERROR, "Error in notifyLocaleChange", e); +296 } +297 }); 298 } 299 -300 -301 public CommandOperationContext createCommandOperationContext(BaseCommand command, CommandIssuer issuer, String commandLabel, String[] args) { -302 return new CommandOperationContext( -303 this, -304 issuer, -305 command, -306 commandLabel, -307 args -308 ); -309 } -310 -311 /** -312 * Gets a list of all currently supported languages for this manager. -313 * These locales will be automatically loaded from -314 * @return -315 */ -316 public Set<Locale> getSupportedLanguages() { -317 return supportedLanguages; -318 } -319 -320 /** -321 * Adds a new locale to the list of automatic Locales to load Message Bundles for. -322 * All bundles loaded under the previous supported languages will now automatically load for this new locale too. -323 * -324 * @param locale -325 */ -326 public void addSupportedLanguage(Locale locale) { -327 supportedLanguages.add(locale); -328 getLocales().loadMissingBundles(); -329 } -330 -331 /** -332 * @deprecated Use this with caution! If you enable and use Unstable API's, your next compile using ACF -333 * may require you to update your implementation to those unstable API's -334 */ -335 @Deprecated -336 public void enableUnstableAPI(String api) { -337 unstableAPIs.add(api); -338 } -339 void verifyUnstableAPI(String api) { -340 if (!unstableAPIs.contains(api)) { -341 throw new IllegalStateException("Using an unstable API that has not been enabled ( " + api + "). See https://acfunstable.emc.gs"); -342 } -343 } -344} +300 public Locale getIssuerLocale(CommandIssuer issuer) { +301 return getLocales().getDefaultLocale(); +302 } +303 +304 +305 public CommandOperationContext createCommandOperationContext(BaseCommand command, CommandIssuer issuer, String commandLabel, String[] args) { +306 return new CommandOperationContext( +307 this, +308 issuer, +309 command, +310 commandLabel, +311 args +312 ); +313 } +314 +315 /** +316 * Gets a list of all currently supported languages for this manager. +317 * These locales will be automatically loaded from +318 * @return +319 */ +320 public Set<Locale> getSupportedLanguages() { +321 return supportedLanguages; +322 } +323 +324 /** +325 * Adds a new locale to the list of automatic Locales to load Message Bundles for. +326 * All bundles loaded under the previous supported languages will now automatically load for this new locale too. +327 * +328 * @param locale +329 */ +330 public void addSupportedLanguage(Locale locale) { +331 supportedLanguages.add(locale); +332 getLocales().loadMissingBundles(); +333 } +334 +335 /** +336 * @deprecated Use this with caution! If you enable and use Unstable API's, your next compile using ACF +337 * may require you to update your implementation to those unstable API's +338 */ +339 @Deprecated +340 public void enableUnstableAPI(String api) { +341 unstableAPIs.add(api); +342 } +343 void verifyUnstableAPI(String api) { +344 if (!unstableAPIs.contains(api)) { +345 throw new IllegalStateException("Using an unstable API that has not been enabled ( " + api + "). See https://acfunstable.emc.gs"); +346 } +347 } +348}
createCommandOperationContext
-public CommandOperationContext createCommandOperationContext(BaseCommand command, +public CommandOperationContext createCommandOperationContext(BaseCommand command, CommandIssuer issuer, String commandLabel, String[] args)@@ -1056,7 +1056,7 @@ public voidgetSupportedLanguages
-public Set<Locale> getSupportedLanguages()+public Set<Locale> getSupportedLanguages()Gets a list of all currently supported languages for this manager. These locales will be automatically loaded from@@ -1070,7 +1070,7 @@ public void
addSupportedLanguage
-public void addSupportedLanguage(Locale locale)+public void addSupportedLanguage(Locale locale)Adds a new locale to the list of automatic Locales to load Message Bundles for. All bundles loaded under the previous supported languages will now automatically load for this new locale too.Deprecated. Use this with caution! If you enable and use Unstable API's, your next compile using ACF may require you to update your implementation to those unstable API's