Commit 07a97f65 authored by KingRainbow44's avatar KingRainbow44
Browse files

Separate aliases from the command map

parent 82eefde4
package emu.grasscutter.command; package emu.grasscutter.command;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.game.Account;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import org.reflections.Reflections; import org.reflections.Reflections;
import java.util.*; import java.util.*;
...@@ -11,6 +9,7 @@ import java.util.*; ...@@ -11,6 +9,7 @@ import java.util.*;
@SuppressWarnings({"UnusedReturnValue", "unused"}) @SuppressWarnings({"UnusedReturnValue", "unused"})
public final class CommandMap { public final class CommandMap {
private final Map<String, CommandHandler> commands = new HashMap<>(); private final Map<String, CommandHandler> commands = new HashMap<>();
private final Map<String, CommandHandler> aliases = new HashMap<>();
private final Map<String, Command> annotations = new HashMap<>(); private final Map<String, Command> annotations = new HashMap<>();
private final Map<String, Integer> targetPlayerIds = new HashMap<>(); private final Map<String, Integer> targetPlayerIds = new HashMap<>();
private static final String consoleId = "console"; private static final String consoleId = "console";
...@@ -34,6 +33,7 @@ public final class CommandMap { ...@@ -34,6 +33,7 @@ public final class CommandMap {
* @param command The command handler. * @param command The command handler.
* @return Instance chaining. * @return Instance chaining.
*/ */
@Deprecated(since = "1.2.1-dev")
public CommandMap registerCommand(String label, CommandHandler command) { public CommandMap registerCommand(String label, CommandHandler command) {
Grasscutter.getLogger().debug("Registered command: " + label); Grasscutter.getLogger().debug("Registered command: " + label);
...@@ -45,7 +45,7 @@ public final class CommandMap { ...@@ -45,7 +45,7 @@ public final class CommandMap {
// Register aliases. // Register aliases.
if (annotation.aliases().length > 0) { if (annotation.aliases().length > 0) {
for (String alias : annotation.aliases()) { for (String alias : annotation.aliases()) {
this.commands.put(alias, command); this.aliases.put(alias, command);
this.annotations.put(alias, annotation); this.annotations.put(alias, annotation);
} }
} }
...@@ -60,6 +60,7 @@ public final class CommandMap { ...@@ -60,6 +60,7 @@ public final class CommandMap {
*/ */
public CommandMap unregisterCommand(String label) { public CommandMap unregisterCommand(String label) {
Grasscutter.getLogger().debug("Unregistered command: " + label); Grasscutter.getLogger().debug("Unregistered command: " + label);
CommandHandler handler = this.commands.get(label); CommandHandler handler = this.commands.get(label);
if (handler == null) return this; if (handler == null) return this;
...@@ -70,7 +71,7 @@ public final class CommandMap { ...@@ -70,7 +71,7 @@ public final class CommandMap {
// Unregister aliases. // Unregister aliases.
if (annotation.aliases().length > 0) { if (annotation.aliases().length > 0) {
for (String alias : annotation.aliases()) { for (String alias : annotation.aliases()) {
this.commands.remove(alias); this.aliases.remove(alias);
this.annotations.remove(alias); this.annotations.remove(alias);
} }
} }
...@@ -78,7 +79,9 @@ public final class CommandMap { ...@@ -78,7 +79,9 @@ public final class CommandMap {
return this; return this;
} }
public List<Command> getAnnotationsAsList() { return new LinkedList<>(this.annotations.values()); } public List<Command> getAnnotationsAsList() {
return new LinkedList<>(this.annotations.values());
}
public HashMap<String, Command> getAnnotations() { public HashMap<String, Command> getAnnotations() {
return new LinkedHashMap<>(this.annotations); return new LinkedHashMap<>(this.annotations);
...@@ -142,7 +145,7 @@ public final class CommandMap { ...@@ -142,7 +145,7 @@ public final class CommandMap {
} }
if (targetUidStr != null) { if (targetUidStr != null) {
if (targetUidStr.equals("")) { // Clears the default targetPlayer. if (targetUidStr.equals("")) { // Clears the default targetPlayer.
targetPlayerIds.remove(playerId); this.targetPlayerIds.remove(playerId);
CommandHandler.sendTranslatedMessage(player, "commands.execution.clear_target"); CommandHandler.sendTranslatedMessage(player, "commands.execution.clear_target");
} else { // Sets default targetPlayer to the UID provided. } else { // Sets default targetPlayer to the UID provided.
try { try {
...@@ -151,9 +154,9 @@ public final class CommandMap { ...@@ -151,9 +154,9 @@ public final class CommandMap {
if (targetPlayer == null) { if (targetPlayer == null) {
CommandHandler.sendTranslatedMessage(player, "commands.execution.player_exist_error"); CommandHandler.sendTranslatedMessage(player, "commands.execution.player_exist_error");
} else { } else {
targetPlayerIds.put(playerId, uid); this.targetPlayerIds.put(playerId, uid);
CommandHandler.sendTranslatedMessage(player, "commands.execution.set_target", targetUidStr); CommandHandler.sendTranslatedMessage(player, "commands.execution.set_target", targetUidStr);
CommandHandler.sendTranslatedMessage(player, targetPlayer.isOnline()? "commands.execution.set_target_online" : "commands.execution.set_target_offline", targetUidStr); CommandHandler.sendTranslatedMessage(player, targetPlayer.isOnline() ? "commands.execution.set_target_online" : "commands.execution.set_target_offline", targetUidStr);
} }
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
CommandHandler.sendTranslatedMessage(player, "commands.execution.uid_error"); CommandHandler.sendTranslatedMessage(player, "commands.execution.uid_error");
...@@ -164,11 +167,19 @@ public final class CommandMap { ...@@ -164,11 +167,19 @@ public final class CommandMap {
// Get command handler. // Get command handler.
CommandHandler handler = this.commands.get(label); CommandHandler handler = this.commands.get(label);
if(handler == null)
// Try to get the handler by alias.
handler = this.aliases.get(label);
// Check if the handler is still null.
if (handler == null) { if (handler == null) {
CommandHandler.sendTranslatedMessage(player, "commands.generic.unknown_command", label); CommandHandler.sendTranslatedMessage(player, "commands.generic.unknown_command", label);
return; return;
} }
// Get the command's annotation.
Command annotation = this.annotations.get(label);
// If any @UID argument is present, override targetPlayer with it. // If any @UID argument is present, override targetPlayer with it.
for (int i = 0; i < args.size(); i++) { for (int i = 0; i < args.size(); i++) {
String arg = args.get(i); String arg = args.get(i);
...@@ -191,8 +202,8 @@ public final class CommandMap { ...@@ -191,8 +202,8 @@ public final class CommandMap {
// If there's still no targetPlayer at this point, use previously-set target // If there's still no targetPlayer at this point, use previously-set target
if (targetPlayer == null) { if (targetPlayer == null) {
if (targetPlayerIds.containsKey(playerId)) { if (this.targetPlayerIds.containsKey(playerId)) {
targetPlayer = Grasscutter.getGameServer().getPlayerByUid(targetPlayerIds.get(playerId), true); // We check every time in case the target is deleted after being targeted targetPlayer = Grasscutter.getGameServer().getPlayerByUid(this.targetPlayerIds.get(playerId), true); // We check every time in case the target is deleted after being targeted
if (targetPlayer == null) { if (targetPlayer == null) {
CommandHandler.sendTranslatedMessage(player, "commands.execution.player_exist_error"); CommandHandler.sendTranslatedMessage(player, "commands.execution.player_exist_error");
return; return;
...@@ -204,32 +215,36 @@ public final class CommandMap { ...@@ -204,32 +215,36 @@ public final class CommandMap {
} }
// Check for permissions. // Check for permissions.
if (!Grasscutter.getPermissionHandler().checkPermission(player, targetPlayer, this.annotations.get(label).permission(), this.annotations.get(label).permissionTargeted())) { if (!Grasscutter.getPermissionHandler().checkPermission(player, targetPlayer, annotation.permission(), this.annotations.get(label).permissionTargeted())) {
return; return;
} }
// Check if command has unfulfilled constraints on targetPlayer // Check if command has unfulfilled constraints on targetPlayer
Command.TargetRequirement targetRequirement = this.annotations.get(label).targetRequirement(); Command.TargetRequirement targetRequirement = annotation.targetRequirement();
if (targetRequirement != Command.TargetRequirement.NONE) { if (targetRequirement != Command.TargetRequirement.NONE) {
if (targetPlayer == null) { if (targetPlayer == null) {
CommandHandler.sendTranslatedMessage(player, "commands.execution.need_target"); CommandHandler.sendTranslatedMessage(null, "commands.execution.need_target");
return; return;
} }
if ((targetRequirement == Command.TargetRequirement.ONLINE) && !targetPlayer.isOnline()) { if ((targetRequirement == Command.TargetRequirement.ONLINE) && !targetPlayer.isOnline()) {
CommandHandler.sendTranslatedMessage(player, "commands.execution.need_target_online"); CommandHandler.sendTranslatedMessage(player, "commands.execution.need_target_online");
return; return;
} }
if ((targetRequirement == Command.TargetRequirement.OFFLINE) && targetPlayer.isOnline()) { if ((targetRequirement == Command.TargetRequirement.OFFLINE) && targetPlayer.isOnline()) {
CommandHandler.sendTranslatedMessage(player, "commands.execution.need_target_offline"); CommandHandler.sendTranslatedMessage(player, "commands.execution.need_target_offline");
return; return;
} }
} }
// Invoke execute method for handler. // Copy player and handler to final properties.
boolean threading = this.annotations.get(label).threading();
final Player targetPlayerF = targetPlayer; // Is there a better way to do this? final Player targetPlayerF = targetPlayer; // Is there a better way to do this?
Runnable runnable = () -> handler.execute(player, targetPlayerF, args); final CommandHandler handlerF = handler; // Is there a better way to do this?
if(threading) {
// Invoke execute method for handler.
Runnable runnable = () -> handlerF.execute(player, targetPlayerF, args);
if (annotation.threading()) {
new Thread(runnable).start(); new Thread(runnable).start();
} else { } else {
runnable.run(); runnable.run();
...@@ -242,10 +257,11 @@ public final class CommandMap { ...@@ -242,10 +257,11 @@ public final class CommandMap {
private void scan() { private void scan() {
Reflections reflector = Grasscutter.reflector; Reflections reflector = Grasscutter.reflector;
Set<Class<?>> classes = reflector.getTypesAnnotatedWith(Command.class); Set<Class<?>> classes = reflector.getTypesAnnotatedWith(Command.class);
classes.forEach(annotated -> { classes.forEach(annotated -> {
try { try {
Command cmdData = annotated.getAnnotation(Command.class); Command cmdData = annotated.getAnnotation(Command.class);
Object object = annotated.newInstance(); Object object = annotated.getDeclaredConstructor().newInstance();
if (object instanceof CommandHandler) if (object instanceof CommandHandler)
this.registerCommand(cmdData.label(), (CommandHandler) object); this.registerCommand(cmdData.label(), (CommandHandler) object);
else Grasscutter.getLogger().error("Class " + annotated.getName() + " is not a CommandHandler!"); else Grasscutter.getLogger().error("Class " + annotated.getName() + " is not a CommandHandler!");
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment