From 4f17362aeb80e5339c58a5d3b0fbaeb88d9e701c Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Mon, 13 Feb 2012 21:47:03 +0000 Subject: Rewritten most of the code for multithreading; still not 100%, but getting there. If this commit proves to be too problematic, we can always undo it. git-svn-id: http://mc-server.googlecode.com/svn/trunk@251 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/cPlayer.cpp | 200 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 117 insertions(+), 83 deletions(-) (limited to 'source/cPlayer.cpp') diff --git a/source/cPlayer.cpp b/source/cPlayer.cpp index fa833ff47..1086e862a 100644 --- a/source/cPlayer.cpp +++ b/source/cPlayer.cpp @@ -126,39 +126,39 @@ cPlayer::~cPlayer(void) delete m_CreativeInventory; } delete m_pState; - GetWorld()->RemovePlayer( this ); // TODO - Remove from correct world? Or get rid of this? + m_World->RemovePlayer( this ); } -void cPlayer::SpawnOn( cClientHandle* a_Target ) + + +cPacket * cPlayer::GetSpawnPacket(void) const { - if( a_Target == m_ClientHandle || !m_bVisible ) return; - LOG("cPlayer::SpawnOn -> Sending %s to %s", m_pState->PlayerName.c_str(), (a_Target) ? a_Target->GetUsername().c_str() : "Everybody" ); - cPacket_NamedEntitySpawn SpawnPacket; - SpawnPacket.m_UniqueID = m_UniqueID; - SpawnPacket.m_PlayerName = m_pState->PlayerName; - SpawnPacket.m_PosX = (int)(m_Pos->x * 32); - SpawnPacket.m_PosY = (int)(m_Pos->y * 32); - SpawnPacket.m_PosZ = (int)(m_Pos->z * 32); - SpawnPacket.m_Rotation = (char)((m_Rot->x/360.f)*256); - SpawnPacket.m_Pitch = (char)((m_Rot->y/360.f)*256); - SpawnPacket.m_CurrentItem = (short)m_Inventory->GetEquippedItem().m_ItemID; - if( a_Target == 0 ) - { - cChunk* Chunk = GetWorld()->GetChunk( m_ChunkX, m_ChunkY, m_ChunkZ ); - Chunk->Broadcast( SpawnPacket, m_ClientHandle ); - } - else + if (!m_bVisible ) { - a_Target->Send( SpawnPacket ); + return NULL; } + + cPacket_NamedEntitySpawn * SpawnPacket = new cPacket_NamedEntitySpawn; + SpawnPacket->m_UniqueID = m_UniqueID; + SpawnPacket->m_PlayerName = m_pState->PlayerName; + SpawnPacket->m_PosX = (int)(m_Pos->x * 32); + SpawnPacket->m_PosY = (int)(m_Pos->y * 32); + SpawnPacket->m_PosZ = (int)(m_Pos->z * 32); + SpawnPacket->m_Rotation = (char)((m_Rot->x / 360.f) * 256); + SpawnPacket->m_Pitch = (char)((m_Rot->y / 360.f) * 256); + SpawnPacket->m_CurrentItem = (short)m_Inventory->GetEquippedItem().m_ItemID; + return SpawnPacket; } + + + + void cPlayer::Tick(float a_Dt) { - cChunk* InChunk = GetWorld()->GetChunk( m_ChunkX, m_ChunkY, m_ChunkZ ); - if ( !InChunk ) return; + cChunkPtr InChunk = GetWorld()->GetChunk( m_ChunkX, m_ChunkY, m_ChunkZ ); cPawn::Tick(a_Dt); @@ -168,16 +168,18 @@ void cPlayer::Tick(float a_Dt) InChunk->Broadcast( EntityLook, m_ClientHandle ); m_bDirtyOrientation = false; } - else if(m_bDirtyPosition ) + else if (m_bDirtyPosition ) { cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::E_PLUGIN_PLAYER_MOVE, 1, this ); float DiffX = (float)(GetPosX() - m_LastPosX ); float DiffY = (float)(GetPosY() - m_LastPosY ); float DiffZ = (float)(GetPosZ() - m_LastPosZ ); - float SqrDist = DiffX*DiffX + DiffY*DiffY + DiffZ*DiffZ; - if( SqrDist > 4*4 // 4 blocks is max Relative Move - || cWorld::GetTime() - m_TimeLastTeleportPacket > 2 ) // Send an absolute position every 2 seconds + float SqrDist = DiffX * DiffX + DiffY * DiffY + DiffZ * DiffZ; + if ( + (SqrDist > 4 * 4) || // 4 blocks is max Relative Move + (cWorld::GetTime() - m_TimeLastTeleportPacket > 2 ) // Send an absolute position every 2 seconds + ) { //LOG("Teleported %f", sqrtf(SqrDist) ); cPacket_TeleportEntity TeleportEntity( this ); @@ -216,49 +218,23 @@ void cPlayer::Tick(float a_Dt) if( m_Health > 0 ) // make sure player is alive { - if( cWorld::GetTime() - m_TimeLastPickupCheck > 0.5f ) // Each 0.5 second, check for pickups - { - m_TimeLastPickupCheck = cWorld::GetTime(); - // and also check if near a pickup - // TODO: Don't only check in current chunks, but also close chunks (chunks within range) - cChunk* Chunk = GetWorld()->GetChunk( m_ChunkX, m_ChunkY, m_ChunkZ ); - Chunk->LockEntities(); - cWorld::EntityList Entities = Chunk->GetEntities(); - for( cWorld::EntityList::iterator itr = Entities.begin(); itr != Entities.end();++itr) - { - if( (*itr)->GetEntityType() != cEntity::E_PICKUP ) continue; // Only pickups - float DiffX = (float)((*itr)->GetPosX() - GetPosX() ); - float DiffY = (float)((*itr)->GetPosY() - GetPosY() ); - float DiffZ = (float)((*itr)->GetPosZ() - GetPosZ() ); - float SqrDist = DiffX*DiffX + DiffY*DiffY + DiffZ*DiffZ; - if(SqrDist < 1.5f*1.5f) // 1.5 block - { - cPickup* Pickup = reinterpret_cast(*itr); - Pickup->CollectedBy( this ); - } - } - Chunk->UnlockEntities(); - } + // TODO: Don't only check in current chunks, but also close chunks (chunks within range) + GetWorld()->GetChunk(m_ChunkX, m_ChunkY, m_ChunkZ)->CollectPickupsByPlayer(this); } cTimer t1; // Send Player List (Once per m_LastPlayerListTime/1000 ms) if (m_LastPlayerListTime + cPlayer::PLAYER_LIST_TIME_MS <= t1.GetNowTime()) { - cWorld::PlayerList PlayerList = cRoot::Get()->GetWorld()->GetAllPlayers(); - for( cWorld::PlayerList::iterator itr = PlayerList.begin(); itr != PlayerList.end(); ++itr) - { - if ((*itr) && (*itr)->GetClientHandle() && !((*itr)->GetClientHandle()->IsDestroyed())) - { - cPacket_PlayerListItem PlayerListItem(GetColor() + m_pState->PlayerName, true, GetClientHandle()->GetPing()); - (*itr)->GetClientHandle()->Send( PlayerListItem ); - } - } + m_World->SendPlayerList(this); m_LastPlayerListTime = t1.GetNowTime(); } - } + + + + void cPlayer::SetTouchGround( bool a_bTouchGround ) { m_bTouchGround = a_bTouchGround; @@ -439,30 +415,36 @@ void cPlayer::CloseWindow(char a_WindowType) ChestClose.m_PosZ = block->GetPosZ(); ChestClose.m_Byte1 = 1; ChestClose.m_Byte2 = 0; - cWorld::PlayerList PlayerList = cRoot::Get()->GetWorld()->GetAllPlayers(); - for( cWorld::PlayerList::iterator itr = PlayerList.begin(); itr != PlayerList.end(); ++itr ) - { - if ((*itr) && (*itr)->GetClientHandle() && !((*itr)->GetClientHandle()->IsDestroyed())) { - (*itr)->GetClientHandle()->Send( ChestClose ); - } - } + m_World->Broadcast(ChestClose); } m_CurrentWindow->Close( *this ); } - m_CurrentWindow = 0; + m_CurrentWindow = NULL; } + + + + void cPlayer::SetLastBlockActionTime() { m_LastBlockActionTime = cRoot::Get()->GetWorld()->GetTime(); } + + + + void cPlayer::SetLastBlockActionCnt( int a_LastBlockActionCnt ) { m_LastBlockActionCnt = a_LastBlockActionCnt; } + + + + void cPlayer::SetGameMode( int a_GameMode ) { if ( (a_GameMode < 2) && (a_GameMode >= 0) ) @@ -487,21 +469,37 @@ void cPlayer::SetGameMode( int a_GameMode ) } } + + + + void cPlayer::LoginSetGameMode( int a_GameMode ) { m_GameMode = a_GameMode; } + + + + void cPlayer::SetIP( std::string a_IP ) { - m_IP = a_IP; + m_IP = a_IP; } + + + + void cPlayer::SendMessage( const char* a_Message ) { m_ClientHandle->Send( cPacket_Chat( a_Message ) ); } + + + + void cPlayer::TeleportTo( const double & a_PosX, const double & a_PosY, const double & a_PosZ ) { SetPosition( a_PosX, a_PosY, a_PosZ ); @@ -515,31 +513,43 @@ void cPlayer::TeleportTo( const double & a_PosX, const double & a_PosY, const do m_ClientHandle->Send( PlayerPosition ); } + + + + void cPlayer::MoveTo( const Vector3d & a_NewPos ) { // TODO: should do some checks to see if player is not moving through terrain SetPosition( a_NewPos ); } + + + + void cPlayer::SetVisible( bool a_bVisible ) { - if( a_bVisible == true && m_bVisible == false ) // Make visible + if (a_bVisible && !m_bVisible) // Make visible { m_bVisible = true; - SpawnOn( 0 ); // Spawn on everybody + SpawnOn( NULL ); // Spawn on everybody } - if( a_bVisible == false && m_bVisible == true ) + if (!a_bVisible && m_bVisible) { m_bVisible = false; cPacket_DestroyEntity DestroyEntity( this ); - cChunk* Chunk = GetWorld()->GetChunkUnreliable( m_ChunkX, m_ChunkY, m_ChunkZ ); - if( Chunk ) + cChunkPtr Chunk = GetWorld()->GetChunk( m_ChunkX, m_ChunkY, m_ChunkZ ); + if ( Chunk != NULL ) { Chunk->Broadcast( DestroyEntity ); // Destroy on all clients } } } + + + + void cPlayer::AddToGroup( const char* a_GroupName ) { cGroup* Group = cRoot::Get()->GetGroupManager()->GetGroup( a_GroupName ); @@ -628,6 +638,10 @@ void cPlayer::ResolvePermissions() } } + + + + void cPlayer::ResolveGroups() { // Clear resolved groups first @@ -666,17 +680,29 @@ void cPlayer::ResolveGroups() } } -std::string cPlayer::GetColor() + + + + +AString cPlayer::GetColor(void) const { - if( m_Color != '-' ) + if ( m_Color != '-' ) + { return cChatColor::MakeColor( m_Color ); + } - if( m_pState->Groups.size() < 1 ) + if ( m_pState->Groups.size() < 1 ) + { return cChatColor::White; + } return (*m_pState->Groups.begin())->GetColor(); } + + + + void cPlayer::TossItem( bool a_bDraggingItem, int a_Amount /* = 1 */ ) { if( a_bDraggingItem ) @@ -714,18 +740,22 @@ void cPlayer::TossItem( bool a_bDraggingItem, int a_Amount /* = 1 */ ) } } + + + + bool cPlayer::MoveToWorld( const char* a_WorldName ) { - cWorld* World = cRoot::Get()->GetWorld( a_WorldName ); - if( World ) + cWorld * World = cRoot::Get()->GetWorld( a_WorldName ); + if ( World ) { /* Remove all links to the old world */ - GetWorld()->RemovePlayer( this ); - GetClientHandle()->RemoveFromAllChunks(); - cChunk* Chunk = GetWorld()->GetChunkUnreliable( m_ChunkX, m_ChunkY, m_ChunkZ ); - if( Chunk ) + m_World->RemovePlayer( this ); + m_ClientHandle->RemoveFromAllChunks(); + cChunkPtr Chunk = m_World->GetChunk( m_ChunkX, m_ChunkY, m_ChunkZ ); + if ( Chunk != NULL ) { - Chunk->RemoveEntity( *this ); + Chunk->RemoveEntity( this ); Chunk->Broadcast( cPacket_DestroyEntity( this ) ); // Remove player entity from all clients in old world } @@ -741,6 +771,10 @@ bool cPlayer::MoveToWorld( const char* a_WorldName ) return false; } + + + + void cPlayer::LoadPermissionsFromDisk() { m_pState->Groups.clear(); -- cgit v1.2.3