From 824b3a4bf48e5a3c637b38b1c3a3510875babdb8 Mon Sep 17 00:00:00 2001 From: KingRainbow44 Date: Mon, 18 Apr 2022 23:46:04 -0400 Subject: [PATCH] Implement basic permission system --- .../emu/grasscutter/commands/Command.java | 2 +- .../emu/grasscutter/commands/CommandMap.java | 23 +++++++--- .../grasscutter/commands/ServerCommands.java | 43 ++++++++++++++++++- .../java/emu/grasscutter/game/Account.java | 19 ++++++++ .../emu/grasscutter/game/GenshinPlayer.java | 7 +-- 5 files changed, 80 insertions(+), 14 deletions(-) diff --git a/src/main/java/emu/grasscutter/commands/Command.java b/src/main/java/emu/grasscutter/commands/Command.java index 3f739d78e..d1e181e20 100644 --- a/src/main/java/emu/grasscutter/commands/Command.java +++ b/src/main/java/emu/grasscutter/commands/Command.java @@ -13,7 +13,7 @@ public @interface Command { Execution execution() default Execution.ALL; - int gmLevel() default 1; + String permission() default ""; enum Execution { ALL, diff --git a/src/main/java/emu/grasscutter/commands/CommandMap.java b/src/main/java/emu/grasscutter/commands/CommandMap.java index 5a70aeb45..e9ca260e7 100644 --- a/src/main/java/emu/grasscutter/commands/CommandMap.java +++ b/src/main/java/emu/grasscutter/commands/CommandMap.java @@ -1,6 +1,7 @@ package emu.grasscutter.commands; import emu.grasscutter.Grasscutter; +import emu.grasscutter.game.Account; import emu.grasscutter.game.GenshinPlayer; import org.reflections.Reflections; @@ -13,7 +14,7 @@ public final class CommandMap { } private final Map commands = new HashMap<>(); - private final Map executionPower = new HashMap<>(); + private final Map annotations = new HashMap<>(); /** * Register a command handler. @@ -26,14 +27,14 @@ public final class CommandMap { // Get command data. Command annotation = command.getClass().getAnnotation(Command.class); - this.executionPower.put(label, annotation.execution()); + this.annotations.put(label, annotation); this.commands.put(label, command); // Register aliases. if(annotation.aliases().length > 0) { for (String alias : annotation.aliases()) { this.commands.put(alias, command); - this.executionPower.put(alias, annotation.execution()); + this.annotations.put(alias, annotation); } } return this; } @@ -49,14 +50,14 @@ public final class CommandMap { if(handler == null) return this; Command annotation = handler.getClass().getAnnotation(Command.class); - this.executionPower.remove(label); + this.annotations.remove(label); this.commands.remove(label); // Unregister aliases. if(annotation.aliases().length > 0) { for (String alias : annotation.aliases()) { this.commands.remove(alias); - this.executionPower.remove(alias); + this.annotations.remove(alias); } } @@ -106,8 +107,18 @@ public final class CommandMap { CommandHandler.sendMessage(player, "Unknown command: " + label); return; } + // Check for permission. + if(player != null) { + String permissionNode = this.annotations.get(label).permission(); + Account account = player.getAccount(); + List permissions = account.getPermissions(); + if(!permissions.contains("*") && !permissions.contains(permissionNode)) { + CommandHandler.sendMessage(player, "You do not have permission to run this command."); return; + } + } + // Execution power check. - Command.Execution executionPower = this.executionPower.get(label); + Command.Execution executionPower = this.annotations.get(label).execution(); if(player == null && executionPower == Command.Execution.PLAYER) { CommandHandler.sendMessage(null, "Run this command in-game."); return; } else if (player != null && executionPower == Command.Execution.CONSOLE) { diff --git a/src/main/java/emu/grasscutter/commands/ServerCommands.java b/src/main/java/emu/grasscutter/commands/ServerCommands.java index fc1e9b142..6ae0bb33c 100644 --- a/src/main/java/emu/grasscutter/commands/ServerCommands.java +++ b/src/main/java/emu/grasscutter/commands/ServerCommands.java @@ -109,7 +109,10 @@ public final class ServerCommands { Account account = DatabaseHelper.createAccountWithId(username, uid); if(account == null) { CommandHandler.sendMessage(null, "Account already exists."); return; - } else CommandHandler.sendMessage(null, "Account created with UID " + account.getPlayerId() + "."); + } else { + CommandHandler.sendMessage(null, "Account created with UID " + account.getPlayerId() + "."); + account.addPermission("*"); // Grant the player superuser permissions. + } return; case "delete": if(DatabaseHelper.deleteAccount(username)) { @@ -120,6 +123,44 @@ public final class ServerCommands { } } + @Command(label = "permission", + usage = "Usage: permission ", + execution = Command.Execution.CONSOLE) + public static class PermissionCommand implements CommandHandler { + + @Override + public void execute(List args) { + if(args.size() < 3) { + CommandHandler.sendMessage(null, "Usage: permission "); return; + } + + String action = args.get(0); + String username = args.get(1); + String permission = args.get(2); + + Account account = DatabaseHelper.getAccountByName(username); + if(account == null) { + CommandHandler.sendMessage(null, "Account not found."); return; + } + + switch(action) { + default: + CommandHandler.sendMessage(null, "Usage: permission "); + return; + case "add": + if(account.addPermission(permission)) { + CommandHandler.sendMessage(null, "Permission added."); return; + } else CommandHandler.sendMessage(null, "They already have this permission!"); + return; + case "remove": + if(account.removePermission(permission)) { + CommandHandler.sendMessage(null, "Permission removed."); return; + } else CommandHandler.sendMessage(null, "They don't have this permission!"); + return; + } + } + } + @Command(label = "help", usage = "Usage: help [command]") public static class HelpCommand implements CommandHandler { diff --git a/src/main/java/emu/grasscutter/game/Account.java b/src/main/java/emu/grasscutter/game/Account.java index 0bb2e9e0b..bba03916a 100644 --- a/src/main/java/emu/grasscutter/game/Account.java +++ b/src/main/java/emu/grasscutter/game/Account.java @@ -9,6 +9,8 @@ import emu.grasscutter.utils.Crypto; import emu.grasscutter.utils.Utils; import dev.morphia.annotations.IndexOptions; +import java.util.List; + @Entity(value = "accounts", noClassnameStored = true) public class Account { @Id private String id; @@ -23,6 +25,7 @@ public class Account { private String token; private String sessionKey; // Session token for dispatch server + private List permissions; @Deprecated public Account() {} @@ -84,6 +87,22 @@ public class Account { this.save(); return this.sessionKey; } + + /** + * The collection of a player's permissions. + */ + public List getPermissions() { + return this.permissions; + } + + public boolean addPermission(String permission) { + if(this.permissions.contains(permission)) return false; + this.permissions.add(permission); return true; + } + + public boolean removePermission(String permission) { + return this.permissions.remove(permission); + } // TODO make unique public String generateLoginToken() { diff --git a/src/main/java/emu/grasscutter/game/GenshinPlayer.java b/src/main/java/emu/grasscutter/game/GenshinPlayer.java index f9f1521e1..bbf80513e 100644 --- a/src/main/java/emu/grasscutter/game/GenshinPlayer.java +++ b/src/main/java/emu/grasscutter/game/GenshinPlayer.java @@ -1,11 +1,6 @@ package emu.grasscutter.game; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; +import java.util.*; import dev.morphia.annotations.*; import emu.grasscutter.GenshinConstants;