[SPIGOT-7911] Location#isWorldLoaded() is broken and causes a chain of problems Created: 02/Oct/24 Updated: 25/Dec/24 Resolved: 06/Oct/24 |
|
Status: | Resolved |
Project: | Spigot |
Component/s: | None |
Affects Version/s: | None |
Fix Version/s: | None |
Type: | Bug | Priority: | Minor |
Reporter: | Marcel | Assignee: | md_5 |
Resolution: | Fixed | Votes: | 0 |
Labels: | None |
Version: | Latest |
Guidelines Read: | Yes |
Description |
Some background information: I have been battling with a bug since years where chunks wouldn't get loaded when teleporting, whereby the player would get in a basically frozen state. Today I have found out that I have been dealing with a world instance that actually doesn't exist anymore, and thereby causes broken results.
I have been relying on Location#isWorldLoaded() to update my cached Location instance, as I am reloading the world frequently. This method still returns true, even after the world strictly speaking isn't loaded anymore, and I am thereby working with a broken instance.
Location#isWorldLoaded() does basically the following: return world != null && Bukkit.getWorld(world.getUID()) != null; The problem is, that world UUIDs are persistent - they do not change after a reload. This is handled properly within World#equals(Object): this.getUID() == other.getUID()
Here, the references are compared (and not the actual matching of the UUIDs), whereby it returns the expected result. Although, I'd suggest comparing the handle, as it otherwise gives a feel of the UUIDs not being persistent (which possibly even lead to the fault with Location#isWorldLoaded()).
The fix, within Location#isWorldLoaded(), could be: return world != null && world.equals(Bukkit.getWorld(world.getUID())); |