mirror of
https://github.com/neoStudiosLCE/neoLegacy.git
synced 2026-06-09 02:32:56 +00:00
it works kinda but its laggy
This commit is contained in:
parent
42ee0b519e
commit
2830b973d4
|
|
@ -93,8 +93,8 @@ MultiPlayerChunkCache::MultiPlayerChunkCache(Level *level)
|
|||
|
||||
this->level = level;
|
||||
|
||||
this->cache = new LevelChunk *[XZSIZE * XZSIZE];
|
||||
memset(this->cache, 0, XZSIZE * XZSIZE * sizeof(LevelChunk *));
|
||||
//this->cache = new LevelChunk *[XZSIZE * XZSIZE];
|
||||
//memset(this->cache, 0, XZSIZE * XZSIZE * sizeof(LevelChunk *));
|
||||
InitializeCriticalSectionAndSpinCount(&m_csLoadCreate,4000);
|
||||
}
|
||||
|
||||
|
|
@ -102,7 +102,7 @@ MultiPlayerChunkCache::~MultiPlayerChunkCache()
|
|||
{
|
||||
delete emptyChunk;
|
||||
delete waterChunk;
|
||||
delete cache;
|
||||
dynamic_cache.clear(); //delete cache;
|
||||
delete hasData;
|
||||
|
||||
for (auto& it : loadedChunkList)
|
||||
|
|
@ -130,12 +130,10 @@ bool MultiPlayerChunkCache::reallyHasChunk(int x, int z)
|
|||
if( ( ix < 0 ) || ( ix >= XZSIZE ) ) return true;
|
||||
if( ( iz < 0 ) || ( iz >= XZSIZE ) ) return true;
|
||||
int idx = ix * XZSIZE + iz;
|
||||
auto itor = dynamic_cache.find(idx);
|
||||
|
||||
if (itor == dynamic_cache.end() || itor->second == nullptr) return false;
|
||||
|
||||
LevelChunk *chunk = cache[idx];
|
||||
if( chunk == nullptr )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return hasData[idx];
|
||||
}
|
||||
|
||||
|
|
@ -146,19 +144,18 @@ void MultiPlayerChunkCache::drop(const int x, const int z)
|
|||
if ((ix < 0) || (ix >= XZSIZE)) return;
|
||||
if ((iz < 0) || (iz >= XZSIZE)) return;
|
||||
const int idx = ix * XZSIZE + iz;
|
||||
LevelChunk* chunk = cache[idx];
|
||||
auto itor = dynamic_cache.find(idx);
|
||||
|
||||
if (itor == dynamic_cache.end() || itor->second == nullptr || itor->second->isEmpty()) return;
|
||||
|
||||
if (chunk != nullptr && !chunk->isEmpty())
|
||||
{
|
||||
// Drop 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.
|
||||
// Don't delete tile entities, as they won't get recreated unless they've got
|
||||
// update packets. Tile entities are created on the client by the chunk rebuild.
|
||||
chunk->unload(false);
|
||||
// Drop 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.
|
||||
// Don't delete tile entities, as they won't get recreated unless they've got
|
||||
// update packets. Tile entities are created on the client by the chunk rebuild.
|
||||
itor->second->unload(false);
|
||||
|
||||
// Keep chunk in cache with structural data intact.
|
||||
chunk->loaded = true;
|
||||
}
|
||||
// Keep chunk in cache with structural data intact.
|
||||
itor->second->loaded = true;
|
||||
}
|
||||
|
||||
LevelChunk *MultiPlayerChunkCache::create(int x, int z)
|
||||
|
|
@ -169,11 +166,16 @@ LevelChunk *MultiPlayerChunkCache::create(int x, int z)
|
|||
if( ( ix < 0 ) || ( ix >= XZSIZE ) ) return ( waterChunk ? waterChunk : emptyChunk );
|
||||
if( ( iz < 0 ) || ( iz >= XZSIZE ) ) return ( waterChunk ? waterChunk : emptyChunk );
|
||||
int idx = ix * XZSIZE + iz;
|
||||
LevelChunk *chunk = cache[idx];
|
||||
LevelChunk *lastChunk = chunk;
|
||||
LevelChunk* chunk = nullptr;
|
||||
LevelChunk* lastChunk = nullptr;
|
||||
auto itor = dynamic_cache.find(idx);
|
||||
|
||||
if( chunk == nullptr )
|
||||
{
|
||||
if (itor != dynamic_cache.end()) {
|
||||
chunk = itor->second;
|
||||
lastChunk = chunk;
|
||||
}
|
||||
|
||||
if (chunk == nullptr) {
|
||||
EnterCriticalSection(&m_csLoadCreate);
|
||||
|
||||
//LevelChunk *chunk;
|
||||
|
|
@ -210,9 +212,9 @@ LevelChunk *MultiPlayerChunkCache::create(int x, int z)
|
|||
LeaveCriticalSection(&m_csLoadCreate);
|
||||
|
||||
#if ( defined _WIN64 || defined __LP64__ )
|
||||
if( InterlockedCompareExchangeRelease64((LONG64 *)&cache[idx],(LONG64)chunk,(LONG64)lastChunk) == (LONG64)lastChunk )
|
||||
if( InterlockedCompareExchangeRelease64((LONG64 *)&dynamic_cache[idx],(LONG64)chunk,(LONG64)lastChunk) == (LONG64)lastChunk )
|
||||
#else
|
||||
if( InterlockedCompareExchangeRelease((LONG *)&cache[idx],(LONG)chunk,(LONG)lastChunk) == (LONG)lastChunk )
|
||||
if( InterlockedCompareExchangeRelease((LONG *)&dynamic_cache[idx],(LONG)chunk,(LONG)lastChunk) == (LONG)lastChunk )
|
||||
#endif // _DURANGO
|
||||
{
|
||||
// If we're sharing with the server, we'll need to calculate our heightmap now, which isn't shared. If we aren't sharing with the server,
|
||||
|
|
@ -232,7 +234,11 @@ LevelChunk *MultiPlayerChunkCache::create(int x, int z)
|
|||
// Something else must have updated the cache. Return that chunk and discard this one. This really shouldn't be happening
|
||||
// in multiplayer
|
||||
delete chunk;
|
||||
return cache[idx];
|
||||
|
||||
itor = dynamic_cache.find(idx);
|
||||
if (itor == dynamic_cache.end()) return nullptr;
|
||||
|
||||
return itor->second;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -252,16 +258,11 @@ LevelChunk *MultiPlayerChunkCache::getChunk(int x, int z)
|
|||
if( ( ix < 0 ) || ( ix >= XZSIZE ) ) return ( waterChunk ? waterChunk : emptyChunk );
|
||||
if( ( iz < 0 ) || ( iz >= XZSIZE ) ) return ( waterChunk ? waterChunk : emptyChunk );
|
||||
int idx = ix * XZSIZE + iz;
|
||||
auto itor = dynamic_cache.find(idx);
|
||||
|
||||
LevelChunk *chunk = cache[idx];
|
||||
if( chunk == nullptr )
|
||||
{
|
||||
return emptyChunk;
|
||||
}
|
||||
else
|
||||
{
|
||||
return chunk;
|
||||
}
|
||||
if (itor == dynamic_cache.end() || itor->second == nullptr) return emptyChunk;
|
||||
|
||||
return itor->second;
|
||||
}
|
||||
|
||||
bool MultiPlayerChunkCache::save(bool force, ProgressListener *progressListener)
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ private:
|
|||
|
||||
vector<LevelChunk *> loadedChunkList;
|
||||
|
||||
LevelChunk **cache;
|
||||
//LevelChunk **cache;
|
||||
// 4J - added for multithreaded support
|
||||
CRITICAL_SECTION m_csLoadCreate;
|
||||
// 4J - size of cache is defined by size of one side - must be even
|
||||
|
|
@ -44,5 +44,5 @@ public:
|
|||
virtual void recreateLogicStructuresForChunk(int chunkX, int chunkZ);
|
||||
virtual void dataReceived(int x, int z); // 4J added
|
||||
|
||||
virtual LevelChunk **getCache() { return cache; } // 4J added
|
||||
virtual std::unordered_map<uint64_t, LevelChunk*>& getCache() { return dynamic_cache; } // 4J added
|
||||
};
|
||||
|
|
@ -33,7 +33,7 @@ MultiPlayerLevel::MultiPlayerLevel(ClientConnection *connection, LevelSettings *
|
|||
// 4J - this this used to be called in parent ctor via a virtual fn
|
||||
chunkSource = createChunkSource();
|
||||
// 4J - optimisation - keep direct reference of underlying cache here
|
||||
chunkSourceCache = chunkSource->getCache();
|
||||
dynamic_chunkSourceCache = chunkSource->getCache();
|
||||
chunkSourceXZSize = chunkSource->m_XZSize;
|
||||
|
||||
// This also used to be called in parent ctor, but can't be called until chunkSource is created. Call now if required.
|
||||
|
|
|
|||
|
|
@ -30,12 +30,12 @@ ServerChunkCache::ServerChunkCache(ServerLevel *level, ChunkStorage *storage, Ch
|
|||
this->source = source;
|
||||
this->m_XZSize = source->m_XZSize;
|
||||
|
||||
this->cache = new LevelChunk *[XZSIZE * XZSIZE];
|
||||
memset(this->cache, 0, XZSIZE * XZSIZE * sizeof(LevelChunk *));
|
||||
//this->cache = new LevelChunk *[XZSIZE * XZSIZE];
|
||||
//memset(this->cache, 0, XZSIZE * XZSIZE * sizeof(LevelChunk *));
|
||||
|
||||
#ifdef _LARGE_WORLDS
|
||||
m_unloadedCache = new LevelChunk *[XZSIZE * XZSIZE];
|
||||
memset(m_unloadedCache, 0, XZSIZE * XZSIZE * sizeof(LevelChunk *));
|
||||
//m_unloadedCache = new LevelChunk *[XZSIZE * XZSIZE];
|
||||
//memset(m_unloadedCache, 0, XZSIZE * XZSIZE * sizeof(LevelChunk *));
|
||||
#endif
|
||||
|
||||
InitializeCriticalSectionAndSpinCount(&m_csLoadCreate,4000);
|
||||
|
|
@ -46,15 +46,15 @@ ServerChunkCache::~ServerChunkCache()
|
|||
{
|
||||
storage->WaitForAll(); // MGH - added to fix crash bug 175183
|
||||
delete emptyChunk;
|
||||
delete cache;
|
||||
dynamic_cache.clear(); //delete cache;
|
||||
delete source;
|
||||
|
||||
#ifdef _LARGE_WORLDS
|
||||
for(unsigned int i = 0; i < XZSIZE * XZSIZE; ++i)
|
||||
{
|
||||
delete m_unloadedCache[i];
|
||||
for (auto& pair : dynamic_unloadedCache) {
|
||||
delete pair.second;
|
||||
}
|
||||
delete m_unloadedCache;
|
||||
|
||||
dynamic_unloadedCache.clear();
|
||||
#endif
|
||||
|
||||
for (auto& it : m_loadedChunkList)
|
||||
|
|
@ -73,8 +73,11 @@ bool ServerChunkCache::hasChunk(int x, int z)
|
|||
if( ( ix < 0 ) || ( ix >= XZSIZE ) ) return true;
|
||||
if( ( iz < 0 ) || ( iz >= XZSIZE ) ) return true;
|
||||
int idx = ix * XZSIZE + iz;
|
||||
LevelChunk *lc = cache[idx];
|
||||
if( lc == nullptr ) return false;
|
||||
auto itor = dynamic_cache.find(idx);
|
||||
|
||||
if (itor == dynamic_cache.end()) return false;
|
||||
if (itor->second == nullptr) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -90,11 +93,11 @@ void ServerChunkCache::drop(const int x, const int z)
|
|||
if ((ix < 0) || (ix >= XZSIZE)) return;
|
||||
if ((iz < 0) || (iz >= XZSIZE)) return;
|
||||
const int idx = ix * XZSIZE + iz;
|
||||
LevelChunk* chunk = cache[idx];
|
||||
auto itor = dynamic_cache.find(idx);
|
||||
|
||||
if (chunk != nullptr)
|
||||
if (itor != dynamic_cache.end() && itor->second != nullptr)
|
||||
{
|
||||
m_toDrop.push_back(chunk);
|
||||
m_toDrop.push_back(itor->second);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -121,38 +124,40 @@ LevelChunk *ServerChunkCache::create(int x, int z, bool asyncPostProcess) // 4J
|
|||
if( ( iz < 0 ) || ( iz >= XZSIZE ) ) return emptyChunk;
|
||||
int idx = ix * XZSIZE + iz;
|
||||
|
||||
LevelChunk *chunk = cache[idx];
|
||||
LevelChunk *lastChunk = chunk;
|
||||
LevelChunk* chunk = nullptr;
|
||||
LevelChunk* lastChunk = nullptr;
|
||||
auto itor = dynamic_cache.find(idx);
|
||||
|
||||
if( ( chunk == nullptr ) || ( chunk->x != x ) || ( chunk->z != z ) )
|
||||
{
|
||||
if (itor != dynamic_cache.end()) {
|
||||
chunk = itor->second;
|
||||
lastChunk = chunk;
|
||||
}
|
||||
|
||||
if (chunk == nullptr || chunk->x != x || chunk->z != z) {
|
||||
EnterCriticalSection(&m_csLoadCreate);
|
||||
chunk = load(x, z);
|
||||
chunk = load(x, z);
|
||||
#ifdef MINECRAFT_SERVER_BUILD
|
||||
bool isNewChunk = (chunk == nullptr);
|
||||
#endif
|
||||
if (chunk == nullptr)
|
||||
{
|
||||
if (source == nullptr)
|
||||
{
|
||||
chunk = emptyChunk;
|
||||
}
|
||||
else
|
||||
{
|
||||
chunk = source->getChunk(x, z);
|
||||
}
|
||||
}
|
||||
if (chunk != nullptr)
|
||||
{
|
||||
|
||||
if (chunk == nullptr) {
|
||||
if (source == nullptr) {
|
||||
chunk = emptyChunk;
|
||||
} else {
|
||||
chunk = source->getChunk(x, z);
|
||||
}
|
||||
}
|
||||
|
||||
if (chunk != nullptr) {
|
||||
chunk->load();
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&m_csLoadCreate);
|
||||
|
||||
#if ( defined _WIN64 || defined __LP64__ )
|
||||
if( InterlockedCompareExchangeRelease64((LONG64 *)&cache[idx],(LONG64)chunk,(LONG64)lastChunk) == (LONG64)lastChunk )
|
||||
if (InterlockedCompareExchangeRelease64((LONG64*)&dynamic_cache[idx], (LONG64)chunk, (LONG64)lastChunk) == (LONG64)lastChunk)
|
||||
#else
|
||||
if( InterlockedCompareExchangeRelease((LONG *)&cache[idx],(LONG)chunk,(LONG)lastChunk) == (LONG)lastChunk )
|
||||
if (InterlockedCompareExchangeRelease((LONG*)&dynamic_cache[idx], (LONG)chunk, (LONG)lastChunk) == (LONG)lastChunk)
|
||||
#endif // _DURANGO
|
||||
{
|
||||
// Successfully updated the cache
|
||||
|
|
@ -162,7 +167,7 @@ LevelChunk *ServerChunkCache::create(int x, int z, bool asyncPostProcess) // 4J
|
|||
// they are in fail ServerChunkCache::hasChunk.
|
||||
source->lightChunk(chunk);
|
||||
|
||||
updatePostProcessFlags( x, z );
|
||||
updatePostProcessFlags(x, z);
|
||||
|
||||
m_loadedChunkList.push_back(chunk);
|
||||
|
||||
|
|
@ -179,13 +184,13 @@ LevelChunk *ServerChunkCache::create(int x, int z, bool asyncPostProcess) // 4J
|
|||
// the chunk which is to be processed itself rather than (what I presume to be) the correct position.
|
||||
// Don't think we should change in case it alters level creation.
|
||||
|
||||
if( asyncPostProcess )
|
||||
if (asyncPostProcess)
|
||||
{
|
||||
// 4J Stu - TODO This should also be calling the same code as chunk->checkPostProcess, but then we cannot guarantee we are in the server add the post-process request
|
||||
if ( ( (chunk->terrainPopulated & LevelChunk::sTerrainPopulatedFromHere) == 0) && hasChunk(x + 1, z + 1) && hasChunk(x, z + 1) && hasChunk(x + 1, z)) MinecraftServer::getInstance()->addPostProcessRequest(this, x, z);
|
||||
if (hasChunk(x - 1, z) && ((getChunk(x - 1, z)->terrainPopulated & LevelChunk::sTerrainPopulatedFromHere ) == 0 ) && hasChunk(x - 1, z + 1) && hasChunk(x, z + 1) && hasChunk(x - 1, z)) MinecraftServer::getInstance()->addPostProcessRequest(this, x - 1, z);
|
||||
if (hasChunk(x, z - 1) && ((getChunk(x, z - 1)->terrainPopulated & LevelChunk::sTerrainPopulatedFromHere ) == 0 ) && hasChunk(x + 1, z - 1) && hasChunk(x, z - 1) && hasChunk(x + 1, z)) MinecraftServer::getInstance()->addPostProcessRequest(this, x, z - 1);
|
||||
if (hasChunk(x - 1, z - 1) && ((getChunk(x - 1, z - 1)->terrainPopulated & LevelChunk::sTerrainPopulatedFromHere ) == 0 ) && hasChunk(x - 1, z - 1) && hasChunk(x, z - 1) && hasChunk(x - 1, z)) MinecraftServer::getInstance()->addPostProcessRequest(this, x - 1, z - 1);
|
||||
if (((chunk->terrainPopulated & LevelChunk::sTerrainPopulatedFromHere) == 0) && hasChunk(x + 1, z + 1) && hasChunk(x, z + 1) && hasChunk(x + 1, z)) MinecraftServer::getInstance()->addPostProcessRequest(this, x, z);
|
||||
if (hasChunk(x - 1, z) && ((getChunk(x - 1, z)->terrainPopulated & LevelChunk::sTerrainPopulatedFromHere) == 0) && hasChunk(x - 1, z + 1) && hasChunk(x, z + 1) && hasChunk(x - 1, z)) MinecraftServer::getInstance()->addPostProcessRequest(this, x - 1, z);
|
||||
if (hasChunk(x, z - 1) && ((getChunk(x, z - 1)->terrainPopulated & LevelChunk::sTerrainPopulatedFromHere) == 0) && hasChunk(x + 1, z - 1) && hasChunk(x, z - 1) && hasChunk(x + 1, z)) MinecraftServer::getInstance()->addPostProcessRequest(this, x, z - 1);
|
||||
if (hasChunk(x - 1, z - 1) && ((getChunk(x - 1, z - 1)->terrainPopulated & LevelChunk::sTerrainPopulatedFromHere) == 0) && hasChunk(x - 1, z - 1) && hasChunk(x, z - 1) && hasChunk(x - 1, z)) MinecraftServer::getInstance()->addPostProcessRequest(this, x - 1, z - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -203,32 +208,33 @@ LevelChunk *ServerChunkCache::create(int x, int z, bool asyncPostProcess) // 4J
|
|||
// oxooo ooooo oooxo oxPxo ooxoo
|
||||
// ooooo ooooo ooooo ooxoo ooooo
|
||||
|
||||
if( hasChunk( x - 1, z ) && hasChunk( x - 2, z ) && hasChunk( x - 1, z + 1 ) && hasChunk( x - 1, z - 1 ) ) chunk->checkChests( this, x - 1, z );
|
||||
if( hasChunk( x, z + 1) && hasChunk( x , z + 2 ) && hasChunk( x - 1, z + 1 ) && hasChunk( x + 1, z + 1 ) ) chunk->checkChests( this, x, z + 1);
|
||||
if( hasChunk( x + 1, z ) && hasChunk( x + 2, z ) && hasChunk( x + 1, z + 1 ) && hasChunk( x + 1, z - 1 ) ) chunk->checkChests( this, x + 1, z );
|
||||
if( hasChunk( x, z - 1) && hasChunk( x , z - 2 ) && hasChunk( x - 1, z - 1 ) && hasChunk( x + 1, z - 1 ) ) chunk->checkChests( this, x, z - 1);
|
||||
if( hasChunk( x - 1, z ) && hasChunk( x + 1, z ) && hasChunk ( x, z - 1 ) && hasChunk( x, z + 1 ) ) chunk->checkChests( this, x, z );
|
||||
if (hasChunk(x - 1, z) && hasChunk(x - 2, z) && hasChunk(x - 1, z + 1) && hasChunk(x - 1, z - 1)) chunk->checkChests(this, x - 1, z);
|
||||
if (hasChunk(x, z + 1) && hasChunk(x, z + 2) && hasChunk(x - 1, z + 1) && hasChunk(x + 1, z + 1)) chunk->checkChests(this, x, z + 1);
|
||||
if (hasChunk(x + 1, z) && hasChunk(x + 2, z) && hasChunk(x + 1, z + 1) && hasChunk(x + 1, z - 1)) chunk->checkChests(this, x + 1, z);
|
||||
if (hasChunk(x, z - 1) && hasChunk(x, z - 2) && hasChunk(x - 1, z - 1) && hasChunk(x + 1, z - 1)) chunk->checkChests(this, x, z - 1);
|
||||
if (hasChunk(x - 1, z) && hasChunk(x + 1, z) && hasChunk(x, z - 1) && hasChunk(x, z + 1)) chunk->checkChests(this, x, z);
|
||||
|
||||
LeaveCriticalSection(&m_csLoadCreate);
|
||||
|
||||
#ifdef MINECRAFT_SERVER_BUILD
|
||||
FourKitBridge::FireChunkLoad(level->dimension->id, x, z, isNewChunk);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
// Something else must have updated the cache. Return that chunk and discard this one
|
||||
} else {
|
||||
chunk->unload(true);
|
||||
delete chunk;
|
||||
return cache[idx];
|
||||
|
||||
itor = dynamic_cache.find(idx);
|
||||
if (itor == dynamic_cache.end()) return nullptr;
|
||||
|
||||
return itor->second;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#ifdef __PS3__
|
||||
Sleep(1);
|
||||
#endif // __PS3__
|
||||
return chunk;
|
||||
|
||||
return chunk;
|
||||
}
|
||||
|
||||
// 4J Stu - Split out this function so that we get a chunk without loading entities
|
||||
|
|
@ -241,11 +247,10 @@ LevelChunk *ServerChunkCache::getChunk(int x, int z)
|
|||
if( ( ix < 0 ) || ( ix >= XZSIZE ) ) return emptyChunk;
|
||||
if( ( iz < 0 ) || ( iz >= XZSIZE ) ) return emptyChunk;
|
||||
int idx = ix * XZSIZE + iz;
|
||||
auto itor = dynamic_cache.find(idx);
|
||||
|
||||
LevelChunk *lc = cache[idx];
|
||||
if( lc )
|
||||
{
|
||||
return lc;
|
||||
if (itor != dynamic_cache.end() && itor->second != nullptr) {
|
||||
return itor->second;
|
||||
}
|
||||
|
||||
if( level->isFindingSpawn || autoCreate )
|
||||
|
|
@ -269,18 +274,19 @@ LevelChunk *ServerChunkCache::getChunkLoadedOrUnloaded(int x, int z)
|
|||
if( ( ix < 0 ) || ( ix >= XZSIZE ) ) return emptyChunk;
|
||||
if( ( iz < 0 ) || ( iz >= XZSIZE ) ) return emptyChunk;
|
||||
int idx = ix * XZSIZE + iz;
|
||||
|
||||
LevelChunk *lc = cache[idx];
|
||||
if( lc )
|
||||
{
|
||||
return lc;
|
||||
auto itor = dynamic_cache.find(idx);
|
||||
if (itor != dynamic_cache.end() && itor->second != nullptr) {
|
||||
return itor->second;
|
||||
}
|
||||
}
|
||||
|
||||
lc = m_unloadedCache[idx];
|
||||
if( lc )
|
||||
{
|
||||
return lc;
|
||||
}
|
||||
auto itor = dynamic_unloadedCache.find(idx);
|
||||
if (itor != dynamic_unloadedCache.end() && itor->second != nullptr) {
|
||||
return itor->second;
|
||||
}
|
||||
}
|
||||
|
||||
if( level->isFindingSpawn || autoCreate )
|
||||
{
|
||||
|
|
@ -412,8 +418,13 @@ LevelChunk *ServerChunkCache::load(int x, int z)
|
|||
int ix = x + XZOFFSET;
|
||||
int iz = z + XZOFFSET;
|
||||
int idx = ix * XZSIZE + iz;
|
||||
levelChunk = m_unloadedCache[idx];
|
||||
m_unloadedCache[idx] = nullptr;
|
||||
|
||||
auto itor = dynamic_unloadedCache.find(idx);
|
||||
if (itor != dynamic_unloadedCache.end()) {
|
||||
levelChunk = itor->second;
|
||||
dynamic_unloadedCache.erase(itor);
|
||||
}
|
||||
|
||||
if(levelChunk == nullptr)
|
||||
#endif
|
||||
{
|
||||
|
|
@ -943,7 +954,7 @@ bool ServerChunkCache::tick()
|
|||
if (!level->noSave)
|
||||
{
|
||||
#ifdef _LARGE_WORLDS
|
||||
for (int i = 0; i < 100; i++)
|
||||
for (int i = 0; i < m_toDrop.size(); i++)
|
||||
{
|
||||
if (!m_toDrop.empty())
|
||||
{
|
||||
|
|
@ -973,9 +984,12 @@ bool ServerChunkCache::tick()
|
|||
int ix = chunk->x + XZOFFSET;
|
||||
int iz = chunk->z + XZOFFSET;
|
||||
int idx = ix * XZSIZE + iz;
|
||||
delete m_unloadedCache[idx];
|
||||
m_unloadedCache[idx] = chunk;
|
||||
cache[idx] = nullptr;
|
||||
|
||||
dynamic_unloadedCache.erase(idx);
|
||||
dynamic_cache.erase(idx);
|
||||
|
||||
dynamic_unloadedCache.emplace(idx, chunk);
|
||||
|
||||
#ifdef MINECRAFT_SERVER_BUILD
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -20,13 +20,14 @@ private:
|
|||
public:
|
||||
bool autoCreate;
|
||||
private:
|
||||
LevelChunk **cache;
|
||||
//LevelChunk **cache;
|
||||
vector<LevelChunk *> m_loadedChunkList;
|
||||
ServerLevel *level;
|
||||
|
||||
#ifdef _LARGE_WORLDS
|
||||
deque<LevelChunk *> m_toDrop;
|
||||
LevelChunk **m_unloadedCache;
|
||||
//LevelChunk **m_unloadedCache;
|
||||
std::unordered_map<uint64_t, LevelChunk*> dynamic_unloadedCache;
|
||||
#endif
|
||||
|
||||
// 4J - added for multithreaded support
|
||||
|
|
@ -52,7 +53,7 @@ public:
|
|||
void updateOverwriteHellChunk(LevelChunk* origChunk, LevelChunk* playerChunk, int xMin, int xMax, int zMin, int zMax);
|
||||
|
||||
#endif
|
||||
virtual LevelChunk **getCache() { return cache; } // 4J added
|
||||
virtual std::unordered_map<uint64_t, LevelChunk*>& getCache() { return dynamic_cache; } // 4J added
|
||||
#ifdef MINECRAFT_SERVER_BUILD
|
||||
void regenerateChunk(int x, int z);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ ServerLevel::ServerLevel(MinecraftServer *server, shared_ptr<LevelStorage>levelS
|
|||
// 4J - this this used to be called in parent ctor via a virtual fn
|
||||
chunkSource = createChunkSource();
|
||||
// 4J - optimisation - keep direct reference of underlying cache here
|
||||
chunkSourceCache = chunkSource->getCache();
|
||||
dynamic_chunkSourceCache = chunkSource->getCache();
|
||||
chunkSourceXZSize = chunkSource->m_XZSize;
|
||||
|
||||
// 4J - The listener used to be added in MinecraftServer::loadLevel but we need it to be set up before we do the next couple of things, or else chunks get loaded before we have the entity tracker set up to listen to them
|
||||
|
|
|
|||
|
|
@ -59,6 +59,9 @@ public:
|
|||
bool m_mediumEdgeMoat;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
std::unordered_map<uint64_t, LevelChunk*> dynamic_cache;
|
||||
|
||||
public:
|
||||
virtual ~ChunkSource() {}
|
||||
|
||||
|
|
@ -73,7 +76,7 @@ public:
|
|||
virtual bool tick() = 0;
|
||||
virtual bool shouldSave() = 0;
|
||||
|
||||
virtual LevelChunk **getCache() { return nullptr; } // 4J added
|
||||
virtual std::unordered_map<uint64_t, LevelChunk*>& getCache() { return dynamic_cache; } // 4J added
|
||||
virtual void dataReceived(int x, int z) {} // 4J added
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1333,14 +1333,14 @@ int Level::getBrightness(LightLayer::variety layer, int x, int y, int z)
|
|||
if( ( ix < 0 ) || ( ix >= chunkSourceXZSize ) ) return 0;
|
||||
if( ( iz < 0 ) || ( iz >= chunkSourceXZSize ) ) return 0;
|
||||
int idx = ix * chunkSourceXZSize + iz;
|
||||
LevelChunk *c = chunkSourceCache[idx];
|
||||
auto itor = dynamic_chunkSourceCache.find(idx);
|
||||
|
||||
if( c == nullptr ) return (int)layer;
|
||||
if (itor == dynamic_chunkSourceCache.end() || itor->second == nullptr) return (int)layer;
|
||||
|
||||
if (y < 0) y = 0;
|
||||
if (y >= maxBuildHeight) y = maxBuildHeight - 1;
|
||||
|
||||
return c->getBrightness(layer, x & 15, y, z & 15);
|
||||
return itor->second->getBrightness(layer, x & 15, y, z & 15);
|
||||
}
|
||||
|
||||
// 4J added as optimisation - if all the neighbouring brightesses are going to be in the one chunk, just get
|
||||
|
|
@ -1382,12 +1382,12 @@ void Level::getNeighbourBrightnesses(int *brightnesses, LightLayer::variety laye
|
|||
}
|
||||
|
||||
int idx = ix * chunkSourceXZSize + iz;
|
||||
LevelChunk *c = chunkSourceCache[idx];
|
||||
auto itor = dynamic_chunkSourceCache.find(idx);
|
||||
|
||||
// 4J Stu - The java LightLayer was an enum class type with a member "surrounding" which is what we
|
||||
// were returning here. Surrounding has the same value as the enum value in our C++ code, so just cast
|
||||
// it to an int
|
||||
if( c == nullptr )
|
||||
if(itor == dynamic_chunkSourceCache.end() || itor->second == nullptr )
|
||||
{
|
||||
for( int i = 0; i < 6; i++ )
|
||||
{
|
||||
|
|
@ -1397,7 +1397,7 @@ void Level::getNeighbourBrightnesses(int *brightnesses, LightLayer::variety laye
|
|||
}
|
||||
|
||||
// Single call to the levelchunk too to avoid overhead of virtual fn calls
|
||||
c->getNeighbourBrightnesses(brightnesses, layer, x & 15, y, z & 15);
|
||||
itor->second->getNeighbourBrightnesses(brightnesses, layer, x & 15, y, z & 15);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -524,7 +524,7 @@ public:
|
|||
int getAuxValueForMap(PlayerUID xuid, int dimension, int centreXC, int centreZC, int scale);
|
||||
|
||||
// 4J - optimisation - keep direct reference of underlying cache here
|
||||
LevelChunk **chunkSourceCache;
|
||||
std::unordered_map<uint64_t, LevelChunk*> dynamic_chunkSourceCache;
|
||||
int chunkSourceXZSize;
|
||||
|
||||
// 4J - added for implementation of finite limit to number of item entities, tnt and falling block entities
|
||||
|
|
|
|||
Loading…
Reference in a new issue