CommandAPI's `NativeProxyCommandSender` cannot run vanilla commands
willkroboth opened this issue · comments
CommandAPI version
9.0.4-SNAPSHOT
Minecraft version
1.20.1
Are you shading the CommandAPI?
Yes
What I did
I registered this test
command in onEnable
:
new CommandAPICommand("test")
.executesNative((sender, args) -> {
Bukkit.dispatchCommand(sender, "say Hello");
})
.register();
Run the test
command
What actually happened
This exception is thrown (running the command as console - similar exceptions happen for other CommandSender
):
[Server thread/ERROR]: Unhandled exception executing '/test'
org.bukkit.command.CommandException: Unhandled exception executing 'say Hello' in org.bukkit.craftbukkit.v1_20_R1.command.VanillaCommandWrapper(say)
at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:156) ~[spigot-api-1.20.1-R0.1-SNAPSHOT.jar:?]
at org.bukkit.craftbukkit.v1_20_R1.CraftServer.dispatchCommand(CraftServer.java:875) ~[spigot-1.20.1-R0.1-SNAPSHOT.jar:3838-Spigot-3374045-a2fafdd]
at org.bukkit.Bukkit.dispatchCommand(Bukkit.java:884) ~[spigot-api-1.20.1-R0.1-SNAPSHOT.jar:?]
at me.willkroboth.CommandAPITest.Main.lambda$onEnable$0(Main.java:24) ~[?:?]
at me.willkroboth.CommandAPITest.commandapi.executors.NativeCommandExecutor.run(NativeCommandExecutor.java:49) ~[?:?]
at me.willkroboth.CommandAPITest.commandapi.executors.NormalExecutor.executeWith(NormalExecutor.java:44) ~[?:?]
at me.willkroboth.CommandAPITest.commandapi.CommandAPIExecutor.execute(CommandAPIExecutor.java:138) ~[?:?]
at me.willkroboth.CommandAPITest.commandapi.CommandAPIExecutor.execute(CommandAPIExecutor.java:113) ~[?:?]
at me.willkroboth.CommandAPITest.commandapi.CommandAPIExecutor.execute(CommandAPIExecutor.java:96) ~[?:?]
at me.willkroboth.CommandAPITest.commandapi.CommandAPIHandler.lambda$generateCommand$0(CommandAPIHandler.java:258) ~[?:?]
at com.mojang.brigadier.CommandDispatcher.execute(CommandDispatcher.java:265) ~[spigot-1.20.1-R0.1-SNAPSHOT.jar:?]
at net.minecraft.commands.CommandDispatcher.performCommand(CommandDispatcher.java:314) ~[spigot-1.20.1-R0.1-SNAPSHOT.jar:3838-Spigot-3374045-a2fafdd]
at net.minecraft.commands.CommandDispatcher.performPrefixedCommand(CommandDispatcher.java:293) ~[spigot-1.20.1-R0.1-SNAPSHOT.jar:3838-Spigot-3374045-a2fafdd]
at org.bukkit.craftbukkit.v1_20_R1.command.VanillaCommandWrapper.execute(VanillaCommandWrapper.java:45) ~[spigot-1.20.1-R0.1-SNAPSHOT.jar:3838-Spigot-3374045-a2fafdd]
at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:149) ~[spigot-api-1.20.1-R0.1-SNAPSHOT.jar:?]
at org.bukkit.craftbukkit.v1_20_R1.CraftServer.dispatchCommand(CraftServer.java:875) ~[spigot-1.20.1-R0.1-SNAPSHOT.jar:3838-Spigot-3374045-a2fafdd]
at org.bukkit.craftbukkit.v1_20_R1.CraftServer.dispatchServerCommand(CraftServer.java:860) ~[spigot-1.20.1-R0.1-SNAPSHOT.jar:3838-Spigot-3374045-a2fafdd]
at net.minecraft.server.dedicated.DedicatedServer.bf(DedicatedServer.java:413) ~[spigot-1.20.1-R0.1-SNAPSHOT.jar:3838-Spigot-3374045-a2fafdd]
at net.minecraft.server.dedicated.DedicatedServer.b(DedicatedServer.java:389) ~[spigot-1.20.1-R0.1-SNAPSHOT.jar:3838-Spigot-3374045-a2fafdd]
at net.minecraft.server.MinecraftServer.a(MinecraftServer.java:1198) ~[spigot-1.20.1-R0.1-SNAPSHOT.jar:3838-Spigot-3374045-a2fafdd]
at net.minecraft.server.MinecraftServer.w(MinecraftServer.java:1015) ~[spigot-1.20.1-R0.1-SNAPSHOT.jar:3838-Spigot-3374045-a2fafdd]
at net.minecraft.server.MinecraftServer.lambda$0(MinecraftServer.java:304) ~[spigot-1.20.1-R0.1-SNAPSHOT.jar:3838-Spigot-3374045-a2fafdd]
at java.lang.Thread.run(Thread.java:833) ~[?:?]
Caused by: java.lang.ClassCastException: class me.willkroboth.CommandAPITest.commandapi.wrappers.NativeProxyCommandSender cannot be cast to class org.bukkit.craftbukkit.v1_20_R1.command.ProxiedNativeCommandSender (me.willkroboth.CommandAPITest.commandapi.wrappers.NativeProxyCommandSender is in unnamed module of loader org.bukkit.plugin.java.PluginClassLoader @5b499bce; org.bukkit.craftbukkit.v1_20_R1.command.ProxiedNativeCommandSender is in unnamed module of loader java.net.URLClassLoader @2e5d6d97)
at org.bukkit.craftbukkit.v1_20_R1.command.VanillaCommandWrapper.getListener(VanillaCommandWrapper.java:83) ~[spigot-1.20.1-R0.1-SNAPSHOT.jar:3838-Spigot-3374045-a2fafdd]
at org.bukkit.craftbukkit.v1_20_R1.command.VanillaCommandWrapper.execute(VanillaCommandWrapper.java:44) ~[spigot-1.20.1-R0.1-SNAPSHOT.jar:3838-Spigot-3374045-a2fafdd]
at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:149) ~[spigot-api-1.20.1-R0.1-SNAPSHOT.jar:?]
... 22 more
[Server thread/INFO]: An unexpected error occurred trying to execute that command
What should have happened
The Vanilla say
command should have been executed without an exception.
Server logs and CommandAPI config
No response
Other
The exception is thrown by VanillaCommandWrapper#getListener
:
public static CommandListenerWrapper getListener(CommandSender sender) {
if (sender instanceof Player) {
return ((CraftPlayer) sender).getHandle().createCommandSourceStack();
}
if (sender instanceof BlockCommandSender) {
return ((CraftBlockCommandSender) sender).getWrapper();
}
if (sender instanceof CommandMinecart) {
return ((EntityMinecartCommandBlock) ((CraftMinecartCommand) sender).getHandle()).getCommandBlock().createCommandSourceStack();
}
if (sender instanceof RemoteConsoleCommandSender) {
return ((DedicatedServer) MinecraftServer.getServer()).rconConsoleSource.createCommandSourceStack();
}
if (sender instanceof ConsoleCommandSender) {
return ((CraftServer) sender.getServer()).getServer().createCommandSourceStack();
}
if (sender instanceof ProxiedCommandSender) {
return ((ProxiedNativeCommandSender) sender).getHandle();
}
throw new IllegalArgumentException("Cannot make " + sender + " a vanilla command listener");
}
Specifically, the exception is thrown when an instance of the CommandAPI's NativeProxyCommandSender
is passed into this method. The test
command here replicates this by using executesNative
to get a NativeProxyCommandSender
, and runs the Vanilla say
command, which is handled by the VanillaCommandWrapper
.
Since NativeProxyCommandSender
extends ProxiedCommandSender
, it passes into the last if-statement. That code assumes the sender is an org.bukkit.craftbukkit.v1_20_R1.command.ProxiedNativeCommandSender
and casts it as such. This cast fails, and the ClassCastException
is thrown.
This is not a Spigot bug. As SPIGOT-7023 states specifically for CommandSender
, classes in the Bukkit API are generally not designed to be implemented, and any bugs resulting from doing so will be disregarded. This bug happens because the CommandAPI tried to implement the org.bukkit.command.ProxiedCommandSender
class, which is not supported.
While Bukkit does not support this situation, it can be worked around. If the CommandAPI's NativeProxyCommandSender
extended ProxiedNativeCommandSender
, then VanillaCommandWrapper
would work as expected. Unfortunately, ProxiedNativeCommandSender
is a version-specific CraftBukkit class, so making this work is not trivial. However, it should be possible to make this work, and personally, I have successfully implemented something similar before.