From 5dba9b5904742c0148434a6bd55c0bddc37aee13 Mon Sep 17 00:00:00 2001 From: Ben Woo <30431861+benwoo1110@users.noreply.github.com> Date: Tue, 29 Aug 2023 15:49:31 +0800 Subject: [PATCH 01/11] Starting to shift worlds.yml to new config api --- .../MultiverseCore/MultiverseCore.java | 6 + .../commands/CreateCommand.java | 8 +- .../commands/DeleteCommand.java | 15 ++- .../handle/FileConfigHandle.java | 1 - .../MultiverseCore/worldnew/WorldManager.java | 65 +++++++++ .../worldnew/config/WorldConfig.java | 47 +++++++ .../worldnew/config/WorldConfigNodes.java | 126 ++++++++++++++++++ .../worldnew/config/WorldsConfigFile.java | 54 ++++++++ 8 files changed, 313 insertions(+), 9 deletions(-) create mode 100644 src/main/java/com/onarandombox/MultiverseCore/worldnew/WorldManager.java create mode 100644 src/main/java/com/onarandombox/MultiverseCore/worldnew/config/WorldConfig.java create mode 100644 src/main/java/com/onarandombox/MultiverseCore/worldnew/config/WorldConfigNodes.java create mode 100644 src/main/java/com/onarandombox/MultiverseCore/worldnew/config/WorldsConfigFile.java diff --git a/src/main/java/com/onarandombox/MultiverseCore/MultiverseCore.java b/src/main/java/com/onarandombox/MultiverseCore/MultiverseCore.java index 6d07455d..798abc13 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/MultiverseCore.java +++ b/src/main/java/com/onarandombox/MultiverseCore/MultiverseCore.java @@ -25,6 +25,7 @@ import com.onarandombox.MultiverseCore.placeholders.MultiverseCorePlaceholders; import com.onarandombox.MultiverseCore.utils.TestingMode; import com.onarandombox.MultiverseCore.utils.metrics.MetricsConfigurator; import com.onarandombox.MultiverseCore.world.WorldProperties; +import com.onarandombox.MultiverseCore.worldnew.WorldManager; import io.vavr.control.Try; import jakarta.inject.Inject; import jakarta.inject.Provider; @@ -58,6 +59,8 @@ public class MultiverseCore extends JavaPlugin implements MVCore { @Inject private Provider worldManagerProvider; @Inject + private Provider newWorldManagerProvider; + @Inject private Provider anchorManagerProvider; @Inject private Provider commandManagerProvider; @@ -125,6 +128,9 @@ public class MultiverseCore extends JavaPlugin implements MVCore { config.setFirstSpawnLocation(firstSpawnWorld.getName()); } + var newWorldManager = newWorldManagerProvider.get(); + newWorldManager.loadAllWorlds(); + //Setup economy here so vault is loaded this.loadEconomist(); diff --git a/src/main/java/com/onarandombox/MultiverseCore/commands/CreateCommand.java b/src/main/java/com/onarandombox/MultiverseCore/commands/CreateCommand.java index 271c61f5..f5ee8c81 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/commands/CreateCommand.java +++ b/src/main/java/com/onarandombox/MultiverseCore/commands/CreateCommand.java @@ -26,6 +26,7 @@ import com.onarandombox.MultiverseCore.commandtools.flags.CommandValueFlag; import com.onarandombox.MultiverseCore.commandtools.flags.ParsedCommandFlags; import com.onarandombox.MultiverseCore.utils.MVCorei18n; import com.onarandombox.MultiverseCore.utils.UnsafeCallWrapper; +import com.onarandombox.MultiverseCore.worldnew.WorldManager; import jakarta.inject.Inject; import org.bukkit.Bukkit; import org.bukkit.World; @@ -39,16 +40,19 @@ import org.jvnet.hk2.annotations.Service; public class CreateCommand extends MultiverseCommand { private final MVWorldManager worldManager; + private final WorldManager newWorldManager; @Inject public CreateCommand( @NotNull MVCommandManager commandManager, @NotNull MVWorldManager worldManager, - @NotNull UnsafeCallWrapper unsafeCallWrapper + @NotNull UnsafeCallWrapper unsafeCallWrapper, + @NotNull WorldManager newWorldManager ) { super(commandManager); this.worldManager = worldManager; + this.newWorldManager = newWorldManager; registerFlagGroup(CommandFlagGroup.builder("mvcreate") .add(CommandValueFlag.builder("--seed", String.class) @@ -112,6 +116,8 @@ public class CreateCommand extends MultiverseCommand { issuer.sendInfo(MVCorei18n.CREATE_LOADING); + newWorldManager.addWorld(worldName); + if (!worldManager.addWorld( worldName, environment, diff --git a/src/main/java/com/onarandombox/MultiverseCore/commands/DeleteCommand.java b/src/main/java/com/onarandombox/MultiverseCore/commands/DeleteCommand.java index 4a1f1c51..ca6c767b 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/commands/DeleteCommand.java +++ b/src/main/java/com/onarandombox/MultiverseCore/commands/DeleteCommand.java @@ -15,6 +15,7 @@ import com.onarandombox.MultiverseCore.commandtools.MVCommandManager; import com.onarandombox.MultiverseCore.commandtools.MultiverseCommand; import com.onarandombox.MultiverseCore.commandtools.queue.QueuedCommand; import com.onarandombox.MultiverseCore.utils.MVCorei18n; +import com.onarandombox.MultiverseCore.worldnew.WorldManager; import jakarta.inject.Inject; import org.jetbrains.annotations.NotNull; import org.jvnet.hk2.annotations.Service; @@ -24,11 +25,13 @@ import org.jvnet.hk2.annotations.Service; public class DeleteCommand extends MultiverseCommand { private final MVWorldManager worldManager; + private final WorldManager newWorldManager; @Inject - public DeleteCommand(@NotNull MVCommandManager commandManager, @NotNull MVWorldManager worldManager) { + public DeleteCommand(@NotNull MVCommandManager commandManager, @NotNull MVWorldManager worldManager, @NotNull WorldManager newWorldManager) { super(commandManager); this.worldManager = worldManager; + this.newWorldManager = newWorldManager; } @Subcommand("delete") @@ -47,15 +50,13 @@ public class DeleteCommand extends MultiverseCommand { this.commandManager.getCommandQueueManager().addToQueue(new QueuedCommand( issuer.getIssuer(), () -> { - issuer.sendInfo(MVCorei18n.DELETE_DELETING, - "{world}", worldName); + issuer.sendInfo(MVCorei18n.DELETE_DELETING, "{world}", worldName); + this.newWorldManager.deleteWorld(worldName); if (!this.worldManager.deleteWorld(worldName)) { - issuer.sendError(MVCorei18n.DELETE_FAILED, - "{world}", worldName); + issuer.sendError(MVCorei18n.DELETE_FAILED, "{world}", worldName); return; } - issuer.sendInfo(MVCorei18n.DELETE_SUCCESS, - "{world}", worldName); + issuer.sendInfo(MVCorei18n.DELETE_SUCCESS, "{world}", worldName); }, this.commandManager.formatMessage( issuer, diff --git a/src/main/java/com/onarandombox/MultiverseCore/configuration/handle/FileConfigHandle.java b/src/main/java/com/onarandombox/MultiverseCore/configuration/handle/FileConfigHandle.java index 3903eba8..d339b437 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/configuration/handle/FileConfigHandle.java +++ b/src/main/java/com/onarandombox/MultiverseCore/configuration/handle/FileConfigHandle.java @@ -23,7 +23,6 @@ abstract class FileConfigHandle extends GenericConf protected final @NotNull Path configPath; protected final @NotNull File configFile; - protected FileConfigHandle(@NotNull Path configPath, @Nullable Logger logger, @Nullable NodeGroup nodes, @Nullable ConfigMigrator migrator) { super(logger, nodes, migrator); this.configPath = configPath; diff --git a/src/main/java/com/onarandombox/MultiverseCore/worldnew/WorldManager.java b/src/main/java/com/onarandombox/MultiverseCore/worldnew/WorldManager.java new file mode 100644 index 00000000..1ef9cba9 --- /dev/null +++ b/src/main/java/com/onarandombox/MultiverseCore/worldnew/WorldManager.java @@ -0,0 +1,65 @@ +package com.onarandombox.MultiverseCore.worldnew; + +import com.onarandombox.MultiverseCore.worldnew.config.WorldConfig; +import com.onarandombox.MultiverseCore.worldnew.config.WorldsConfigFile; +import jakarta.inject.Inject; +import org.bukkit.configuration.ConfigurationSection; +import org.jetbrains.annotations.NotNull; +import org.jvnet.hk2.annotations.Service; + +@Service +public class WorldManager { + private final WorldsConfigFile worldsConfigFile; + + @Inject + WorldManager(@NotNull WorldsConfigFile worldsConfigFile) { + this.worldsConfigFile = worldsConfigFile; + this.worldsConfigFile.load(); + } + + public void loadAllWorlds() { + for (String worldName : worldsConfigFile.getAllWorldsInConfig()) { + loadWorld(worldName); + } + saveWorldsConfig(); + } + + public void addWorld(String worldName) { + ConfigurationSection worldConfigSection = worldsConfigFile.addWorldConfigSection(worldName); + WorldConfig worldConfig = new WorldConfig(worldConfigSection); + //todo + saveWorldsConfig(); + } + + public void loadWorld(String worldName) { + ConfigurationSection worldConfigSection = worldsConfigFile.addWorldConfigSection(worldName); + WorldConfig worldConfig = new WorldConfig(worldConfigSection); + //todo + } + + public void unloadWorld() { + //todo + } + + public void removeWorld(String worldName) { + //todo + worldsConfigFile.deleteWorldConfigSection(worldName); + } + + public void deleteWorld(String worldName) { + //todo + worldsConfigFile.deleteWorldConfigSection(worldName); + } + + public void getMVWorld(String worldName) { + //todo + } + + public void getUnloadedWorld(String worldName) { + //todo + } + + public void saveWorldsConfig() { + worldsConfigFile.save(); + } +} diff --git a/src/main/java/com/onarandombox/MultiverseCore/worldnew/config/WorldConfig.java b/src/main/java/com/onarandombox/MultiverseCore/worldnew/config/WorldConfig.java new file mode 100644 index 00000000..d3829dd1 --- /dev/null +++ b/src/main/java/com/onarandombox/MultiverseCore/worldnew/config/WorldConfig.java @@ -0,0 +1,47 @@ +package com.onarandombox.MultiverseCore.worldnew.config; + +import com.dumptruckman.minecraft.util.Logging; +import com.onarandombox.MultiverseCore.configuration.handle.ConfigurationSectionHandle; +import io.vavr.control.Try; +import org.bukkit.configuration.ConfigurationSection; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class WorldConfig { + private final WorldConfigNodes configNodes; + private final ConfigurationSectionHandle configHandle; + + public WorldConfig(@NotNull final ConfigurationSection configSection) { + this.configNodes = new WorldConfigNodes(); + //todo: Config migration and version + this.configHandle = ConfigurationSectionHandle.builder(configSection) + .logger(Logging.getLogger()) + .nodes(configNodes.getNodes()) + .build(); + this.configHandle.load(); + } + + public Try getProperty(String name) { + return configHandle.get(name); + } + + public Try setProperty(String name, Object value) { + return configHandle.set(name, value); + } + + public void setAlias(String alias) { + configHandle.set(configNodes.ALIAS, alias); + } + + public @Nullable String getAlias() { + return configHandle.get(configNodes.ALIAS); + } + + public void setHidden(boolean hidden) { + configHandle.set(configNodes.HIDDEN, hidden); + } + + public boolean isHidden() { + return configHandle.get(configNodes.HIDDEN); + } +} diff --git a/src/main/java/com/onarandombox/MultiverseCore/worldnew/config/WorldConfigNodes.java b/src/main/java/com/onarandombox/MultiverseCore/worldnew/config/WorldConfigNodes.java new file mode 100644 index 00000000..43a03523 --- /dev/null +++ b/src/main/java/com/onarandombox/MultiverseCore/worldnew/config/WorldConfigNodes.java @@ -0,0 +1,126 @@ +package com.onarandombox.MultiverseCore.worldnew.config; + +import com.onarandombox.MultiverseCore.configuration.node.ConfigNode; +import com.onarandombox.MultiverseCore.configuration.node.Node; +import com.onarandombox.MultiverseCore.configuration.node.NodeGroup; +import com.onarandombox.MultiverseCore.world.configuration.AllowedPortalType; +import org.bukkit.Difficulty; +import org.bukkit.GameMode; +import org.bukkit.World; + +public class WorldConfigNodes { + private final NodeGroup nodes = new NodeGroup(); + + WorldConfigNodes() { + } + + public NodeGroup getNodes() { + return nodes; + } + + private N node(N node) { + nodes.add(node); + return node; + } + + public final ConfigNode ADJUST_SPAWN = node(ConfigNode.builder("adjust-spawn", Boolean.class) + .defaultValue(false) + .name("adjust-spawn") + .build()); + + public final ConfigNode ALIAS = node(ConfigNode.builder("alias", String.class) + .defaultValue("") + .name("alias") + .build()); + + public final ConfigNode ALLOW_FLIGHT = node(ConfigNode.builder("allow-flight", Boolean.class) + .defaultValue(false) + .name("allow-flight") + .build()); + + public final ConfigNode ALLOW_WEATHER = node(ConfigNode.builder("allow-weather", Boolean.class) + .defaultValue(true) + .name("allow-weather") + .build()); + + public final ConfigNode AUTO_HEAL = node(ConfigNode.builder("auto-heal", Boolean.class) + .defaultValue(true) + .name("auto-heal") + .build()); + + public final ConfigNode AUTO_LOAD = node(ConfigNode.builder("auto-load", Boolean.class) + .defaultValue(true) + .name("auto-load") + .build()); + + public final ConfigNode DIFFICULTY = node(ConfigNode.builder("difficulty", Difficulty.class) + .defaultValue(Difficulty.NORMAL) + .name("difficulty") + .build()); + + public final ConfigNode ENVIRONMENT = node(ConfigNode.builder("environment", World.Environment.class) + .defaultValue(World.Environment.NORMAL) + .name("environment") + .build()); + + public final ConfigNode GAMEMODE = node(ConfigNode.builder("gamemode", GameMode.class) + .defaultValue(GameMode.SURVIVAL) + .name("gamemode") + .build()); + + public final ConfigNode GENERATOR = node(ConfigNode.builder("generator", String.class) + .defaultValue("") + .name("generator") + .build()); + + public final ConfigNode HIDDEN = node(ConfigNode.builder("hidden", Boolean.class) + .defaultValue(false) + .name("hidden") + .build()); + + public final ConfigNode HUNGER = node(ConfigNode.builder("hunger", Boolean.class) + .defaultValue(true) + .name("hunger") + .build()); + + public final ConfigNode KEEP_SPAWN_IN_MEMORY = node(ConfigNode.builder("keep-spawn-in-memory", Boolean.class) + .defaultValue(true) + .name("keep-spawn-in-memory") + .build()); + + public final ConfigNode PLAYER_LIMIT = node(ConfigNode.builder("player-limit", Integer.class) + .defaultValue(-1) + .name("player-limit") + .build()); + + public final ConfigNode PORTAL_FORM = node(ConfigNode.builder("portal-form", AllowedPortalType.class) + .defaultValue(AllowedPortalType.ALL) + .name("portal-form") + .build()); + + public final ConfigNode PVP = node(ConfigNode.builder("pvp", Boolean.class) + .defaultValue(true) + .name("pvp") + .build()); + + public final ConfigNode RESPAWN_WORLD = node(ConfigNode.builder("respawn-world", String.class) + .defaultValue("") + .name("respawn-world") + .build()); + + public final ConfigNode SCALE = node(ConfigNode.builder("scale", Double.class) + .defaultValue(1.0) + .name("scale") + .build()); + + public final ConfigNode SEED = node(ConfigNode.builder("seed", String.class) + .defaultValue("") + .name("seed") + .build()); + + //todo: color and style + //todo: spawning + //todo: entryfee + //todo: spawnLocation + //todo: worldBlacklist +} diff --git a/src/main/java/com/onarandombox/MultiverseCore/worldnew/config/WorldsConfigFile.java b/src/main/java/com/onarandombox/MultiverseCore/worldnew/config/WorldsConfigFile.java new file mode 100644 index 00000000..6cf55fab --- /dev/null +++ b/src/main/java/com/onarandombox/MultiverseCore/worldnew/config/WorldsConfigFile.java @@ -0,0 +1,54 @@ +package com.onarandombox.MultiverseCore.worldnew.config; + +import com.onarandombox.MultiverseCore.MultiverseCore; +import jakarta.inject.Inject; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.YamlConfiguration; +import org.jetbrains.annotations.NotNull; +import org.jvnet.hk2.annotations.Service; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +@Service +public class WorldsConfigFile { + private static final String CONFIG_FILENAME = "worlds2.yml"; + + private final File worldConfigFile; + private YamlConfiguration worldConfig; + + @Inject + public WorldsConfigFile(@NotNull MultiverseCore core) { + worldConfigFile = core.getDataFolder().toPath().resolve(CONFIG_FILENAME).toFile(); + } + + public void load() { + //todo: Migration from old worlds.yml + worldConfig = YamlConfiguration.loadConfiguration(worldConfigFile); + } + + public void save() { + try { + worldConfig.save(worldConfigFile); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public Collection getAllWorldsInConfig() { + return worldConfig.getKeys(false); + } + + public ConfigurationSection addWorldConfigSection(String worldName) { + return worldConfig.isConfigurationSection(worldName) + ? worldConfig.getConfigurationSection(worldName) : worldConfig.createSection(worldName); + } + + public void deleteWorldConfigSection(String worldName) { + worldConfig.set(worldName, null); + } +} From c569bc797fb58684b6d5f9280aeb5731d7244460 Mon Sep 17 00:00:00 2001 From: Ben Woo <30431861+benwoo1110@users.noreply.github.com> Date: Tue, 29 Aug 2023 16:39:20 +0800 Subject: [PATCH 02/11] Implement node serialisation --- .../handle/GenericConfigHandle.java | 16 +++++++++++++--- .../configuration/node/ConfigNode.java | 15 ++++++++++++++- .../configuration/node/EnumNodeSerializer.java | 16 ++++++++++++++++ .../configuration/node/NodeSerializer.java | 6 ++++++ .../configuration/node/ValueNode.java | 7 +++++++ .../MultiverseCore/worldnew/WorldManager.java | 2 ++ .../worldnew/config/WorldConfigNodes.java | 8 ++++++++ 7 files changed, 66 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/onarandombox/MultiverseCore/configuration/node/EnumNodeSerializer.java create mode 100644 src/main/java/com/onarandombox/MultiverseCore/configuration/node/NodeSerializer.java diff --git a/src/main/java/com/onarandombox/MultiverseCore/configuration/handle/GenericConfigHandle.java b/src/main/java/com/onarandombox/MultiverseCore/configuration/handle/GenericConfigHandle.java index 654b0cc4..1ba4c7f0 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/configuration/handle/GenericConfigHandle.java +++ b/src/main/java/com/onarandombox/MultiverseCore/configuration/handle/GenericConfigHandle.java @@ -3,7 +3,9 @@ package com.onarandombox.MultiverseCore.configuration.handle; import com.onarandombox.MultiverseCore.configuration.migration.ConfigMigrator; import com.onarandombox.MultiverseCore.configuration.node.ConfigNodeNotFoundException; import com.onarandombox.MultiverseCore.configuration.node.NodeGroup; +import com.onarandombox.MultiverseCore.configuration.node.NodeSerializer; import com.onarandombox.MultiverseCore.configuration.node.ValueNode; +import io.vavr.control.Option; import io.vavr.control.Try; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.plugin.Plugin; @@ -58,7 +60,7 @@ public abstract class GenericConfigHandle { nodes.forEach(node -> { if (node instanceof ValueNode valueNode) { - set(valueNode, config.getObject(valueNode.getPath(), valueNode.getType(), valueNode.getDefaultValue())); + set(valueNode, get(valueNode)); } }); } @@ -81,7 +83,10 @@ public abstract class GenericConfigHandle { * @return The value of the node. */ public T get(@NotNull ValueNode node) { - return config.getObject(node.getPath(), node.getType(), node.getDefaultValue()); + if (node.getSerializer() == null) { + return config.getObject(node.getPath(), node.getType(), node.getDefaultValue()); + } + return node.getSerializer().deserialize(config.get(node.getPath(), node.getDefaultValue()), node.getType()); } /** @@ -108,7 +113,12 @@ public abstract class GenericConfigHandle { public Try set(@NotNull ValueNode node, T value) { return node.validate(value).map(ignore -> { T oldValue = get(node); - config.set(node.getPath(), value); + if (node.getSerializer() != null) { + var serialized = node.getSerializer().serialize(value, node.getType()); + config.set(node.getPath(), serialized); + } else { + config.set(node.getPath(), value); + } node.onSetValue(oldValue, get(node)); return null; }); diff --git a/src/main/java/com/onarandombox/MultiverseCore/configuration/node/ConfigNode.java b/src/main/java/com/onarandombox/MultiverseCore/configuration/node/ConfigNode.java index d575b7e5..5985d22c 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/configuration/node/ConfigNode.java +++ b/src/main/java/com/onarandombox/MultiverseCore/configuration/node/ConfigNode.java @@ -32,6 +32,7 @@ public class ConfigNode extends ConfigHeaderNode implements ValueNode { protected final @Nullable String name; protected final @NotNull Class type; protected final @Nullable T defaultValue; + protected final @Nullable NodeSerializer serializer; protected final @Nullable Function> validator; protected final @Nullable BiConsumer onSetValue; @@ -41,6 +42,7 @@ public class ConfigNode extends ConfigHeaderNode implements ValueNode { @Nullable String name, @NotNull Class type, @Nullable T defaultValue, + @Nullable NodeSerializer serializer, @Nullable Function> validator, @Nullable BiConsumer onSetValue ) { @@ -48,6 +50,7 @@ public class ConfigNode extends ConfigHeaderNode implements ValueNode { this.name = name; this.type = type; this.defaultValue = defaultValue; + this.serializer = serializer; this.validator = validator; this.onSetValue = onSetValue; } @@ -76,6 +79,10 @@ public class ConfigNode extends ConfigHeaderNode implements ValueNode { return defaultValue; } + public @Nullable NodeSerializer getSerializer() { + return serializer; + } + /** * {@inheritDoc} */ @@ -108,6 +115,7 @@ public class ConfigNode extends ConfigHeaderNode implements ValueNode { protected @Nullable String name; protected @NotNull final Class type; protected @Nullable T defaultValue; + protected @Nullable NodeSerializer serializer; protected @Nullable Function> validator; protected @Nullable BiConsumer onSetValue; @@ -145,6 +153,11 @@ public class ConfigNode extends ConfigHeaderNode implements ValueNode { return (B) this; } + public @NotNull B serializer(@NotNull NodeSerializer serializer) { + this.serializer = serializer; + return (B) this; + } + public @NotNull B validator(@NotNull Function> validator) { this.validator = validator; return (B) this; @@ -166,7 +179,7 @@ public class ConfigNode extends ConfigHeaderNode implements ValueNode { */ @Override public @NotNull ConfigNode build() { - return new ConfigNode<>(path, comments.toArray(new String[0]), name, type, defaultValue, validator, onSetValue); + return new ConfigNode<>(path, comments.toArray(new String[0]), name, type, defaultValue, serializer, validator, onSetValue); } } } diff --git a/src/main/java/com/onarandombox/MultiverseCore/configuration/node/EnumNodeSerializer.java b/src/main/java/com/onarandombox/MultiverseCore/configuration/node/EnumNodeSerializer.java new file mode 100644 index 00000000..08ecfaf7 --- /dev/null +++ b/src/main/java/com/onarandombox/MultiverseCore/configuration/node/EnumNodeSerializer.java @@ -0,0 +1,16 @@ +package com.onarandombox.MultiverseCore.configuration.node; + +import com.dumptruckman.minecraft.util.Logging; + +public class EnumNodeSerializer> implements NodeSerializer { + + @Override + public T deserialize(Object object, Class type) { + return Enum.valueOf(type, object.toString().toUpperCase()); + } + + @Override + public Object serialize(T object, Class type) { + return object.toString(); + } +} diff --git a/src/main/java/com/onarandombox/MultiverseCore/configuration/node/NodeSerializer.java b/src/main/java/com/onarandombox/MultiverseCore/configuration/node/NodeSerializer.java new file mode 100644 index 00000000..a98a3cc6 --- /dev/null +++ b/src/main/java/com/onarandombox/MultiverseCore/configuration/node/NodeSerializer.java @@ -0,0 +1,6 @@ +package com.onarandombox.MultiverseCore.configuration.node; + +public interface NodeSerializer { + T deserialize(Object object, Class type); + Object serialize(T object, Class type); +} diff --git a/src/main/java/com/onarandombox/MultiverseCore/configuration/node/ValueNode.java b/src/main/java/com/onarandombox/MultiverseCore/configuration/node/ValueNode.java index 9aebfae5..ffacb760 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/configuration/node/ValueNode.java +++ b/src/main/java/com/onarandombox/MultiverseCore/configuration/node/ValueNode.java @@ -28,6 +28,13 @@ public interface ValueNode extends Node { */ @Nullable T getDefaultValue(); + /** + * Gets the serializer for this node. + * + * @return The serializer for this node. + */ + @Nullable NodeSerializer getSerializer(); + /** * Validates the value of this node. * diff --git a/src/main/java/com/onarandombox/MultiverseCore/worldnew/WorldManager.java b/src/main/java/com/onarandombox/MultiverseCore/worldnew/WorldManager.java index 1ef9cba9..35b5e1cd 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/worldnew/WorldManager.java +++ b/src/main/java/com/onarandombox/MultiverseCore/worldnew/WorldManager.java @@ -1,5 +1,6 @@ package com.onarandombox.MultiverseCore.worldnew; +import com.dumptruckman.minecraft.util.Logging; import com.onarandombox.MultiverseCore.worldnew.config.WorldConfig; import com.onarandombox.MultiverseCore.worldnew.config.WorldsConfigFile; import jakarta.inject.Inject; @@ -19,6 +20,7 @@ public class WorldManager { public void loadAllWorlds() { for (String worldName : worldsConfigFile.getAllWorldsInConfig()) { + Logging.fine("Loading world: " + worldName); loadWorld(worldName); } saveWorldsConfig(); diff --git a/src/main/java/com/onarandombox/MultiverseCore/worldnew/config/WorldConfigNodes.java b/src/main/java/com/onarandombox/MultiverseCore/worldnew/config/WorldConfigNodes.java index 43a03523..eb02847c 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/worldnew/config/WorldConfigNodes.java +++ b/src/main/java/com/onarandombox/MultiverseCore/worldnew/config/WorldConfigNodes.java @@ -1,14 +1,18 @@ package com.onarandombox.MultiverseCore.worldnew.config; import com.onarandombox.MultiverseCore.configuration.node.ConfigNode; +import com.onarandombox.MultiverseCore.configuration.node.EnumNodeSerializer; import com.onarandombox.MultiverseCore.configuration.node.Node; import com.onarandombox.MultiverseCore.configuration.node.NodeGroup; +import com.onarandombox.MultiverseCore.configuration.node.NodeSerializer; import com.onarandombox.MultiverseCore.world.configuration.AllowedPortalType; import org.bukkit.Difficulty; import org.bukkit.GameMode; import org.bukkit.World; public class WorldConfigNodes { + private static final NodeSerializer ENUM_NODE_SERIALIZER = new EnumNodeSerializer<>(); + private final NodeGroup nodes = new NodeGroup(); WorldConfigNodes() { @@ -56,16 +60,19 @@ public class WorldConfigNodes { public final ConfigNode DIFFICULTY = node(ConfigNode.builder("difficulty", Difficulty.class) .defaultValue(Difficulty.NORMAL) .name("difficulty") + .serializer((NodeSerializer) ENUM_NODE_SERIALIZER) .build()); public final ConfigNode ENVIRONMENT = node(ConfigNode.builder("environment", World.Environment.class) .defaultValue(World.Environment.NORMAL) .name("environment") + .serializer((NodeSerializer) ENUM_NODE_SERIALIZER) .build()); public final ConfigNode GAMEMODE = node(ConfigNode.builder("gamemode", GameMode.class) .defaultValue(GameMode.SURVIVAL) .name("gamemode") + .serializer((NodeSerializer) ENUM_NODE_SERIALIZER) .build()); public final ConfigNode GENERATOR = node(ConfigNode.builder("generator", String.class) @@ -96,6 +103,7 @@ public class WorldConfigNodes { public final ConfigNode PORTAL_FORM = node(ConfigNode.builder("portal-form", AllowedPortalType.class) .defaultValue(AllowedPortalType.ALL) .name("portal-form") + .serializer((NodeSerializer) ENUM_NODE_SERIALIZER) .build()); public final ConfigNode PVP = node(ConfigNode.builder("pvp", Boolean.class) From 6888783d014d76d192da03d1cfc8cef1238d972e Mon Sep 17 00:00:00 2001 From: Ben Woo <30431861+benwoo1110@users.noreply.github.com> Date: Thu, 31 Aug 2023 10:47:49 +0800 Subject: [PATCH 03/11] Implement world blacklist config --- .../MultiverseCore/worldnew/config/WorldConfig.java | 10 ++++++++++ .../worldnew/config/WorldConfigNodes.java | 8 ++++++++ 2 files changed, 18 insertions(+) diff --git a/src/main/java/com/onarandombox/MultiverseCore/worldnew/config/WorldConfig.java b/src/main/java/com/onarandombox/MultiverseCore/worldnew/config/WorldConfig.java index d3829dd1..926f77a7 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/worldnew/config/WorldConfig.java +++ b/src/main/java/com/onarandombox/MultiverseCore/worldnew/config/WorldConfig.java @@ -7,6 +7,8 @@ import org.bukkit.configuration.ConfigurationSection; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.List; + public class WorldConfig { private final WorldConfigNodes configNodes; private final ConfigurationSectionHandle configHandle; @@ -44,4 +46,12 @@ public class WorldConfig { public boolean isHidden() { return configHandle.get(configNodes.HIDDEN); } + + public List getWorldBlacklist() { + return (List) configHandle.get(configNodes.WORLD_BLACKLIST); + } + + public void setWorldBlacklist(List worldBlacklist) { + configHandle.set(configNodes.WORLD_BLACKLIST, worldBlacklist); + } } diff --git a/src/main/java/com/onarandombox/MultiverseCore/worldnew/config/WorldConfigNodes.java b/src/main/java/com/onarandombox/MultiverseCore/worldnew/config/WorldConfigNodes.java index eb02847c..482a9437 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/worldnew/config/WorldConfigNodes.java +++ b/src/main/java/com/onarandombox/MultiverseCore/worldnew/config/WorldConfigNodes.java @@ -10,6 +10,9 @@ import org.bukkit.Difficulty; import org.bukkit.GameMode; import org.bukkit.World; +import java.util.ArrayList; +import java.util.List; + public class WorldConfigNodes { private static final NodeSerializer ENUM_NODE_SERIALIZER = new EnumNodeSerializer<>(); @@ -126,6 +129,11 @@ public class WorldConfigNodes { .name("seed") .build()); + public final ConfigNode WORLD_BLACKLIST = node(ConfigNode.builder("world-blacklist", List.class) + .defaultValue(new ArrayList<>()) + .name("world-blacklist") + .build()); + //todo: color and style //todo: spawning //todo: entryfee From decf20f95f0576a3402c3904887687a7dcdfc2d7 Mon Sep 17 00:00:00 2001 From: Ben Woo <30431861+benwoo1110@users.noreply.github.com> Date: Thu, 31 Aug 2023 14:59:31 +0800 Subject: [PATCH 04/11] Add basic tests for world config --- .../MultiverseCore/worldnew/WorldManager.java | 8 +- .../worldnew/config/WorldsConfigFile.java | 9 ++- .../multiverse/core/world/WorldConfigTest.kt | 75 +++++++++++++++++++ src/test/resources/default_worlds.yml | 42 +++++++++++ src/test/resources/delete_worlds.yml | 21 ++++++ src/test/resources/newworld_worlds.yml | 63 ++++++++++++++++ src/test/resources/properties_worlds.yml | 42 +++++++++++ 7 files changed, 254 insertions(+), 6 deletions(-) create mode 100644 src/test/java/org/mvplugins/multiverse/core/world/WorldConfigTest.kt create mode 100644 src/test/resources/default_worlds.yml create mode 100644 src/test/resources/delete_worlds.yml create mode 100644 src/test/resources/newworld_worlds.yml create mode 100644 src/test/resources/properties_worlds.yml diff --git a/src/main/java/com/onarandombox/MultiverseCore/worldnew/WorldManager.java b/src/main/java/com/onarandombox/MultiverseCore/worldnew/WorldManager.java index 35b5e1cd..097950bb 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/worldnew/WorldManager.java +++ b/src/main/java/com/onarandombox/MultiverseCore/worldnew/WorldManager.java @@ -8,6 +8,8 @@ import org.bukkit.configuration.ConfigurationSection; import org.jetbrains.annotations.NotNull; import org.jvnet.hk2.annotations.Service; +import java.util.List; + @Service public class WorldManager { private final WorldsConfigFile worldsConfigFile; @@ -27,14 +29,14 @@ public class WorldManager { } public void addWorld(String worldName) { - ConfigurationSection worldConfigSection = worldsConfigFile.addWorldConfigSection(worldName); + ConfigurationSection worldConfigSection = worldsConfigFile.getWorldConfigSection(worldName); WorldConfig worldConfig = new WorldConfig(worldConfigSection); //todo saveWorldsConfig(); } public void loadWorld(String worldName) { - ConfigurationSection worldConfigSection = worldsConfigFile.addWorldConfigSection(worldName); + ConfigurationSection worldConfigSection = worldsConfigFile.getWorldConfigSection(worldName); WorldConfig worldConfig = new WorldConfig(worldConfigSection); //todo } @@ -46,11 +48,13 @@ public class WorldManager { public void removeWorld(String worldName) { //todo worldsConfigFile.deleteWorldConfigSection(worldName); + saveWorldsConfig(); } public void deleteWorld(String worldName) { //todo worldsConfigFile.deleteWorldConfigSection(worldName); + saveWorldsConfig(); } public void getMVWorld(String worldName) { diff --git a/src/main/java/com/onarandombox/MultiverseCore/worldnew/config/WorldsConfigFile.java b/src/main/java/com/onarandombox/MultiverseCore/worldnew/config/WorldsConfigFile.java index 6cf55fab..a51a986b 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/worldnew/config/WorldsConfigFile.java +++ b/src/main/java/com/onarandombox/MultiverseCore/worldnew/config/WorldsConfigFile.java @@ -9,10 +9,7 @@ import org.jvnet.hk2.annotations.Service; import java.io.File; import java.io.IOException; -import java.nio.file.Path; import java.util.Collection; -import java.util.Collections; -import java.util.List; @Service public class WorldsConfigFile { @@ -31,6 +28,10 @@ public class WorldsConfigFile { worldConfig = YamlConfiguration.loadConfiguration(worldConfigFile); } + public boolean isLoaded() { + return worldConfig != null; + } + public void save() { try { worldConfig.save(worldConfigFile); @@ -43,7 +44,7 @@ public class WorldsConfigFile { return worldConfig.getKeys(false); } - public ConfigurationSection addWorldConfigSection(String worldName) { + public ConfigurationSection getWorldConfigSection(String worldName) { return worldConfig.isConfigurationSection(worldName) ? worldConfig.getConfigurationSection(worldName) : worldConfig.createSection(worldName); } diff --git a/src/test/java/org/mvplugins/multiverse/core/world/WorldConfigTest.kt b/src/test/java/org/mvplugins/multiverse/core/world/WorldConfigTest.kt new file mode 100644 index 00000000..e0113e70 --- /dev/null +++ b/src/test/java/org/mvplugins/multiverse/core/world/WorldConfigTest.kt @@ -0,0 +1,75 @@ +package org.mvplugins.multiverse.core.world + +import com.onarandombox.MultiverseCore.worldnew.config.WorldConfig +import com.onarandombox.MultiverseCore.worldnew.config.WorldsConfigFile +import org.mvplugins.multiverse.core.TestWithMockBukkit +import java.io.File +import java.nio.file.Path +import kotlin.io.path.absolutePathString +import kotlin.test.BeforeTest +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertNotNull +import kotlin.test.assertTrue + +class WorldConfigTest : TestWithMockBukkit() { + + private lateinit var worldConfigFile : WorldsConfigFile + + @BeforeTest + fun setUp() { + val defaultConfig = getResourceAsText("/default_worlds.yml") + assertNotNull(defaultConfig) + File(Path.of(multiverseCore.dataFolder.absolutePath, "worlds2.yml").absolutePathString()).writeText(defaultConfig) + + worldConfigFile = WorldsConfigFile(multiverseCore) + worldConfigFile.load() + } + + @Test + fun `World config is loaded`() { + assertTrue(worldConfigFile.isLoaded) + } + + @Test + fun `Old world config is migrated`() { + // TODO + } + + @Test + fun `Add a new world to config`() { + val worldConfig = WorldConfig(worldConfigFile.getWorldConfigSection("newworld")) + worldConfigFile.save() + + compareConfigFile("worlds2.yml", "/newworld_worlds.yml") + } + + @Test + fun `Updating existing world properties`() { + val worldConfig = WorldConfig(worldConfigFile.getWorldConfigSection("world")) + worldConfig.setProperty("adjust-spawn", true) + worldConfig.setProperty("alias", "newalias") + + worldConfigFile.save() + + assertEquals(true, worldConfig.getProperty("adjust-spawn").get()) + assertEquals("newalias", worldConfig.getProperty("alias").get()) + + compareConfigFile("worlds2.yml", "/properties_worlds.yml") + } + + @Test + fun `Delete world section from config`() { + worldConfigFile.deleteWorldConfigSection("world") + worldConfigFile.save() + + compareConfigFile("worlds2.yml", "/delete_worlds.yml") + } + + private fun compareConfigFile(configPath: String, comparePath: String) { + val config = multiverseCore.dataFolder.toPath().resolve(configPath).toFile().readText() + val configCompare = getResourceAsText(comparePath) + assertNotNull(configCompare) + assertEquals(configCompare, config) + } +} diff --git a/src/test/resources/default_worlds.yml b/src/test/resources/default_worlds.yml new file mode 100644 index 00000000..631963b1 --- /dev/null +++ b/src/test/resources/default_worlds.yml @@ -0,0 +1,42 @@ +world: + adjust-spawn: false + alias: '' + allow-flight: false + allow-weather: true + auto-heal: true + auto-load: true + difficulty: NORMAL + environment: NORMAL + gamemode: SURVIVAL + generator: '' + hidden: false + hunger: true + keep-spawn-in-memory: true + player-limit: -1 + portal-form: ALL + pvp: true + respawn-world: '' + scale: 1.0 + seed: '' + world-blacklist: [] +world_nether: + adjust-spawn: false + alias: '' + allow-flight: false + allow-weather: true + auto-heal: true + auto-load: true + difficulty: NORMAL + environment: NETHER + gamemode: SURVIVAL + generator: '' + hidden: false + hunger: true + keep-spawn-in-memory: true + player-limit: -1 + portal-form: ALL + pvp: true + respawn-world: '' + scale: 1.0 + seed: '' + world-blacklist: [] diff --git a/src/test/resources/delete_worlds.yml b/src/test/resources/delete_worlds.yml new file mode 100644 index 00000000..0f4ba42c --- /dev/null +++ b/src/test/resources/delete_worlds.yml @@ -0,0 +1,21 @@ +world_nether: + adjust-spawn: false + alias: '' + allow-flight: false + allow-weather: true + auto-heal: true + auto-load: true + difficulty: NORMAL + environment: NETHER + gamemode: SURVIVAL + generator: '' + hidden: false + hunger: true + keep-spawn-in-memory: true + player-limit: -1 + portal-form: ALL + pvp: true + respawn-world: '' + scale: 1.0 + seed: '' + world-blacklist: [] diff --git a/src/test/resources/newworld_worlds.yml b/src/test/resources/newworld_worlds.yml new file mode 100644 index 00000000..7852a07e --- /dev/null +++ b/src/test/resources/newworld_worlds.yml @@ -0,0 +1,63 @@ +world: + adjust-spawn: false + alias: '' + allow-flight: false + allow-weather: true + auto-heal: true + auto-load: true + difficulty: NORMAL + environment: NORMAL + gamemode: SURVIVAL + generator: '' + hidden: false + hunger: true + keep-spawn-in-memory: true + player-limit: -1 + portal-form: ALL + pvp: true + respawn-world: '' + scale: 1.0 + seed: '' + world-blacklist: [] +world_nether: + adjust-spawn: false + alias: '' + allow-flight: false + allow-weather: true + auto-heal: true + auto-load: true + difficulty: NORMAL + environment: NETHER + gamemode: SURVIVAL + generator: '' + hidden: false + hunger: true + keep-spawn-in-memory: true + player-limit: -1 + portal-form: ALL + pvp: true + respawn-world: '' + scale: 1.0 + seed: '' + world-blacklist: [] +newworld: + adjust-spawn: false + alias: '' + allow-flight: false + allow-weather: true + auto-heal: true + auto-load: true + difficulty: NORMAL + environment: NORMAL + gamemode: SURVIVAL + generator: '' + hidden: false + hunger: true + keep-spawn-in-memory: true + player-limit: -1 + portal-form: ALL + pvp: true + respawn-world: '' + scale: 1.0 + seed: '' + world-blacklist: [] diff --git a/src/test/resources/properties_worlds.yml b/src/test/resources/properties_worlds.yml new file mode 100644 index 00000000..0e526a3d --- /dev/null +++ b/src/test/resources/properties_worlds.yml @@ -0,0 +1,42 @@ +world: + adjust-spawn: true + alias: newalias + allow-flight: false + allow-weather: true + auto-heal: true + auto-load: true + difficulty: NORMAL + environment: NORMAL + gamemode: SURVIVAL + generator: '' + hidden: false + hunger: true + keep-spawn-in-memory: true + player-limit: -1 + portal-form: ALL + pvp: true + respawn-world: '' + scale: 1.0 + seed: '' + world-blacklist: [] +world_nether: + adjust-spawn: false + alias: '' + allow-flight: false + allow-weather: true + auto-heal: true + auto-load: true + difficulty: NORMAL + environment: NETHER + gamemode: SURVIVAL + generator: '' + hidden: false + hunger: true + keep-spawn-in-memory: true + player-limit: -1 + portal-form: ALL + pvp: true + respawn-world: '' + scale: 1.0 + seed: '' + world-blacklist: [] From 54c8bac3d3f62ce12603b33ce515af903084482f Mon Sep 17 00:00:00 2001 From: Ben Woo <30431861+benwoo1110@users.noreply.github.com> Date: Thu, 31 Aug 2023 15:16:41 +0800 Subject: [PATCH 05/11] Config node automatically use the enum node serializer --- .../MultiverseCore/configuration/node/ConfigNode.java | 4 ++++ .../MultiverseCore/worldnew/config/WorldConfigNodes.java | 8 -------- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/onarandombox/MultiverseCore/configuration/node/ConfigNode.java b/src/main/java/com/onarandombox/MultiverseCore/configuration/node/ConfigNode.java index 5985d22c..f9efbd22 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/configuration/node/ConfigNode.java +++ b/src/main/java/com/onarandombox/MultiverseCore/configuration/node/ConfigNode.java @@ -111,6 +111,7 @@ public class ConfigNode extends ConfigHeaderNode implements ValueNode { * @param The type of the builder. */ public static class Builder> extends ConfigHeaderNode.Builder { + private static final NodeSerializer ENUM_NODE_SERIALIZER = new EnumNodeSerializer<>(); protected @Nullable String name; protected @NotNull final Class type; @@ -129,6 +130,9 @@ public class ConfigNode extends ConfigHeaderNode implements ValueNode { super(path); this.name = path; this.type = type; + if (type.isEnum()) { + this.serializer = (NodeSerializer) ENUM_NODE_SERIALIZER; + } } /** diff --git a/src/main/java/com/onarandombox/MultiverseCore/worldnew/config/WorldConfigNodes.java b/src/main/java/com/onarandombox/MultiverseCore/worldnew/config/WorldConfigNodes.java index 482a9437..12bfc65d 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/worldnew/config/WorldConfigNodes.java +++ b/src/main/java/com/onarandombox/MultiverseCore/worldnew/config/WorldConfigNodes.java @@ -1,10 +1,8 @@ package com.onarandombox.MultiverseCore.worldnew.config; import com.onarandombox.MultiverseCore.configuration.node.ConfigNode; -import com.onarandombox.MultiverseCore.configuration.node.EnumNodeSerializer; import com.onarandombox.MultiverseCore.configuration.node.Node; import com.onarandombox.MultiverseCore.configuration.node.NodeGroup; -import com.onarandombox.MultiverseCore.configuration.node.NodeSerializer; import com.onarandombox.MultiverseCore.world.configuration.AllowedPortalType; import org.bukkit.Difficulty; import org.bukkit.GameMode; @@ -14,8 +12,6 @@ import java.util.ArrayList; import java.util.List; public class WorldConfigNodes { - private static final NodeSerializer ENUM_NODE_SERIALIZER = new EnumNodeSerializer<>(); - private final NodeGroup nodes = new NodeGroup(); WorldConfigNodes() { @@ -63,19 +59,16 @@ public class WorldConfigNodes { public final ConfigNode DIFFICULTY = node(ConfigNode.builder("difficulty", Difficulty.class) .defaultValue(Difficulty.NORMAL) .name("difficulty") - .serializer((NodeSerializer) ENUM_NODE_SERIALIZER) .build()); public final ConfigNode ENVIRONMENT = node(ConfigNode.builder("environment", World.Environment.class) .defaultValue(World.Environment.NORMAL) .name("environment") - .serializer((NodeSerializer) ENUM_NODE_SERIALIZER) .build()); public final ConfigNode GAMEMODE = node(ConfigNode.builder("gamemode", GameMode.class) .defaultValue(GameMode.SURVIVAL) .name("gamemode") - .serializer((NodeSerializer) ENUM_NODE_SERIALIZER) .build()); public final ConfigNode GENERATOR = node(ConfigNode.builder("generator", String.class) @@ -106,7 +99,6 @@ public class WorldConfigNodes { public final ConfigNode PORTAL_FORM = node(ConfigNode.builder("portal-form", AllowedPortalType.class) .defaultValue(AllowedPortalType.ALL) .name("portal-form") - .serializer((NodeSerializer) ENUM_NODE_SERIALIZER) .build()); public final ConfigNode PVP = node(ConfigNode.builder("pvp", Boolean.class) From aa412b10608bdbe2049f7d9fa905e216ffbe3c5c Mon Sep 17 00:00:00 2001 From: Ben Woo <30431861+benwoo1110@users.noreply.github.com> Date: Thu, 31 Aug 2023 15:17:51 +0800 Subject: [PATCH 06/11] Add todo for loading worlds --- .../java/com/onarandombox/MultiverseCore/MultiverseCore.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/onarandombox/MultiverseCore/MultiverseCore.java b/src/main/java/com/onarandombox/MultiverseCore/MultiverseCore.java index 798abc13..dece119b 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/MultiverseCore.java +++ b/src/main/java/com/onarandombox/MultiverseCore/MultiverseCore.java @@ -129,7 +129,7 @@ public class MultiverseCore extends JavaPlugin implements MVCore { } var newWorldManager = newWorldManagerProvider.get(); - newWorldManager.loadAllWorlds(); + newWorldManager.loadAllWorlds(); // TODO: Possibly move this to constructor of WorldManager //Setup economy here so vault is loaded this.loadEconomist(); From 5fca5b18b8e5b89acf29a8703418f719e59ddcef Mon Sep 17 00:00:00 2001 From: Ben Woo <30431861+benwoo1110@users.noreply.github.com> Date: Thu, 31 Aug 2023 22:58:33 +0800 Subject: [PATCH 07/11] Remove from commands and add to tests --- .../commands/CreateCommand.java | 8 +----- .../commands/DeleteCommand.java | 6 +--- .../multiverse/core/world/WorldManagerTest.kt | 28 +++++++++++++++++++ 3 files changed, 30 insertions(+), 12 deletions(-) create mode 100644 src/test/java/org/mvplugins/multiverse/core/world/WorldManagerTest.kt diff --git a/src/main/java/com/onarandombox/MultiverseCore/commands/CreateCommand.java b/src/main/java/com/onarandombox/MultiverseCore/commands/CreateCommand.java index f5ee8c81..271c61f5 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/commands/CreateCommand.java +++ b/src/main/java/com/onarandombox/MultiverseCore/commands/CreateCommand.java @@ -26,7 +26,6 @@ import com.onarandombox.MultiverseCore.commandtools.flags.CommandValueFlag; import com.onarandombox.MultiverseCore.commandtools.flags.ParsedCommandFlags; import com.onarandombox.MultiverseCore.utils.MVCorei18n; import com.onarandombox.MultiverseCore.utils.UnsafeCallWrapper; -import com.onarandombox.MultiverseCore.worldnew.WorldManager; import jakarta.inject.Inject; import org.bukkit.Bukkit; import org.bukkit.World; @@ -40,19 +39,16 @@ import org.jvnet.hk2.annotations.Service; public class CreateCommand extends MultiverseCommand { private final MVWorldManager worldManager; - private final WorldManager newWorldManager; @Inject public CreateCommand( @NotNull MVCommandManager commandManager, @NotNull MVWorldManager worldManager, - @NotNull UnsafeCallWrapper unsafeCallWrapper, - @NotNull WorldManager newWorldManager + @NotNull UnsafeCallWrapper unsafeCallWrapper ) { super(commandManager); this.worldManager = worldManager; - this.newWorldManager = newWorldManager; registerFlagGroup(CommandFlagGroup.builder("mvcreate") .add(CommandValueFlag.builder("--seed", String.class) @@ -116,8 +112,6 @@ public class CreateCommand extends MultiverseCommand { issuer.sendInfo(MVCorei18n.CREATE_LOADING); - newWorldManager.addWorld(worldName); - if (!worldManager.addWorld( worldName, environment, diff --git a/src/main/java/com/onarandombox/MultiverseCore/commands/DeleteCommand.java b/src/main/java/com/onarandombox/MultiverseCore/commands/DeleteCommand.java index ca6c767b..0dfe37f9 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/commands/DeleteCommand.java +++ b/src/main/java/com/onarandombox/MultiverseCore/commands/DeleteCommand.java @@ -15,7 +15,6 @@ import com.onarandombox.MultiverseCore.commandtools.MVCommandManager; import com.onarandombox.MultiverseCore.commandtools.MultiverseCommand; import com.onarandombox.MultiverseCore.commandtools.queue.QueuedCommand; import com.onarandombox.MultiverseCore.utils.MVCorei18n; -import com.onarandombox.MultiverseCore.worldnew.WorldManager; import jakarta.inject.Inject; import org.jetbrains.annotations.NotNull; import org.jvnet.hk2.annotations.Service; @@ -25,13 +24,11 @@ import org.jvnet.hk2.annotations.Service; public class DeleteCommand extends MultiverseCommand { private final MVWorldManager worldManager; - private final WorldManager newWorldManager; @Inject - public DeleteCommand(@NotNull MVCommandManager commandManager, @NotNull MVWorldManager worldManager, @NotNull WorldManager newWorldManager) { + public DeleteCommand(@NotNull MVCommandManager commandManager, @NotNull MVWorldManager worldManager) { super(commandManager); this.worldManager = worldManager; - this.newWorldManager = newWorldManager; } @Subcommand("delete") @@ -51,7 +48,6 @@ public class DeleteCommand extends MultiverseCommand { issuer.getIssuer(), () -> { issuer.sendInfo(MVCorei18n.DELETE_DELETING, "{world}", worldName); - this.newWorldManager.deleteWorld(worldName); if (!this.worldManager.deleteWorld(worldName)) { issuer.sendError(MVCorei18n.DELETE_FAILED, "{world}", worldName); return; diff --git a/src/test/java/org/mvplugins/multiverse/core/world/WorldManagerTest.kt b/src/test/java/org/mvplugins/multiverse/core/world/WorldManagerTest.kt new file mode 100644 index 00000000..0fd856cd --- /dev/null +++ b/src/test/java/org/mvplugins/multiverse/core/world/WorldManagerTest.kt @@ -0,0 +1,28 @@ +package org.mvplugins.multiverse.core.world + +import com.onarandombox.MultiverseCore.worldnew.WorldManager +import org.mvplugins.multiverse.core.TestWithMockBukkit +import kotlin.test.BeforeTest +import kotlin.test.Test + +class WorldManagerTest : TestWithMockBukkit() { + private lateinit var worldManager: WorldManager + + @BeforeTest + fun setUp() { + worldManager = multiverseCore.getService(WorldManager::class.java).takeIf { it != null } ?: run { + throw IllegalStateException("WorldManager is not available as a service") } + } + + @Test + fun `Add world`() { + worldManager.addWorld("world") + // TODO: When logic is implemented, check that the world is added + } + + @Test + fun `Delete world`() { + worldManager.deleteWorld("world") + // TODO: When logic is implemented, check that the world is removed + } +} From 02b02530bd681d423d73d05f1b599388dc099a70 Mon Sep 17 00:00:00 2001 From: Ben Woo <30431861+benwoo1110@users.noreply.github.com> Date: Thu, 31 Aug 2023 23:02:19 +0800 Subject: [PATCH 08/11] Revert delete command changes --- .../MultiverseCore/commands/DeleteCommand.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/onarandombox/MultiverseCore/commands/DeleteCommand.java b/src/main/java/com/onarandombox/MultiverseCore/commands/DeleteCommand.java index 0dfe37f9..4a1f1c51 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/commands/DeleteCommand.java +++ b/src/main/java/com/onarandombox/MultiverseCore/commands/DeleteCommand.java @@ -47,12 +47,15 @@ public class DeleteCommand extends MultiverseCommand { this.commandManager.getCommandQueueManager().addToQueue(new QueuedCommand( issuer.getIssuer(), () -> { - issuer.sendInfo(MVCorei18n.DELETE_DELETING, "{world}", worldName); + issuer.sendInfo(MVCorei18n.DELETE_DELETING, + "{world}", worldName); if (!this.worldManager.deleteWorld(worldName)) { - issuer.sendError(MVCorei18n.DELETE_FAILED, "{world}", worldName); + issuer.sendError(MVCorei18n.DELETE_FAILED, + "{world}", worldName); return; } - issuer.sendInfo(MVCorei18n.DELETE_SUCCESS, "{world}", worldName); + issuer.sendInfo(MVCorei18n.DELETE_SUCCESS, + "{world}", worldName); }, this.commandManager.formatMessage( issuer, From 904bd8634a24ca7c9ee7065fa1efeeca66be3c5d Mon Sep 17 00:00:00 2001 From: Ben Woo <30431861+benwoo1110@users.noreply.github.com> Date: Thu, 31 Aug 2023 23:21:27 +0800 Subject: [PATCH 09/11] Improve tests for world config file --- .../core/world/WorldConfigFileTest.kt | 69 +++++++++++++++++++ .../multiverse/core/world/WorldConfigTest.kt | 55 +++++++-------- .../multiverse/core/world/WorldManagerTest.kt | 3 +- src/test/resources/default_worlds.yml | 2 +- src/test/resources/newworld_worlds.yml | 2 +- 5 files changed, 98 insertions(+), 33 deletions(-) create mode 100644 src/test/java/org/mvplugins/multiverse/core/world/WorldConfigFileTest.kt diff --git a/src/test/java/org/mvplugins/multiverse/core/world/WorldConfigFileTest.kt b/src/test/java/org/mvplugins/multiverse/core/world/WorldConfigFileTest.kt new file mode 100644 index 00000000..31d83841 --- /dev/null +++ b/src/test/java/org/mvplugins/multiverse/core/world/WorldConfigFileTest.kt @@ -0,0 +1,69 @@ +package org.mvplugins.multiverse.core.world + +import com.onarandombox.MultiverseCore.worldnew.config.WorldConfig +import com.onarandombox.MultiverseCore.worldnew.config.WorldsConfigFile +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertTrue +import org.mvplugins.multiverse.core.TestWithMockBukkit +import java.io.File +import java.nio.file.Path +import kotlin.io.path.absolutePathString +import kotlin.test.BeforeTest +import kotlin.test.Test +import kotlin.test.assertNotNull + +class WorldConfigFileTest : TestWithMockBukkit() { + + private lateinit var worldConfigFile : WorldsConfigFile + + @BeforeTest + fun setUp() { + val defaultConfig = getResourceAsText("/default_worlds.yml") + assertNotNull(defaultConfig) + File(Path.of(multiverseCore.dataFolder.absolutePath, "worlds2.yml").absolutePathString()).writeText(defaultConfig) + + worldConfigFile = WorldsConfigFile(multiverseCore) + worldConfigFile.load() + } + + + @Test + fun `World config is loaded`() { + assertTrue(worldConfigFile.isLoaded) + } + + @Test + fun `Old world config is migrated`() { + // TODO: When logic is implemented, check that the old config is migrated + } + + @Test + fun `Add a new world to config`() { + val worldConfig = WorldConfig(worldConfigFile.getWorldConfigSection("newworld")) + worldConfigFile.save() + compareConfigFile("worlds2.yml", "/newworld_worlds.yml") + } + + @Test + fun `Updating existing world properties`() { + val worldConfig = WorldConfig(worldConfigFile.getWorldConfigSection("world")) + worldConfig.setProperty("adjust-spawn", true) + worldConfig.setProperty("alias", "newalias") + worldConfigFile.save() + compareConfigFile("worlds2.yml", "/properties_worlds.yml") + } + + @Test + fun `Delete world section from config`() { + worldConfigFile.deleteWorldConfigSection("world") + worldConfigFile.save() + compareConfigFile("worlds2.yml", "/delete_worlds.yml") + } + + private fun compareConfigFile(configPath: String, comparePath: String) { + val config = multiverseCore.dataFolder.toPath().resolve(configPath).toFile().readText() + val configCompare = getResourceAsText(comparePath) + assertNotNull(configCompare) + assertEquals(configCompare, config) + } +} \ No newline at end of file diff --git a/src/test/java/org/mvplugins/multiverse/core/world/WorldConfigTest.kt b/src/test/java/org/mvplugins/multiverse/core/world/WorldConfigTest.kt index e0113e70..5d57836b 100644 --- a/src/test/java/org/mvplugins/multiverse/core/world/WorldConfigTest.kt +++ b/src/test/java/org/mvplugins/multiverse/core/world/WorldConfigTest.kt @@ -15,6 +15,7 @@ import kotlin.test.assertTrue class WorldConfigTest : TestWithMockBukkit() { private lateinit var worldConfigFile : WorldsConfigFile + private lateinit var worldConfig : WorldConfig @BeforeTest fun setUp() { @@ -24,52 +25,46 @@ class WorldConfigTest : TestWithMockBukkit() { worldConfigFile = WorldsConfigFile(multiverseCore) worldConfigFile.load() + worldConfig = WorldConfig(worldConfigFile.getWorldConfigSection("world")) } @Test - fun `World config is loaded`() { - assertTrue(worldConfigFile.isLoaded) + fun `Getting existing world property with getProperty returns expected value`() { + assertEquals("my world", worldConfig.getProperty("alias").get()) + assertEquals(false, worldConfig.getProperty("hidden").get()) } @Test - fun `Old world config is migrated`() { - // TODO + fun `Getting non-existing world property with getProperty returns null`() { + assertTrue(worldConfig.getProperty("invalid-property").isFailure) + assertTrue(worldConfig.getProperty("version").isFailure) } @Test - fun `Add a new world to config`() { - val worldConfig = WorldConfig(worldConfigFile.getWorldConfigSection("newworld")) - worldConfigFile.save() - - compareConfigFile("worlds2.yml", "/newworld_worlds.yml") + fun `Getting existing world property by getter returns expected value`() { + assertEquals("my world", worldConfig.alias) + assertEquals(false, worldConfig.isHidden) } @Test - fun `Updating existing world properties`() { - val worldConfig = WorldConfig(worldConfigFile.getWorldConfigSection("world")) - worldConfig.setProperty("adjust-spawn", true) - worldConfig.setProperty("alias", "newalias") - - worldConfigFile.save() - + fun `Updating an existing world property with setProperty reflects the changes in getProperty`() { + assertTrue(worldConfig.setProperty("adjust-spawn", true).isSuccess) assertEquals(true, worldConfig.getProperty("adjust-spawn").get()) - assertEquals("newalias", worldConfig.getProperty("alias").get()) - compareConfigFile("worlds2.yml", "/properties_worlds.yml") + assertTrue(worldConfig.setProperty("alias", "abc").isSuccess) + assertEquals("abc", worldConfig.getProperty("alias").get()) + + assertTrue(worldConfig.setProperty("scale", 2.0).isSuccess) + assertEquals(2.0, worldConfig.getProperty("scale").get()) + + val blacklists = listOf("a", "b", "c") + assertTrue(worldConfig.setProperty("world-blacklist", blacklists).isSuccess) + assertEquals(blacklists, worldConfig.getProperty("world-blacklist").get()) } @Test - fun `Delete world section from config`() { - worldConfigFile.deleteWorldConfigSection("world") - worldConfigFile.save() - - compareConfigFile("worlds2.yml", "/delete_worlds.yml") - } - - private fun compareConfigFile(configPath: String, comparePath: String) { - val config = multiverseCore.dataFolder.toPath().resolve(configPath).toFile().readText() - val configCompare = getResourceAsText(comparePath) - assertNotNull(configCompare) - assertEquals(configCompare, config) + fun `Updating a non-existing property with setProperty returns false`() { + assertTrue(worldConfig.setProperty("invalid-property", false).isFailure) + assertTrue(worldConfig.setProperty("version", 1.1).isFailure) } } diff --git a/src/test/java/org/mvplugins/multiverse/core/world/WorldManagerTest.kt b/src/test/java/org/mvplugins/multiverse/core/world/WorldManagerTest.kt index 0fd856cd..2366c62d 100644 --- a/src/test/java/org/mvplugins/multiverse/core/world/WorldManagerTest.kt +++ b/src/test/java/org/mvplugins/multiverse/core/world/WorldManagerTest.kt @@ -5,7 +5,8 @@ import org.mvplugins.multiverse.core.TestWithMockBukkit import kotlin.test.BeforeTest import kotlin.test.Test -class WorldManagerTest : TestWithMockBukkit() { +class WorldManagerTest : TestWithMockBukkit() { + private lateinit var worldManager: WorldManager @BeforeTest diff --git a/src/test/resources/default_worlds.yml b/src/test/resources/default_worlds.yml index 631963b1..37f8528b 100644 --- a/src/test/resources/default_worlds.yml +++ b/src/test/resources/default_worlds.yml @@ -1,6 +1,6 @@ world: adjust-spawn: false - alias: '' + alias: my world allow-flight: false allow-weather: true auto-heal: true diff --git a/src/test/resources/newworld_worlds.yml b/src/test/resources/newworld_worlds.yml index 7852a07e..745cc596 100644 --- a/src/test/resources/newworld_worlds.yml +++ b/src/test/resources/newworld_worlds.yml @@ -1,6 +1,6 @@ world: adjust-spawn: false - alias: '' + alias: my world allow-flight: false allow-weather: true auto-heal: true From 55fd08e0b10e1c4a4a34c67330d1314531f04fd7 Mon Sep 17 00:00:00 2001 From: Ben Woo <30431861+benwoo1110@users.noreply.github.com> Date: Thu, 31 Aug 2023 23:22:23 +0800 Subject: [PATCH 10/11] Remove stray white spacing --- .../org/mvplugins/multiverse/core/world/WorldConfigFileTest.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/org/mvplugins/multiverse/core/world/WorldConfigFileTest.kt b/src/test/java/org/mvplugins/multiverse/core/world/WorldConfigFileTest.kt index 31d83841..191ea69d 100644 --- a/src/test/java/org/mvplugins/multiverse/core/world/WorldConfigFileTest.kt +++ b/src/test/java/org/mvplugins/multiverse/core/world/WorldConfigFileTest.kt @@ -26,7 +26,6 @@ class WorldConfigFileTest : TestWithMockBukkit() { worldConfigFile.load() } - @Test fun `World config is loaded`() { assertTrue(worldConfigFile.isLoaded) From 5208028e6530c10e435018b1ff6cc7da87a4fafc Mon Sep 17 00:00:00 2001 From: Ben Woo <30431861+benwoo1110@users.noreply.github.com> Date: Thu, 31 Aug 2023 23:25:30 +0800 Subject: [PATCH 11/11] Add todo on comparing config file --- .../org/mvplugins/multiverse/core/world/WorldConfigFileTest.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/java/org/mvplugins/multiverse/core/world/WorldConfigFileTest.kt b/src/test/java/org/mvplugins/multiverse/core/world/WorldConfigFileTest.kt index 191ea69d..cea40d17 100644 --- a/src/test/java/org/mvplugins/multiverse/core/world/WorldConfigFileTest.kt +++ b/src/test/java/org/mvplugins/multiverse/core/world/WorldConfigFileTest.kt @@ -60,6 +60,7 @@ class WorldConfigFileTest : TestWithMockBukkit() { } private fun compareConfigFile(configPath: String, comparePath: String) { + // TODO: Map keys may not guaranteed order. Potentially look at Hamkrest and assertThat. val config = multiverseCore.dataFolder.toPath().resolve(configPath).toFile().readText() val configCompare = getResourceAsText(comparePath) assertNotNull(configCompare)