diff --git a/patches/minecraft/net/minecraft/client/multiplayer/ClientChunkCache.java.patch b/patches/minecraft/net/minecraft/client/multiplayer/ClientChunkCache.java.patch index d595d17988..542ee5dcdb 100644 --- a/patches/minecraft/net/minecraft/client/multiplayer/ClientChunkCache.java.patch +++ b/patches/minecraft/net/minecraft/client/multiplayer/ClientChunkCache.java.patch @@ -12,7 +12,7 @@ } this.f_104411_.m_171649_(chunkpos); -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.level.ChunkEvent.Load(levelchunk)); ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.level.ChunkEvent.Load(levelchunk, false)); return levelchunk; } } diff --git a/patches/minecraft/net/minecraft/server/level/ChunkMap.java.patch b/patches/minecraft/net/minecraft/server/level/ChunkMap.java.patch index 2fcf85dc76..4ce23207af 100644 --- a/patches/minecraft/net/minecraft/server/level/ChunkMap.java.patch +++ b/patches/minecraft/net/minecraft/server/level/ChunkMap.java.patch @@ -24,7 +24,7 @@ + p_140384_.currentlyLoading = levelchunk; // Forge - bypass the future chain when getChunk is called, this prevents deadlocks. levelchunk.m_156369_(); levelchunk.m_187958_(this.f_140133_); -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.level.ChunkEvent.Load(levelchunk)); ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.level.ChunkEvent.Load(levelchunk, !(protochunk instanceof ImposterProtoChunk))); + } finally { + p_140384_.currentlyLoading = null; // Forge - Stop bypassing the future chain. + } diff --git a/src/main/java/net/minecraftforge/event/level/ChunkEvent.java b/src/main/java/net/minecraftforge/event/level/ChunkEvent.java index ac8d32ca7d..b1c39b3d96 100644 --- a/src/main/java/net/minecraftforge/event/level/ChunkEvent.java +++ b/src/main/java/net/minecraftforge/event/level/ChunkEvent.java @@ -12,6 +12,7 @@ import net.minecraft.world.level.chunk.LevelChunk; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.eventbus.api.Cancelable; import net.minecraftforge.eventbus.api.Event; +import org.jetbrains.annotations.ApiStatus; /** * ChunkEvent is fired when an event involving a chunk occurs.
@@ -58,9 +59,32 @@ public class ChunkEvent extends LevelEvent **/ public static class Load extends ChunkEvent { + private final boolean newChunk; + + @ApiStatus.Internal + @Deprecated(forRemoval = true, since = "1.19.3") public Load(ChunkAccess chunk) + { + this(chunk, false); + } + + @ApiStatus.Internal + public Load(ChunkAccess chunk, boolean newChunk) { super(chunk); + this.newChunk = newChunk; + } + + /** + * Check whether the Chunk is newly generated, and being loaded for the first time. + * + *

Will only ever return {@code true} on the {@linkplain net.minecraftforge.fml.LogicalSide#SERVER logical server}.

+ * + * @return whether the Chunk is newly generated + */ + public boolean isNewChunk() + { + return newChunk; } } diff --git a/src/test/java/net/minecraftforge/debug/world/ChunkEventLoadNewChunkTest.java b/src/test/java/net/minecraftforge/debug/world/ChunkEventLoadNewChunkTest.java new file mode 100644 index 0000000000..6c9b1fa297 --- /dev/null +++ b/src/test/java/net/minecraftforge/debug/world/ChunkEventLoadNewChunkTest.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) Forge Development LLC and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.minecraftforge.debug.world; + +import com.mojang.logging.LogUtils; +import net.minecraft.server.level.ServerLevel; +import net.minecraftforge.event.level.ChunkEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; +import org.slf4j.Logger; + +/** + * Simple test for {@link ChunkEvent.Load#isNewChunk()}. Will log a message to console each time + * the event is fired for a newly generated chunk. + * + *

A simple way to check that it's behaving as expected is as follows:

+ * + */ +@Mod(ChunkEventLoadNewChunkTest.MODID) +@Mod.EventBusSubscriber +public class ChunkEventLoadNewChunkTest +{ + static final String MODID = "chunk_event_load_new_chunk_test"; + private static final boolean ENABLED = true; + private static final Logger LOGGER = LogUtils.getLogger(); + + @SubscribeEvent + public static void onChunkLoad(final ChunkEvent.Load event) + { + if (!ENABLED) + { + return; + } + + if (!event.isNewChunk()) + { + return; + } + + LOGGER.info("Loaded freshly generated chunk at {}{}", ((ServerLevel) event.getLevel()).dimension().location(), event.getChunk().getPos()); + } +} diff --git a/src/test/resources/META-INF/mods.toml b/src/test/resources/META-INF/mods.toml index 810a867b3d..1cb879d01d 100644 --- a/src/test/resources/META-INF/mods.toml +++ b/src/test/resources/META-INF/mods.toml @@ -280,6 +280,8 @@ modId="creative_mode_tab_test" modId="render_level_stages_test" [[mods]] modId="trade_with_villager_event_test" +[[mods]] +modId="chunk_event_load_new_chunk_test" # ADD ABOVE THIS LINE