From a24318eedc44af2f5967c4727b7ebf578b8e233a Mon Sep 17 00:00:00 2001 From: ModMaker101 <119018978+ModMaker101@users.noreply.github.com> Date: Wed, 25 Mar 2026 00:25:18 -0400 Subject: Memory leak fix: Make chunks unload properly (#1406) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix chunk unload and cleanup logic, fixes #1347 * Applying formatting to code I edited 😝 --- Minecraft.Client/MultiPlayerChunkCache.cpp | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'Minecraft.Client/MultiPlayerChunkCache.cpp') diff --git a/Minecraft.Client/MultiPlayerChunkCache.cpp b/Minecraft.Client/MultiPlayerChunkCache.cpp index 62361ce3..03c47fcc 100644 --- a/Minecraft.Client/MultiPlayerChunkCache.cpp +++ b/Minecraft.Client/MultiPlayerChunkCache.cpp @@ -139,19 +139,26 @@ bool MultiPlayerChunkCache::reallyHasChunk(int x, int z) return hasData[idx]; } -void MultiPlayerChunkCache::drop(int x, int z) +void MultiPlayerChunkCache::drop(const int x, const int z) { - // 4J Stu - We do want to drop any entities in the chunks, especially for the case when a player is dead as they will - // not get the RemoveEntity packet if an entity is removed. - LevelChunk *chunk = getChunk(x, z); - if (!chunk->isEmpty()) + const int ix = x + XZOFFSET; + const int iz = z + XZOFFSET; + if ((ix < 0) || (ix >= XZSIZE)) return; + if ((iz < 0) || (iz >= XZSIZE)) return; + const int idx = ix * XZSIZE + iz; + LevelChunk* chunk = cache[idx]; + + if (chunk != nullptr && !chunk->isEmpty()) { - // Added parameter here specifies that we don't want to delete tile entities, as they won't get recreated unless they've got update packets - // The tile entities are in general only created on the client by virtue of the chunk rebuild + // Unload chunk but keep tile entities chunk->unload(false); - // 4J - We just want to clear out the entities in the chunk, but everything else should be valid - chunk->loaded = true; + const auto it = std::find(loadedChunkList.begin(), loadedChunkList.end(), chunk); + if (it != loadedChunkList.end()) loadedChunkList.erase(it); + + cache[idx] = nullptr; + hasData[idx] = false; + chunk->loaded = false; } } -- cgit v1.2.3