From 210ee9f2ef2b3a22a6cc035e6bb94ffe6fd11d9b Mon Sep 17 00:00:00 2001 From: Jordan Date: Thu, 5 May 2022 20:39:45 +0100 Subject: [PATCH] Implement getNameUnsafe method to allow an unloaded world's name to be accessed (#1712) * Implement getNameUnsafe method to allow an unloaded world's name to be accessed - Fixes #1671 and #504 * Add javadoc since tag Co-authored-by: Alexander Brandes Co-authored-by: Alexander Brandes --- .../bukkit/util/WorldUnloadedException.java | 7 ++++++ .../sk89q/worldedit/bukkit/BukkitWorld.java | 25 +++++++++++++++---- .../cli/schematic/ClipboardWorld.java | 7 ++++++ .../core/wrappers/WorldWrapper.java | 7 ++++++ .../com/sk89q/worldedit/LocalSession.java | 3 ++- .../com/sk89q/worldedit/world/NullWorld.java | 7 ++++++ .../java/com/sk89q/worldedit/world/World.java | 13 +++++++++- .../src/main/resources/lang/strings.json | 1 + 8 files changed, 63 insertions(+), 7 deletions(-) diff --git a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/util/WorldUnloadedException.java b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/util/WorldUnloadedException.java index 0f22e196d..870dccbc7 100644 --- a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/util/WorldUnloadedException.java +++ b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/util/WorldUnloadedException.java @@ -15,4 +15,11 @@ public class WorldUnloadedException extends WorldEditException { super(Caption.of("worldedit.error.world-unloaded")); } + /** + * Create a new instance. + */ + public WorldUnloadedException(String name) { + super(Caption.of("worldedit.error.named-world-unloaded", name)); + } + } diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java index a653bd7f5..9017f9866 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java @@ -193,19 +193,34 @@ public class BukkitWorld extends AbstractWorld { * @return the world */ protected World getWorldChecked() throws WorldEditException { - World world = worldRef.get(); - if (world == null) { - throw new WorldUnloadedException(); + World tmp = worldRef.get(); + if (tmp == null) { + tmp = Bukkit.getWorld(worldNameRef); + if (tmp != null) { + worldRef = new WeakReference<>(tmp); + } } - return world; + if (tmp == null) { + throw new WorldUnloadedException(worldNameRef); + } + return tmp; } //FAWE end @Override public String getName() { - return getWorld().getName(); + //FAWE start - Throw WorldUnloadedException rather than NPE when world unloaded and attempted to be accessed + return getWorldChecked().getName(); + //FAWE end } + //FAWE start - allow history to read an unloaded world's name + @Override + public String getNameUnsafe() { + return worldNameRef; + } + //FAWE end + @Override public String getId() { return getWorld().getName().replace(" ", "_").toLowerCase(Locale.ROOT); diff --git a/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/schematic/ClipboardWorld.java b/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/schematic/ClipboardWorld.java index b448b8048..b164ecfa3 100644 --- a/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/schematic/ClipboardWorld.java +++ b/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/schematic/ClipboardWorld.java @@ -76,6 +76,13 @@ public class ClipboardWorld extends AbstractWorld implements Clipboard, CLIWorld return this.name; } + //FAWE start - allow history to read an unloaded world's name + @Override + public String getNameUnsafe() { + return this.name; + } + //FAWE end + @Override public String getId() { return getName().replace(" ", "_").toLowerCase(Locale.ROOT); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/wrappers/WorldWrapper.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/wrappers/WorldWrapper.java index 0537aef0a..282f37509 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/wrappers/WorldWrapper.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/wrappers/WorldWrapper.java @@ -198,6 +198,13 @@ public class WorldWrapper extends AbstractWorld { return parent.getName(); } + //FAWE start - allow history to read an unloaded world's name + @Override + public String getNameUnsafe() { + return parent.getNameUnsafe(); + } + //FAWE end + @Override public > boolean setBlock(BlockVector3 position, B block, boolean notifyAndLight) throws WorldEditException { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java index 236ea7403..1ef2af6d6 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java @@ -306,7 +306,8 @@ public class LocalSession implements TextureHolder { } File file = MainUtil.getFile( Fawe.platform().getDirectory(), - Settings.settings().PATHS.HISTORY + File.separator + world.getName() + File.separator + uuid + File.separator + "index" + // Use "unsafe" method here as world does not need to be loaded to save this information. + Settings.settings().PATHS.HISTORY + File.separator + world.getNameUnsafe() + File.separator + uuid + File.separator + "index" ); if (getHistoryNegativeIndex() != 0) { try { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/NullWorld.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/NullWorld.java index 91038a22e..73d9110f0 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/NullWorld.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/NullWorld.java @@ -69,6 +69,13 @@ public class NullWorld extends AbstractWorld { return "null"; } + //FAWE start - allow history to read an unloaded world's name + @Override + public String getNameUnsafe() { + return "null"; + } + //FAWE end + @Override public String getId() { return "null"; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java index d12cd70b2..c9229fbc0 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java @@ -63,12 +63,23 @@ public interface World extends Extent, Keyed, IChunkCache { //FAWE end /** - * Get the name of the world. + * Get the name of the world. This will error if world has been unloaded by the server. * * @return a name for the world */ String getName(); + //FAWE start - allow history to read an unloaded world's name + /** + * Get the name of the world. If the world referenced has been unloaded, this will still return the name. + * + * @return a name for the world + * @since TODO + */ + String getNameUnsafe(); + //FAWE end + + /** * Get the folder in which this world is stored. May return null if unknown * or if this world is not serialized to disk. diff --git a/worldedit-core/src/main/resources/lang/strings.json b/worldedit-core/src/main/resources/lang/strings.json index 62db569de..3560b7949 100644 --- a/worldedit-core/src/main/resources/lang/strings.json +++ b/worldedit-core/src/main/resources/lang/strings.json @@ -248,6 +248,7 @@ "worldedit.tool.error.cannot-bind": "Can't bind tool to {0}: {1}", "worldedit.error.file-aborted": "File selection aborted.", "worldedit.error.world-unloaded": "The world was unloaded already.", + "worldedit.error.named-world-unloaded": "The world '{0}' was unloaded already.", "worldedit.error.blocks-cant-be-used": "Blocks can't be used", "worldedit.error.unknown-tag": "Tag name '{0}' was not recognized.", "worldedit.error.empty-tag": "Tag name '{0}' has no contents.",