Fix CraftServer#syncCommands breaking commodore
This commit is contained in:
parent
1632da717b
commit
814a41da93
4 changed files with 141 additions and 7 deletions
|
|
@ -13,11 +13,13 @@ import java.util.Optional;
|
|||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import net.frankheijden.serverutils.bukkit.entities.BukkitPluginDescription;
|
||||
import net.frankheijden.serverutils.bukkit.events.BukkitPluginDisableEvent;
|
||||
import net.frankheijden.serverutils.bukkit.events.BukkitPluginEnableEvent;
|
||||
import net.frankheijden.serverutils.bukkit.events.BukkitPluginLoadEvent;
|
||||
import net.frankheijden.serverutils.bukkit.events.BukkitPluginUnloadEvent;
|
||||
import net.frankheijden.serverutils.bukkit.reflection.RCommandDispatcher;
|
||||
import net.frankheijden.serverutils.bukkit.reflection.RCommandMap;
|
||||
import net.frankheijden.serverutils.bukkit.reflection.RCraftServer;
|
||||
import net.frankheijden.serverutils.bukkit.reflection.RCraftingManager;
|
||||
|
|
@ -220,11 +222,14 @@ public class BukkitPluginManager extends AbstractPluginManager<Plugin, BukkitPlu
|
|||
Map<String, Command> knownCommands = getKnownCommands();
|
||||
if (knownCommands == null) return;
|
||||
|
||||
knownCommands.values().removeIf(c -> {
|
||||
List<String> unregisteredCommands = new ArrayList<>();
|
||||
knownCommands.entrySet().removeIf(e -> {
|
||||
Command c = e.getValue();
|
||||
if (c instanceof PluginIdentifiableCommand) {
|
||||
PluginIdentifiableCommand pc = (PluginIdentifiableCommand) c;
|
||||
if (pc.getPlugin().getName().equals(plugin.getName())) {
|
||||
c.unregister(RCraftServer.getCommandMap());
|
||||
unregisteredCommands.add(e.getKey());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -232,7 +237,8 @@ public class BukkitPluginManager extends AbstractPluginManager<Plugin, BukkitPlu
|
|||
return false;
|
||||
});
|
||||
|
||||
RCraftServer.syncCommands();
|
||||
RCommandDispatcher.removeCommands(unregisteredCommands);
|
||||
RCraftServer.updateCommands();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -263,7 +269,8 @@ public class BukkitPluginManager extends AbstractPluginManager<Plugin, BukkitPlu
|
|||
return false;
|
||||
});
|
||||
|
||||
RCraftServer.syncCommands();
|
||||
RCommandDispatcher.removeCommands(commands);
|
||||
RCraftServer.updateCommands();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -282,7 +289,8 @@ public class BukkitPluginManager extends AbstractPluginManager<Plugin, BukkitPlu
|
|||
map.remove(command);
|
||||
}
|
||||
|
||||
RCraftServer.syncCommands();
|
||||
RCommandDispatcher.removeCommands(Arrays.asList(commands));
|
||||
RCraftServer.updateCommands();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -294,7 +302,8 @@ public class BukkitPluginManager extends AbstractPluginManager<Plugin, BukkitPlu
|
|||
if (knownCommands == null) return;
|
||||
knownCommands.values().removeAll(commands);
|
||||
|
||||
RCraftServer.syncCommands();
|
||||
RCommandDispatcher.removeCommands(commands.stream().map(Command::getName).collect(Collectors.toList()));
|
||||
RCraftServer.updateCommands();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -0,0 +1,65 @@
|
|||
package net.frankheijden.serverutils.bukkit.reflection;
|
||||
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import dev.frankheijden.minecraftreflection.MinecraftReflection;
|
||||
import dev.frankheijden.minecraftreflection.MinecraftReflectionVersion;
|
||||
import dev.frankheijden.minecraftreflection.exceptions.MinecraftReflectionException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
public class RCommandDispatcher {
|
||||
|
||||
private static final MinecraftReflection reflection;
|
||||
private static final Method getCommandDispatcherMethod;
|
||||
private static final Method getDispatcherMethod;
|
||||
|
||||
static {
|
||||
if (MinecraftReflectionVersion.MINOR < 13) {
|
||||
reflection = null;
|
||||
getCommandDispatcherMethod = null;
|
||||
getDispatcherMethod = null;
|
||||
} else {
|
||||
if (MinecraftReflectionVersion.MINOR >= 17) {
|
||||
reflection = MinecraftReflection.of("net.minecraft.commands.CommandDispatcher");
|
||||
} else {
|
||||
reflection = MinecraftReflection.of("net.minecraft.server.%s.CommandDispatcher");
|
||||
}
|
||||
|
||||
getCommandDispatcherMethod = Arrays.stream(RMinecraftServer.getReflection().getClazz().getDeclaredMethods())
|
||||
.filter(m -> m.getReturnType().equals(reflection.getClazz()))
|
||||
.distinct()
|
||||
.findAny()
|
||||
.get();
|
||||
getDispatcherMethod = Arrays.stream(getCommandDispatcherMethod.getReturnType().getDeclaredMethods())
|
||||
.filter(m -> CommandDispatcher.class.equals(m.getReturnType()))
|
||||
.findAny()
|
||||
.get();
|
||||
}
|
||||
}
|
||||
|
||||
public RCommandDispatcher() {}
|
||||
|
||||
/**
|
||||
* Retrieves the command dispatcher.
|
||||
*/
|
||||
public static CommandDispatcher<?> getDispatcher() {
|
||||
try {
|
||||
Object minecraftDispatcher = getCommandDispatcherMethod.invoke(RCraftServer.getConsole());
|
||||
return (CommandDispatcher<?>) getDispatcherMethod.invoke(minecraftDispatcher);
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
throw new MinecraftReflectionException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes commands from the brigadier root node.
|
||||
*/
|
||||
public static void removeCommands(Collection<? extends String> commands) {
|
||||
if (MinecraftReflectionVersion.MINOR < 13) return;
|
||||
CommandDispatcher<?> dispatcher = getDispatcher();
|
||||
for (String command : commands) {
|
||||
RCommandNode.removeCommand(dispatcher.getRoot(), command);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package net.frankheijden.serverutils.bukkit.reflection;
|
||||
|
||||
import com.mojang.brigadier.tree.CommandNode;
|
||||
import dev.frankheijden.minecraftreflection.ClassObject;
|
||||
import dev.frankheijden.minecraftreflection.MinecraftReflection;
|
||||
|
||||
public class RCommandNode {
|
||||
|
||||
private static final MinecraftReflection reflection;
|
||||
|
||||
static {
|
||||
reflection = MinecraftReflection.of(CommandNode.class);
|
||||
}
|
||||
|
||||
public RCommandNode() {}
|
||||
|
||||
public static void removeCommand(Object node, String name) {
|
||||
reflection.invoke(node, "removeCommand", name);
|
||||
}
|
||||
|
||||
public static String getName(Object node) {
|
||||
return reflection.invoke(node, "getName");
|
||||
}
|
||||
|
||||
public static void addChild(Object parent, Object child) {
|
||||
reflection.invoke(parent, "addChild", ClassObject.of(CommandNode.class, child));
|
||||
}
|
||||
}
|
||||
|
|
@ -3,12 +3,15 @@ package net.frankheijden.serverutils.bukkit.reflection;
|
|||
import dev.frankheijden.minecraftreflection.MinecraftReflection;
|
||||
import dev.frankheijden.minecraftreflection.MinecraftReflectionVersion;
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Warning;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.SimpleCommandMap;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class RCraftServer {
|
||||
|
||||
|
|
@ -41,8 +44,35 @@ public class RCraftServer {
|
|||
return reflection.get(Bukkit.getServer(), "commandMap");
|
||||
}
|
||||
|
||||
/**
|
||||
* Syncs and registers all commands, but keeping the old values that haven't been added.
|
||||
*/
|
||||
@SuppressWarnings({"rawtypes"})
|
||||
public static void syncCommands() {
|
||||
if (MinecraftReflectionVersion.MINOR >= 13) reflection.invoke(Bukkit.getServer(), "syncCommands");
|
||||
if (MinecraftReflectionVersion.MINOR < 13) return;
|
||||
|
||||
Collection children = RCommandDispatcher.getDispatcher().getRoot().getChildren();
|
||||
reflection.invoke(Bukkit.getServer(), "syncCommands");
|
||||
Object root = RCommandDispatcher.getDispatcher().getRoot();
|
||||
|
||||
for (Object child : children) {
|
||||
RCommandNode.removeCommand(root, RCommandNode.getName(child));
|
||||
RCommandNode.addChild(root, child);
|
||||
}
|
||||
updateCommands();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates commands for all online players.
|
||||
*/
|
||||
public static void updateCommands() {
|
||||
if (MinecraftReflectionVersion.MINOR < 13) return;
|
||||
Bukkit.getOnlinePlayers().forEach(RCraftServer::updateCommands);
|
||||
}
|
||||
|
||||
public static void updateCommands(Player player) {
|
||||
if (MinecraftReflectionVersion.MINOR < 13) return;
|
||||
player.updateCommands();
|
||||
}
|
||||
|
||||
public static Object getConsole() {
|
||||
|
|
@ -89,7 +119,9 @@ public class RCraftServer {
|
|||
SimpleCommandMap commandMap = getCommandMap();
|
||||
Map<String, Command> map = RCommandMap.getKnownCommands(commandMap);
|
||||
|
||||
for (String alias : Bukkit.getCommandAliases().keySet()) {
|
||||
Set<String> commandNames = Bukkit.getCommandAliases().keySet();
|
||||
RCommandDispatcher.removeCommands(commandNames);
|
||||
for (String alias : commandNames) {
|
||||
Command aliasCommand = map.remove(alias);
|
||||
if (aliasCommand == null) continue;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue