diff --git a/src/main/java/com/onarandombox/MultiverseCore/MultiverseCore.java b/src/main/java/com/onarandombox/MultiverseCore/MultiverseCore.java index 03b97e39..acaf568f 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/MultiverseCore.java +++ b/src/main/java/com/onarandombox/MultiverseCore/MultiverseCore.java @@ -122,16 +122,16 @@ public class MultiverseCore extends JavaPlugin implements MVCore { var worldManager = worldManagerProvider.get(); worldManager.loadWorldsConfig(); - worldManager.getDefaultWorldGenerators(); - worldManager.loadDefaultWorlds(); - worldManager.loadWorlds(true); - - // Now set the firstspawnworld (after the worlds are loaded): - worldManager.setFirstSpawnWorld(config.getFirstSpawnLocation()); - MVWorld firstSpawnWorld = worldManager.getFirstSpawnWorld(); - if (firstSpawnWorld != null) { - config.setFirstSpawnLocation(firstSpawnWorld.getName()); - } +// worldManager.getDefaultWorldGenerators(); +// worldManager.loadDefaultWorlds(); +// worldManager.loadWorlds(true); +// +// // Now set the firstspawnworld (after the worlds are loaded): +// worldManager.setFirstSpawnWorld(config.getFirstSpawnLocation()); +// MVWorld firstSpawnWorld = worldManager.getFirstSpawnWorld(); +// if (firstSpawnWorld != null) { +// config.setFirstSpawnLocation(firstSpawnWorld.getName()); +// } var newWorldManager = newWorldManagerProvider.get(); newWorldManager.initAllWorlds(); // TODO: Possibly move this to constructor of WorldManager diff --git a/src/main/java/com/onarandombox/MultiverseCore/listeners/MVWorldInitListener.java b/src/main/java/com/onarandombox/MultiverseCore/listeners/MVWorldInitListener.java deleted file mode 100644 index 5954b1f6..00000000 --- a/src/main/java/com/onarandombox/MultiverseCore/listeners/MVWorldInitListener.java +++ /dev/null @@ -1,33 +0,0 @@ -/****************************************************************************** - * Multiverse 2 Copyright (c) the Multiverse Team 2011. * - * Multiverse 2 is licensed under the BSD License. * - * For more information please check the README.md file included * - * with this project. * - ******************************************************************************/ - -package com.onarandombox.MultiverseCore.listeners; - -import com.onarandombox.MultiverseCore.api.MVWorldManager; -import com.onarandombox.MultiverseCore.inject.InjectableListener; -import jakarta.inject.Inject; -import org.bukkit.event.EventHandler; -import org.bukkit.event.world.WorldInitEvent; -import org.jvnet.hk2.annotations.Service; - -@Service -public class MVWorldInitListener implements InjectableListener { - - private final MVWorldManager worldManager; - - @Inject - public MVWorldInitListener(MVWorldManager worldManager) { - this.worldManager = worldManager; - } - - @EventHandler - public void initWorld(WorldInitEvent event) { - if (!worldManager.isKeepingSpawnInMemory(event.getWorld())) { - event.getWorld().setKeepSpawnInMemory(false); - } - } -} diff --git a/src/main/java/com/onarandombox/MultiverseCore/listeners/MVWorldListener.java b/src/main/java/com/onarandombox/MultiverseCore/listeners/MVWorldListener.java index e533910c..cde05238 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/listeners/MVWorldListener.java +++ b/src/main/java/com/onarandombox/MultiverseCore/listeners/MVWorldListener.java @@ -7,12 +7,16 @@ package com.onarandombox.MultiverseCore.listeners; +import com.dumptruckman.minecraft.util.Logging; import com.onarandombox.MultiverseCore.api.MVWorld; import com.onarandombox.MultiverseCore.api.MVWorldManager; import com.onarandombox.MultiverseCore.inject.InjectableListener; +import com.onarandombox.MultiverseCore.worldnew.WorldManager; import jakarta.inject.Inject; import org.bukkit.World; import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.world.WorldInitEvent; import org.bukkit.event.world.WorldLoadEvent; import org.bukkit.event.world.WorldUnloadEvent; import org.jvnet.hk2.annotations.Service; @@ -23,10 +27,10 @@ import org.jvnet.hk2.annotations.Service; @Service public class MVWorldListener implements InjectableListener { - private MVWorldManager worldManager; + private final WorldManager worldManager; @Inject - public MVWorldListener(MVWorldManager worldManager) { + public MVWorldListener(WorldManager worldManager) { this.worldManager = worldManager; } @@ -34,36 +38,24 @@ public class MVWorldListener implements InjectableListener { * This method is called when Bukkit fires off a WorldUnloadEvent. * @param event The Event that was fired. */ - @EventHandler + @EventHandler(priority = EventPriority.MONITOR) public void unloadWorld(WorldUnloadEvent event) { if (event.isCancelled()) { return; } - if (event.getWorld() instanceof World) { - World world = (World) event.getWorld(); - if (world != null) { - this.worldManager.unloadWorld(world.getName(), false); - } - } + this.worldManager.unloadWorld(event.getWorld()); } /** * This method is called when Bukkit fires off a WorldLoadEvent. * @param event The Event that was fired. */ - @EventHandler + @EventHandler(priority = EventPriority.MONITOR) public void loadWorld(WorldLoadEvent event) { - World world = event.getWorld(); - if (world != null) { - if (this.worldManager.getUnloadedWorlds().contains(world.getName())) { - this.worldManager.loadWorld(world.getName()); - } - MVWorld mvWorld = worldManager.getMVWorld(world); - if (mvWorld != null) { - // This is where we can temporarily fix those pesky property issues! - world.setPVP(mvWorld.isPVPEnabled()); - world.setDifficulty(mvWorld.getDifficulty()); - } - } + worldManager.getOfflineOnlyWorld(event.getWorld().getName()) + .peek(offlineWorld -> { + Logging.fine("Loading world: " + offlineWorld.getName()); + worldManager.loadWorld(offlineWorld); + }); } } diff --git a/src/main/java/com/onarandombox/MultiverseCore/worldnew/WorldManager.java b/src/main/java/com/onarandombox/MultiverseCore/worldnew/WorldManager.java index 5666ddd7..487b6ff2 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/worldnew/WorldManager.java +++ b/src/main/java/com/onarandombox/MultiverseCore/worldnew/WorldManager.java @@ -26,8 +26,10 @@ import org.jetbrains.annotations.Nullable; import org.jvnet.hk2.annotations.Service; import java.io.File; +import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import java.util.List; import java.util.Map; @Service @@ -35,6 +37,8 @@ public class WorldManager { private final Map offlineWorldsMap; private final Map worldsMap; + private final List unloadTracker; + private final List loadTracker; private final WorldsConfigManager worldsConfigManager; private final WorldNameChecker worldNameChecker; private final BlockSafety blockSafety; @@ -51,6 +55,8 @@ public class WorldManager { ) { this.offlineWorldsMap = new HashMap<>(); this.worldsMap = new HashMap<>(); + this.unloadTracker = new ArrayList<>(); + this.loadTracker = new ArrayList<>(); this.worldsConfigManager = worldsConfigManager; this.worldNameChecker = worldNameChecker; this.blockSafety = blockSafety; @@ -122,6 +128,7 @@ public class WorldManager { } // Create bukkit world + this.loadTracker.add(options.worldName()); World world = WorldCreator.name(options.worldName()) .environment(options.environment()) .generateStructures(options.generateStructures()) @@ -129,6 +136,7 @@ public class WorldManager { .seed(options.seed()) .type(options.worldType()) .createWorld(); + this.loadTracker.remove(options.worldName()); if (world == null) { Logging.severe("Failed to create world: " + options.worldName()); return Result.failure(CreateWorldResult.Failure.BUKKIT_CREATION_FAILED); @@ -158,10 +166,12 @@ public class WorldManager { // TODO: Check if world folder exists // Create bukkit world + this.loadTracker.add(options.worldName()); World world = WorldCreator.name(options.worldName()) .environment(options.environment()) .generator(Strings.isNullOrEmpty(options.generator()) ? null : options.generator()) .createWorld(); + this.loadTracker.remove(options.worldName()); if (world == null) { Logging.severe("Failed to create world: " + options.worldName()); return Result.failure(CreateWorldResult.Failure.BUKKIT_CREATION_FAILED); @@ -193,17 +203,25 @@ public class WorldManager { } public Result loadWorld(@NotNull OfflineWorld offlineWorld) { + if (loadTracker.contains(offlineWorld.getName())) { + // This is to prevent recursive calls by WorldLoadEvent + Logging.fine("World already loading: " + offlineWorld.getName()); + return Result.failure(LoadWorldResult.Failure.WORLD_ALREADY_LOADING); + } + if (isMVWorld(offlineWorld)) { Logging.severe("World already loaded: " + offlineWorld.getName()); return Result.failure(LoadWorldResult.Failure.WORLD_EXIST_LOADED); } // TODO: Reduce copy paste from createWorld method + this.loadTracker.add(offlineWorld.getName()); World world = WorldCreator.name(offlineWorld.getName()) .environment(offlineWorld.getEnvironment()) .generator(Strings.isNullOrEmpty(offlineWorld.getGenerator()) ? null : offlineWorld.getGenerator()) .seed(offlineWorld.getSeed()) .createWorld(); + this.loadTracker.remove(offlineWorld.getName()); if (world == null) { Logging.severe("Failed to create world: " + offlineWorld.getName()); return Result.failure(LoadWorldResult.Failure.BUKKIT_CREATION_FAILED); @@ -219,6 +237,12 @@ public class WorldManager { return Result.success(LoadWorldResult.Success.LOADED); } + public Result unloadWorld(@NotNull World world) { + return getMVWorld(world) + .map(this::unloadWorld) + .getOrElse(() -> Result.failure(UnloadWorldResult.Failure.WORLD_NON_EXISTENT)); + } + public Result unloadWorld(@NotNull String worldName) { return getMVWorld(worldName) .map(this::unloadWorld) @@ -226,9 +250,18 @@ public class WorldManager { } public Result unloadWorld(@NotNull MVWorld world) { + if (unloadTracker.contains(world.getName())) { + // This is to prevent recursive calls by WorldUnloadEvent + Logging.fine("World already unloading: " + world.getName()); + return Result.failure(UnloadWorldResult.Failure.WORLD_ALREADY_UNLOADING); + } + World bukkitWorld = world.getBukkitWorld().getOrNull(); // TODO: removePlayersFromWorld? - if (!Bukkit.unloadWorld(bukkitWorld, true)) { + unloadTracker.add(world.getName()); + boolean unloadSuccess = Bukkit.unloadWorld(bukkitWorld, true); + unloadTracker.remove(world.getName()); + if (!unloadSuccess) { Logging.severe("Failed to unload world: " + world.getName()); return Result.failure(UnloadWorldResult.Failure.BUKKIT_UNLOAD_FAILED); } diff --git a/src/main/java/com/onarandombox/MultiverseCore/worldnew/results/LoadWorldResult.java b/src/main/java/com/onarandombox/MultiverseCore/worldnew/results/LoadWorldResult.java index 9808465c..b2dbe9aa 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/worldnew/results/LoadWorldResult.java +++ b/src/main/java/com/onarandombox/MultiverseCore/worldnew/results/LoadWorldResult.java @@ -12,6 +12,7 @@ public class LoadWorldResult { } public enum Failure implements FailureReason { + WORLD_ALREADY_LOADING(MVCorei18n.GENERIC_FAILURE), WORLD_NON_EXISTENT(MVCorei18n.GENERIC_FAILURE), WORLD_EXIST_FOLDER(MVCorei18n.GENERIC_FAILURE), WORLD_EXIST_LOADED(MVCorei18n.GENERIC_FAILURE), diff --git a/src/main/java/com/onarandombox/MultiverseCore/worldnew/results/UnloadWorldResult.java b/src/main/java/com/onarandombox/MultiverseCore/worldnew/results/UnloadWorldResult.java index 3bb8b951..d360f540 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/worldnew/results/UnloadWorldResult.java +++ b/src/main/java/com/onarandombox/MultiverseCore/worldnew/results/UnloadWorldResult.java @@ -12,6 +12,7 @@ public class UnloadWorldResult { } public static class Failure implements FailureReason { + public static final Failure WORLD_ALREADY_UNLOADING = new Failure(MVCorei18n.GENERIC_FAILURE); public static final Failure WORLD_NON_EXISTENT = new Failure(MVCorei18n.GENERIC_FAILURE); public static final Failure WORLD_OFFLINE = new Failure(MVCorei18n.GENERIC_FAILURE); public static final Failure BUKKIT_UNLOAD_FAILED = new Failure(MVCorei18n.GENERIC_FAILURE); diff --git a/src/test/java/org/mvplugins/multiverse/core/inject/InjectionTest.kt b/src/test/java/org/mvplugins/multiverse/core/inject/InjectionTest.kt index a08f28f7..c6350232 100644 --- a/src/test/java/org/mvplugins/multiverse/core/inject/InjectionTest.kt +++ b/src/test/java/org/mvplugins/multiverse/core/inject/InjectionTest.kt @@ -15,7 +15,6 @@ import com.onarandombox.MultiverseCore.listeners.MVEntityListener import com.onarandombox.MultiverseCore.listeners.MVPlayerListener import com.onarandombox.MultiverseCore.listeners.MVPortalListener import com.onarandombox.MultiverseCore.listeners.MVWeatherListener -import com.onarandombox.MultiverseCore.listeners.MVWorldInitListener import com.onarandombox.MultiverseCore.listeners.MVWorldListener import com.onarandombox.MultiverseCore.teleportation.SimpleBlockSafety import com.onarandombox.MultiverseCore.teleportation.SimpleLocationManipulation @@ -110,11 +109,6 @@ class InjectionTest : TestWithMockBukkit() { assertNotNull(multiverseCore.getService(MVWorldListener::class.java)) } - @Test - fun `MVWorldInitListener is available as a service`() { - assertNotNull(multiverseCore.getService(MVWorldInitListener::class.java)) - } - @Test fun `MVCoreConfig is available as a service`() { assertNotNull(multiverseCore.getService(MVCoreConfig::class.java))