Skip to content

Commit

Permalink
fail silently in command reflections
Browse files Browse the repository at this point in the history
  • Loading branch information
xGinko committed Jan 6, 2025
1 parent 2d80e99 commit aa68538
Showing 1 changed file with 62 additions and 76 deletions.
138 changes: 62 additions & 76 deletions shared/src/main/java/me/xginko/aef/commands/BukkitCommandWrap.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public final class BukkitCommandWrap {

private final boolean nmsVersioning;
private String nmsVersion;
private Class minecraftServerClass;
private Class<?> minecraftServerClass;
private Method getServerMethod, syncCommandsMethod, removeCommandMethod;
private Field bField, vanillaCommandDispatcherField, commandMapField, knownCommandsField;

Expand All @@ -32,14 +32,14 @@ public BukkitCommandWrap() {
String[] packageParts = prefix.split("\\.");
String versionPart = packageParts[packageParts.length - 1];
if (versionPart.startsWith("v1_")) {
this.nmsVersion = versionPart;
nmsVersion = versionPart;
}
boolean nmsVers = true;
try {
Class.forName("net.minecraft.server.MinecraftServer");
nmsVers = false;
} catch (ClassNotFoundException ignore) {}
this.nmsVersioning = nmsVers;
nmsVersioning = nmsVers;
}

public static BukkitCommandWrap getInstance() {
Expand All @@ -58,208 +58,194 @@ public static BukkitCommandWrap getInstance() {
}

private @NotNull String getNetMinecraftServerPrefix(String nmsClassName) {
if (this.nmsVersioning) return "net.minecraft.server." + this.nmsVersion + "." + nmsClassName;
if (nmsVersioning) return "net.minecraft.server." + nmsVersion + "." + nmsClassName;
return "net.minecraft.server." + nmsClassName;
}

private boolean resolveSyncCommandsMethod() {
if (this.syncCommandsMethod != null) return true;
if (syncCommandsMethod != null) return true;

try {
this.syncCommandsMethod = Class.forName(getCraftBukkitPrefix("CraftServer")).getDeclaredMethod("syncCommands");
this.syncCommandsMethod.setAccessible(true);
syncCommandsMethod = Class.forName(getCraftBukkitPrefix("CraftServer")).getDeclaredMethod("syncCommands");
syncCommandsMethod.setAccessible(true);
return true;
} catch (NoSuchMethodException | ClassNotFoundException e) {
e.printStackTrace();

return false;
}
}

private boolean fetchCommandMapField() {
if (this.commandMapField != null) return true;
if (commandMapField != null) return true;
try {
this.commandMapField = Class.forName(getCraftBukkitPrefix("CraftServer")).getDeclaredField("commandMap");
this.commandMapField.setAccessible(true);
commandMapField = Class.forName(getCraftBukkitPrefix("CraftServer")).getDeclaredField("commandMap");
commandMapField.setAccessible(true);
return true;
} catch (NoSuchFieldException | ClassNotFoundException e) {
e.printStackTrace();

return false;
}
}

private boolean fetchKnownCommandsField() {
if (this.knownCommandsField != null) return true;
if (knownCommandsField != null) return true;

try {
this.knownCommandsField = SimpleCommandMap.class.getDeclaredField("knownCommands");
this.knownCommandsField.setAccessible(true);
knownCommandsField = SimpleCommandMap.class.getDeclaredField("knownCommands");
knownCommandsField.setAccessible(true);
return true;
} catch (NoSuchFieldException e) {
e.printStackTrace();

return false;
}
}

public void setKnownCommands(Map<String, Command> knownCommands) {
if (!this.fetchCommandMapField())
throw new RuntimeException("Cannot find command map");
if (!fetchCommandMapField()) return;

SimpleCommandMap commandMap;
try {
commandMap = (SimpleCommandMap) this.commandMapField.get(Bukkit.getServer());
commandMap = (SimpleCommandMap) commandMapField.get(Bukkit.getServer());
} catch (Exception e) {
e.printStackTrace();
return;
}

if (!this.fetchKnownCommandsField())
throw new RuntimeException("Unable to find known commands");
if (!fetchKnownCommandsField()) return;

try {
this.knownCommandsField.set(commandMap, knownCommands);
} catch (IllegalAccessException e) {
e.printStackTrace();
knownCommandsField.set(commandMap, knownCommands);
} catch (IllegalAccessException ignored) {
}
}

public void sync() {
if (!this.resolveSyncCommandsMethod()) return;
if (!resolveSyncCommandsMethod()) return;

try {
this.syncCommandsMethod.invoke(Bukkit.getServer());
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
syncCommandsMethod.invoke(Bukkit.getServer());
} catch (IllegalAccessException | InvocationTargetException ignored) {
}

if (Bukkit.getOnlinePlayers().isEmpty()) return;

Bukkit.getOnlinePlayers().forEach(Player::updateCommands);
for (Player player : Bukkit.getOnlinePlayers()) {
player.updateCommands();
}
}

public void unwrap(String command) {
if (this.nmsVersion == null) return;
if (nmsVersion == null) return;

if (!this.resolveMinecraftServerClass()) return;
if (!resolveMinecraftServerClass()) return;

if (!this.resolveGetServerMethod()) return;
Object server = this.getServerInstance();
if (!resolveGetServerMethod()) return;
Object server = getServerInstance();

if (!this.resolveVanillaCommandDispatcherField()) return;
Object commandDispatcher = this.getCommandDispatcher(server);
if (!resolveVanillaCommandDispatcherField()) return;
Object commandDispatcher = getCommandDispatcher(server);

if (!this.resolveBField()) return;
if (!resolveBField()) return;

CommandDispatcher b = this.getDispatcher(commandDispatcher);
if (b == null) return;
CommandDispatcher<?> dispatcher = getDispatcher(commandDispatcher);
if (dispatcher == null) return;

if (!this.resolveRemoveCommandMethod()) return;
if (!resolveRemoveCommandMethod()) return;

try {
this.removeCommandMethod.invoke(b.getRoot(), command);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
removeCommandMethod.invoke(dispatcher.getRoot(), command);
} catch (IllegalAccessException | InvocationTargetException ignored) {
}
}

private boolean resolveRemoveCommandMethod() {
if (this.removeCommandMethod == null) try {
if (removeCommandMethod == null) try {
try {
this.removeCommandMethod = RootCommandNode.class.getDeclaredMethod("removeCommand", String.class);
removeCommandMethod = RootCommandNode.class.getDeclaredMethod("removeCommand", String.class);
} catch (NoSuchMethodException | NoSuchMethodError ex) {
this.removeCommandMethod = CommandNode.class.getDeclaredMethod("removeCommand", String.class);
removeCommandMethod = CommandNode.class.getDeclaredMethod("removeCommand", String.class);
}
return true;
} catch (NoSuchMethodException e) {
e.printStackTrace();
return false;
}
return true;
}

private @Nullable CommandDispatcher getDispatcher(Object commandDispatcher) {
private @Nullable CommandDispatcher<?> getDispatcher(Object commandDispatcher) {
try {
return (CommandDispatcher) this.bField.get(commandDispatcher);
return (CommandDispatcher<?>) bField.get(commandDispatcher);
} catch (IllegalAccessException e) {
e.printStackTrace();
return null;
}
}

private @Nullable Object getCommandDispatcher(Object server) {
try {
return this.vanillaCommandDispatcherField.get(server);
return vanillaCommandDispatcherField.get(server);
} catch (IllegalAccessException e) {
e.printStackTrace();

return null;
}
}

private Object getServerInstance() {
try {
return this.getServerMethod.invoke(this.minecraftServerClass);
return getServerMethod.invoke(minecraftServerClass);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();

return null;
}
}

private boolean resolveMinecraftServerClass() {
if (this.minecraftServerClass != null) return true;
if (minecraftServerClass != null) return true;
try {
this.minecraftServerClass = Class.forName(this.getNetMinecraftServerPrefix("MinecraftServer"));
minecraftServerClass = Class.forName(getNetMinecraftServerPrefix("MinecraftServer"));
return true;
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
return false;
}
}

private boolean resolveGetServerMethod() {
if (this.getServerMethod != null) return true;
if (getServerMethod != null) return true;
try {
this.getServerMethod = this.minecraftServerClass.getMethod("getServer");
this.getServerMethod.setAccessible(true);
getServerMethod = minecraftServerClass.getMethod("getServer");
getServerMethod.setAccessible(true);
return true;
} catch (NoSuchMethodException e) {
e.printStackTrace();
return false;
}
}

private boolean resolveVanillaCommandDispatcherField() {
if (this.vanillaCommandDispatcherField != null) return true;
if (vanillaCommandDispatcherField != null) return true;
try {
this.vanillaCommandDispatcherField = this.minecraftServerClass.getDeclaredField("vanillaCommandDispatcher");
this.vanillaCommandDispatcherField.setAccessible(true);
vanillaCommandDispatcherField = minecraftServerClass.getDeclaredField("vanillaCommandDispatcher");
vanillaCommandDispatcherField.setAccessible(true);
return true;
} catch (NoSuchFieldException e) {
e.printStackTrace();
return false;
}
}

private boolean resolveBField() {
if (this.bField != null) return true;
if (bField != null) return true;
try {
this.bField = Class.forName(this.getNetMinecraftServerPrefix("CommandDispatcher")).getDeclaredField("b");
this.bField.setAccessible(true);
bField = Class.forName(getNetMinecraftServerPrefix("CommandDispatcher")).getDeclaredField("b");
bField.setAccessible(true);
return true;
} catch (NoSuchFieldException | ClassNotFoundException e) {
try {
Class<?> clazz = Class.forName("net.minecraft.commands.CommandDispatcher");
Field gField = clazz.getDeclaredField("g");
if (gField.getType() == CommandDispatcher.class)
this.bField = gField;
bField = gField;
else
this.bField = clazz.getDeclaredField("h");
this.bField.setAccessible(true);
bField = clazz.getDeclaredField("h");
bField.setAccessible(true);
return true;
} catch (NoSuchFieldException | ClassNotFoundException ex) {
ex.addSuppressed(e);
e.printStackTrace();
return false;
}
}
}

}

0 comments on commit aa68538

Please sign in to comment.