From c29c8d6e72e5284489103719bcd025ec0e66e9f1 Mon Sep 17 00:00:00 2001 From: Yeregorix Date: Mon, 10 May 2021 21:45:37 +0200 Subject: [PATCH] New config system: WorldMap 1.0.0 --- build.gradle | 3 + .../superpiston/SuperPiston.java | 97 +++++++------------ .../superpiston/config/world/WorldConfig.java | 37 ++++++- ...EventListener.java => PistonListener.java} | 13 ++- .../superpiston/util/IOUtil.java | 34 +++++-- 5 files changed, 105 insertions(+), 79 deletions(-) rename src/main/java/net/smoofyuniverse/superpiston/event/{WorldEventListener.java => PistonListener.java} (81%) diff --git a/build.gradle b/build.gradle index 0aba2a0..a7ce96c 100644 --- a/build.gradle +++ b/build.gradle @@ -74,6 +74,7 @@ repositories { dependencies { compile 'org.spongepowered:spongecommon:1.12.2-7.3.0:dev' compile 'net.smoofyuniverse:oreupdater:1.0.1' + compile 'net.smoofyuniverse:worldmap:1.0.0' } jar { @@ -99,9 +100,11 @@ shadowJar { dependencies { include dependency('net.smoofyuniverse:oreapi') include dependency('net.smoofyuniverse:oreupdater') + include dependency('net.smoofyuniverse:worldmap') } relocate 'net.smoofyuniverse.ore', 'net.smoofyuniverse.superpiston.ore' + relocate 'net.smoofyuniverse.map', 'net.smoofyuniverse.autopickup.map' exclude "dummyThing" afterEvaluate { diff --git a/src/main/java/net/smoofyuniverse/superpiston/SuperPiston.java b/src/main/java/net/smoofyuniverse/superpiston/SuperPiston.java index 3e5c82a..1f02c1f 100644 --- a/src/main/java/net/smoofyuniverse/superpiston/SuperPiston.java +++ b/src/main/java/net/smoofyuniverse/superpiston/SuperPiston.java @@ -23,21 +23,21 @@ package net.smoofyuniverse.superpiston; import com.google.inject.Inject; +import net.smoofyuniverse.map.WorldMap; +import net.smoofyuniverse.map.WorldMapLoader; import net.smoofyuniverse.ore.update.UpdateChecker; import net.smoofyuniverse.superpiston.config.world.WorldConfig; -import net.smoofyuniverse.superpiston.event.WorldEventListener; +import net.smoofyuniverse.superpiston.config.world.WorldConfig.Immutable; +import net.smoofyuniverse.superpiston.event.PistonListener; import net.smoofyuniverse.superpiston.impl.internal.InternalServer; import net.smoofyuniverse.superpiston.util.IOUtil; -import ninja.leaping.configurate.ConfigurationNode; -import ninja.leaping.configurate.commented.CommentedConfigurationNode; -import ninja.leaping.configurate.hocon.HoconConfigurationLoader; -import ninja.leaping.configurate.loader.ConfigurationLoader; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.spongepowered.api.Game; import org.spongepowered.api.config.ConfigDir; import org.spongepowered.api.event.Listener; import org.spongepowered.api.event.game.GameReloadEvent; +import org.spongepowered.api.event.game.state.GameInitializationEvent; import org.spongepowered.api.event.game.state.GamePreInitializationEvent; import org.spongepowered.api.event.game.state.GameStartedServerEvent; import org.spongepowered.api.plugin.Plugin; @@ -47,11 +47,6 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; - -import static net.smoofyuniverse.superpiston.util.MathUtil.clamp; @Plugin(id = "superpiston", name = "SuperPiston", version = "1.0.7", authors = "Yeregorix", description = "Allows to modify vanilla pistons") public class SuperPiston { @@ -66,9 +61,8 @@ public class SuperPiston { @Inject private PluginContainer container; - private Path worldConfigsDir; - - private final Map configs = new HashMap<>(); + private WorldMapLoader configMapLoader; + private WorldMap configMap; public SuperPiston() { if (instance != null) @@ -78,61 +72,46 @@ public SuperPiston() { @Listener public void onGamePreInit(GamePreInitializationEvent e) { - this.worldConfigsDir = this.configDir.resolve("worlds"); try { - Files.createDirectories(this.worldConfigsDir); + Files.createDirectories(this.configDir); } catch (IOException ignored) { } - this.game.getEventManager().registerListeners(this, new WorldEventListener()); - - this.game.getEventManager().registerListeners(this, new UpdateChecker(LOGGER, this.container, - createConfigLoader(this.configDir.resolve("update.conf")), "Yeregorix", "SuperPiston")); + this.configMapLoader = new WorldMapLoader(LOGGER, + IOUtil.createConfigLoader(this.configDir.resolve("map.conf")), + this.configDir.resolve("configs"), WorldConfig.VANILLA) { + @Override + protected WorldConfig.Immutable loadConfig(Path file) throws Exception { + return WorldConfig.load(file).toImmutable(); + } + }; } @Listener - public void onGameReload(GameReloadEvent e) { - this.configs.clear(); - this.game.getServer().getWorlds().forEach(this::loadConfig); - } - - public void loadConfig(World world) { - String name = world.getName(); - - LOGGER.info("Loading configuration for world " + name + " .."); - try { - Path file = this.worldConfigsDir.resolve(name + ".conf"); - ConfigurationLoader loader = createConfigLoader(file); - - CommentedConfigurationNode root = loader.load(); - int version = root.getNode("Version").getInt(); - if ((version > WorldConfig.CURRENT_VERSION || version < WorldConfig.MINIMUM__VERSION) && IOUtil.backupFile(file)) { - LOGGER.info("Your config version is not supported. A new one will be generated."); - root = loader.createEmptyNode(); - } + public void onGameInit(GameInitializationEvent e) { + loadConfigs(); - ConfigurationNode cfgNode = root.getNode("Config"); - WorldConfig cfg = cfgNode.getValue(WorldConfig.TOKEN, new WorldConfig()); + this.game.getEventManager().registerListeners(this, new PistonListener(this)); - if (cfg.blockReactions == null) - cfg.blockReactions = new HashMap<>(); - - if (cfg.stickyBlocks == null) - cfg.stickyBlocks = new HashMap<>(); - - cfg.maxBlocks = clamp(cfg.maxBlocks, 1, 500); - - version = WorldConfig.CURRENT_VERSION; - root.getNode("Version").setValue(version); - cfgNode.setValue(WorldConfig.TOKEN, cfg); - loader.save(root); + this.game.getEventManager().registerListeners(this, new UpdateChecker(LOGGER, this.container, + IOUtil.createConfigLoader(this.configDir.resolve("update.conf")), "Yeregorix", "SuperPiston")); + } - this.configs.put(name, cfg.toImmutable()); - } catch (Exception e) { - LOGGER.error("Failed to load configuration for world " + name, e); + private void loadConfigs() { + if (Files.exists(this.configDir.resolve("worlds")) && Files.notExists(this.configDir.resolve("map.conf"))) { + LOGGER.info("Updating config directory structure ..."); + Path worlds = IOUtil.backup(this.configDir).orElse(this.configDir).resolve("worlds"); + this.configMap = this.configMapLoader.importWorlds(worlds); + } else { + this.configMap = this.configMapLoader.load(); } } + @Listener + public void onGameReload(GameReloadEvent e) { + loadConfigs(); + } + @Listener public void onServerStarted(GameStartedServerEvent e) { if (this.game.getServer() instanceof InternalServer) @@ -141,12 +120,8 @@ public void onServerStarted(GameStartedServerEvent e) { LOGGER.error("!!WARNING!! SuperPiston was not loaded correctly. Be sure that the jar file is at the root of your mods folder!"); } - public ConfigurationLoader createConfigLoader(Path file) { - return HoconConfigurationLoader.builder().setPath(file).build(); - } - - public Optional getConfig(World world) { - return Optional.ofNullable(this.configs.get(world.getName())); + public WorldConfig.Immutable getConfig(World world) { + return this.configMap.get(world.getProperties()); } public PluginContainer getContainer() { diff --git a/src/main/java/net/smoofyuniverse/superpiston/config/world/WorldConfig.java b/src/main/java/net/smoofyuniverse/superpiston/config/world/WorldConfig.java index 332aed0..eb0cffb 100644 --- a/src/main/java/net/smoofyuniverse/superpiston/config/world/WorldConfig.java +++ b/src/main/java/net/smoofyuniverse/superpiston/config/world/WorldConfig.java @@ -24,22 +24,34 @@ import com.google.common.collect.ImmutableMap; import com.google.common.reflect.TypeToken; +import net.smoofyuniverse.superpiston.SuperPiston; import net.smoofyuniverse.superpiston.api.structure.calculator.DefaultStructureCalculator.MovementReaction; +import net.smoofyuniverse.superpiston.util.IOUtil; +import ninja.leaping.configurate.ConfigurationNode; +import ninja.leaping.configurate.commented.CommentedConfigurationNode; +import ninja.leaping.configurate.loader.ConfigurationLoader; +import ninja.leaping.configurate.objectmapping.ObjectMappingException; import ninja.leaping.configurate.objectmapping.Setting; import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable; import org.spongepowered.api.block.BlockState; +import java.io.IOException; +import java.nio.file.Path; +import java.util.HashMap; import java.util.Map; +import static net.smoofyuniverse.superpiston.util.MathUtil.clamp; + @ConfigSerializable public class WorldConfig { public static final int CURRENT_VERSION = 1, MINIMUM__VERSION = 1; public static final TypeToken TOKEN = TypeToken.of(WorldConfig.class); + public static final Immutable VANILLA = new WorldConfig().toImmutable(); @Setting(value = "BlockReactions") - public Map blockReactions; + public Map blockReactions = new HashMap<>(); @Setting(value = "StickyBlocks") - public Map stickyBlocks; + public Map stickyBlocks = new HashMap<>(); @Setting(value = "MaxBlocks") public int maxBlocks = 12; @@ -47,6 +59,27 @@ public Immutable toImmutable() { return new Immutable(this.blockReactions, this.stickyBlocks, this.maxBlocks); } + public static WorldConfig load(Path file) throws IOException, ObjectMappingException { + ConfigurationLoader loader = IOUtil.createConfigLoader(file); + + CommentedConfigurationNode root = loader.load(); + int version = root.getNode("Version").getInt(); + if ((version > CURRENT_VERSION || version < MINIMUM__VERSION) && IOUtil.backup(file).isPresent()) { + SuperPiston.LOGGER.info("Your config version is not supported. A new one will be generated."); + root = loader.createEmptyNode(); + } + + ConfigurationNode cfgNode = root.getNode("Config"); + WorldConfig cfg = cfgNode.getValue(TOKEN, new WorldConfig()); + + cfg.maxBlocks = clamp(cfg.maxBlocks, 1, 500); + + root.getNode("Version").setValue(CURRENT_VERSION); + cfgNode.setValue(TOKEN, cfg); + loader.save(root); + return cfg; + } + public static class Immutable { public final Map blockReactions; public final Map stickyBlocks; diff --git a/src/main/java/net/smoofyuniverse/superpiston/event/WorldEventListener.java b/src/main/java/net/smoofyuniverse/superpiston/event/PistonListener.java similarity index 81% rename from src/main/java/net/smoofyuniverse/superpiston/event/WorldEventListener.java rename to src/main/java/net/smoofyuniverse/superpiston/event/PistonListener.java index 390a8cd..9a8c7c2 100644 --- a/src/main/java/net/smoofyuniverse/superpiston/event/WorldEventListener.java +++ b/src/main/java/net/smoofyuniverse/superpiston/event/PistonListener.java @@ -27,20 +27,19 @@ import net.smoofyuniverse.superpiston.impl.calculator.SuperPistonStructureCalculator; import org.spongepowered.api.event.Listener; import org.spongepowered.api.event.Order; -import org.spongepowered.api.event.world.LoadWorldEvent; import org.spongepowered.api.world.World; -public class WorldEventListener { +public class PistonListener { + private final SuperPiston plugin; - @Listener - public void onLoadWorld(LoadWorldEvent e) { - SuperPiston.get().loadConfig(e.getTargetWorld()); + public PistonListener(SuperPiston plugin) { + this.plugin = plugin; } @Listener(order = Order.FIRST) public void onPreStructureCalculation(PistonStructureCalculationEvent.Pre e) { World world = e.getTargetWorld(); - SuperPiston.get().getConfig(world).ifPresent(config -> - e.setCalculator(new SuperPistonStructureCalculator(world, e.getPiston(), e.getPistonDirection(), e.getPistonMovement(), config))); + e.setCalculator(new SuperPistonStructureCalculator(world, + e.getPiston(), e.getPistonDirection(), e.getPistonMovement(), this.plugin.getConfig(world))); } } diff --git a/src/main/java/net/smoofyuniverse/superpiston/util/IOUtil.java b/src/main/java/net/smoofyuniverse/superpiston/util/IOUtil.java index a5b079f..16b9f96 100644 --- a/src/main/java/net/smoofyuniverse/superpiston/util/IOUtil.java +++ b/src/main/java/net/smoofyuniverse/superpiston/util/IOUtil.java @@ -22,24 +22,40 @@ package net.smoofyuniverse.superpiston.util; +import net.smoofyuniverse.superpiston.SuperPiston; +import ninja.leaping.configurate.commented.CommentedConfigurationNode; +import ninja.leaping.configurate.hocon.HoconConfigurationLoader; +import ninja.leaping.configurate.loader.ConfigurationLoader; + import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.util.Optional; public class IOUtil { - public static boolean backupFile(Path file) throws IOException { + public static ConfigurationLoader createConfigLoader(Path file) { + return HoconConfigurationLoader.builder().setPath(file).build(); + } + + public static Optional backup(Path file) { if (!Files.exists(file)) - return false; + return Optional.empty(); String fn = file.getFileName() + ".backup"; - Path backup = null; - for (int i = 0; i < 100; i++) { - backup = file.resolveSibling(fn + i); - if (!Files.exists(backup)) - break; + Path backup; + int i = 0; + while (Files.exists(backup = file.resolveSibling(fn + i))) { + i++; } - Files.move(file, backup); - return true; + + try { + Files.move(file, backup); + } catch (IOException e) { + SuperPiston.LOGGER.warn("Failed to backup: " + backup, e); + return Optional.empty(); + } + + return Optional.of(backup); } }