diff --git a/src/main/java/serverutils/lib/command/CommandTreeBase.java b/src/main/java/serverutils/lib/command/CommandTreeBase.java index 5dd5b8dd..bedbd3d3 100644 --- a/src/main/java/serverutils/lib/command/CommandTreeBase.java +++ b/src/main/java/serverutils/lib/command/CommandTreeBase.java @@ -13,9 +13,11 @@ import net.minecraft.command.CommandException; import net.minecraft.command.ICommand; import net.minecraft.command.ICommandSender; -import net.minecraft.server.MinecraftServer; +import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.util.ChatComponentTranslation; +import serverutils.ranks.ICommandWithPermission; + /** * Base class for commands that has subcommands. *

@@ -108,14 +110,14 @@ public boolean isUsernameIndex(String[] args, int index) { @Override public void processCommand(ICommandSender sender, String[] args) throws CommandException { if (args.length < 1) { - String subCommandsString = getAvailableSubCommandsString(MinecraftServer.getServer(), sender); + String subCommandsString = getAvailableSubCommandsString(sender); sender.addChatMessage( new ChatComponentTranslation("commands.tree_base.available_subcommands", subCommandsString)); } else { ICommand cmd = getSubCommand(args[0]); if (cmd == null) { - String subCommandsString = getAvailableSubCommandsString(MinecraftServer.getServer(), sender); + String subCommandsString = getAvailableSubCommandsString(sender); throw new CommandException( "commands.tree_base.invalid_cmd.list_subcommands", args[0], @@ -128,13 +130,21 @@ public void processCommand(ICommandSender sender, String[] args) throws CommandE } } - private String getAvailableSubCommandsString(MinecraftServer server, ICommandSender sender) { + private String getAvailableSubCommandsString(ICommandSender sender) { Collection availableCommands = new ArrayList<>(); for (ICommand command : getSubCommands()) { - if (command.canCommandSenderUseCommand(sender)) { + if (canUseSubcommand(sender, command)) { availableCommands.add(command.getCommandName()); } } return CommandBase.joinNiceStringFromCollection(availableCommands); } + + private boolean canUseSubcommand(ICommandSender sender, ICommand command) { + if (command instanceof ICommandWithPermission permCmd && sender instanceof EntityPlayerMP player) { + return permCmd.serverutilities$hasPermission(player); + } + + return command.canCommandSenderUseCommand(sender); + } } diff --git a/src/main/java/serverutils/ranks/ICommandWithPermission.java b/src/main/java/serverutils/ranks/ICommandWithPermission.java index 6c7336a3..b5c84ba2 100644 --- a/src/main/java/serverutils/ranks/ICommandWithPermission.java +++ b/src/main/java/serverutils/ranks/ICommandWithPermission.java @@ -3,6 +3,8 @@ import java.util.HashMap; import java.util.Map; +import net.minecraft.entity.player.EntityPlayerMP; + import org.jetbrains.annotations.NotNull; public interface ICommandWithPermission { @@ -18,4 +20,6 @@ public interface ICommandWithPermission { String serverutilities$getModName(); void serverutilities$setModName(@NotNull String modName); + + boolean serverutilities$hasPermission(EntityPlayerMP player); } diff --git a/src/mixins/java/serverutils/mixins/early/minecraft/MixinCommandHandler.java b/src/mixins/java/serverutils/mixins/early/minecraft/MixinCommandHandler.java index 288a87b9..c581aa99 100644 --- a/src/mixins/java/serverutils/mixins/early/minecraft/MixinCommandHandler.java +++ b/src/mixins/java/serverutils/mixins/early/minecraft/MixinCommandHandler.java @@ -21,7 +21,6 @@ import cpw.mods.fml.common.Loader; import cpw.mods.fml.common.LoaderState; import cpw.mods.fml.common.ModContainer; -import cpw.mods.fml.common.eventhandler.Event; import serverutils.ServerUtilitiesPermissions; import serverutils.data.NodeEntry; import serverutils.lib.command.CommandTreeBase; @@ -29,7 +28,6 @@ import serverutils.lib.util.permission.PermissionAPI; import serverutils.ranks.ICommandWithPermission; import serverutils.ranks.Rank; -import serverutils.ranks.Ranks; @Mixin(CommandHandler.class) public abstract class MixinCommandHandler { @@ -38,24 +36,31 @@ public abstract class MixinCommandHandler { private static final Matcher PERMISSION_REPLACE_MATCHER = Pattern.compile("[^a-zA-Z0-9._]").matcher(""); @ModifyExpressionValue( - method = { "getPossibleCommands(Lnet/minecraft/command/ICommandSender;)Ljava/util/List;", - "executeCommand" }, + method = "getPossibleCommands(Lnet/minecraft/command/ICommandSender;)Ljava/util/List;", at = @At( value = "INVOKE", target = "Lnet/minecraft/command/ICommand;canCommandSenderUseCommand(Lnet/minecraft/command/ICommandSender;)Z")) private boolean serverutilities$checkPermission(boolean original, @Local(argsOnly = true) ICommandSender sender, @Local ICommand command) { - if (sender instanceof EntityPlayerMP player) { - Event.Result result = Ranks.INSTANCE.getPermissionResult( - player, - ((ICommandWithPermission) command).serverutilities$getPermissionNode(), - true); - - if (result != Event.Result.DEFAULT) { - return result == Event.Result.ALLOW; - } + if (!(sender instanceof EntityPlayerMP player)) return original; + return ((ICommandWithPermission) command).serverutilities$hasPermission(player); + } + + @ModifyExpressionValue( + method = "executeCommand", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/command/ICommand;canCommandSenderUseCommand(Lnet/minecraft/command/ICommandSender;)Z")) + private boolean serverutilities$checkPermissionExecute(boolean original, + @Local(argsOnly = true) ICommandSender sender, @Local ICommand command, @Local String[] args) { + if (!(sender instanceof EntityPlayerMP player)) return original; + + if (command instanceof CommandTreeBase treeCmd && args.length >= 1) { + ICommand subCommand = treeCmd.getSubCommand(args[0]); + if (subCommand != null) command = subCommand; } - return original; + + return ((ICommandWithPermission) command).serverutilities$hasPermission(player); } @Inject(method = "registerCommand", at = @At(value = "HEAD")) diff --git a/src/mixins/java/serverutils/mixins/early/minecraft/MixinICommand.java b/src/mixins/java/serverutils/mixins/early/minecraft/MixinICommand.java index ce013359..fc96d281 100644 --- a/src/mixins/java/serverutils/mixins/early/minecraft/MixinICommand.java +++ b/src/mixins/java/serverutils/mixins/early/minecraft/MixinICommand.java @@ -1,12 +1,16 @@ package serverutils.mixins.early.minecraft; import net.minecraft.command.ICommand; +import net.minecraft.command.ICommandSender; +import net.minecraft.entity.player.EntityPlayerMP; import org.jetbrains.annotations.NotNull; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; +import cpw.mods.fml.common.eventhandler.Event; import serverutils.ranks.ICommandWithPermission; +import serverutils.ranks.Ranks; @Mixin(ICommand.class) public interface MixinICommand extends ICommandWithPermission { @@ -14,6 +18,9 @@ public interface MixinICommand extends ICommandWithPermission { @Shadow String getCommandName(); + @Shadow + boolean canCommandSenderUseCommand(ICommandSender sender); + @Override default String serverutilities$getPermissionNode() { return commandPermissions.get(getCommandName()); @@ -33,4 +40,14 @@ public interface MixinICommand extends ICommandWithPermission { default void serverutilities$setModName(@NotNull String modName) { commandOwners.put(getCommandName(), modName); } + + @Override + default boolean serverutilities$hasPermission(@NotNull EntityPlayerMP player) { + Event.Result result = Ranks.INSTANCE.getPermissionResult(player, serverutilities$getPermissionNode(), true); + if (result == Event.Result.DEFAULT) { + return canCommandSenderUseCommand(player); + } + + return result == Event.Result.ALLOW; + } }