Fix CraftServer#syncCommands with commands unloaded by plugins
This commit is contained in:
parent
4054a3eca9
commit
f9e2379e88
2 changed files with 44 additions and 25 deletions
|
|
@ -6,6 +6,7 @@ import java.util.ArrayList;
|
|||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
|
@ -109,11 +110,14 @@ public class BukkitPluginManager extends AbstractPluginManager<Plugin, BukkitPlu
|
|||
public PluginResults<Plugin> disableOrderedPlugins(List<Plugin> plugins) {
|
||||
PluginResults<Plugin> disableResults = new PluginResults<>();
|
||||
|
||||
Set<String> removedCommands = new HashSet<>();
|
||||
for (Plugin plugin : plugins) {
|
||||
String pluginId = getPluginId(plugin);
|
||||
if (!isPluginEnabled(pluginId)) return disableResults.addResult(pluginId, Result.ALREADY_DISABLED);
|
||||
|
||||
Bukkit.getPluginManager().callEvent(new BukkitPluginDisableEvent(plugin, PluginEvent.Stage.PRE));
|
||||
Map<String, ? extends Command> pluginCommands = getPluginCommands(plugin);
|
||||
|
||||
try {
|
||||
Bukkit.getPluginManager().disablePlugin(plugin);
|
||||
RCraftingManager.removeRecipesFor(plugin);
|
||||
|
|
@ -122,12 +126,14 @@ public class BukkitPluginManager extends AbstractPluginManager<Plugin, BukkitPlu
|
|||
return disableResults.addResult(pluginId, Result.ERROR);
|
||||
}
|
||||
|
||||
unregisterCommands(plugin);
|
||||
unregisterCommands(pluginCommands);
|
||||
removedCommands.addAll(pluginCommands.keySet());
|
||||
Bukkit.getPluginManager().callEvent(new BukkitPluginDisableEvent(plugin, PluginEvent.Stage.POST));
|
||||
|
||||
disableResults.addResult(pluginId, plugin);
|
||||
}
|
||||
|
||||
RCraftServer.syncCommands(removedCommands);
|
||||
return disableResults;
|
||||
}
|
||||
|
||||
|
|
@ -192,7 +198,7 @@ public class BukkitPluginManager extends AbstractPluginManager<Plugin, BukkitPlu
|
|||
enableResults.addResult(pluginId, plugin);
|
||||
}
|
||||
|
||||
RCraftServer.syncCommands();
|
||||
RCraftServer.syncCommands(Collections.emptySet());
|
||||
return enableResults;
|
||||
}
|
||||
|
||||
|
|
@ -214,31 +220,40 @@ public class BukkitPluginManager extends AbstractPluginManager<Plugin, BukkitPlu
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the commands associated to a plugin.
|
||||
*/
|
||||
public static <C extends Command & PluginIdentifiableCommand> Map<String, C> getPluginCommands(Plugin plugin) {
|
||||
Map<String, C> commands = new HashMap<>();
|
||||
|
||||
Map<String, Command> knownCommands = getKnownCommands();
|
||||
if (knownCommands == null) return commands;
|
||||
|
||||
for (Map.Entry<String, Command> entry : knownCommands.entrySet()) {
|
||||
Command c = entry.getValue();
|
||||
if (c instanceof PluginIdentifiableCommand) {
|
||||
@SuppressWarnings("unchecked")
|
||||
C pc = (C) c;
|
||||
if (pc.getPlugin().getName().equals(plugin.getName())) {
|
||||
commands.put(entry.getKey(), pc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return commands;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters all commands from the specified plugin.
|
||||
* @param plugin The plugin.
|
||||
*/
|
||||
public static void unregisterCommands(Plugin plugin) {
|
||||
Map<String, Command> knownCommands = getKnownCommands();
|
||||
if (knownCommands == null) return;
|
||||
unregisterCommands(getPluginCommands(plugin));
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
RCommandDispatcher.removeCommands(unregisteredCommands);
|
||||
RCraftServer.updateCommands();
|
||||
private static void unregisterCommands(Map<String, ? extends Command> pluginCommands) {
|
||||
pluginCommands.values().forEach(c -> c.unregister(RCraftServer.getCommandMap()));
|
||||
RCommandDispatcher.removeCommands(pluginCommands.keySet());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ public class RCraftServer {
|
|||
* 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(Set<String> removedCommands) {
|
||||
if (MinecraftReflectionVersion.MINOR < 13) return;
|
||||
|
||||
Collection children = RCommandDispatcher.getDispatcher().getRoot().getChildren();
|
||||
|
|
@ -56,8 +56,12 @@ public class RCraftServer {
|
|||
Object root = RCommandDispatcher.getDispatcher().getRoot();
|
||||
|
||||
for (Object child : children) {
|
||||
RCommandNode.removeCommand(root, RCommandNode.getName(child));
|
||||
RCommandNode.addChild(root, child);
|
||||
String name = RCommandNode.getName(child);
|
||||
RCommandNode.removeCommand(root, name);
|
||||
|
||||
if (!removedCommands.contains(name)) {
|
||||
RCommandNode.addChild(root, child);
|
||||
}
|
||||
}
|
||||
updateCommands();
|
||||
}
|
||||
|
|
@ -144,7 +148,7 @@ public class RCraftServer {
|
|||
);
|
||||
|
||||
commandMap.registerServerAliases();
|
||||
RCraftServer.syncCommands();
|
||||
RCraftServer.syncCommands(commandNames);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue