mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-01-10 12:42:52 +08:00
Separate aliases from the command map
This commit is contained in:
parent
82eefde4c0
commit
07a97f65f6
@ -1,9 +1,7 @@
|
|||||||
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.*;
|
|||||||
@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 {
|
|||||||
* @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 {
|
|||||||
// 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 {
|
|||||||
*/
|
*/
|
||||||
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 {
|
|||||||
// 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 {
|
|||||||
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);
|
||||||
@ -125,7 +128,7 @@ public final class CommandMap {
|
|||||||
List<String> args = new LinkedList<>(Arrays.asList(split));
|
List<String> args = new LinkedList<>(Arrays.asList(split));
|
||||||
String label = args.remove(0);
|
String label = args.remove(0);
|
||||||
String playerId = (player == null) ? consoleId : player.getAccount().getId();
|
String playerId = (player == null) ? consoleId : player.getAccount().getId();
|
||||||
|
|
||||||
// Check for special cases - currently only target command.
|
// Check for special cases - currently only target command.
|
||||||
String targetUidStr = null;
|
String targetUidStr = null;
|
||||||
if (label.startsWith("@")) { // @[UID]
|
if (label.startsWith("@")) { // @[UID]
|
||||||
@ -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 {
|
|||||||
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 {
|
|||||||
|
|
||||||
// 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);
|
||||||
@ -188,11 +199,11 @@ 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 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Copy player and handler to final properties.
|
||||||
|
final Player targetPlayerF = targetPlayer; // Is there a better way to do this?
|
||||||
|
final CommandHandler handlerF = handler; // Is there a better way to do this?
|
||||||
|
|
||||||
// Invoke execute method for handler.
|
// Invoke execute method for handler.
|
||||||
boolean threading = this.annotations.get(label).threading();
|
Runnable runnable = () -> handlerF.execute(player, targetPlayerF, args);
|
||||||
final Player targetPlayerF = targetPlayer; // Is there a better way to do this?
|
if (annotation.threading()) {
|
||||||
Runnable runnable = () -> handler.execute(player, targetPlayerF, args);
|
|
||||||
if(threading) {
|
|
||||||
new Thread(runnable).start();
|
new Thread(runnable).start();
|
||||||
} else {
|
} else {
|
||||||
runnable.run();
|
runnable.run();
|
||||||
@ -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!");
|
||||||
|
Loading…
Reference in New Issue
Block a user