diff options
| author | daoge <3523206925@qq.com> | 2026-03-03 03:04:10 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-03-03 03:04:10 +0800 |
| commit | b3feddfef372618c8a9d7a0abcaf18cfad866c18 (patch) | |
| tree | 267761c3bb39241ba5c347bfbe2254d06686e287 /Minecraft.Client/ServerChunkCache.cpp | |
| parent | 84c31a2331f7a0ec85b9d438992e244f60e5020f (diff) | |
feat: TU19 (Dec 2014) Features & Content (#155)
* try to resolve merge conflict
* feat: TU19 (Dec 2014) Features & Content (#32)
* December 2014 files
* Working release build
* Fix compilation issues
* Add sound to Windows64Media
* Add DLC content and force Tutorial DLC
* Revert "Add DLC content and force Tutorial DLC"
This reverts commit 97a43994725008e35fceb984d5549df9c8cea470.
* Disable broken light packing
* Disable breakpoint during DLC texture map load
Allows DLC loading but the DLC textures are still broken
* Fix post build not working
* ...
* fix vs2022 build
* fix cmake build
---------
Co-authored-by: Loki <lokirautio@gmail.com>
Diffstat (limited to 'Minecraft.Client/ServerChunkCache.cpp')
| -rw-r--r-- | Minecraft.Client/ServerChunkCache.cpp | 116 |
1 files changed, 100 insertions, 16 deletions
diff --git a/Minecraft.Client/ServerChunkCache.cpp b/Minecraft.Client/ServerChunkCache.cpp index 1fe1a86f..619efa98 100644 --- a/Minecraft.Client/ServerChunkCache.cpp +++ b/Minecraft.Client/ServerChunkCache.cpp @@ -11,6 +11,7 @@ #include "..\Minecraft.World\ThreadName.h" #include "..\Minecraft.World\compression.h" #include "..\Minecraft.World\OldChunkStorage.h" +#include "..\Minecraft.World\Tile.h" ServerChunkCache::ServerChunkCache(ServerLevel *level, ChunkStorage *storage, ChunkSource *source) { @@ -40,6 +41,7 @@ ServerChunkCache::ServerChunkCache(ServerLevel *level, ChunkStorage *storage, Ch // 4J-PB added ServerChunkCache::~ServerChunkCache() { + storage->WaitForAll(); // MGH - added to fix crash bug 175183 delete emptyChunk; delete cache; delete source; @@ -307,6 +309,76 @@ LevelChunk *ServerChunkCache::getChunkLoadedOrUnloaded(int x, int z) } #endif + +// 4J MGH added, for expanding worlds, to kill any player changes and reset the chunk +#ifdef _LARGE_WORLDS +void ServerChunkCache::overwriteLevelChunkFromSource(int x, int z) +{ + int ix = x + XZOFFSET; + int iz = z + XZOFFSET; + // Check we're in range of the stored level + if( ( ix < 0 ) || ( ix >= XZSIZE ) ) assert(0); + if( ( iz < 0 ) || ( iz >= XZSIZE ) ) assert(0); + int idx = ix * XZSIZE + iz; + + LevelChunk *chunk = NULL; + chunk = source->getChunk(x, z); + assert(chunk); + if(chunk) + { + save(chunk); + } +} + + + +void ServerChunkCache::updateOverwriteHellChunk(LevelChunk* origChunk, LevelChunk* playerChunk, int xMin, int xMax, int zMin, int zMax) +{ + + // replace a section of the chunk with the original source data, if it hasn't already changed + for(int x=xMin;x<xMax;x++) + { + for(int z=zMin;z<zMax;z++) + { + for(int y=0;y<256;y++) + { + int playerTile = playerChunk->getTile(x,y,z); + if(playerTile == Tile::unbreakable_Id) // if the tile is still unbreakable, the player hasn't changed it, so we can replace with the source + playerChunk->setTileAndData(x, y, z, origChunk->getTile(x,y,z), origChunk->getData(x,y,z)); + } + } + } +} + +void ServerChunkCache::overwriteHellLevelChunkFromSource(int x, int z, int minVal, int maxVal) +{ + int ix = x + XZOFFSET; + int iz = z + XZOFFSET; + // Check we're in range of the stored level + if( ( ix < 0 ) || ( ix >= XZSIZE ) ) assert(0); + if( ( iz < 0 ) || ( iz >= XZSIZE ) ) assert(0); + int idx = ix * XZSIZE + iz; + autoCreate = true; + LevelChunk* playerChunk = getChunk(x, z); + autoCreate = false; + LevelChunk* origChunk = source->getChunk(x, z); + assert(origChunk); + if(playerChunk!= emptyChunk) + { + if(x == minVal) + updateOverwriteHellChunk(origChunk, playerChunk, 0, 4, 0, 16); + if(x == maxVal) + updateOverwriteHellChunk(origChunk, playerChunk, 12, 16, 0, 16); + if(z == minVal) + updateOverwriteHellChunk(origChunk, playerChunk, 0, 16, 0, 4); + if(z == maxVal) + updateOverwriteHellChunk(origChunk, playerChunk, 0, 16, 12, 16); + } + save(playerChunk); +} + +#endif + // 4J Added // #ifdef _LARGE_WORLDS void ServerChunkCache::dontDrop(int x, int z) @@ -335,7 +407,7 @@ LevelChunk *ServerChunkCache::load(int x, int z) } if (levelChunk != NULL) { - levelChunk->lastSaveTime = level->getTime(); + levelChunk->lastSaveTime = level->getGameTime(); } return levelChunk; } @@ -351,7 +423,7 @@ void ServerChunkCache::save(LevelChunk *levelChunk) { if (storage == NULL) return; - levelChunk->lastSaveTime = level->getTime(); + levelChunk->lastSaveTime = level->getGameTime(); storage->save(level, levelChunk); } @@ -866,20 +938,28 @@ bool ServerChunkCache::tick() LevelChunk *chunk = m_toDrop.front(); if(!chunk->isUnloaded()) { - save(chunk); - saveEntities(chunk); - chunk->unload(true); - - //loadedChunks.remove(cp); - //loadedChunkList.remove(chunk); - AUTO_VAR(it, std::find( m_loadedChunkList.begin(), m_loadedChunkList.end(), chunk) ); - if(it != m_loadedChunkList.end()) m_loadedChunkList.erase(it); - - int ix = chunk->x + XZOFFSET; - int iz = chunk->z + XZOFFSET; - int idx = ix * XZSIZE + iz; - m_unloadedCache[idx] = chunk; - cache[idx] = NULL; + // Don't unload a chunk that contains a player, as this will cause their entity to be removed from the level itself and they will never tick again. + // This can happen if a player moves a long distance in one tick, for example when the server thread has locked up doing something for a while whilst a player + // kept moving. In this case, the player is moved in the player chunk map (driven by the network packets being processed for their new position) before the + // player's tick is called to remove them from the chunk they used to be in, and add them to their current chunk. This will only be a temporary state and + // we should be able to unload the chunk on the next call to this tick. + if( !chunk->containsPlayer() ) + { + save(chunk); + saveEntities(chunk); + chunk->unload(true); + + //loadedChunks.remove(cp); + //loadedChunkList.remove(chunk); + AUTO_VAR(it, std::find( m_loadedChunkList.begin(), m_loadedChunkList.end(), chunk) ); + if(it != m_loadedChunkList.end()) m_loadedChunkList.erase(it); + + int ix = chunk->x + XZOFFSET; + int iz = chunk->z + XZOFFSET; + int idx = ix * XZSIZE + iz; + m_unloadedCache[idx] = chunk; + cache[idx] = NULL; + } } m_toDrop.pop_front(); } @@ -912,6 +992,10 @@ TilePos *ServerChunkCache::findNearestMapFeature(Level *level, const wstring &fe return source->findNearestMapFeature(level, featureName, x, y, z); } +void ServerChunkCache::recreateLogicStructuresForChunk(int chunkX, int chunkZ) +{ +} + int ServerChunkCache::runSaveThreadProc(LPVOID lpParam) { SaveThreadData *params = (SaveThreadData *)lpParam; |
