From e6293cb480e90d5d3797b44428f47c2276121101 Mon Sep 17 00:00:00 2001 From: Florian CUNY Date: Mon, 24 Dec 2018 10:11:19 +0100 Subject: [PATCH 1/4] Created an UML Class Diagram as a template --- src/main/puml/GameWorld.puml | 123 +++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 src/main/puml/GameWorld.puml diff --git a/src/main/puml/GameWorld.puml b/src/main/puml/GameWorld.puml new file mode 100644 index 000000000..d94cd25bd --- /dev/null +++ b/src/main/puml/GameWorld.puml @@ -0,0 +1,123 @@ +@startuml + +note as N1 + This UML Class Diagram introduces the + GameWorlds and GameModes concepts that + are introduced in 1.0. + + This diagram is not meant to be updated + alongside modifications that could be done + to GameWorlds and GameModes: it is meant + to serve as a template, and hopefully to keep + track of what we had in mind when we started + to work on this API. + + - Poslovitch, @BentoBoxWorld + December 24th, 2018. +end note + +package world.bentobox.bentobox { + + class BentoBox << (M,orchid) Main >> { + - addonsManager : AddonsManager + - worldsManager : WorldsManager + + getAddons() : AddonsManager + + getWorlds() : WorldsManager + } + + package api { + package addons { + abstract class Addon + + abstract class GameMode extends Addon { + Specific Addon implementation allowing to register GameWorlds. + + + registerGameWorld(gameWorld:GameWorld) : void + + getGameWorlds() : List + } + } + + package worlds { + interface WorldSettings + + class GameWorld { + Represents a set of three Worlds + (Overworld, Nether, End) which is + registered by a GameMode addon and + managed by BentoBox. + It features its own implementation + of WorldSettings and provides + Islands and Schems managers. + __ Fields __ + - name : String + - friendlyName : String + - overWorld : World + - netherWorld : World + - endWorld : World + - worldSettings : WorldSettings + .. Managers .. + - islandsManager : IslandsManager + - schemsManager : SchemsManager + __ Methods __ + + createWorlds() : boolean + + inWorld(location:Location) : boolean + .. Getters .. + + getName() : String + + getFriendlyName() : String + + getOverWorld() : World + + getNetherWorld() : World + + getEndWorld() : World + + getSettings() : WorldSettings + + getIslands() : IslandsManager + + getSchems() : SchemsManager + } + + GameWorld *-- "1" WorldSettings + + GameMode *-- "*" GameWorld + } + } + + + package managers { + class AddonsManager + + BentoBox *-- "1" AddonsManager + AddonsManager *-- "*" Addon + + class WorldsManager { + Manages GameWorlds that are registered by GameMode addons. + It basically replaces IslandWorldManager. + __ Fields __ + - gameWorlds : Map> + __ Methods __ + + registerGameWorld(gameMode:GameMode, gameWorld:GameWorld) : boolean + .. Getters .. + + getGameWorldsMap() : Map> + + getGameWorldsList() : List + + getGameWorlds(gameMode:GameMode) : List + + getGameWorld(name:String) : Optional + + getGameWorld(world:World) : Optional + .. Multiverse .. + + registerWorldsToMultiverse() : void + + registerWorldToMultiverse(gameWorld:GameWorld) : void + } + + BentoBox *-- "1" WorldsManager + WorldsManager *-- "*" GameWorld + + class SchemsManager { + - schems : List + + - copySchems(schems:File, name:String) : void + - loadSchem(name:String) : boolean + + getSchems() : List + + paste(island:Island, task:Runnable) : void + + paste(island:Island) : void + } + + GameWorld *-- "1" SchemsManager + } +} + +@enduml From 17c087469bd5729f260508a72aba8bcde9a1e093 Mon Sep 17 00:00:00 2001 From: tastybento Date: Mon, 24 Dec 2018 20:18:33 -0800 Subject: [PATCH 2/4] WIP - attempt at implementing GameModeAddon API https://github.com/BentoBoxWorld/BentoBox/pull/415 --- .../world/bentobox/bentobox/BentoBox.java | 11 ---- .../bentobox/api/addons/GameModeAddon.java | 58 +++++++++++++++++++ .../api/commands/CompositeCommand.java | 5 ++ .../bentobox/managers/AddonsManager.java | 12 ++++ .../bentobox/managers/SchemsManager.java | 52 ++++++++--------- 5 files changed, 100 insertions(+), 38 deletions(-) create mode 100644 src/main/java/world/bentobox/bentobox/api/addons/GameModeAddon.java diff --git a/src/main/java/world/bentobox/bentobox/BentoBox.java b/src/main/java/world/bentobox/bentobox/BentoBox.java index 10f3098fd..ec242204b 100644 --- a/src/main/java/world/bentobox/bentobox/BentoBox.java +++ b/src/main/java/world/bentobox/bentobox/BentoBox.java @@ -3,12 +3,10 @@ package world.bentobox.bentobox; import java.util.Optional; import org.bukkit.Bukkit; -import org.bukkit.World; import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.java.JavaPlugin; import world.bentobox.bentobox.api.configuration.Config; -import world.bentobox.bentobox.api.configuration.WorldSettings; import world.bentobox.bentobox.api.events.BentoBoxReadyEvent; import world.bentobox.bentobox.api.user.Notifier; import world.bentobox.bentobox.commands.BentoBoxCommand; @@ -312,15 +310,6 @@ public class BentoBox extends JavaPlugin { getLogger().warning(warning); } - /** - * Registers a world as a world to be covered by this plugin - * @param world - Bukkit overworld - * @param worldSettings - settings for this world - */ - public void registerWorld(World world, WorldSettings worldSettings) { - islandWorldManager.addWorld(world, worldSettings); - } - /** * @return the schemsManager */ diff --git a/src/main/java/world/bentobox/bentobox/api/addons/GameModeAddon.java b/src/main/java/world/bentobox/bentobox/api/addons/GameModeAddon.java new file mode 100644 index 000000000..5572a7a88 --- /dev/null +++ b/src/main/java/world/bentobox/bentobox/api/addons/GameModeAddon.java @@ -0,0 +1,58 @@ +/** + * + */ +package world.bentobox.bentobox.api.addons; + +import org.bukkit.Location; +import org.bukkit.World; + +import world.bentobox.bentobox.api.configuration.WorldSettings; +import world.bentobox.bentobox.util.Util; + +/** + * Defines the addon as a game mode. A game mode creates worlds, registers world settings and schems. + * @author tastybento + * + */ +public abstract class GameModeAddon extends Addon { + + protected World islandWorld; + protected World netherWorld; + protected World endWorld; + + /** + * Make the worlds for this GameMode in this method. BentoBox will call it + * after onLoad() and before onEnable(). + * {@link #islandWorld} must be created, + * {@link #netherWorld} and {@link #endWorld} are optional and may be null. + */ + public abstract void createWorlds(); + + /** + * @return WorldSettings for this GameMode + */ + public abstract WorldSettings getWorldSettings(); + + /** + * Checks if a player is in any of the island worlds + * @param loc - player to check + * @return true if in a world or false if not + */ + public boolean inWorld(Location loc) { + return Util.sameWorld(loc.getWorld(), islandWorld); + } + + public World getOverWorld() { + return islandWorld; + } + + public World getNetherWorld() { + return netherWorld; + } + + public World getEndWorld() { + return endWorld; + } + + +} 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 00459c661..d0daf681f 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/CompositeCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/CompositeCommand.java @@ -22,6 +22,7 @@ import org.bukkit.entity.Player; 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; @@ -133,6 +134,10 @@ public abstract class CompositeCommand extends Command implements PluginIdentifi setParametersHelp(COMMANDS + label + ".parameters"); permissionPrefix = (addon != null) ? addon.getPermissionPrefix() : ""; setup(); + // Set up world if this is an AddonGameMode + if (addon instanceof GameModeAddon) { + this.world = ((GameModeAddon)addon).getOverWorld(); + } if (!getSubCommand("help").isPresent() && !label.equals("help")) { new DefaultHelpCommand(this); } diff --git a/src/main/java/world/bentobox/bentobox/managers/AddonsManager.java b/src/main/java/world/bentobox/bentobox/managers/AddonsManager.java index 2a3c24777..eee328675 100644 --- a/src/main/java/world/bentobox/bentobox/managers/AddonsManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/AddonsManager.java @@ -25,6 +25,7 @@ import org.bukkit.configuration.file.YamlConfiguration; import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.addons.Addon; import world.bentobox.bentobox.api.addons.AddonClassLoader; +import world.bentobox.bentobox.api.addons.GameModeAddon; import world.bentobox.bentobox.api.addons.exceptions.InvalidAddonFormatException; import world.bentobox.bentobox.api.events.addon.AddonEvent; @@ -147,6 +148,17 @@ public class AddonsManager { loaders.put(addon, addonClassLoader); // Run the onLoad. addon.onLoad(); + // If this is a GameMode, get the GameWorld + if (addon instanceof GameModeAddon) { + GameModeAddon gameMode = (GameModeAddon)addon; + // Create the gameWorlds + gameMode.createWorlds(); + plugin.logDebug("GameModeAddon found! overWorld = " + gameMode.getOverWorld()); + plugin.getIWM().addWorld(gameMode.getOverWorld(), gameMode.getWorldSettings()); + // Register the schems + plugin.logDebug("Trying to register schems"); + plugin.getSchemsManager().loadIslands(gameMode); + } } catch (Exception e) { plugin.logError(e.getMessage()); } diff --git a/src/main/java/world/bentobox/bentobox/managers/SchemsManager.java b/src/main/java/world/bentobox/bentobox/managers/SchemsManager.java index 2171a3b4e..960c8f004 100644 --- a/src/main/java/world/bentobox/bentobox/managers/SchemsManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/SchemsManager.java @@ -14,6 +14,7 @@ import org.bukkit.configuration.InvalidConfigurationException; import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.addons.Addon; +import world.bentobox.bentobox.api.addons.GameModeAddon; import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.schems.Clipboard; @@ -43,7 +44,8 @@ public class SchemsManager { // Save any schems that try (JarFile jar = new JarFile(addon.getFile())) { plugin.getAddonsManager().listJarFiles(jar, "schems", ".schem").forEach(name -> { - addon.saveResource("schems/" + name, false); + plugin.logDebug("Found " + name); + addon.saveResource(name, false); }); } catch (IOException e) { plugin.logError("Could not load schem files from addon jar " + e.getMessage()); @@ -61,33 +63,29 @@ public class SchemsManager { /** * Load schems for addon. Will try and load nether and end schems too if settings are set. - * @param world - world + * @param addon - GameModeAddon */ - public void loadIslands(World world) { - plugin.getIWM().getAddon(world).ifPresent(addon -> { - File schems = new File(addon.getDataFolder(), "schems"); - // Copy any schems fould in the jar - copySchems(addon, schems); - // Load all schems in folder - // Look through the folder - FilenameFilter schemFilter = (File dir, String name) -> name.toLowerCase(java.util.Locale.ENGLISH).endsWith(".schem") - && !name.toLowerCase(java.util.Locale.ENGLISH).startsWith("nether-") - && !name.toLowerCase(java.util.Locale.ENGLISH).startsWith("end-"); - Arrays.stream(Objects.requireNonNull(schems.list(schemFilter))).map(name -> name.substring(0, name.length() - 6)).forEach(name -> { - if (!plugin.getSchemsManager().loadSchem(world, schems, name)) { - plugin.logError("Could not load " + name + ".schem for " + plugin.getIWM().getFriendlyName(world)); - } - if (plugin.getIWM().isNetherGenerate(world) && plugin.getIWM().isNetherIslands(world) - && !plugin.getSchemsManager().loadSchem(plugin.getIWM().getNetherWorld(world), schems, "nether-" + name)) { - plugin.logError("Could not load nether-" + name + ".schem for " + plugin.getIWM().getFriendlyName(world)); - } - if (plugin.getIWM().isEndGenerate(world) && plugin.getIWM().isEndIslands(world) - && !plugin.getSchemsManager().loadSchem(plugin.getIWM().getEndWorld(world), schems, "end-" + name)) { - plugin.logError("Could not load end-" + name + ".schem for " + plugin.getIWM().getFriendlyName(world)); - } - }); - - + public void loadIslands(GameModeAddon addon) { + File schems = new File(addon.getDataFolder(), "schems"); + // Copy any schems fould in the jar + copySchems(addon, schems); + // Load all schems in folder + // Look through the folder + FilenameFilter schemFilter = (File dir, String name) -> name.toLowerCase(java.util.Locale.ENGLISH).endsWith(".schem") + && !name.toLowerCase(java.util.Locale.ENGLISH).startsWith("nether-") + && !name.toLowerCase(java.util.Locale.ENGLISH).startsWith("end-"); + Arrays.stream(Objects.requireNonNull(schems.list(schemFilter))).map(name -> name.substring(0, name.length() - 6)).forEach(name -> { + if (!plugin.getSchemsManager().loadSchem(addon.getOverWorld(), schems, name)) { + plugin.logError("Could not load " + name + ".schem for " + addon.getWorldSettings().getFriendlyName()); + } + if (addon.getWorldSettings().isNetherGenerate() && addon.getWorldSettings().isNetherIslands() + && !plugin.getSchemsManager().loadSchem(addon.getNetherWorld(), schems, "nether-" + name)) { + plugin.logError("Could not load nether-" + name + ".schem for " + addon.getWorldSettings().getFriendlyName()); + } + if (addon.getWorldSettings().isEndGenerate() && addon.getWorldSettings().isEndIslands() + && !plugin.getSchemsManager().loadSchem(addon.getEndWorld(), schems, "end-" + name)) { + plugin.logError("Could not load end-" + name + ".schem for " + addon.getWorldSettings().getFriendlyName()); + } }); } From e5c69e42a6f12726f632ecee792501d4e874aad8 Mon Sep 17 00:00:00 2001 From: tastybento Date: Mon, 24 Dec 2018 20:49:43 -0800 Subject: [PATCH 3/4] Fixes bugs with CompositeCommand world setting. Removes debug from previous commit. Relates to https://github.com/BentoBoxWorld/BentoBox/pull/415 --- .../bentobox/api/commands/CompositeCommand.java | 10 ++++++---- .../bentobox/bentobox/managers/AddonsManager.java | 2 -- .../bentobox/bentobox/managers/LocalesManager.java | 2 +- .../bentobox/bentobox/managers/SchemsManager.java | 7 ++----- 4 files changed, 9 insertions(+), 12 deletions(-) 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 d0daf681f..9cfcd28bb 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/CompositeCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/CompositeCommand.java @@ -85,7 +85,7 @@ public abstract class CompositeCommand extends Command implements PluginIdentifi /** * The prefix to be used in this command */ - private String permissionPrefix = ""; + private String permissionPrefix; /** * The world that this command operates in. This is an overworld and will cover any associated nether or end @@ -101,7 +101,7 @@ public abstract class CompositeCommand extends Command implements PluginIdentifi /** * The top level label */ - private String topLabel = ""; + private String topLabel; /** * Cool down tracker @@ -133,11 +133,13 @@ public abstract class CompositeCommand extends Command implements PluginIdentifi setDescription(COMMANDS + label + ".description"); setParametersHelp(COMMANDS + label + ".parameters"); permissionPrefix = (addon != null) ? addon.getPermissionPrefix() : ""; - setup(); // Set up world if this is an AddonGameMode if (addon instanceof GameModeAddon) { - this.world = ((GameModeAddon)addon).getOverWorld(); + addon.log("DEBUG: gamemode command - world = " +((GameModeAddon)addon).getOverWorld()); + setWorld(((GameModeAddon)addon).getOverWorld()); } + // Run setup + setup(); if (!getSubCommand("help").isPresent() && !label.equals("help")) { new DefaultHelpCommand(this); } diff --git a/src/main/java/world/bentobox/bentobox/managers/AddonsManager.java b/src/main/java/world/bentobox/bentobox/managers/AddonsManager.java index eee328675..3a8435eac 100644 --- a/src/main/java/world/bentobox/bentobox/managers/AddonsManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/AddonsManager.java @@ -153,10 +153,8 @@ public class AddonsManager { GameModeAddon gameMode = (GameModeAddon)addon; // Create the gameWorlds gameMode.createWorlds(); - plugin.logDebug("GameModeAddon found! overWorld = " + gameMode.getOverWorld()); plugin.getIWM().addWorld(gameMode.getOverWorld(), gameMode.getWorldSettings()); // Register the schems - plugin.logDebug("Trying to register schems"); plugin.getSchemsManager().loadIslands(gameMode); } } catch (Exception e) { diff --git a/src/main/java/world/bentobox/bentobox/managers/LocalesManager.java b/src/main/java/world/bentobox/bentobox/managers/LocalesManager.java index cedd58bdc..ffe8c18db 100644 --- a/src/main/java/world/bentobox/bentobox/managers/LocalesManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/LocalesManager.java @@ -119,7 +119,7 @@ public class LocalesManager { // We cannot use Bukkit's saveResource, because we want it to go into a specific folder, so... // Get the last part of the name int lastIndex = name.lastIndexOf('/'); - File targetFile = new File(localeDir, name.substring(lastIndex >= 0 ? lastIndex : 0, name.length())); + File targetFile = new File(localeDir, name.substring(lastIndex >= 0 ? lastIndex : 0)); copyFile(name, targetFile); } } catch (IOException e) { diff --git a/src/main/java/world/bentobox/bentobox/managers/SchemsManager.java b/src/main/java/world/bentobox/bentobox/managers/SchemsManager.java index 960c8f004..13d870a01 100644 --- a/src/main/java/world/bentobox/bentobox/managers/SchemsManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/SchemsManager.java @@ -41,12 +41,9 @@ public class SchemsManager { plugin.logError("Could not make schems folder!"); return; } - // Save any schems that + // Save any schems that are in the jar try (JarFile jar = new JarFile(addon.getFile())) { - plugin.getAddonsManager().listJarFiles(jar, "schems", ".schem").forEach(name -> { - plugin.logDebug("Found " + name); - addon.saveResource(name, false); - }); + plugin.getAddonsManager().listJarFiles(jar, "schems", ".schem").forEach(name -> addon.saveResource(name, false)); } catch (IOException e) { plugin.logError("Could not load schem files from addon jar " + e.getMessage()); } From 86c13fa60ebc52d02beb58dd9cd4092ca9543e97 Mon Sep 17 00:00:00 2001 From: tastybento Date: Mon, 24 Dec 2018 21:10:49 -0800 Subject: [PATCH 4/4] Remove console debug. Improved comments and JavaDoc. --- .../bentobox/api/addons/GameModeAddon.java | 19 +++++++++++++------ .../api/commands/CompositeCommand.java | 1 - .../bentobox/managers/AddonsManager.java | 2 +- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/main/java/world/bentobox/bentobox/api/addons/GameModeAddon.java b/src/main/java/world/bentobox/bentobox/api/addons/GameModeAddon.java index 5572a7a88..37940bfeb 100644 --- a/src/main/java/world/bentobox/bentobox/api/addons/GameModeAddon.java +++ b/src/main/java/world/bentobox/bentobox/api/addons/GameModeAddon.java @@ -1,6 +1,3 @@ -/** - * - */ package world.bentobox.bentobox.api.addons; import org.bukkit.Location; @@ -10,8 +7,9 @@ import world.bentobox.bentobox.api.configuration.WorldSettings; import world.bentobox.bentobox.util.Util; /** - * Defines the addon as a game mode. A game mode creates worlds, registers world settings and schems. - * @author tastybento + * Defines the addon as a game mode. + * A game mode creates worlds, registers world settings and has schems in a jar folder. + * @author tastybento, Postlovitch * */ public abstract class GameModeAddon extends Addon { @@ -23,7 +21,7 @@ public abstract class GameModeAddon extends Addon { /** * Make the worlds for this GameMode in this method. BentoBox will call it * after onLoad() and before onEnable(). - * {@link #islandWorld} must be created, + * {@link #islandWorld} must be created and assigned, * {@link #netherWorld} and {@link #endWorld} are optional and may be null. */ public abstract void createWorlds(); @@ -42,14 +40,23 @@ public abstract class GameModeAddon extends Addon { return Util.sameWorld(loc.getWorld(), islandWorld); } + /** + * @return over world + */ public World getOverWorld() { return islandWorld; } + /** + * @return nether world, or null if it does not exist + */ public World getNetherWorld() { return netherWorld; } + /** + * @return end world, or null if it does not exist + */ public World getEndWorld() { return endWorld; } 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 9cfcd28bb..8aed721d3 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/CompositeCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/CompositeCommand.java @@ -135,7 +135,6 @@ public abstract class CompositeCommand extends Command implements PluginIdentifi permissionPrefix = (addon != null) ? addon.getPermissionPrefix() : ""; // Set up world if this is an AddonGameMode if (addon instanceof GameModeAddon) { - addon.log("DEBUG: gamemode command - world = " +((GameModeAddon)addon).getOverWorld()); setWorld(((GameModeAddon)addon).getOverWorld()); } // Run setup diff --git a/src/main/java/world/bentobox/bentobox/managers/AddonsManager.java b/src/main/java/world/bentobox/bentobox/managers/AddonsManager.java index 3a8435eac..71cc709cc 100644 --- a/src/main/java/world/bentobox/bentobox/managers/AddonsManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/AddonsManager.java @@ -148,7 +148,7 @@ public class AddonsManager { loaders.put(addon, addonClassLoader); // Run the onLoad. addon.onLoad(); - // If this is a GameMode, get the GameWorld + // 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