From 9af5ed43fd7f85c3b2813485d0a37a559589d694 Mon Sep 17 00:00:00 2001 From: faketruth Date: Sat, 31 Dec 2011 21:08:23 +0000 Subject: [PATCH] Made a couple of functions in cChunk inline, this should speed up several block operations on chunks Players should not spawn in the ground anymore. When an entity was added to cWorld twice (which shouldn't happen actually), the server would crash when the entity is destroyed, this should be fixed now. git-svn-id: http://mc-server.googlecode.com/svn/trunk@158 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- VC2010/MCServer.vcxproj | 1 + VC2010/MCServer.vcxproj.filters | 3 + source/cChunk.cpp | 113 +++--------------------------- source/cChunk.h | 15 +++- source/cChunk.inl.h | 118 ++++++++++++++++++++++++++++++++ source/cClientHandle.cpp | 22 ++---- source/cWorld.cpp | 4 +- 7 files changed, 152 insertions(+), 124 deletions(-) create mode 100644 source/cChunk.inl.h diff --git a/VC2010/MCServer.vcxproj b/VC2010/MCServer.vcxproj index 842d9226f..229310226 100644 --- a/VC2010/MCServer.vcxproj +++ b/VC2010/MCServer.vcxproj @@ -526,6 +526,7 @@ + diff --git a/VC2010/MCServer.vcxproj.filters b/VC2010/MCServer.vcxproj.filters index 2d249551a..23d9dba63 100644 --- a/VC2010/MCServer.vcxproj.filters +++ b/VC2010/MCServer.vcxproj.filters @@ -1362,6 +1362,9 @@ cNoise + + cChunk + diff --git a/source/cChunk.cpp b/source/cChunk.cpp index a5f3943f7..fae2c2507 100644 --- a/source/cChunk.cpp +++ b/source/cChunk.cpp @@ -435,108 +435,6 @@ void cChunk::CreateBlockEntities() m_pState->BlockListCriticalSection.Unlock(); } -char cChunk::GetLight(char* a_Buffer, int a_BlockIdx) -{ - if( a_BlockIdx > -1 && a_BlockIdx < c_NumBlocks ) - { - const int cindex = (a_BlockIdx/2); - if( (a_BlockIdx & 1) == 0 ) - { // First half byte - return (a_Buffer[cindex] & 0x0f); - } - else - { - return ((a_Buffer[cindex] & 0xf0) >> 4); - } - } - return 0; -} - -char cChunk::GetLight(char* a_Buffer, int x, int y, int z) -{ - if( x < 16 && x > -1 && y < 128 && y > -1 && z < 16 && z > -1 ) - { - const int cindex = (y/2) + (z * 64) + (x * 64 * 16); - if( (y & 1) == 0 ) - { // First half byte - return (a_Buffer[cindex] & 0x0f); - } - else - { - return ((a_Buffer[cindex] & 0xf0) >> 4); - } - } - return 0; -} - -void cChunk::SetLight(char* a_Buffer, int a_BlockIdx, char a_Light) -{ - if( a_BlockIdx > -1 && a_BlockIdx < c_NumBlocks ) - { - const int cindex = (a_BlockIdx/2); - if( (a_BlockIdx & 1) == 0 ) - { // First half byte - a_Buffer[cindex] &= 0xf0; // Set first half to 0 - a_Buffer[cindex] |= (a_Light) & 0x0f; - } - else - { - a_Buffer[cindex] &= 0x0f; // Set second half to 0 - a_Buffer[cindex] |= (a_Light << 4) & 0xf0; - } - } -} - -void cChunk::SetLight(char* a_Buffer, int x, int y, int z, char light) -{ - if( x < 16 && x > -1 && y < 128 && y > -1 && z < 16 && z > -1 ) - { - int cindex = (y/2) + (z * 64) + (x * 64 * 16); - if( (y & 1) == 0 ) - { // First half byte - a_Buffer[cindex] &= 0xf0; // Set first half to 0 - a_Buffer[cindex] |= (light) & 0x0f; - } - else - { - a_Buffer[cindex] &= 0x0f; // Set second half to 0 - a_Buffer[cindex] |= (light << 4) & 0xf0; - } - } -} - -inline void cChunk::SpreadLightOfBlock(char* a_LightBuffer, int a_X, int a_Y, int a_Z, char a_Falloff) -{ - unsigned char CurrentLight = GetLight( a_LightBuffer, a_X, a_Y, a_Z ); - SetLight( a_LightBuffer, a_X-1, a_Y, a_Z, MAX(GetLight( a_LightBuffer, a_X-1, a_Y, a_Z ), MAX(0,CurrentLight-a_Falloff) ) ); - SetLight( a_LightBuffer, a_X+1, a_Y, a_Z, MAX(GetLight( a_LightBuffer, a_X+1, a_Y, a_Z ), MAX(0,CurrentLight-a_Falloff) ) ); - SetLight( a_LightBuffer, a_X, a_Y-1, a_Z, MAX(GetLight( a_LightBuffer, a_X, a_Y-1, a_Z ), MAX(0,CurrentLight-a_Falloff) ) ); - SetLight( a_LightBuffer, a_X, a_Y+1, a_Z, MAX(GetLight( a_LightBuffer, a_X, a_Y+1, a_Z ), MAX(0,CurrentLight-a_Falloff) ) ); - SetLight( a_LightBuffer, a_X, a_Y, a_Z-1, MAX(GetLight( a_LightBuffer, a_X, a_Y, a_Z-1 ), MAX(0,CurrentLight-a_Falloff) ) ); - SetLight( a_LightBuffer, a_X, a_Y, a_Z+1, MAX(GetLight( a_LightBuffer, a_X, a_Y, a_Z+1 ), MAX(0,CurrentLight-a_Falloff) ) ); -} - -inline void cChunk::SpreadLightOfBlockX(char* a_LightBuffer, int a_X, int a_Y, int a_Z) -{ - unsigned char CurrentLight = GetLight( a_LightBuffer, a_X, a_Y, a_Z ); - SetLight( a_LightBuffer, a_X-1, a_Y, a_Z, MAX(GetLight( a_LightBuffer, a_X-1, a_Y, a_Z ), CurrentLight-1) ); - SetLight( a_LightBuffer, a_X+1, a_Y, a_Z, MAX(GetLight( a_LightBuffer, a_X+1, a_Y, a_Z ), CurrentLight-1) ); -} - -inline void cChunk::SpreadLightOfBlockY(char* a_LightBuffer, int a_X, int a_Y, int a_Z) -{ - unsigned char CurrentLight = GetLight( a_LightBuffer, a_X, a_Y, a_Z ); - SetLight( a_LightBuffer, a_X, a_Y-1, a_Z, MAX(GetLight( a_LightBuffer, a_X, a_Y-1, a_Z ), CurrentLight-1) ); - SetLight( a_LightBuffer, a_X, a_Y+1, a_Z, MAX(GetLight( a_LightBuffer, a_X, a_Y+1, a_Z ), CurrentLight-1) ); -} - -inline void cChunk::SpreadLightOfBlockZ(char* a_LightBuffer, int a_X, int a_Y, int a_Z) -{ - unsigned char CurrentLight = GetLight( a_LightBuffer, a_X, a_Y, a_Z ); - SetLight( a_LightBuffer, a_X, a_Y, a_Z-1, MAX(GetLight( a_LightBuffer, a_X, a_Y, a_Z-1 ), CurrentLight-1) ); - SetLight( a_LightBuffer, a_X, a_Y, a_Z+1, MAX(GetLight( a_LightBuffer, a_X, a_Y, a_Z+1 ), CurrentLight-1) ); -} - void cChunk::CalculateHeightmap() { m_bCalculateHeightmap = false; @@ -783,8 +681,8 @@ void cChunk::SetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_Block m_pState->BlockListCriticalSection.Unlock(); } - CalculateHeightmap(); - RecalculateLighting(); + //RecalculateHeightmap(); + //RecalculateLighting(); } void cChunk::FastSetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockMeta ) @@ -1258,4 +1156,9 @@ void cChunk::PositionToWorldPosition(int a_ChunkX, int a_ChunkY, int a_ChunkZ, i a_Y = a_ChunkY; a_X = m_PosX * 16 + a_ChunkX; a_Z = m_PosZ * 16 + a_ChunkZ; -} \ No newline at end of file +} + + +#if !C_CHUNK_USE_INLINE +# include "cChunk.inc" +#endif \ No newline at end of file diff --git a/source/cChunk.h b/source/cChunk.h index 5bb64697d..fcf258bab 100644 --- a/source/cChunk.h +++ b/source/cChunk.h @@ -1,5 +1,14 @@ #pragma once +#define C_CHUNK_USE_INLINE 1 + +// Do not touch +#if C_CHUNK_USE_INLINE +# define __C_CHUNK_INLINE__ inline +#else +# define __C_CHUNK_INLINE__ +#endif + #include namespace Json @@ -128,4 +137,8 @@ private: unsigned int m_BlockTickX, m_BlockTickY, m_BlockTickZ; cCriticalSection* m_EntitiesCriticalSection; -}; \ No newline at end of file +}; + +#if C_CHUNK_USE_INLINE +# include "cChunk.inl.h" +#endif \ No newline at end of file diff --git a/source/cChunk.inl.h b/source/cChunk.inl.h new file mode 100644 index 000000000..c47061784 --- /dev/null +++ b/source/cChunk.inl.h @@ -0,0 +1,118 @@ +#ifndef __C_CHUNK_INL_H__ +#define __C_CHUNK_INL_H__ + +#ifndef MAX +# define MAX(a,b) (((a)>(b))?(a):(b)) +#endif + +__C_CHUNK_INLINE__ +char cChunk::GetLight(char* a_Buffer, int a_BlockIdx) +{ + if( a_BlockIdx > -1 && a_BlockIdx < c_NumBlocks ) + { + const int cindex = (a_BlockIdx/2); + if( (a_BlockIdx & 1) == 0 ) + { // First half byte + return (a_Buffer[cindex] & 0x0f); + } + else + { + return ((a_Buffer[cindex] & 0xf0) >> 4); + } + } + return 0; +} + +__C_CHUNK_INLINE__ +char cChunk::GetLight(char* a_Buffer, int x, int y, int z) +{ + if( x < 16 && x > -1 && y < 128 && y > -1 && z < 16 && z > -1 ) + { + const int cindex = (y/2) + (z * 64) + (x * 64 * 16); + if( (y & 1) == 0 ) + { // First half byte + return (a_Buffer[cindex] & 0x0f); + } + else + { + return ((a_Buffer[cindex] & 0xf0) >> 4); + } + } + return 0; +} + +__C_CHUNK_INLINE__ +void cChunk::SetLight(char* a_Buffer, int a_BlockIdx, char a_Light) +{ + if( a_BlockIdx > -1 && a_BlockIdx < c_NumBlocks ) + { + const int cindex = (a_BlockIdx/2); + if( (a_BlockIdx & 1) == 0 ) + { // First half byte + a_Buffer[cindex] &= 0xf0; // Set first half to 0 + a_Buffer[cindex] |= (a_Light) & 0x0f; + } + else + { + a_Buffer[cindex] &= 0x0f; // Set second half to 0 + a_Buffer[cindex] |= (a_Light << 4) & 0xf0; + } + } +} + +__C_CHUNK_INLINE__ +void cChunk::SetLight(char* a_Buffer, int x, int y, int z, char light) +{ + if( x < 16 && x > -1 && y < 128 && y > -1 && z < 16 && z > -1 ) + { + int cindex = (y/2) + (z * 64) + (x * 64 * 16); + if( (y & 1) == 0 ) + { // First half byte + a_Buffer[cindex] &= 0xf0; // Set first half to 0 + a_Buffer[cindex] |= (light) & 0x0f; + } + else + { + a_Buffer[cindex] &= 0x0f; // Set second half to 0 + a_Buffer[cindex] |= (light << 4) & 0xf0; + } + } +} + +__C_CHUNK_INLINE__ +void cChunk::SpreadLightOfBlock(char* a_LightBuffer, int a_X, int a_Y, int a_Z, char a_Falloff) +{ + unsigned char CurrentLight = GetLight( a_LightBuffer, a_X, a_Y, a_Z ); + SetLight( a_LightBuffer, a_X-1, a_Y, a_Z, MAX(GetLight( a_LightBuffer, a_X-1, a_Y, a_Z ), MAX(0,CurrentLight-a_Falloff) ) ); + SetLight( a_LightBuffer, a_X+1, a_Y, a_Z, MAX(GetLight( a_LightBuffer, a_X+1, a_Y, a_Z ), MAX(0,CurrentLight-a_Falloff) ) ); + SetLight( a_LightBuffer, a_X, a_Y-1, a_Z, MAX(GetLight( a_LightBuffer, a_X, a_Y-1, a_Z ), MAX(0,CurrentLight-a_Falloff) ) ); + SetLight( a_LightBuffer, a_X, a_Y+1, a_Z, MAX(GetLight( a_LightBuffer, a_X, a_Y+1, a_Z ), MAX(0,CurrentLight-a_Falloff) ) ); + SetLight( a_LightBuffer, a_X, a_Y, a_Z-1, MAX(GetLight( a_LightBuffer, a_X, a_Y, a_Z-1 ), MAX(0,CurrentLight-a_Falloff) ) ); + SetLight( a_LightBuffer, a_X, a_Y, a_Z+1, MAX(GetLight( a_LightBuffer, a_X, a_Y, a_Z+1 ), MAX(0,CurrentLight-a_Falloff) ) ); +} + +__C_CHUNK_INLINE__ +void cChunk::SpreadLightOfBlockX(char* a_LightBuffer, int a_X, int a_Y, int a_Z) +{ + unsigned char CurrentLight = GetLight( a_LightBuffer, a_X, a_Y, a_Z ); + SetLight( a_LightBuffer, a_X-1, a_Y, a_Z, MAX(GetLight( a_LightBuffer, a_X-1, a_Y, a_Z ), CurrentLight-1) ); + SetLight( a_LightBuffer, a_X+1, a_Y, a_Z, MAX(GetLight( a_LightBuffer, a_X+1, a_Y, a_Z ), CurrentLight-1) ); +} + +__C_CHUNK_INLINE__ +void cChunk::SpreadLightOfBlockY(char* a_LightBuffer, int a_X, int a_Y, int a_Z) +{ + unsigned char CurrentLight = GetLight( a_LightBuffer, a_X, a_Y, a_Z ); + SetLight( a_LightBuffer, a_X, a_Y-1, a_Z, MAX(GetLight( a_LightBuffer, a_X, a_Y-1, a_Z ), CurrentLight-1) ); + SetLight( a_LightBuffer, a_X, a_Y+1, a_Z, MAX(GetLight( a_LightBuffer, a_X, a_Y+1, a_Z ), CurrentLight-1) ); +} + +__C_CHUNK_INLINE__ +void cChunk::SpreadLightOfBlockZ(char* a_LightBuffer, int a_X, int a_Y, int a_Z) +{ + unsigned char CurrentLight = GetLight( a_LightBuffer, a_X, a_Y, a_Z ); + SetLight( a_LightBuffer, a_X, a_Y, a_Z-1, MAX(GetLight( a_LightBuffer, a_X, a_Y, a_Z-1 ), CurrentLight-1) ); + SetLight( a_LightBuffer, a_X, a_Y, a_Z+1, MAX(GetLight( a_LightBuffer, a_X, a_Y, a_Z+1 ), CurrentLight-1) ); +} + +#endif \ No newline at end of file diff --git a/source/cClientHandle.cpp b/source/cClientHandle.cpp index 6badd5ae1..6f38a1f27 100644 --- a/source/cClientHandle.cpp +++ b/source/cClientHandle.cpp @@ -516,25 +516,19 @@ void cClientHandle::HandlePacket( cPacket* a_Packet ) cPacket_Chat Joined( m_pState->Username + " joined the game!"); cRoot::Get()->GetServer()->Broadcast( Joined, this ); } - int posx = (int) m_Player->GetPosX(); - int posy = (int) m_Player->GetPosY(); - int posz = (int) m_Player->GetPosZ(); + // Now initialize player (adds to entity list etc.) cWorld* PlayerWorld = cRoot::Get()->GetWorld( m_Player->GetLoadedWorldName() ); if( !PlayerWorld ) PlayerWorld = cRoot::Get()->GetDefaultWorld(); - m_Player->Initialize( PlayerWorld ); // TODO - Get correct world for player - - // Broadcasts to all but this ( this is actually handled in cChunk.cpp, after entity is added to the chunk ) - //m_Player->SpawnOn( 0 ); - - // Send all already connected players to new player - //cRoot::Get()->GetServer()->SendAllEntitiesTo( this ); + m_Player->Initialize( PlayerWorld ); // Then we can start doing more stuffs! :D m_bLoggedIn = true; LOG("%s completely logged in", GetUsername() ); - m_Player->TeleportTo( posx, posy, posz ); StreamChunks(); + + // Send position + Send( cPacket_PlayerMoveLook( m_Player ) ); } break; case E_KEEP_ALIVE: @@ -1268,7 +1262,7 @@ void cClientHandle::Tick(float a_Dt) // Spawn player (only serversided, so data is loaded) m_Player = new cPlayer( this, GetUsername() ); // !!DO NOT INITIALIZE!! <- is done after receiving MoveLook Packet - cWorld* World = cRoot::Get()->GetWorld( m_Player->GetLoadedWorldName() ); // TODO - Get the correct world or better yet, move this to the main thread so we don't have to lock anything + cWorld* World = cRoot::Get()->GetWorld( m_Player->GetLoadedWorldName() ); if( !World ) World = cRoot::Get()->GetDefaultWorld(); World->LockEntities(); m_Player->LoginSetGameMode ( World->GetGameMode() ); //set player's gamemode to server's gamemode at login. TODO: set to last player's gamemode at logout @@ -1295,9 +1289,6 @@ void cClientHandle::Tick(float a_Dt) Send( RainPacket ); } - // Send position - Send( cPacket_PlayerMoveLook( m_Player ) ); - // Send time Send( cPacket_TimeUpdate( World->GetWorldTime() ) ); @@ -1310,7 +1301,6 @@ void cClientHandle::Tick(float a_Dt) Health.m_Food = m_Player->GetFood(); Health.m_Saturation = m_Player->GetFoodSaturation(); Send(Health); - //Send( cPacket_UpdateHealth( (short)m_Player->GetHealth() ) ); World->UnlockEntities(); } diff --git a/source/cWorld.cpp b/source/cWorld.cpp index 501f78332..0b1ee7010 100644 --- a/source/cWorld.cpp +++ b/source/cWorld.cpp @@ -415,8 +415,8 @@ void cWorld::Tick(float a_Dt) { LOG("Destroy that entity! %i", (*itr)->GetUniqueID() ); cEntity* RemoveMe = *itr; - itr++; - AddToRemoveEntityQueue( *RemoveMe ); + itr = m_pState->AllEntities.erase( itr ); + m_pState->RemoveEntityQueue.push_back( RemoveMe ); continue; } (*itr)->Tick(a_Dt);