Skip to content

Modify CraftWorld#getChunkAt(x, z) to functional by sync operation.#308

Closed
ColdeZhang wants to merge 2 commits into
PaperMC:dev/1.21.4from
ColdeZhang:dev/1.21.4
Closed

Modify CraftWorld#getChunkAt(x, z) to functional by sync operation.#308
ColdeZhang wants to merge 2 commits into
PaperMC:dev/1.21.4from
ColdeZhang:dev/1.21.4

Conversation

@ColdeZhang
Copy link
Copy Markdown

@ColdeZhang ColdeZhang commented Dec 10, 2024

When I was using getForceLoadedChunks() it throw:

[21:44:53 ERROR]: [ca.spottedleaf.moonrise.common.util.TickThread] Thread Region Scheduler Thread #2 failed main thread check: Async chunk retrieval
java.lang.Throwable: null
        at ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(TickThread.java:51) ~[deerfolia-1.21.4.jar:1.21.4-DEV-2bd64a2]
        at org.bukkit.craftbukkit.CraftWorld.getChunkAt(CraftWorld.java:373) ~[deerfolia-1.21.4.jar:1.21.4-DEV-2bd64a2]
        at org.bukkit.craftbukkit.CraftWorld.getForceLoadedChunks(CraftWorld.java:690) ~[deerfolia-1.21.4.jar:1.21.4-DEV-2bd64a2]

If getChunkAt forced ensureTickThread, then other api wont get proper reult forever.

Since this method was a 'read-only', why don't we just sync it to get what we want?

@ColdeZhang
Copy link
Copy Markdown
Author

ColdeZhang commented Dec 10, 2024

    @Override
    public Chunk getChunkAt(int x, int z) {
        net.minecraft.world.level.chunk.LevelChunk chunk;
        try {
            if (((ServerLevel) world).regioniser.getRegionAtUnsynchronised(x >> 4, z >> 4) != null)
                ((ServerLevel) world).regioniser.getRegionAtUnsynchronised(x >> 4, z >> 4).regioniser.acquireReadLock(); // Folia - region threading
            warnUnsafeChunk("getting a faraway chunk", x, z); // Paper
            chunk = (net.minecraft.world.level.chunk.LevelChunk) this.world.getChunk(x, z, ChunkStatus.FULL, true);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (((ServerLevel) world).regioniser.getRegionAtUnsynchronised(x >> 4, z >> 4) != null)
                ((ServerLevel) world).regioniser.getRegionAtUnsynchronised(x >> 4, z >> 4).regioniser.releaseReadLock(); // Folia - region threading
        }
        return new CraftChunk(chunk);
    }

@ColdeZhang ColdeZhang closed this Dec 10, 2024
@PedroMPagani
Copy link
Copy Markdown

PedroMPagani commented Dec 10, 2024

That's not a proper solution, you should never call getChunk with possibility of loading it like that, it's a blocking call.

@masmc05
Copy link
Copy Markdown

masmc05 commented Dec 10, 2024

For multiple versions CraftChunk is just a wrapper around coordinates (like CraftBlock) without any real information or reference to the chunk. Just create craft chunks in getForceLoadedChunks() with the coordinates without loading them (and they're most probably already loaded anyway), there is a SeverLevel,int,int constructor that you can use instead of the one that takes LevelChunk

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants