diff --git a/src/main/java/org/bukkit/command/CommandMap.java b/src/main/java/org/bukkit/command/CommandMap.java index a60ebd17..e40a0221 100644 --- a/src/main/java/org/bukkit/command/CommandMap.java +++ b/src/main/java/org/bukkit/command/CommandMap.java @@ -26,4 +26,8 @@ public interface CommandMap { */ public boolean dispatch(Player sender, String cmdLine); + /** + * Clears all registered commands. + */ + public void clearCommands(); } diff --git a/src/main/java/org/bukkit/command/SimpleCommandMap.java b/src/main/java/org/bukkit/command/SimpleCommandMap.java index 9415e7ff..79fe285b 100644 --- a/src/main/java/org/bukkit/command/SimpleCommandMap.java +++ b/src/main/java/org/bukkit/command/SimpleCommandMap.java @@ -86,6 +86,12 @@ public final class SimpleCommandMap implements CommandMap { return isRegisteredCommand; } + public void clearCommands() { + synchronized (this) { + knownCommands.clear(); + } + } + private static class VersionCommand extends Command { private final Server server; diff --git a/src/main/java/org/bukkit/plugin/PluginManager.java b/src/main/java/org/bukkit/plugin/PluginManager.java index 01656a45..99f0c2f3 100644 --- a/src/main/java/org/bukkit/plugin/PluginManager.java +++ b/src/main/java/org/bukkit/plugin/PluginManager.java @@ -80,6 +80,11 @@ public interface PluginManager { */ public void disablePlugins(); + /** + * Disables and removes all plugins + */ + public void clearPlugins(); + /** * Calls a player related event with the given details * diff --git a/src/main/java/org/bukkit/plugin/SimplePluginManager.java b/src/main/java/org/bukkit/plugin/SimplePluginManager.java index 91d2b3ba..0193a8d4 100644 --- a/src/main/java/org/bukkit/plugin/SimplePluginManager.java +++ b/src/main/java/org/bukkit/plugin/SimplePluginManager.java @@ -188,6 +188,15 @@ public final class SimplePluginManager implements PluginManager { } } + public void clearPlugins() { + synchronized (this) { + disablePlugins(); + plugins.clear(); + lookupNames.clear(); + listeners.clear(); + } + } + /** * Calls a player related event with the given details * diff --git a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java index 7f8594cd..9e638ff8 100644 --- a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java +++ b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java @@ -8,6 +8,7 @@ import java.lang.reflect.Constructor; import java.net.URL; import java.util.HashMap; import java.util.Map; +import java.util.Set; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.regex.Pattern; @@ -301,10 +302,20 @@ public final class JavaPluginLoader implements PluginLoader { if (plugin.isEnabled()) { JavaPlugin jPlugin = (JavaPlugin)plugin; + ClassLoader cloader = jPlugin.getClassLoader(); server.getPluginManager().callEvent(new PluginEvent(Event.Type.PLUGIN_DISABLE, plugin)); jPlugin.setEnabled(false); + + if (cloader instanceof PluginClassLoader) { + PluginClassLoader loader = (PluginClassLoader)cloader; + Set names = loader.getClasses(); + + for (String name : names) { + classes.remove(name); + } + } } } } diff --git a/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java b/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java index 0dbaf4eb..d17e0f4f 100644 --- a/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java +++ b/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java @@ -4,6 +4,7 @@ import java.net.URL; import java.net.URLClassLoader; import java.util.HashMap; import java.util.Map; +import java.util.Set; /** * A ClassLoader for plugins, to allow shared classes across multiple plugins @@ -38,4 +39,8 @@ public class PluginClassLoader extends URLClassLoader { return result; } + + public Set getClasses() { + return classes.keySet(); + } }