This bug should be fixed now http://mc-server.org/support/index.php?do=details&task_id=112
git-svn-id: http://mc-server.googlecode.com/svn/trunk@145 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
parent
85debf0860
commit
9e4184ca8d
@ -58,13 +58,15 @@ typedef std::list< cBlockEntity* > BlockEntityList;
|
|||||||
typedef std::list< cEntity* > EntityList;
|
typedef std::list< cEntity* > EntityList;
|
||||||
struct cChunk::sChunkState
|
struct cChunk::sChunkState
|
||||||
{
|
{
|
||||||
std::map< unsigned int, int > ToTickBlocks;
|
|
||||||
FurnaceEntityList TickBlockEntities;
|
FurnaceEntityList TickBlockEntities;
|
||||||
std::vector< unsigned int > PendingSendBlocks;
|
std::map< unsigned int, int > ToTickBlocks; // Protected by BlockListCriticalSection
|
||||||
|
std::vector< unsigned int > PendingSendBlocks; // Protected by BlockListCriticalSection
|
||||||
ClientHandleList LoadedByClient;
|
ClientHandleList LoadedByClient;
|
||||||
ClientHandleList UnloadQuery;
|
ClientHandleList UnloadQuery;
|
||||||
BlockEntityList BlockEntities;
|
BlockEntityList BlockEntities; // Protected by BlockListCriticalSection
|
||||||
EntityList Entities;
|
EntityList Entities;
|
||||||
|
|
||||||
|
cCriticalSection BlockListCriticalSection;
|
||||||
};
|
};
|
||||||
|
|
||||||
cChunk::~cChunk()
|
cChunk::~cChunk()
|
||||||
@ -75,11 +77,13 @@ cChunk::~cChunk()
|
|||||||
LOGWARN("WARNING: Deleting cChunk while it contains %i clients!", m_pState->LoadedByClient.size() );
|
LOGWARN("WARNING: Deleting cChunk while it contains %i clients!", m_pState->LoadedByClient.size() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_pState->BlockListCriticalSection.Lock();
|
||||||
for( std::list<cBlockEntity*>::iterator itr = m_pState->BlockEntities.begin(); itr != m_pState->BlockEntities.end(); ++itr)
|
for( std::list<cBlockEntity*>::iterator itr = m_pState->BlockEntities.begin(); itr != m_pState->BlockEntities.end(); ++itr)
|
||||||
{
|
{
|
||||||
delete *itr;
|
delete *itr;
|
||||||
}
|
}
|
||||||
m_pState->BlockEntities.clear();
|
m_pState->BlockEntities.clear();
|
||||||
|
m_pState->BlockListCriticalSection.Unlock();
|
||||||
|
|
||||||
LockEntities();
|
LockEntities();
|
||||||
if( m_pState->Entities.size() > 0 )
|
if( m_pState->Entities.size() > 0 )
|
||||||
@ -143,7 +147,9 @@ void cChunk::Initialize()
|
|||||||
|
|
||||||
// During generation, some blocks might have been set by using (Fast)SetBlock() causing this list to fill.
|
// During generation, some blocks might have been set by using (Fast)SetBlock() causing this list to fill.
|
||||||
// This chunk has not been sent to anybody yet, so there is no need for separately sending block changes when you can send an entire chunk
|
// This chunk has not been sent to anybody yet, so there is no need for separately sending block changes when you can send an entire chunk
|
||||||
|
m_pState->BlockListCriticalSection.Lock();
|
||||||
m_pState->PendingSendBlocks.clear();
|
m_pState->PendingSendBlocks.clear();
|
||||||
|
m_pState->BlockListCriticalSection.Unlock();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -159,6 +165,7 @@ void cChunk::Tick(float a_Dt)
|
|||||||
if( m_bCalculateHeightmap )
|
if( m_bCalculateHeightmap )
|
||||||
CalculateHeightmap();
|
CalculateHeightmap();
|
||||||
|
|
||||||
|
m_pState->BlockListCriticalSection.Lock();
|
||||||
unsigned int PendingSendBlocks = m_pState->PendingSendBlocks.size();
|
unsigned int PendingSendBlocks = m_pState->PendingSendBlocks.size();
|
||||||
if( PendingSendBlocks > 1 )
|
if( PendingSendBlocks > 1 )
|
||||||
{
|
{
|
||||||
@ -205,6 +212,7 @@ void cChunk::Tick(float a_Dt)
|
|||||||
}
|
}
|
||||||
m_pState->PendingSendBlocks.clear();
|
m_pState->PendingSendBlocks.clear();
|
||||||
}
|
}
|
||||||
|
m_pState->BlockListCriticalSection.Unlock();
|
||||||
|
|
||||||
while( !m_pState->UnloadQuery.empty() )
|
while( !m_pState->UnloadQuery.empty() )
|
||||||
{
|
{
|
||||||
@ -216,10 +224,11 @@ void cChunk::Tick(float a_Dt)
|
|||||||
m_pState->UnloadQuery.remove( *m_pState->UnloadQuery.begin() );
|
m_pState->UnloadQuery.remove( *m_pState->UnloadQuery.begin() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_pState->BlockListCriticalSection.Lock();
|
||||||
std::map< unsigned int, int > ToTickBlocks = m_pState->ToTickBlocks;
|
std::map< unsigned int, int > ToTickBlocks = m_pState->ToTickBlocks;
|
||||||
//unsigned int NumTickBlocks = ToTickBlocks.size();
|
|
||||||
//if( NumTickBlocks > 0 ) LOG("To tick: %i", NumTickBlocks );
|
|
||||||
m_pState->ToTickBlocks.clear();
|
m_pState->ToTickBlocks.clear();
|
||||||
|
m_pState->BlockListCriticalSection.Unlock();
|
||||||
|
|
||||||
bool isRedstone = false;
|
bool isRedstone = false;
|
||||||
for( std::map< unsigned int, int>::iterator itr = ToTickBlocks.begin(); itr != ToTickBlocks.end(); ++itr )
|
for( std::map< unsigned int, int>::iterator itr = ToTickBlocks.begin(); itr != ToTickBlocks.end(); ++itr )
|
||||||
{
|
{
|
||||||
@ -309,6 +318,7 @@ void cChunk::Tick(float a_Dt)
|
|||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
MTRand r1;
|
MTRand r1;
|
||||||
// Tick dem blocks
|
// Tick dem blocks
|
||||||
int RandomX = r1.randInt();
|
int RandomX = r1.randInt();
|
||||||
@ -388,6 +398,7 @@ char cChunk::GetHeight( int a_X, int a_Z )
|
|||||||
|
|
||||||
void cChunk::CreateBlockEntities()
|
void cChunk::CreateBlockEntities()
|
||||||
{
|
{
|
||||||
|
m_pState->BlockListCriticalSection.Lock();
|
||||||
for(int x = 0; x < 16; x++)
|
for(int x = 0; x < 16; x++)
|
||||||
{
|
{
|
||||||
for(int z = 0; z < 16; z++)
|
for(int z = 0; z < 16; z++)
|
||||||
@ -421,6 +432,7 @@ void cChunk::CreateBlockEntities()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
m_pState->BlockListCriticalSection.Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
char cChunk::GetLight(char* a_Buffer, int a_BlockIdx)
|
char cChunk::GetLight(char* a_Buffer, int a_BlockIdx)
|
||||||
@ -708,10 +720,12 @@ void cChunk::Send( cClientHandle* a_Client )
|
|||||||
a_Client->Send( PreChunk );
|
a_Client->Send( PreChunk );
|
||||||
a_Client->Send( cPacket_MapChunk( this ) );
|
a_Client->Send( cPacket_MapChunk( this ) );
|
||||||
|
|
||||||
|
m_pState->BlockListCriticalSection.Lock();
|
||||||
for( BlockEntityList::iterator itr = m_pState->BlockEntities.begin(); itr != m_pState->BlockEntities.end(); ++itr )
|
for( BlockEntityList::iterator itr = m_pState->BlockEntities.begin(); itr != m_pState->BlockEntities.end(); ++itr )
|
||||||
{
|
{
|
||||||
(*itr)->SendTo( a_Client );
|
(*itr)->SendTo( a_Client );
|
||||||
}
|
}
|
||||||
|
m_pState->BlockListCriticalSection.Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void cChunk::SetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockMeta )
|
void cChunk::SetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockMeta )
|
||||||
@ -732,6 +746,7 @@ void cChunk::SetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_Block
|
|||||||
if( OldBlockType != a_BlockType || OldBlockMeta != a_BlockMeta )
|
if( OldBlockType != a_BlockType || OldBlockMeta != a_BlockMeta )
|
||||||
{
|
{
|
||||||
//LOG("Old: %i %i New: %i %i", OldBlockType, OldBlockMeta, a_BlockType, a_BlockMeta );
|
//LOG("Old: %i %i New: %i %i", OldBlockType, OldBlockMeta, a_BlockType, a_BlockMeta );
|
||||||
|
m_pState->BlockListCriticalSection.Lock();
|
||||||
m_pState->PendingSendBlocks.push_back( index );
|
m_pState->PendingSendBlocks.push_back( index );
|
||||||
|
|
||||||
m_pState->ToTickBlocks[ MakeIndex( a_X, a_Y, a_Z ) ]++;
|
m_pState->ToTickBlocks[ MakeIndex( a_X, a_Y, a_Z ) ]++;
|
||||||
@ -764,6 +779,8 @@ void cChunk::SetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_Block
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
m_pState->BlockListCriticalSection.Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
CalculateHeightmap();
|
CalculateHeightmap();
|
||||||
@ -781,7 +798,10 @@ void cChunk::FastSetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_B
|
|||||||
const int index = a_Y + (a_Z * 128) + (a_X * 128 * 16);
|
const int index = a_Y + (a_Z * 128) + (a_X * 128 * 16);
|
||||||
const char OldBlock = m_BlockType[index];
|
const char OldBlock = m_BlockType[index];
|
||||||
m_BlockType[index] = a_BlockType;
|
m_BlockType[index] = a_BlockType;
|
||||||
|
|
||||||
|
m_pState->BlockListCriticalSection.Lock();
|
||||||
m_pState->PendingSendBlocks.push_back( index );
|
m_pState->PendingSendBlocks.push_back( index );
|
||||||
|
m_pState->BlockListCriticalSection.Unlock();
|
||||||
SetLight( m_BlockMeta, index, a_BlockMeta );
|
SetLight( m_BlockMeta, index, a_BlockMeta );
|
||||||
|
|
||||||
// ONLY recalculate lighting if it's necessary!
|
// ONLY recalculate lighting if it's necessary!
|
||||||
@ -800,7 +820,9 @@ void cChunk::SendBlockTo( int a_X, int a_Y, int a_Z, cClientHandle* a_Client )
|
|||||||
{
|
{
|
||||||
if( a_Client == 0 )
|
if( a_Client == 0 )
|
||||||
{
|
{
|
||||||
|
m_pState->BlockListCriticalSection.Lock();
|
||||||
m_pState->PendingSendBlocks.push_back( MakeIndex( a_X, a_Y, a_Z ) );
|
m_pState->PendingSendBlocks.push_back( MakeIndex( a_X, a_Y, a_Z ) );
|
||||||
|
m_pState->BlockListCriticalSection.Unlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -823,12 +845,16 @@ void cChunk::SendBlockTo( int a_X, int a_Y, int a_Z, cClientHandle* a_Client )
|
|||||||
|
|
||||||
void cChunk::AddBlockEntity( cBlockEntity* a_BlockEntity )
|
void cChunk::AddBlockEntity( cBlockEntity* a_BlockEntity )
|
||||||
{
|
{
|
||||||
|
m_pState->BlockListCriticalSection.Lock();
|
||||||
m_pState->BlockEntities.push_back( a_BlockEntity );
|
m_pState->BlockEntities.push_back( a_BlockEntity );
|
||||||
|
m_pState->BlockListCriticalSection.Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void cChunk::RemoveBlockEntity( cBlockEntity* a_BlockEntity )
|
void cChunk::RemoveBlockEntity( cBlockEntity* a_BlockEntity )
|
||||||
{
|
{
|
||||||
|
m_pState->BlockListCriticalSection.Lock();
|
||||||
m_pState->BlockEntities.remove( a_BlockEntity );
|
m_pState->BlockEntities.remove( a_BlockEntity );
|
||||||
|
m_pState->BlockListCriticalSection.Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void cChunk::AddClient( cClientHandle* a_Client )
|
void cChunk::AddClient( cClientHandle* a_Client )
|
||||||
@ -915,15 +941,19 @@ char cChunk::GetBlock( int a_BlockIdx )
|
|||||||
|
|
||||||
cBlockEntity* cChunk::GetBlockEntity( int a_X, int a_Y, int a_Z )
|
cBlockEntity* cChunk::GetBlockEntity( int a_X, int a_Y, int a_Z )
|
||||||
{
|
{
|
||||||
|
m_pState->BlockListCriticalSection.Lock();
|
||||||
for( std::list<cBlockEntity*>::iterator itr = m_pState->BlockEntities.begin(); itr != m_pState->BlockEntities.end(); ++itr)
|
for( std::list<cBlockEntity*>::iterator itr = m_pState->BlockEntities.begin(); itr != m_pState->BlockEntities.end(); ++itr)
|
||||||
{
|
{
|
||||||
if( (*itr)->GetPosX() == a_X &&
|
if( (*itr)->GetPosX() == a_X &&
|
||||||
(*itr)->GetPosY() == a_Y &&
|
(*itr)->GetPosY() == a_Y &&
|
||||||
(*itr)->GetPosZ() == a_Z )
|
(*itr)->GetPosZ() == a_Z )
|
||||||
{
|
{
|
||||||
return *itr;
|
cBlockEntity* BlockEnt = *itr;
|
||||||
|
m_pState->BlockListCriticalSection.Unlock();
|
||||||
|
return BlockEnt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
m_pState->BlockListCriticalSection.Unlock();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -942,6 +972,7 @@ bool cChunk::LoadFromDisk()
|
|||||||
if( fread( m_BlockData, sizeof(char)*c_BlockDataSize, 1, f) != 1 ) { LOGERROR("ERROR READING FROM FILE %s", SourceFile); fclose(f); return false; }
|
if( fread( m_BlockData, sizeof(char)*c_BlockDataSize, 1, f) != 1 ) { LOGERROR("ERROR READING FROM FILE %s", SourceFile); fclose(f); return false; }
|
||||||
|
|
||||||
// Now load Block Entities
|
// Now load Block Entities
|
||||||
|
m_pState->BlockListCriticalSection.Lock();
|
||||||
ENUM_BLOCK_ID BlockType;
|
ENUM_BLOCK_ID BlockType;
|
||||||
while( fread( &BlockType, sizeof(ENUM_BLOCK_ID), 1, f) == 1 )
|
while( fread( &BlockType, sizeof(ENUM_BLOCK_ID), 1, f) == 1 )
|
||||||
{
|
{
|
||||||
@ -992,6 +1023,7 @@ bool cChunk::LoadFromDisk()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
m_pState->BlockListCriticalSection.Unlock();
|
||||||
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
@ -1040,6 +1072,7 @@ bool cChunk::SaveToDisk()
|
|||||||
{
|
{
|
||||||
fwrite( m_BlockData, sizeof(char)*c_BlockDataSize, 1, f );
|
fwrite( m_BlockData, sizeof(char)*c_BlockDataSize, 1, f );
|
||||||
|
|
||||||
|
m_pState->BlockListCriticalSection.Lock();
|
||||||
// Now write Block Entities
|
// Now write Block Entities
|
||||||
for( std::list<cBlockEntity*>::iterator itr = m_pState->BlockEntities.begin(); itr != m_pState->BlockEntities.end(); ++itr)
|
for( std::list<cBlockEntity*>::iterator itr = m_pState->BlockEntities.begin(); itr != m_pState->BlockEntities.end(); ++itr)
|
||||||
{
|
{
|
||||||
@ -1069,6 +1102,7 @@ bool cChunk::SaveToDisk()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
m_pState->BlockListCriticalSection.Unlock();
|
||||||
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return true;
|
return true;
|
||||||
@ -1092,6 +1126,7 @@ void cChunk::Broadcast( const cPacket & a_Packet, cClientHandle* a_Exclude /* =
|
|||||||
|
|
||||||
void cChunk::LoadFromJson( const Json::Value & a_Value )
|
void cChunk::LoadFromJson( const Json::Value & a_Value )
|
||||||
{
|
{
|
||||||
|
m_pState->BlockListCriticalSection.Lock();
|
||||||
// Load chests
|
// Load chests
|
||||||
Json::Value AllChests = a_Value.get("Chests", Json::nullValue);
|
Json::Value AllChests = a_Value.get("Chests", Json::nullValue);
|
||||||
if( !AllChests.empty() )
|
if( !AllChests.empty() )
|
||||||
@ -1142,6 +1177,7 @@ void cChunk::LoadFromJson( const Json::Value & a_Value )
|
|||||||
else m_pState->BlockEntities.push_back( SignEntity );
|
else m_pState->BlockEntities.push_back( SignEntity );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
m_pState->BlockListCriticalSection.Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void cChunk::SaveToJson( Json::Value & a_Value )
|
void cChunk::SaveToJson( Json::Value & a_Value )
|
||||||
@ -1149,6 +1185,7 @@ void cChunk::SaveToJson( Json::Value & a_Value )
|
|||||||
Json::Value AllChests;
|
Json::Value AllChests;
|
||||||
Json::Value AllFurnaces;
|
Json::Value AllFurnaces;
|
||||||
Json::Value AllSigns;
|
Json::Value AllSigns;
|
||||||
|
m_pState->BlockListCriticalSection.Lock();
|
||||||
for( std::list<cBlockEntity*>::iterator itr = m_pState->BlockEntities.begin(); itr != m_pState->BlockEntities.end(); ++itr)
|
for( std::list<cBlockEntity*>::iterator itr = m_pState->BlockEntities.begin(); itr != m_pState->BlockEntities.end(); ++itr)
|
||||||
{
|
{
|
||||||
cBlockEntity* BlockEntity = *itr;
|
cBlockEntity* BlockEntity = *itr;
|
||||||
@ -1183,6 +1220,7 @@ void cChunk::SaveToJson( Json::Value & a_Value )
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
m_pState->BlockListCriticalSection.Unlock();
|
||||||
|
|
||||||
if( !AllChests.empty() )
|
if( !AllChests.empty() )
|
||||||
a_Value["Chests"] = AllChests;
|
a_Value["Chests"] = AllChests;
|
||||||
|
Loading…
Reference in New Issue
Block a user