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;
+ }
}