Skip to content

Commit

Permalink
Fixed command dispatcher in MC 1.20.6
Browse files Browse the repository at this point in the history
- Updated Internals class

 > Related to #125
  • Loading branch information
josemmo committed May 26, 2024
1 parent a90aad5 commit 7726b9a
Showing 1 changed file with 24 additions and 14 deletions.
38 changes: 24 additions & 14 deletions src/main/java/io/josemmo/bukkit/plugin/utils/Internals.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@
import org.bukkit.command.CommandMap;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Internals {
public static final float MINECRAFT_VERSION;
private static final CommandDispatcher<?> DISPATCHER;
private static final CommandMap COMMAND_MAP;
private static final Method GET_BUKKIT_SENDER_METHOD;
private static @Nullable Method GET_BUKKIT_SENDER_METHOD = null;

static {
try {
Expand All @@ -30,24 +31,30 @@ public class Internals {
Object nmsInstance = obcClass.getDeclaredMethod("getServer").invoke(obcInstance);
Class<?> nmsClass = nmsInstance.getClass().getSuperclass();

// Get "net.minecraft.server.CommandDispatcher" references
Object nmsDispatcherInstance = nmsClass.getDeclaredField("vanillaCommandDispatcher").get(nmsInstance);
Class<?> nmsDispatcherClass = nmsDispatcherInstance.getClass();
if (MINECRAFT_VERSION >= 20.6) {
// Get "net.minecraft.commands.Commands" references
Object nmsCommandsInstance = nmsClass.getDeclaredMethod("getCommands").invoke(nmsInstance);
Class<?> nmsCommandsClass = nmsCommandsInstance.getClass();

// Get Brigadier dispatcher instance
Method getDispatcherMethod = nmsDispatcherClass.getDeclaredMethod("a");
getDispatcherMethod.setAccessible(true);
DISPATCHER = (CommandDispatcher<?>) getDispatcherMethod.invoke(nmsDispatcherInstance);
// Get "com.mojang.brigadier.CommandDispatcher" instance
Field nmsDispatcherField = nmsCommandsClass.getDeclaredField("dispatcher");
nmsDispatcherField.setAccessible(true);
DISPATCHER = (CommandDispatcher<?>) nmsDispatcherField.get(nmsCommandsInstance);
} else {
// Get "net.minecraft.server.CommandDispatcher" references
Object nmsDispatcherInstance = nmsClass.getDeclaredField("vanillaCommandDispatcher").get(nmsInstance);
Class<?> nmsDispatcherClass = nmsDispatcherInstance.getClass();

// Get "com.mojang.brigadier.CommandDispatcher" instance
Method getDispatcherMethod = nmsDispatcherClass.getDeclaredMethod("a");
getDispatcherMethod.setAccessible(true);
DISPATCHER = (CommandDispatcher<?>) getDispatcherMethod.invoke(nmsDispatcherInstance);
}

// Get command map instance
Field commandMapField = obcClass.getDeclaredField("commandMap");
commandMapField.setAccessible(true);
COMMAND_MAP = (CommandMap) commandMapField.get(obcInstance);

// Get CommandListenerWrapper.getBukkitSender() method
Class<?> clwClass = Class.forName(nmsDispatcherClass.getPackage().getName() + ".CommandListenerWrapper");
GET_BUKKIT_SENDER_METHOD = clwClass.getDeclaredMethod("getBukkitSender");
GET_BUKKIT_SENDER_METHOD.setAccessible(true);
} catch (Exception e) {
throw new RuntimeException("Failed to get internal classes due to incompatible Minecraft server", e);
}
Expand Down Expand Up @@ -76,9 +83,12 @@ public class Internals {
*/
public static @NotNull CommandSender getBukkitSender(@NotNull Object source) {
try {
if (GET_BUKKIT_SENDER_METHOD == null) {
GET_BUKKIT_SENDER_METHOD = source.getClass().getDeclaredMethod("getBukkitSender");
}
return (CommandSender) GET_BUKKIT_SENDER_METHOD.invoke(source);
} catch (Exception e) {
throw new RuntimeException("Failed to extract bukkit sender from source", e);
throw new RuntimeException("Failed to extract Bukkit sender from source", e);
}
}
}

0 comments on commit 7726b9a

Please sign in to comment.