WIP - reloads addons

This commit is contained in:
tastybento 2019-05-07 07:47:38 -07:00
parent 91034f956e
commit 9ba62e1711
3 changed files with 126 additions and 70 deletions

View File

@ -189,12 +189,12 @@ public abstract class Addon {
}
/**
* Register a listener for this addon
* Register a listener for this addon. This MUST be used in order for the addon to be reloadable
*
* @param listener - listener
*/
public void registerListener(Listener listener) {
Bukkit.getPluginManager().registerEvents(listener, BentoBox.getInstance());
BentoBox.getInstance().getAddonsManager().registerListener(this, listener);
}
/**

View File

@ -29,19 +29,29 @@ public class BentoBoxReloadCommand extends ConfirmableCommand {
@Override
public boolean execute(User user, String label, List<String> args) {
this.askConfirmation(user, () -> {
// Reload settings
getPlugin().loadSettings();
user.sendMessage("commands.bentobox.reload.settings-reloaded");
if (args.isEmpty()) {
this.askConfirmation(user, () -> {
// Reload settings
getPlugin().loadSettings();
user.sendMessage("commands.bentobox.reload.settings-reloaded");
// Reload addons
getPlugin().getAddonsManager().reloadAddons();
user.sendMessage("commands.bentobox.reload.addons-reloaded");
// Reload addons
getPlugin().getAddonsManager().reloadAddons();
user.sendMessage("commands.bentobox.reload.addons-reloaded");
// Reload locales
getPlugin().getLocalesManager().reloadLanguages();
user.sendMessage("commands.bentobox.reload.locales-reloaded");
});
// Reload locales
getPlugin().getLocalesManager().reloadLanguages();
user.sendMessage("commands.bentobox.reload.locales-reloaded");
});
} else if (args.size() == 1) {
if (!getPlugin().getAddonsManager().getAddonByName(args.get(0)).isPresent()) {
user.sendRawMessage("Unknown addon");
return false;
}
this.askConfirmation(user, () -> getPlugin().getAddonsManager().getAddonByName(args.get(0)).ifPresent(getPlugin().getAddonsManager()::reloadAddon));
} else {
showHelp(this, user);
}
return true;
}
}

View File

@ -3,6 +3,8 @@ package world.bentobox.bentobox.managers;
import org.bukkit.Bukkit;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.generator.ChunkGenerator;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
@ -17,6 +19,7 @@ import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@ -43,12 +46,14 @@ public class AddonsManager {
private final Map<String, Class<?>> classes;
private BentoBox plugin;
private @NonNull Map<@NonNull String, @Nullable GameModeAddon> worldNames;
private @NonNull Map<Addon, List<Listener>> listeners;
public AddonsManager(@NonNull BentoBox plugin) {
this.plugin = plugin;
addons = new ArrayList<>();
loaders = new HashMap<>();
classes = new HashMap<>();
listeners = new HashMap<>();
worldNames = new HashMap<>();
}
@ -101,6 +106,9 @@ public class AddonsManager {
Bukkit.getPluginManager().callEvent(new AddonEvent().builder().addon(addon).reason(AddonEvent.Reason.LOAD).build());
// Add it to the list of addons
if (addons.contains(addon)) {
addons.remove(addon);
}
addons.add(addon);
// Add to the list of loaders
@ -133,43 +141,48 @@ public class AddonsManager {
public void enableAddons() {
if (!getLoadedAddons().isEmpty()) {
plugin.log("Enabling addons...");
getLoadedAddons().forEach(addon -> {
try {
// If this is a GameModeAddon create the worlds, register it and load the schems
if (addon instanceof GameModeAddon) {
GameModeAddon gameMode = (GameModeAddon) addon;
// Create the gameWorlds
gameMode.createWorlds();
plugin.getIWM().addGameMode(gameMode);
// Register the schems
plugin.getSchemsManager().loadIslands(gameMode);
plugin.getBlueprintsManager().extractDefaultBlueprints(gameMode);
plugin.getBlueprintsManager().loadBlueprints(gameMode);
}
addon.onEnable();
if (addon instanceof GameModeAddon) {
GameModeAddon gameMode = (GameModeAddon) addon;
// Set the worlds for the commands
gameMode.getPlayerCommand().ifPresent(c -> c.setWorld(gameMode.getOverWorld()));
gameMode.getAdminCommand().ifPresent(c -> c.setWorld(gameMode.getOverWorld()));
}
Bukkit.getPluginManager().callEvent(new AddonEvent().builder().addon(addon).reason(AddonEvent.Reason.ENABLE).build());
addon.setState(Addon.State.ENABLED);
plugin.log("Enabling " + addon.getDescription().getName() + "...");
} catch (NoClassDefFoundError | NoSuchMethodError | NoSuchFieldError e) {
// Looks like the addon is incompatible, because it tries to refer to missing classes...
handleAddonIncompatibility(addon);
} catch (Exception e) {
// Unhandled exception. We'll give a bit of debug here.
handleAddonError(addon, e);
}
});
getLoadedAddons().forEach(this::enableAddon);
plugin.log("Addons successfully enabled.");
}
}
/**
* Enables an addon
* @param addon addon
*/
private void enableAddon(Addon addon) {
try {
// If this is a GameModeAddon create the worlds, register it and load the schems
if (addon instanceof GameModeAddon) {
GameModeAddon gameMode = (GameModeAddon) addon;
// Create the gameWorlds
gameMode.createWorlds();
plugin.getIWM().addGameMode(gameMode);
// Register the schems
plugin.getSchemsManager().loadIslands(gameMode);
plugin.getBlueprintsManager().extractDefaultBlueprints(gameMode);
plugin.getBlueprintsManager().loadBlueprints(gameMode);
}
addon.onEnable();
if (addon instanceof GameModeAddon) {
GameModeAddon gameMode = (GameModeAddon) addon;
// Set the worlds for the commands
gameMode.getPlayerCommand().ifPresent(c -> c.setWorld(gameMode.getOverWorld()));
gameMode.getAdminCommand().ifPresent(c -> c.setWorld(gameMode.getOverWorld()));
}
Bukkit.getPluginManager().callEvent(new AddonEvent().builder().addon(addon).reason(AddonEvent.Reason.ENABLE).build());
addon.setState(Addon.State.ENABLED);
plugin.log("Enabling " + addon.getDescription().getName() + "...");
} catch (NoClassDefFoundError | NoSuchMethodError | NoSuchFieldError e) {
// Looks like the addon is incompatible, because it tries to refer to missing classes...
handleAddonIncompatibility(addon);
} catch (Exception e) {
// Unhandled exception. We'll give a bit of debug here.
handleAddonError(addon, e);
}
}
/**
* Handles an addon which failed to load due to an incompatibility (missing class, missing method).
* @param addon instance of the Addon.
@ -201,14 +214,19 @@ public class AddonsManager {
* Reloads all the enabled addons
*/
public void reloadAddons() {
if (!getEnabledAddons().isEmpty()) {
plugin.log("Reloading addons...");
getEnabledAddons().stream().filter(Addon::isEnabled).forEach(addon -> {
plugin.log("Reloading " + addon.getDescription().getName() + "...");
addon.onReload();
});
plugin.log("Addons successfully reloaded.");
}
disableAddons();
loadAddons();
enableAddons();
}
/**
* Reloads one addon
* @param addon - addon
*/
public void reloadAddon(Addon addon) {
Path p = addon.getFile().toPath();
disable(addon);
loadAddon(p.toFile());
}
/**
@ -218,7 +236,7 @@ public class AddonsManager {
*/
@NonNull
public Optional<Addon> getAddonByName(@NonNull String name){
return addons.stream().filter(a -> a.getDescription().getName().contains(name)).findFirst();
return addons.stream().filter(a -> a.getDescription().getName().equalsIgnoreCase(name)).findFirst();
}
@NonNull
@ -243,23 +261,14 @@ public class AddonsManager {
if (!getEnabledAddons().isEmpty()) {
plugin.log("Disabling addons...");
// Disable addons
getEnabledAddons().forEach(addon -> {
if (addon.isEnabled()) {
addon.onDisable();
Bukkit.getPluginManager().callEvent(new AddonEvent().builder().addon(addon).reason(AddonEvent.Reason.DISABLE).build());
plugin.log("Disabling " + addon.getDescription().getName() + "...");
}
});
loaders.values().forEach(l -> {
try {
l.close();
} catch (IOException ignore) {
// Ignore
}
});
getEnabledAddons().forEach(this::disable);
plugin.log("Addons successfully disabled.");
}
// Clear all maps
listeners.clear();
addons.clear();
loaders.clear();
classes.clear();
}
@NonNull
@ -383,4 +392,41 @@ public class AddonsManager {
}
return null;
}
/**
* Register a listener
* @param addon - the addon registering
* @param listener - listener
*/
public void registerListener(Addon addon, Listener listener) {
Bukkit.getPluginManager().registerEvents(listener, BentoBox.getInstance());
listeners.computeIfAbsent(addon, k -> new ArrayList<>()).add(listener);
}
/**
* Disables an addon
* @param addon - addon
*/
private void disable(Addon addon) {
// Clear listeners
if (listeners.containsKey(addon)) {
listeners.get(addon).forEach(HandlerList::unregisterAll);
listeners.remove(addon);
}
// Disable
if (addon.isEnabled()) {
addon.onDisable();
Bukkit.getPluginManager().callEvent(new AddonEvent().builder().addon(addon).reason(AddonEvent.Reason.DISABLE).build());
plugin.log("Disabling " + addon.getDescription().getName() + "...");
}
// Clear loaders
if (loaders.containsKey(addon)) {
try {
loaders.get(addon).close();
} catch (IOException ignore) {
// Nothing
}
}
}
}