Merge pull request #46 from FrankHeijden/fix/commodore-sync-commands
Fix CraftServer#syncCommands breaking commodore
This commit is contained in:
commit
ea22eccdd8
4 changed files with 140 additions and 7 deletions
|
|
@ -13,11 +13,13 @@ import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import net.frankheijden.serverutils.bukkit.entities.BukkitPluginDescription;
|
import net.frankheijden.serverutils.bukkit.entities.BukkitPluginDescription;
|
||||||
import net.frankheijden.serverutils.bukkit.events.BukkitPluginDisableEvent;
|
import net.frankheijden.serverutils.bukkit.events.BukkitPluginDisableEvent;
|
||||||
import net.frankheijden.serverutils.bukkit.events.BukkitPluginEnableEvent;
|
import net.frankheijden.serverutils.bukkit.events.BukkitPluginEnableEvent;
|
||||||
import net.frankheijden.serverutils.bukkit.events.BukkitPluginLoadEvent;
|
import net.frankheijden.serverutils.bukkit.events.BukkitPluginLoadEvent;
|
||||||
import net.frankheijden.serverutils.bukkit.events.BukkitPluginUnloadEvent;
|
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.RCommandMap;
|
||||||
import net.frankheijden.serverutils.bukkit.reflection.RCraftServer;
|
import net.frankheijden.serverutils.bukkit.reflection.RCraftServer;
|
||||||
import net.frankheijden.serverutils.bukkit.reflection.RCraftingManager;
|
import net.frankheijden.serverutils.bukkit.reflection.RCraftingManager;
|
||||||
|
|
@ -220,11 +222,14 @@ public class BukkitPluginManager extends AbstractPluginManager<Plugin, BukkitPlu
|
||||||
Map<String, Command> knownCommands = getKnownCommands();
|
Map<String, Command> knownCommands = getKnownCommands();
|
||||||
if (knownCommands == null) return;
|
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) {
|
if (c instanceof PluginIdentifiableCommand) {
|
||||||
PluginIdentifiableCommand pc = (PluginIdentifiableCommand) c;
|
PluginIdentifiableCommand pc = (PluginIdentifiableCommand) c;
|
||||||
if (pc.getPlugin().getName().equals(plugin.getName())) {
|
if (pc.getPlugin().getName().equals(plugin.getName())) {
|
||||||
c.unregister(RCraftServer.getCommandMap());
|
c.unregister(RCraftServer.getCommandMap());
|
||||||
|
unregisteredCommands.add(e.getKey());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -232,7 +237,8 @@ public class BukkitPluginManager extends AbstractPluginManager<Plugin, BukkitPlu
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
RCraftServer.syncCommands();
|
RCommandDispatcher.removeCommands(unregisteredCommands);
|
||||||
|
RCraftServer.updateCommands();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -263,7 +269,8 @@ public class BukkitPluginManager extends AbstractPluginManager<Plugin, BukkitPlu
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
RCraftServer.syncCommands();
|
RCommandDispatcher.removeCommands(commands);
|
||||||
|
RCraftServer.updateCommands();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -282,7 +289,8 @@ public class BukkitPluginManager extends AbstractPluginManager<Plugin, BukkitPlu
|
||||||
map.remove(command);
|
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;
|
if (knownCommands == null) return;
|
||||||
knownCommands.values().removeAll(commands);
|
knownCommands.values().removeAll(commands);
|
||||||
|
|
||||||
RCraftServer.syncCommands();
|
RCommandDispatcher.removeCommands(commands.stream().map(Command::getName).collect(Collectors.toList()));
|
||||||
|
RCraftServer.updateCommands();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,64 @@
|
||||||
|
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()))
|
||||||
|
.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.MinecraftReflection;
|
||||||
import dev.frankheijden.minecraftreflection.MinecraftReflectionVersion;
|
import dev.frankheijden.minecraftreflection.MinecraftReflectionVersion;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Warning;
|
import org.bukkit.Warning;
|
||||||
import org.bukkit.command.Command;
|
import org.bukkit.command.Command;
|
||||||
import org.bukkit.command.SimpleCommandMap;
|
import org.bukkit.command.SimpleCommandMap;
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
public class RCraftServer {
|
public class RCraftServer {
|
||||||
|
|
||||||
|
|
@ -41,8 +44,35 @@ public class RCraftServer {
|
||||||
return reflection.get(Bukkit.getServer(), "commandMap");
|
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() {
|
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() {
|
public static Object getConsole() {
|
||||||
|
|
@ -89,7 +119,9 @@ public class RCraftServer {
|
||||||
SimpleCommandMap commandMap = getCommandMap();
|
SimpleCommandMap commandMap = getCommandMap();
|
||||||
Map<String, Command> map = RCommandMap.getKnownCommands(commandMap);
|
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);
|
Command aliasCommand = map.remove(alias);
|
||||||
if (aliasCommand == null) continue;
|
if (aliasCommand == null) continue;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue