From 2d94e4447a74bb4082408c150efcadd1e2cfc4d0 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sat, 4 May 2019 13:56:55 -0700 Subject: [PATCH] Enables game mode addons to run as the only world (#661) * Enables game mode addons to run as the only world. Requires game mode addons to do the following in their onLoad: 1. Register commands 2. Be able to provide the chunk generator object because it will be used to generate the worlds 3. Be able to provide the WorldSettings because the world name (string) is required * Sets world in CompositeCommand after onEnable * Added Javadoc to Addon#onEnable and Addon#onLoad to better explain where to do what. --- .../world/bentobox/bentobox/BentoBox.java | 11 +++-- .../bentobox/bentobox/api/addons/Addon.java | 26 ++++++------ .../api/commands/CompositeCommand.java | 11 ++--- .../bentobox/managers/AddonsManager.java | 40 ++++++++++++++----- src/main/resources/plugin.yml | 2 + 5 files changed, 56 insertions(+), 34 deletions(-) diff --git a/src/main/java/world/bentobox/bentobox/BentoBox.java b/src/main/java/world/bentobox/bentobox/BentoBox.java index 8855dfdc4..522668025 100644 --- a/src/main/java/world/bentobox/bentobox/BentoBox.java +++ b/src/main/java/world/bentobox/bentobox/BentoBox.java @@ -152,13 +152,16 @@ public class BentoBox extends JavaPlugin { // Load addons. Addons may load worlds, so they must go before islands are loaded. addonsManager = new AddonsManager(this); addonsManager.loadAddons(); - // Enable addons - addonsManager.enableAddons(); - // Register default gamemode placeholders - addonsManager.getGameModeAddons().forEach(placeholdersManager::registerDefaultPlaceholders); getServer().getScheduler().runTask(instance, () -> { + + // Enable addons + addonsManager.enableAddons(); + + // Register default gamemode placeholders + addonsManager.getGameModeAddons().forEach(placeholdersManager::registerDefaultPlaceholders); + // Register Listeners registerListeners(); diff --git a/src/main/java/world/bentobox/bentobox/api/addons/Addon.java b/src/main/java/world/bentobox/bentobox/api/addons/Addon.java index 64ba4440f..ea3fb1ab7 100644 --- a/src/main/java/world/bentobox/bentobox/api/addons/Addon.java +++ b/src/main/java/world/bentobox/bentobox/api/addons/Addon.java @@ -1,5 +1,15 @@ package world.bentobox.bentobox.api.addons; +import org.bukkit.Bukkit; +import org.bukkit.Server; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.event.Listener; +import world.bentobox.bentobox.BentoBox; +import world.bentobox.bentobox.api.addons.request.AddonRequestHandler; +import world.bentobox.bentobox.managers.IslandsManager; +import world.bentobox.bentobox.managers.PlayersManager; + import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -10,17 +20,6 @@ import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.logging.Logger; -import org.bukkit.Bukkit; -import org.bukkit.Server; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.event.Listener; - -import world.bentobox.bentobox.BentoBox; -import world.bentobox.bentobox.api.addons.request.AddonRequestHandler; -import world.bentobox.bentobox.managers.IslandsManager; -import world.bentobox.bentobox.managers.PlayersManager; - /** * Add-on class for BentoBox. Extend this to create an add-on. The operation * and methods are very similar to Bukkit's JavaPlugin. @@ -44,6 +43,9 @@ public abstract class Addon { /** * Executes code when enabling the addon. * This is called after {@link #onLoad()}. + *
+ * Note that commands and worlds registration must be done in {@link #onLoad()}, if need be. + * Failure to do so will result in issues such as tab-completion not working for commands. */ public abstract void onEnable(); @@ -55,7 +57,7 @@ public abstract class Addon { /** * Executes code when loading the addon. * This is called before {@link #onEnable()}. - * This should preferably be used to setup configuration and worlds. + * This must be used to setup configuration, worlds and commands. */ public void onLoad() {} diff --git a/src/main/java/world/bentobox/bentobox/api/commands/CompositeCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/CompositeCommand.java index 8c42065aa..da3c36a79 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/CompositeCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/CompositeCommand.java @@ -24,7 +24,6 @@ import org.eclipse.jdt.annotation.Nullable; import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.Settings; import world.bentobox.bentobox.api.addons.Addon; -import world.bentobox.bentobox.api.addons.GameModeAddon; import world.bentobox.bentobox.api.events.command.CommandEvent; import world.bentobox.bentobox.api.localization.TextVariables; import world.bentobox.bentobox.api.user.User; @@ -135,10 +134,7 @@ public abstract class CompositeCommand extends Command implements PluginIdentifi setDescription(COMMANDS + label + ".description"); setParametersHelp(COMMANDS + label + ".parameters"); permissionPrefix = (addon != null) ? addon.getPermissionPrefix() : ""; - // Set up world if this is an AddonGameMode - if (addon instanceof GameModeAddon) { - setWorld(((GameModeAddon)addon).getOverWorld()); - } + // Run setup setup(); if (!getSubCommand("help").isPresent() && !label.equals("help")) { @@ -190,8 +186,6 @@ public abstract class CompositeCommand extends Command implements PluginIdentifi setUsage(""); // Inherit permission prefix this.permissionPrefix = parent.getPermissionPrefix(); - // Inherit world - this.world = parent.getWorld(); // Default references to description and parameters StringBuilder reference = new StringBuilder(); @@ -649,7 +643,8 @@ public abstract class CompositeCommand extends Command implements PluginIdentifi * @return the world */ public World getWorld() { - return world; + // Search up the tree until the world at the top is found + return parent != null ? parent.getWorld() : world; } /** diff --git a/src/main/java/world/bentobox/bentobox/managers/AddonsManager.java b/src/main/java/world/bentobox/bentobox/managers/AddonsManager.java index bf0ab0dd1..6413b0c97 100644 --- a/src/main/java/world/bentobox/bentobox/managers/AddonsManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/AddonsManager.java @@ -42,12 +42,14 @@ public class AddonsManager { @NonNull private final Map> classes; private BentoBox plugin; + private @NonNull Map<@NonNull String, @Nullable GameModeAddon> worldNames; public AddonsManager(@NonNull BentoBox plugin) { this.plugin = plugin; addons = new ArrayList<>(); loaders = new HashMap<>(); classes = new HashMap<>(); + worldNames = new HashMap<>(); } /** @@ -107,17 +109,12 @@ public class AddonsManager { try { // Run the onLoad. addon.onLoad(); - // If this is a GameModeAddon create the worlds, register it and load the schems + // if game mode, get the world name and generate 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); + if (!gameMode.getWorldSettings().getWorldName().isEmpty()) { + worldNames.put(gameMode.getWorldSettings().getWorldName(), gameMode); + } } // Addon successfully loaded addon.setState(Addon.State.LOADED); @@ -139,7 +136,25 @@ public class AddonsManager { 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() + "..."); @@ -361,6 +376,11 @@ public class AddonsManager { */ @Nullable public ChunkGenerator getDefaultWorldGenerator(String worldName, String id) { - return getGameModeAddons().stream().filter(gm -> gm.inWorld(Bukkit.getWorld(worldName))).findFirst().map(gm -> gm.getDefaultWorldGenerator(worldName, id)).orElse(null); + // Clean up world name + String w = worldName.replace("_nether", "").replace("_the_end", ""); + if (worldNames.containsKey(w)) { + return worldNames.get(w).getDefaultWorldGenerator(worldName, id); + } + return null; } } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index e08fc4497..9fd1b8c0d 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -6,6 +6,8 @@ api-version: 1.13 authors: [tastybento, Poslovitch] website: https://bentobox.world +load: STARTUP + loadbefore: [Multiverse-Core, Residence] softdepend: [Vault, PlaceholderAPI, MVdWPlaceholderAPI]