From 28f9b1a3cbd226006821adbafc30e1db1c9eccd4 Mon Sep 17 00:00:00 2001 From: willkroboth <46540330+willkroboth@users.noreply.github.com> Date: Sat, 24 Sep 2022 01:19:05 -0400 Subject: [PATCH] Add method isTickingWorlds to Bukkit (#8316) Co-authored-by: Shane Freeder Also, restores un/loading worlds mid tick. This will not be officially supported API contract that such a routine is safe, and these restrictions may be restored in the future. --- ...Add-method-isTickingWorlds-to-Bukkit.patch | 117 ++++++++++++++++++ ...n-on-world-create-while-being-ticked.patch | 16 ++- 2 files changed, 131 insertions(+), 2 deletions(-) create mode 100644 patches/api/Add-method-isTickingWorlds-to-Bukkit.patch diff --git a/patches/api/Add-method-isTickingWorlds-to-Bukkit.patch b/patches/api/Add-method-isTickingWorlds-to-Bukkit.patch new file mode 100644 index 0000000000..5d2486c932 --- /dev/null +++ b/patches/api/Add-method-isTickingWorlds-to-Bukkit.patch @@ -0,0 +1,117 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: BuildTools <46540330+willkroboth@users.noreply.github.com> +Date: Fri, 19 Aug 2022 16:11:51 -0400 +Subject: [PATCH] Add method isTickingWorlds() to Bukkit. + + +diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/org/bukkit/Bukkit.java ++++ b/src/main/java/org/bukkit/Bukkit.java +@@ -0,0 +0,0 @@ public final class Bukkit { + return server.getWorlds(); + } + ++ // Paper start ++ /** ++ * Gets whether the worlds are being ticked right not or not. ++ * ++ * @return true if the worlds are being ticked, false otherwise. ++ */ ++ public static boolean isTickingWorlds(){ ++ return server.isTickingWorlds(); ++ } ++ // Paper end ++ + /** + * Creates or loads a world with the given name using the specified + * options. + *

+ * If the world is already loaded, it will just return the equivalent of + * getWorld(creator.name()). ++ *

++ * Do note that un/loading worlds mid-tick may have potential side effects, we strongly recommend ++ * ensuring that you're not loading worlds midtick by checking {@link Bukkit#isTickingWorlds()} + * + * @param creator the options to use when creating the world + * @return newly created or loaded world +@@ -0,0 +0,0 @@ public final class Bukkit { + + /** + * Unloads a world with the given name. ++ *

++ * Do note that un/loading worlds mid-tick may have potential side effects, we strongly recommend ++ * ensuring that you're not loading worlds midtick by checking {@link Bukkit#isTickingWorlds()} + * + * @param name Name of the world to unload + * @param save whether to save the chunks before unloading +@@ -0,0 +0,0 @@ public final class Bukkit { + + /** + * Unloads the given world. ++ *

++ * Do note that un/loading worlds mid-tick may have potential side effects, we strongly recommend ++ * ensuring that you're not loading worlds midtick by checking {@link Bukkit#isTickingWorlds()} + * + * @param world the world to unload + * @param save whether to save the chunks before unloading +diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/org/bukkit/Server.java ++++ b/src/main/java/org/bukkit/Server.java +@@ -0,0 +0,0 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi + @NotNull + public List getWorlds(); + ++ // Paper start ++ /** ++ * Gets whether the worlds are being ticked right not or not. ++ * ++ * @return true if the worlds are being ticked, false otherwise. ++ */ ++ public boolean isTickingWorlds(); ++ // Paper end ++ + /** + * Creates or loads a world with the given name using the specified + * options. + *

+ * If the world is already loaded, it will just return the equivalent of + * getWorld(creator.name()). ++ *

++ * Do note that un/loading worlds mid-tick may have potential side effects, we strongly recommend ++ * ensuring that you're not loading worlds midtick by checking {@link Bukkit#isTickingWorlds()} + * + * @param creator the options to use when creating the world + * @return newly created or loaded world ++ * @throws IllegalStateException when {@link #isTickingWorlds() isTickingWorlds} is true + */ + @Nullable + public World createWorld(@NotNull WorldCreator creator); + + /** + * Unloads a world with the given name. ++ *

++ * Do note that un/loading worlds mid-tick may have potential side effects, we strongly recommend ++ * ensuring that you're not loading worlds midtick by checking {@link Bukkit#isTickingWorlds()} + * + * @param name Name of the world to unload + * @param save whether to save the chunks before unloading + * @return true if successful, false otherwise ++ * @throws IllegalStateException when {@link #isTickingWorlds() isTickingWorlds} is true + */ + public boolean unloadWorld(@NotNull String name, boolean save); + + /** + * Unloads the given world. ++ *

++ * Do note that un/loading worlds mid-tick may have potential side effects, we strongly recommend ++ * ensuring that you're not loading worlds midtick by checking {@link Bukkit#isTickingWorlds()} + * + * @param world the world to unload + * @param save whether to save the chunks before unloading + * @return true if successful, false otherwise ++ * @throws IllegalStateException when {@link #isTickingWorlds() isTickingWorlds} is true + */ + public boolean unloadWorld(@NotNull World world, boolean save); + diff --git a/patches/server/Throw-exception-on-world-create-while-being-ticked.patch b/patches/server/Throw-exception-on-world-create-while-being-ticked.patch index a41c84d961..24e256ed66 100644 --- a/patches/server/Throw-exception-on-world-create-while-being-ticked.patch +++ b/patches/server/Throw-exception-on-world-create-while-being-ticked.patch @@ -48,11 +48,23 @@ diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/ja index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +@@ -0,0 +0,0 @@ public final class CraftServer implements Server { + return new ArrayList(this.worlds.values()); + } + ++ @Override ++ public boolean isTickingWorlds() { ++ return console.isIteratingOverLevels; ++ } ++ + public DedicatedPlayerList getHandle() { + return this.playerList; + } @@ -0,0 +0,0 @@ public final class CraftServer implements Server { @Override public World createWorld(WorldCreator creator) { Preconditions.checkState(this.console.getAllLevels().iterator().hasNext(), "Cannot create additional worlds on STARTUP"); -+ Preconditions.checkState(!this.console.isIteratingOverLevels, "Cannot create a world while worlds are being ticked"); // Paper ++ //Preconditions.checkState(!this.console.isIteratingOverLevels, "Cannot create a world while worlds are being ticked"); // Paper - Cat - Temp disable. We'll see how this goes. Validate.notNull(creator, "Creator may not be null"); String name = creator.name(); @@ -60,7 +72,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public boolean unloadWorld(World world, boolean save) { -+ Preconditions.checkState(!this.console.isIteratingOverLevels, "Cannot unload a world while worlds are being ticked"); // Paper ++ //Preconditions.checkState(!this.console.isIteratingOverLevels, "Cannot unload a world while worlds are being ticked"); // Paper - Cat - Temp disable. We'll see how this goes. if (world == null) { return false; }