Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GameWorlds and GameModes #415

Merged
merged 6 commits into from
Dec 27, 2018
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 0 additions & 11 deletions src/main/java/world/bentobox/bentobox/BentoBox.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@
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;
Expand Down Expand Up @@ -312,15 +310,6 @@ public void logWarning(String warning) {
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
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
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 has schems in a jar folder.
* @author tastybento, Postlovitch
*
*/
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 and assigned,
* {@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);
}

/**
* @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;
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
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;
Expand Down Expand Up @@ -84,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
Expand All @@ -100,7 +101,7 @@ public abstract class CompositeCommand extends Command implements PluginIdentifi
/**
* The top level label
*/
private String topLabel = "";
private String topLabel;

/**
* Cool down tracker
Expand Down Expand Up @@ -132,6 +133,11 @@ public CompositeCommand(Addon addon, String label, String... aliases) {
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")) {
new DefaultHelpCommand(this);
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/world/bentobox/bentobox/managers/AddonsManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
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;

Expand Down Expand Up @@ -147,6 +148,15 @@ private void loadAddon(File f) {
loaders.put(addon, addonClassLoader);
// Run the onLoad.
addon.onLoad();
// 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().addWorld(gameMode.getOverWorld(), gameMode.getWorldSettings());
// Register the schems
plugin.getSchemsManager().loadIslands(gameMode);
}
} catch (Exception e) {
plugin.logError(e.getMessage());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ private void copyLocalesFromJar(String folderName) {
// 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) {
Expand Down
55 changes: 25 additions & 30 deletions src/main/java/world/bentobox/bentobox/managers/SchemsManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

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;

Expand All @@ -40,11 +41,9 @@ private void copySchems(Addon addon, File schems) {
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 -> {
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());
}
Expand All @@ -61,33 +60,29 @@ public Map<String, Clipboard> get(World world) {

/**
* 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());
}
});
}

Expand Down
123 changes: 123 additions & 0 deletions src/main/puml/GameWorld.puml
Original file line number Diff line number Diff line change
@@ -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<GameWorld>
}
}

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<GameMode, List<GameWorld>>
__ Methods __
+ registerGameWorld(gameMode:GameMode, gameWorld:GameWorld) : boolean
.. Getters ..
+ getGameWorldsMap() : Map<GameMode, List<GameWorld>>
+ getGameWorldsList() : List<GameWorld>
+ getGameWorlds(gameMode:GameMode) : List<GameWorld>
+ getGameWorld(name:String) : Optional<GameWorld>
+ getGameWorld(world:World) : Optional<GameWorld>
.. Multiverse ..
+ registerWorldsToMultiverse() : void
+ registerWorldToMultiverse(gameWorld:GameWorld) : void
}

BentoBox *-- "1" WorldsManager
WorldsManager *-- "*" GameWorld

class SchemsManager {
- schems : List<Clipboard>

- copySchems(schems:File, name:String) : void
- loadSchem(name:String) : boolean
+ getSchems() : List<Clipboard>
+ paste(island:Island, task:Runnable) : void
+ paste(island:Island) : void
}

GameWorld *-- "1" SchemsManager
}
}

@enduml