mirror of
https://github.com/BentoBoxWorld/BentoBox.git
synced 2024-11-24 19:55:17 +01:00
Merge pull request #415 from BentoBoxWorld/gameworlds-and-gamemodes
GameWorlds and GameModes
This commit is contained in:
commit
bd3157366f
@ -3,12 +3,10 @@ package world.bentobox.bentobox;
|
|||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.plugin.PluginManager;
|
import org.bukkit.plugin.PluginManager;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
import world.bentobox.bentobox.api.configuration.Config;
|
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.events.BentoBoxReadyEvent;
|
||||||
import world.bentobox.bentobox.api.user.Notifier;
|
import world.bentobox.bentobox.api.user.Notifier;
|
||||||
import world.bentobox.bentobox.commands.BentoBoxCommand;
|
import world.bentobox.bentobox.commands.BentoBoxCommand;
|
||||||
@ -312,15 +310,6 @@ public class BentoBox extends JavaPlugin {
|
|||||||
getLogger().warning(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
|
* @return the schemsManager
|
||||||
*/
|
*/
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -22,6 +22,7 @@ import org.bukkit.entity.Player;
|
|||||||
import world.bentobox.bentobox.BentoBox;
|
import world.bentobox.bentobox.BentoBox;
|
||||||
import world.bentobox.bentobox.Settings;
|
import world.bentobox.bentobox.Settings;
|
||||||
import world.bentobox.bentobox.api.addons.Addon;
|
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.events.command.CommandEvent;
|
||||||
import world.bentobox.bentobox.api.localization.TextVariables;
|
import world.bentobox.bentobox.api.localization.TextVariables;
|
||||||
import world.bentobox.bentobox.api.user.User;
|
import world.bentobox.bentobox.api.user.User;
|
||||||
@ -84,7 +85,7 @@ public abstract class CompositeCommand extends Command implements PluginIdentifi
|
|||||||
/**
|
/**
|
||||||
* The prefix to be used in this command
|
* 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
|
* The world that this command operates in. This is an overworld and will cover any associated nether or end
|
||||||
@ -100,7 +101,7 @@ public abstract class CompositeCommand extends Command implements PluginIdentifi
|
|||||||
/**
|
/**
|
||||||
* The top level label
|
* The top level label
|
||||||
*/
|
*/
|
||||||
private String topLabel = "";
|
private String topLabel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cool down tracker
|
* Cool down tracker
|
||||||
@ -132,6 +133,11 @@ public abstract class CompositeCommand extends Command implements PluginIdentifi
|
|||||||
setDescription(COMMANDS + label + ".description");
|
setDescription(COMMANDS + label + ".description");
|
||||||
setParametersHelp(COMMANDS + label + ".parameters");
|
setParametersHelp(COMMANDS + label + ".parameters");
|
||||||
permissionPrefix = (addon != null) ? addon.getPermissionPrefix() : "";
|
permissionPrefix = (addon != null) ? addon.getPermissionPrefix() : "";
|
||||||
|
// Set up world if this is an AddonGameMode
|
||||||
|
if (addon instanceof GameModeAddon) {
|
||||||
|
setWorld(((GameModeAddon)addon).getOverWorld());
|
||||||
|
}
|
||||||
|
// Run setup
|
||||||
setup();
|
setup();
|
||||||
if (!getSubCommand("help").isPresent() && !label.equals("help")) {
|
if (!getSubCommand("help").isPresent() && !label.equals("help")) {
|
||||||
new DefaultHelpCommand(this);
|
new DefaultHelpCommand(this);
|
||||||
|
@ -24,6 +24,7 @@ import org.bukkit.configuration.file.YamlConfiguration;
|
|||||||
import world.bentobox.bentobox.BentoBox;
|
import world.bentobox.bentobox.BentoBox;
|
||||||
import world.bentobox.bentobox.api.addons.Addon;
|
import world.bentobox.bentobox.api.addons.Addon;
|
||||||
import world.bentobox.bentobox.api.addons.AddonClassLoader;
|
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.addons.exceptions.InvalidAddonFormatException;
|
||||||
import world.bentobox.bentobox.api.events.addon.AddonEvent;
|
import world.bentobox.bentobox.api.events.addon.AddonEvent;
|
||||||
|
|
||||||
@ -149,6 +150,15 @@ public class AddonsManager {
|
|||||||
|
|
||||||
// Run the onLoad.
|
// Run the onLoad.
|
||||||
addon.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) {
|
} catch (Exception e) {
|
||||||
plugin.logError(e.getMessage());
|
plugin.logError(e.getMessage());
|
||||||
}
|
}
|
||||||
|
@ -139,7 +139,7 @@ public class LocalesManager {
|
|||||||
// We cannot use Bukkit's saveResource, because we want it to go into a specific folder, so...
|
// We cannot use Bukkit's saveResource, because we want it to go into a specific folder, so...
|
||||||
// Get the last part of the name
|
// Get the last part of the name
|
||||||
int lastIndex = name.lastIndexOf('/');
|
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);
|
copyFile(name, targetFile);
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -14,6 +14,7 @@ import org.bukkit.configuration.InvalidConfigurationException;
|
|||||||
|
|
||||||
import world.bentobox.bentobox.BentoBox;
|
import world.bentobox.bentobox.BentoBox;
|
||||||
import world.bentobox.bentobox.api.addons.Addon;
|
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.database.objects.Island;
|
||||||
import world.bentobox.bentobox.schems.Clipboard;
|
import world.bentobox.bentobox.schems.Clipboard;
|
||||||
import world.bentobox.bentobox.util.Util;
|
import world.bentobox.bentobox.util.Util;
|
||||||
@ -41,7 +42,7 @@ public class SchemsManager {
|
|||||||
plugin.logError("Could not make schems folder!");
|
plugin.logError("Could not make schems folder!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Save any schems that
|
// Save any schems that are in the jar
|
||||||
try (JarFile jar = new JarFile(addon.getFile())) {
|
try (JarFile jar = new JarFile(addon.getFile())) {
|
||||||
Util.listJarFiles(jar, "schems", ".schem").forEach(name -> addon.saveResource(name, false));
|
Util.listJarFiles(jar, "schems", ".schem").forEach(name -> addon.saveResource(name, false));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@ -60,33 +61,29 @@ public class SchemsManager {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Load schems for addon. Will try and load nether and end schems too if settings are set.
|
* 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) {
|
public void loadIslands(GameModeAddon addon) {
|
||||||
plugin.getIWM().getAddon(world).ifPresent(addon -> {
|
File schems = new File(addon.getDataFolder(), "schems");
|
||||||
File schems = new File(addon.getDataFolder(), "schems");
|
// Copy any schems fould in the jar
|
||||||
// Copy any schems fould in the jar
|
copySchems(addon, schems);
|
||||||
copySchems(addon, schems);
|
// Load all schems in folder
|
||||||
// Load all schems in folder
|
// Look through the folder
|
||||||
// Look through the folder
|
FilenameFilter schemFilter = (File dir, String name) -> name.toLowerCase(java.util.Locale.ENGLISH).endsWith(".schem")
|
||||||
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("nether-")
|
&& !name.toLowerCase(java.util.Locale.ENGLISH).startsWith("end-");
|
||||||
&& !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 -> {
|
||||||
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)) {
|
||||||
if (!plugin.getSchemsManager().loadSchem(world, schems, name)) {
|
plugin.logError("Could not load " + name + ".schem for " + addon.getWorldSettings().getFriendlyName());
|
||||||
plugin.logError("Could not load " + name + ".schem for " + plugin.getIWM().getFriendlyName(world));
|
}
|
||||||
}
|
if (addon.getWorldSettings().isNetherGenerate() && addon.getWorldSettings().isNetherIslands()
|
||||||
if (plugin.getIWM().isNetherGenerate(world) && plugin.getIWM().isNetherIslands(world)
|
&& !plugin.getSchemsManager().loadSchem(addon.getNetherWorld(), schems, "nether-" + name)) {
|
||||||
&& !plugin.getSchemsManager().loadSchem(plugin.getIWM().getNetherWorld(world), schems, "nether-" + name)) {
|
plugin.logError("Could not load nether-" + name + ".schem for " + addon.getWorldSettings().getFriendlyName());
|
||||||
plugin.logError("Could not load nether-" + name + ".schem for " + plugin.getIWM().getFriendlyName(world));
|
}
|
||||||
}
|
if (addon.getWorldSettings().isEndGenerate() && addon.getWorldSettings().isEndIslands()
|
||||||
if (plugin.getIWM().isEndGenerate(world) && plugin.getIWM().isEndIslands(world)
|
&& !plugin.getSchemsManager().loadSchem(addon.getEndWorld(), schems, "end-" + name)) {
|
||||||
&& !plugin.getSchemsManager().loadSchem(plugin.getIWM().getEndWorld(world), schems, "end-" + name)) {
|
plugin.logError("Could not load end-" + name + ".schem for " + addon.getWorldSettings().getFriendlyName());
|
||||||
plugin.logError("Could not load end-" + name + ".schem for " + plugin.getIWM().getFriendlyName(world));
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
123
src/main/puml/GameWorld.puml
Normal file
123
src/main/puml/GameWorld.puml
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user