diff --git a/src/main/java/org/mvplugins/multiverse/core/world/WorldsConfigManager.java b/src/main/java/org/mvplugins/multiverse/core/world/WorldsConfigManager.java index 5d25dcea3..23361271f 100644 --- a/src/main/java/org/mvplugins/multiverse/core/world/WorldsConfigManager.java +++ b/src/main/java/org/mvplugins/multiverse/core/world/WorldsConfigManager.java @@ -84,7 +84,7 @@ private void migrateRemoveOldConfigSerializable() { Path oldWorldConfig = worldConfigFile.toPath().getParent().resolve(CONFIG_FILENAME + ".old"); Files.copy(worldConfigFile.toPath(), oldWorldConfig, COPY_ATTRIBUTES); - return configData.replace("==: MVWorld", "") + return configData.replace("==: MVWorld", "w@: world") .replace("==: MVSpawnSettings", "") .replace("==: MVSpawnSubSettings", "") .replace("==: MVEntryFee", ""); @@ -92,16 +92,26 @@ private void migrateRemoveOldConfigSerializable() { .andThenTry(configData -> Files.writeString(worldConfigFile.toPath(), configData)) .andThenTry(() -> { YamlConfiguration config = YamlConfiguration.loadConfiguration(worldConfigFile); - List worlds = config.getConfigurationSection("worlds") - .getKeys(false) - .stream() - .map(worldName -> config.getConfigurationSection("worlds." + worldName)) - .toList(); + + ConfigurationSection worldsSection = config.getConfigurationSection("worlds"); + if (worldsSection == null) { + worldsSection = config.createSection("worlds"); + } + + List worldNames = getOldConfigWorldNames(worldsSection); + + Map worldConfigMap = new HashMap<>(); + for (String worldName : worldNames) { + ConfigurationSection worldSection = worldsSection.getConfigurationSection(worldName); + if (worldSection != null) { + worldConfigMap.put(worldName, worldSection); + } + } config.set("worlds", null); - for (ConfigurationSection world : worlds) { - config.createSection(world.getName(), world.getValues(true)); + for (Map.Entry entry : worldConfigMap.entrySet()) { + config.set(encodeWorldName(entry.getKey()), entry.getValue()); } config.save(worldConfigFile); }) @@ -115,6 +125,35 @@ private void migrateRemoveOldConfigSerializable() { }); } + private @NotNull List getOldConfigWorldNames(ConfigurationSection worldsSection) { + List worldNames = new ArrayList<>(); + recursiveGetOldConfigWorldNames(worldsSection, worldNames); + return worldNames; + } + + private void recursiveGetOldConfigWorldNames(ConfigurationSection section, List worldNames) { + Set keys = section.getKeys(false); + if (keys.isEmpty()) { + // No keys in this section, nothing to do + return; + } + + if (keys.contains("w@")) { + // this is the world data section already, get path without the "worlds." prefix + worldNames.add(section.getCurrentPath().substring(7)); + return; + } + + for (String key : keys) { + ConfigurationSection dataSection = section.getConfigurationSection(key); + if (dataSection == null) { + // Something is wrong with the config, skip this key + continue; + } + recursiveGetOldConfigWorldNames(dataSection, worldNames); + } + } + /** * Parses the worlds.yml file and creates a WorldConfig for each world in the file if it doesn't already exist. * diff --git a/src/test/java/org/mvplugins/multiverse/core/world/WorldConfigMangerTest.kt b/src/test/java/org/mvplugins/multiverse/core/world/WorldConfigMangerTest.kt index 6af67ce2f..86d6b7e92 100644 --- a/src/test/java/org/mvplugins/multiverse/core/world/WorldConfigMangerTest.kt +++ b/src/test/java/org/mvplugins/multiverse/core/world/WorldConfigMangerTest.kt @@ -49,7 +49,7 @@ class WorldConfigMangerTest : TestWithMockBukkit() { assertEquals(MVEconomist.VAULT_ECONOMY_MATERIAL, endWorldConfig.entryFeeCurrency) assertEquals(0.0, endWorldConfig.entryFeeAmount) - val worldConfig = worldConfigManager.getWorldConfig("world").orNull + val worldConfig = worldConfigManager.getWorldConfig("world.a.b").orNull assertNotNull(worldConfig) assertEquals(-5176596003035866649, worldConfig.seed) @@ -58,6 +58,9 @@ class WorldConfigMangerTest : TestWithMockBukkit() { assertEquals(Material.DIRT, worldConfig.entryFeeCurrency) assertEquals(5.0, worldConfig.entryFeeAmount) + val world2Config = worldConfigManager.getWorldConfig("world.a.c").orNull + assertNotNull(world2Config) + assertConfigEquals("/worlds/migrated_worlds.yml", "worlds.yml") } diff --git a/src/test/resources/worlds/migrated_worlds.yml b/src/test/resources/worlds/migrated_worlds.yml index 686abd2ec..b6cae3de3 100644 --- a/src/test/resources/worlds/migrated_worlds.yml +++ b/src/test/resources/worlds/migrated_worlds.yml @@ -46,7 +46,7 @@ world_the_end: tick-rate: -1 world-blacklist: [] version: 1.2 -world: +world[dot]a[dot]b: adjust-spawn: true alias: '' allow-advancement-grant: true @@ -95,3 +95,52 @@ world: world-blacklist: - test version: 1.2 +world[dot]a[dot]c: + adjust-spawn: true + alias: '' + allow-advancement-grant: true + allow-flight: false + allow-weather: true + anchor-respawn: true + auto-heal: true + auto-load: true + bed-respawn: true + difficulty: normal + entry-fee: + enabled: true + amount: 5.0 + currency: DIRT + environment: normal + gamemode: survival + biome: '' + generator: '' + hidden: false + hunger: true + keep-spawn-in-memory: true + player-limit: -1 + portal-form: all + pvp: true + respawn-world: '' + scale: 1.0 + seed: -5176596003035866649 + spawn-location: + ==: MVSpawnLocation + x: -64.0 + y: 64.0 + z: 48.0 + pitch: 0.0 + yaw: 0.0 + spawning: + animal: + exceptions: [ ] + spawn: true + spawn-limit: -1 + tick-rate: -1 + monster: + exceptions: [ ] + spawn: true + spawn-limit: -1 + tick-rate: -1 + world-blacklist: + - test + version: 1.2 diff --git a/src/test/resources/worlds/old_worlds.yml b/src/test/resources/worlds/old_worlds.yml index 2c592f60f..cc222d7a6 100644 --- a/src/test/resources/worlds/old_worlds.yml +++ b/src/test/resources/worlds/old_worlds.yml @@ -46,7 +46,7 @@ worlds: generator: 'null' playerLimit: '-1' allowFlight: 'true' - world: + world.a.b: ==: MVWorld hidden: 'false' alias: '' @@ -95,3 +95,52 @@ worlds: generator: 'null' playerLimit: '-1' allowFlight: 'false' + world.a.c: + ==: MVWorld + hidden: 'false' + alias: '' + color: WHITE + style: NORMAL + pvp: 'true' + scale: '1.0' + respawnWorld: '' + allowWeather: 'true' + difficulty: NORMAL + spawning: + ==: MVSpawnSettings + animals: + ==: MVSpawnSubSettings + spawn: 'true' + spawnrate: '-1' + exceptions: [] + monsters: + ==: MVSpawnSubSettings + spawn: 'true' + spawnrate: '-1' + exceptions: [] + entryfee: + ==: MVEntryFee + amount: '5.0' + currency: 'DIRT' + hunger: 'true' + autoHeal: 'true' + adjustSpawn: 'true' + portalForm: ALL + gameMode: SURVIVAL + keepSpawnInMemory: 'true' + spawnLocation: + ==: MVSpawnLocation + x: -64.0 + y: 64.0 + z: 48.0 + pitch: 0.0 + yaw: 0.0 + autoLoad: 'true' + bedRespawn: 'true' + worldBlacklist: + - test + environment: NORMAL + seed: '-5176596003035866649' + generator: 'null' + playerLimit: '-1' + allowFlight: 'false' \ No newline at end of file