summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormadmaxoft@gmail.com <madmaxoft@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6>2012-02-02 22:13:24 +0100
committermadmaxoft@gmail.com <madmaxoft@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6>2012-02-02 22:13:24 +0100
commitf86d796295c366d2715921797c2a153ed56728fd (patch)
tree29860b621d7bdb50fddedcadf19b5b2d1d56c413
parentSocket-related assert fixes (diff)
downloadcuberite-f86d796295c366d2715921797c2a153ed56728fd.tar
cuberite-f86d796295c366d2715921797c2a153ed56728fd.tar.gz
cuberite-f86d796295c366d2715921797c2a153ed56728fd.tar.bz2
cuberite-f86d796295c366d2715921797c2a153ed56728fd.tar.lz
cuberite-f86d796295c366d2715921797c2a153ed56728fd.tar.xz
cuberite-f86d796295c366d2715921797c2a153ed56728fd.tar.zst
cuberite-f86d796295c366d2715921797c2a153ed56728fd.zip
-rw-r--r--source/cClientHandle.cpp665
-rw-r--r--source/cClientHandle.h69
-rw-r--r--source/cPlayer.cpp17
-rw-r--r--source/packets/cPacket.h5
4 files changed, 405 insertions, 351 deletions
diff --git a/source/cClientHandle.cpp b/source/cClientHandle.cpp
index 492c2b7ea..6cfda7648 100644
--- a/source/cClientHandle.cpp
+++ b/source/cClientHandle.cpp
@@ -75,8 +75,6 @@
#define MAX_SEMAPHORES (2000)
-typedef std::list<cPacket*> PacketList;
-
@@ -88,59 +86,22 @@ extern std::string GetWSAError();
-struct cClientHandle::sClientHandleState
-{
- int ProtocolVersion;
- std::string Username;
- std::string Password;
-
- PacketList PendingParsePackets;
- PacketList PendingNrmSendPackets;
- PacketList PendingLowSendPackets;
-
- cThread* pReceiveThread;
- cThread* pSendThread;
- cThread* pAuthenticateThread;
-
- cSocket Socket;
-
- cCriticalSection CriticalSection;
- cCriticalSection SendCriticalSection;
- cCriticalSection SocketCriticalSection;
- cSemaphore* pSemaphore;
-
- Vector3d ConfirmPosition;
-
- cPacket* PacketMap[256];
-
- sClientHandleState(void)
- : ProtocolVersion( 23 )
- , pReceiveThread( 0 )
- , pSendThread( 0 )
- , pAuthenticateThread( 0 )
- , pSemaphore( 0 )
- {
- for( int i = 0; i < 256; ++i )
- PacketMap[i] = 0;
- }
-} ;
-
-
-
-
-
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cClientHandle:
cClientHandle::cClientHandle(const cSocket & a_Socket)
- : m_bDestroyed( false )
- , m_Player( 0 )
+ : mProtocolVersion( 23 )
+ , pReceiveThread(NULL)
+ , pSendThread(NULL)
+ , mSocket(a_Socket)
+ , mSemaphore(MAX_SEMAPHORES)
+ , m_bDestroyed( false )
+ , m_Player(NULL)
, m_bKicking( false )
, m_TimeLastPacket( cWorld::GetTime() )
, m_bLoggedIn( false )
, m_bKeepThreadGoing( true )
, m_bSendLoginResponse( false )
- , m_pState( new sClientHandleState )
, m_Ping(1000)
, m_bPositionConfirmed( false )
{
@@ -149,43 +110,43 @@ cClientHandle::cClientHandle(const cSocket & a_Socket)
cTimer t1;
m_LastPingTime = t1.GetNowTime();
- m_pState->Socket = a_Socket;
-
- m_pState->pSemaphore = new cSemaphore( MAX_SEMAPHORES, 0 );
-
// All the packets that can be received from the client
- m_pState->PacketMap[E_KEEP_ALIVE] = new cPacket_KeepAlive;
- m_pState->PacketMap[E_HANDSHAKE] = new cPacket_Handshake;
- m_pState->PacketMap[E_LOGIN] = new cPacket_Login;
- m_pState->PacketMap[E_PLAYERPOS] = new cPacket_PlayerPosition;
- m_pState->PacketMap[E_PLAYERLOOK] = new cPacket_PlayerLook;
- m_pState->PacketMap[E_PLAYERMOVELOOK] = new cPacket_PlayerMoveLook;
- m_pState->PacketMap[E_CHAT] = new cPacket_Chat;
- m_pState->PacketMap[E_ANIMATION] = new cPacket_ArmAnim;
- m_pState->PacketMap[E_FLYING] = new cPacket_Flying;
- m_pState->PacketMap[E_BLOCK_DIG] = new cPacket_BlockDig;
- m_pState->PacketMap[E_BLOCK_PLACE] = new cPacket_BlockPlace;
- m_pState->PacketMap[E_DISCONNECT] = new cPacket_Disconnect;
- m_pState->PacketMap[E_ITEM_SWITCH] = new cPacket_ItemSwitch;
- m_pState->PacketMap[E_ENTITY_EQUIPMENT] = new cPacket_EntityEquipment;
- m_pState->PacketMap[E_CREATIVE_INVENTORY_ACTION] = new cPacket_CreativeInventoryAction;
- m_pState->PacketMap[E_NEW_INVALID_STATE] = new cPacket_NewInvalidState;
- m_pState->PacketMap[E_PICKUP_SPAWN] = new cPacket_PickupSpawn;
- m_pState->PacketMap[E_USE_ENTITY] = new cPacket_UseEntity;
- m_pState->PacketMap[E_WINDOW_CLOSE] = new cPacket_WindowClose;
- m_pState->PacketMap[E_WINDOW_CLICK] = new cPacket_WindowClick;
- m_pState->PacketMap[E_PACKET_13] = new cPacket_13;
- m_pState->PacketMap[E_UPDATE_SIGN] = new cPacket_UpdateSign;
- m_pState->PacketMap[E_RESPAWN] = new cPacket_Respawn;
- m_pState->PacketMap[E_PING] = new cPacket_Ping;
-
- memset( m_LoadedChunks, 0x00, sizeof(cChunk*)*VIEWDISTANCE*VIEWDISTANCE );
+ for (int i = 0; i < ARRAYCOUNT(mPacketMap); ++i)
+ {
+ mPacketMap[i] = NULL;
+ }
+ mPacketMap[E_KEEP_ALIVE] = new cPacket_KeepAlive;
+ mPacketMap[E_HANDSHAKE] = new cPacket_Handshake;
+ mPacketMap[E_LOGIN] = new cPacket_Login;
+ mPacketMap[E_PLAYERPOS] = new cPacket_PlayerPosition;
+ mPacketMap[E_PLAYERLOOK] = new cPacket_PlayerLook;
+ mPacketMap[E_PLAYERMOVELOOK] = new cPacket_PlayerMoveLook;
+ mPacketMap[E_CHAT] = new cPacket_Chat;
+ mPacketMap[E_ANIMATION] = new cPacket_ArmAnim;
+ mPacketMap[E_FLYING] = new cPacket_Flying;
+ mPacketMap[E_BLOCK_DIG] = new cPacket_BlockDig;
+ mPacketMap[E_BLOCK_PLACE] = new cPacket_BlockPlace;
+ mPacketMap[E_DISCONNECT] = new cPacket_Disconnect;
+ mPacketMap[E_ITEM_SWITCH] = new cPacket_ItemSwitch;
+ mPacketMap[E_ENTITY_EQUIPMENT] = new cPacket_EntityEquipment;
+ mPacketMap[E_CREATIVE_INVENTORY_ACTION] = new cPacket_CreativeInventoryAction;
+ mPacketMap[E_NEW_INVALID_STATE] = new cPacket_NewInvalidState;
+ mPacketMap[E_PICKUP_SPAWN] = new cPacket_PickupSpawn;
+ mPacketMap[E_USE_ENTITY] = new cPacket_UseEntity;
+ mPacketMap[E_WINDOW_CLOSE] = new cPacket_WindowClose;
+ mPacketMap[E_WINDOW_CLICK] = new cPacket_WindowClick;
+ mPacketMap[E_PACKET_13] = new cPacket_13;
+ mPacketMap[E_UPDATE_SIGN] = new cPacket_UpdateSign;
+ mPacketMap[E_RESPAWN] = new cPacket_Respawn;
+ mPacketMap[E_PING] = new cPacket_Ping;
+
+ memset(m_LoadedChunks, 0x00, sizeof(m_LoadedChunks));
//////////////////////////////////////////////////////////////////////////
- m_pState->pReceiveThread = new cThread( ReceiveThread, this, "cClientHandle::ReceiveThread" );
- m_pState->pSendThread = new cThread( SendThread, this, "cClientHandle::SendThread" );
- m_pState->pReceiveThread->Start( true );
- m_pState->pSendThread->Start( true );
+ pReceiveThread = new cThread( ReceiveThread, this, "cClientHandle::ReceiveThread" );
+ pSendThread = new cThread( SendThread, this, "cClientHandle::SendThread" );
+ pReceiveThread->Start( true );
+ pSendThread->Start( true );
//////////////////////////////////////////////////////////////////////////
LOG("New ClientHandle" );
@@ -215,60 +176,55 @@ cClientHandle::~cClientHandle()
}
}
- if (m_pState && m_pState->Username.size() > 0)
+ if (mUsername.size() > 0)
{
- cPacket_Chat Left( m_pState->Username + " left the game!");
+ cPacket_Chat Left(mUsername + " left the game!");
cRoot::Get()->GetServer()->Broadcast( Left, this );
}
// First stop sending thread
m_bKeepThreadGoing = false;
- m_pState->SocketCriticalSection.Lock();
- if( m_pState->Socket )
+ cCSLock Lock(mSocketCriticalSection);
+ if (mSocket.IsValid())
{
cPacket_Disconnect Disconnect;
Disconnect.m_Reason = "Server shut down? Kthnxbai";
- Disconnect.Send( m_pState->Socket );
+ Disconnect.Send(mSocket);
- m_pState->Socket.CloseSocket();
- m_pState->Socket = 0;
+ mSocket.CloseSocket();
}
- m_pState->SocketCriticalSection.Unlock();
+ Lock.Unlock();
- m_pState->pSemaphore->Signal();
- delete m_pState->pReceiveThread;
- delete m_pState->pSendThread;
- delete m_pState->pSemaphore;
+ mSemaphore.Signal();
+ delete pReceiveThread;
+ delete pSendThread;
- while( !m_pState->PendingParsePackets.empty() )
+ while (!mPendingParsePackets.empty())
{
- delete *m_pState->PendingParsePackets.begin();
- m_pState->PendingParsePackets.erase( m_pState->PendingParsePackets.begin() );
+ delete *mPendingParsePackets.begin();
+ mPendingParsePackets.erase(mPendingParsePackets.begin());
}
- while( !m_pState->PendingNrmSendPackets.empty() )
+ while (!mPendingNrmSendPackets.empty())
{
- delete *m_pState->PendingNrmSendPackets.begin();
- m_pState->PendingNrmSendPackets.erase( m_pState->PendingNrmSendPackets.begin() );
+ delete *mPendingNrmSendPackets.begin();
+ mPendingNrmSendPackets.erase(mPendingNrmSendPackets.begin());
}
- while( !m_pState->PendingLowSendPackets.empty() )
+ while (!mPendingLowSendPackets.empty())
{
- delete *m_pState->PendingLowSendPackets.begin();
- m_pState->PendingLowSendPackets.erase( m_pState->PendingLowSendPackets.begin() );
+ delete *mPendingLowSendPackets.begin();
+ mPendingLowSendPackets.erase(mPendingLowSendPackets.begin());
}
- if(m_Player)
+ if (m_Player != NULL)
{
- m_Player->SetClientHandle( 0 );
+ m_Player->SetClientHandle(NULL);
m_Player->Destroy();
- m_Player = 0;
+ m_Player = NULL;
}
- for(int i = 0; i < 256; i++)
+ for (int i = 0; i < ARRAYCOUNT(mPacketMap); i++)
{
- if( m_pState->PacketMap[i] )
- delete m_pState->PacketMap[i];
+ delete mPacketMap[i];
}
-
- delete m_pState;
}
@@ -278,13 +234,11 @@ cClientHandle::~cClientHandle()
void cClientHandle::Destroy()
{
m_bDestroyed = true;
- m_pState->SocketCriticalSection.Lock();
- if( m_pState->Socket )
+ cCSLock Lock(mSocketCriticalSection);
+ if (mSocket.IsValid())
{
- m_pState->Socket.CloseSocket();
- m_pState->Socket = 0;
+ mSocket.CloseSocket();
}
- m_pState->SocketCriticalSection.Unlock();
}
@@ -312,32 +266,43 @@ void cClientHandle::Authenticate(void)
void cClientHandle::StreamChunks(void)
{
- if( !m_bLoggedIn )
+ if (!m_bLoggedIn)
+ {
return;
+ }
+ assert(m_Player != NULL);
+
int ChunkPosX = (int)floor(m_Player->GetPosX() / 16);
int ChunkPosZ = (int)floor(m_Player->GetPosZ() / 16);
- cWorld* World = m_Player->GetWorld();
+ cWorld * World = m_Player->GetWorld();
- cChunk* NeededChunks[VIEWDISTANCE*VIEWDISTANCE] = { 0 };
- const int MaxDist = VIEWDISTANCE+GENERATEDISTANCE*2;
- for(int x = 0; x < MaxDist; x++)
+ cChunk * NeededChunks[VIEWDISTANCE * VIEWDISTANCE] = { 0 };
+ const int MaxDist = VIEWDISTANCE + GENERATEDISTANCE * 2;
+ for (int x = 0; x < MaxDist; x++)
{
- for(int z = 0; z < MaxDist; z++)
+ for (int z = 0; z < MaxDist; z++)
{
- int RelX = x - (MaxDist-1)/2;
- int RelZ = z - (MaxDist-1)/2;
- cChunk* Chunk = World->GetChunk( ChunkPosX + RelX, 0, ChunkPosZ + RelZ ); // Touch all chunks in wide range, so they get generated
- if( x >= GENERATEDISTANCE && x < VIEWDISTANCE+GENERATEDISTANCE && z >= GENERATEDISTANCE && z < VIEWDISTANCE+GENERATEDISTANCE ) // but player only needs chunks in view distance
- NeededChunks[(x-GENERATEDISTANCE) + (z-GENERATEDISTANCE)*VIEWDISTANCE] = Chunk;
+ int RelX = x - (MaxDist - 1) / 2;
+ int RelZ = z - (MaxDist - 1) / 2;
+ cChunk * Chunk = World->GetChunk( ChunkPosX + RelX, 0, ChunkPosZ + RelZ ); // Touch all chunks in wide range, so they get generated
+ if (
+ (x >= GENERATEDISTANCE) &&
+ (x < VIEWDISTANCE + GENERATEDISTANCE) &&
+ (z >= GENERATEDISTANCE) &&
+ (z < VIEWDISTANCE + GENERATEDISTANCE)
+ ) // but player only needs chunks in view distance
+ {
+ NeededChunks[(x - GENERATEDISTANCE) + (z - GENERATEDISTANCE) * VIEWDISTANCE] = Chunk;
+ }
}
}
- cChunk* MissingChunks[VIEWDISTANCE*VIEWDISTANCE];
- memset( MissingChunks, 0, VIEWDISTANCE*VIEWDISTANCE*sizeof(cChunk*) );
+ cChunk * MissingChunks[VIEWDISTANCE * VIEWDISTANCE];
+ memset(MissingChunks, 0, sizeof(MissingChunks));
unsigned int MissIndex = 0;
- for(int i = 0; i < VIEWDISTANCE*VIEWDISTANCE; i++) // Handshake loop - touch each chunk once
+ for(int i = 0; i < VIEWDISTANCE * VIEWDISTANCE; i++) // Handshake loop - touch each chunk once
{
if( NeededChunks[i] == 0 ) continue; // Chunk is not yet loaded, so ignore
// This can cause MissIndex to be 0 and thus chunks will not be unloaded while they are actually out of range,
@@ -358,25 +323,27 @@ void cClientHandle::StreamChunks(void)
}
}
- if( MissIndex > 0 )
- { // Chunks are gonna be streamed in, so chunks probably also need to be streamed out <- optimization
+ if (MissIndex > 0)
+ {
+ // Chunks are gonna be streamed in, so chunks probably also need to be streamed out <- optimization
for(int x = 0; x < VIEWDISTANCE; x++)
{
for(int z = 0; z < VIEWDISTANCE; z++)
{
cChunk* Chunk = m_LoadedChunks[x + z*VIEWDISTANCE];
- if( Chunk )
+ if (Chunk != NULL)
{
- if( Chunk->GetPosX() < ChunkPosX-(VIEWDISTANCE-1)/2
- || Chunk->GetPosX() > ChunkPosX+(VIEWDISTANCE-1)/2
- || Chunk->GetPosZ() < ChunkPosZ-(VIEWDISTANCE-1)/2
- || Chunk->GetPosZ() > ChunkPosZ+(VIEWDISTANCE-1)/2 )
+ if ( (Chunk->GetPosX() < ChunkPosX - (VIEWDISTANCE - 1) / 2)
+ || (Chunk->GetPosX() > ChunkPosX + (VIEWDISTANCE - 1) / 2)
+ || (Chunk->GetPosZ() < ChunkPosZ - (VIEWDISTANCE - 1) / 2)
+ || (Chunk->GetPosZ() > ChunkPosZ + (VIEWDISTANCE - 1) / 2)
+ )
{
Chunk->RemoveClient( this );
Chunk->AsyncUnload( this ); // TODO - I think it's possible to unload the chunk immediately instead of next tick
// I forgot why I made it happen next tick
- m_LoadedChunks[x + z*VIEWDISTANCE] = 0;
+ m_LoadedChunks[x + z * VIEWDISTANCE] = NULL;
}
}
}
@@ -384,7 +351,7 @@ void cClientHandle::StreamChunks(void)
StreamChunksSmart( MissingChunks, MissIndex );
- memcpy( m_LoadedChunks, NeededChunks, VIEWDISTANCE*VIEWDISTANCE*sizeof(cChunk*) );
+ memcpy(m_LoadedChunks, NeededChunks, sizeof(NeededChunks));
}
}
@@ -455,9 +422,8 @@ void cClientHandle::RemoveFromAllChunks()
void cClientHandle::AddPacket(cPacket * a_Packet)
{
- m_pState->CriticalSection.Lock();
- m_pState->PendingParsePackets.push_back( a_Packet->Clone() );
- m_pState->CriticalSection.Unlock();
+ cCSLock Lock(mCriticalSection);
+ mPendingParsePackets.push_back(a_Packet->Clone());
}
@@ -467,7 +433,7 @@ void cClientHandle::AddPacket(cPacket * a_Packet)
void cClientHandle::RemovePacket( cPacket * a_Packet )
{
delete a_Packet;
- m_pState->PendingParsePackets.remove( a_Packet );
+ mPendingParsePackets.remove( a_Packet );
}
@@ -476,13 +442,12 @@ void cClientHandle::RemovePacket( cPacket * a_Packet )
void cClientHandle::HandlePendingPackets()
{
- m_pState->CriticalSection.Lock();
- while( m_pState->PendingParsePackets.begin() != m_pState->PendingParsePackets.end() )
+ cCSLock Lock(mCriticalSection);
+ while (!mPendingParsePackets.empty())
{
- HandlePacket( *m_pState->PendingParsePackets.begin() );
- RemovePacket( *m_pState->PendingParsePackets.begin() );
+ HandlePacket( *mPendingParsePackets.begin() );
+ RemovePacket( *mPendingParsePackets.begin() );
}
- m_pState->CriticalSection.Unlock();
}
@@ -498,19 +463,22 @@ void cClientHandle::HandlePacket( cPacket* a_Packet )
//LOG("Packet: 0x%02x", a_Packet->m_PacketID );
- if( m_bKicking ) return;
+ if (m_bKicking)
+ {
+ return;
+ }
- if(!m_bLoggedIn)
+ if (!m_bLoggedIn)
{
- switch( a_Packet->m_PacketID )
+ switch (a_Packet->m_PacketID)
{
- case E_NEW_INVALID_STATE: // New/Invalid State packet received. I'm guessing the client only sends it when there's a problem with the bed?
+ case E_NEW_INVALID_STATE: // New/Invalid State packet received. I'm guessing the client only sends it when there's a problem with the bed?
{
LOGINFO("Got New Invalid State packet");
+ break;
}
- break;
- case E_PING: // Somebody tries to retrieve information about the server
+ case E_PING: // Somebody tries to retrieve information about the server
{
LOGINFO("Got ping");
AString Reply;
@@ -522,66 +490,78 @@ void cClientHandle::HandlePacket( cPacket* a_Packet )
cRoot::Get()->GetWorld()->GetMaxPlayers()
);
Kick(Reply.c_str());
+ break;
}
- break;
- case E_HANDSHAKE:
+
+ case E_HANDSHAKE:
{
- cPacket_Handshake* PacketData = reinterpret_cast<cPacket_Handshake*>(a_Packet);
- m_pState->Username = PacketData->m_Username;
+ cPacket_Handshake * PacketData = reinterpret_cast<cPacket_Handshake*>(a_Packet);
+ mUsername = PacketData->m_Username;
LOG("HANDSHAKE %s", GetUsername().c_str());
- cPacket_Chat Connecting(m_pState->Username + " is connecting.");
- if (cRoot::Get()->GetWorld()->GetNumPlayers() >= cRoot::Get()->GetWorld()->GetMaxPlayers()) {
+ if (cRoot::Get()->GetWorld()->GetNumPlayers() >= cRoot::Get()->GetWorld()->GetMaxPlayers())
+ {
Kick("The server is currently full :( -- Try again later");
break;
}
+ cPacket_Chat Connecting(mUsername + " is connecting.");
cRoot::Get()->GetServer()->Broadcast( Connecting, this );
// Give a server handshake thingy back
cPacket_Handshake Handshake;
Handshake.m_Username = cRoot::Get()->GetServer()->GetServerID();//ServerID;//"2e66f1dc032ab5f0";
Send( Handshake );
+ break;
}
- break;
- case E_LOGIN:
+
+ case E_LOGIN:
{
LOG("LOGIN %s", GetUsername().c_str());
- cPacket_Login* PacketData = reinterpret_cast<cPacket_Login*>(a_Packet);
- if (PacketData->m_ProtocolVersion < m_pState->ProtocolVersion) {
+ cPacket_Login * PacketData = reinterpret_cast<cPacket_Login*>(a_Packet);
+ if (PacketData->m_ProtocolVersion < mProtocolVersion)
+ {
Kick("Your client is outdated!");
return;
}
- else if( PacketData->m_ProtocolVersion > m_pState->ProtocolVersion ) {
+ else if( PacketData->m_ProtocolVersion > mProtocolVersion )
+ {
Kick("Your client version is higher than the server!");
return;
}
- if( m_pState->Username.compare( PacketData->m_Username ) != 0 )
+ if (mUsername.compare(PacketData->m_Username) != 0)
{
- Kick("Login Username does not match Handshake username!");
+ LOGWARNING("Login Username does not match Handshake username (\"%s\" / \"%s\" for client \"%s\")",
+ mUsername.c_str(),
+ PacketData->m_Username.c_str(),
+ mSocket.GetIPString().c_str()
+ );
+ Kick("Hacked client"); // Don't tell them why we don't want them
return;
}
- if( cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::E_PLUGIN_LOGIN, 1, PacketData ) )
+ if (cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::E_PLUGIN_LOGIN, 1, PacketData))
{
Destroy();
return;
}
// Schedule for authentication; until then, let them wait (but do not block)
- cRoot::Get()->GetAuthenticator().Authenticate(m_pState->Username, cRoot::Get()->GetServer()->GetServerID());
+ cRoot::Get()->GetAuthenticator().Authenticate(mUsername, cRoot::Get()->GetServer()->GetServerID());
+ break;
}
- break;
- case E_PLAYERMOVELOOK: // After this is received we're safe to send anything
+
+ case E_PLAYERMOVELOOK: // After this is received we're safe to send anything
{
- if( !m_Player )
+ if (m_Player == NULL)
{
- Kick("Received wrong packet! Check your login sequence!");
+ LOGWARNING("Received PlayerMoveLook packet for NULL player from client \"%s\", kicking.", mSocket.GetIPString().c_str());
+ Kick("Hacked client"); // Don't tell them why we don't want them
return;
}
- if( !cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::E_PLUGIN_PLAYER_JOIN, 1, m_Player ) )
+ if ( !cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::E_PLUGIN_PLAYER_JOIN, 1, m_Player))
{
// Broadcast that this player has joined the game! Yay~
- cPacket_Chat Joined( m_pState->Username + " joined the game!");
+ cPacket_Chat Joined(mUsername + " joined the game!");
cRoot::Get()->GetServer()->Broadcast( Joined, this );
}
@@ -592,52 +572,60 @@ void cClientHandle::HandlePacket( cPacket* a_Packet )
// Then we can start doing more stuffs! :D
m_bLoggedIn = true;
- LOG("%s completely logged in", GetUsername().c_str());
+ LOG("Player \"%s\" completely logged in", GetUsername().c_str());
StreamChunks();
// Send position
- m_pState->ConfirmPosition = m_Player->GetPosition();
+ mConfirmPosition = m_Player->GetPosition();
Send( cPacket_PlayerMoveLook( m_Player ) );
+ break;
}
- break;
- case E_KEEP_ALIVE:
- break;
- default:
+
+ case E_KEEP_ALIVE:
{
- LOG("INVALID RESPONSE FOR LOGIN: needed 0x%02x got 0x%02x", E_PLAYERMOVELOOK, a_Packet->m_PacketID );
- Kick("INVALID RESPONSE FOR LOGIN: needed 0x0d!");
+ break;
}
- break;
- }
+
+ default:
+ {
+ LOG("INVALID RESPONSE FOR LOGIN: needed 0x%02x, got 0x%02x from client \"%s\", username \"%s\"",
+ E_PLAYERMOVELOOK,
+ a_Packet->m_PacketID,
+ mSocket.GetIPString().c_str(),
+ mUsername.c_str()
+ );
+ Kick("Hacked client"); // Don't tell them why we don't like them
+ break;
+ }
+ } // switch (Packet type)
}
- else if( !m_bPositionConfirmed ) // m_bLoggedIn == true
+ else if (!m_bPositionConfirmed) // m_bLoggedIn is true
{
- switch( a_Packet->m_PacketID )
+ switch (a_Packet->m_PacketID)
{
- case E_PLAYERMOVELOOK:
+ case E_PLAYERMOVELOOK:
{
cPacket_PlayerMoveLook* PacketData = reinterpret_cast<cPacket_PlayerMoveLook*>(a_Packet);
- Vector3d ReceivedPosition = Vector3d( PacketData->m_PosX, PacketData->m_PosY, PacketData->m_PosZ );
+ Vector3d ReceivedPosition = Vector3d(PacketData->m_PosX, PacketData->m_PosY, PacketData->m_PosZ);
// Test the distance between points with a small/large enough value instead of comparing directly. Floating point inaccuracies might screw stuff up
- if( ( ReceivedPosition - m_pState->ConfirmPosition ).SqrLength() < 1.0 )
+ if ((ReceivedPosition - mConfirmPosition).SqrLength() < 1.0)
{
// Test
- if( ReceivedPosition.Equals( m_pState->ConfirmPosition ) )
+ if( ReceivedPosition.Equals(mConfirmPosition))
{
LOGINFO("Exact position confirmed by client!");
}
m_bPositionConfirmed = true;
}
- }
- break;
- }
-
- }
+ break;
+ } // case E_PLAYERMOVELOOK
+ } // switch (Packet type)
+ } // if (! position confirmed)
- if( m_bPositionConfirmed )
+ if (m_bPositionConfirmed)
{
- switch( a_Packet->m_PacketID )
+ switch (a_Packet->m_PacketID)
{
case E_CREATIVE_INVENTORY_ACTION: // This is for creative Inventory changes
{
@@ -647,19 +635,19 @@ void cClientHandle::HandlePacket( cPacket* a_Packet )
}
break;
}
- break;
- case E_PLAYERPOS:
+
+ case E_PLAYERPOS:
{
cPacket_PlayerPosition* PacketData = reinterpret_cast<cPacket_PlayerPosition*>(a_Packet);
//LOG("recv player pos: %0.2f %0.2f %0.2f", PacketData->m_PosX, PacketData->m_PosY, PacketData->m_PosZ );
m_Player->MoveTo( Vector3d( PacketData->m_PosX, PacketData->m_PosY, PacketData->m_PosZ ) );
m_Player->SetStance( PacketData->m_Stance );
m_Player->SetTouchGround( PacketData->m_bFlying );
+ break;
}
- break;
- case E_BLOCK_DIG:
+
+ case E_BLOCK_DIG:
{
-
int LastActionCnt = m_Player->GetLastBlockActionCnt();
if ( (cRoot::Get()->GetWorld()->GetTime() - m_Player->GetLastBlockActionTime()) < 0.1 ) { //only allow block interactions every 0.1 seconds
m_Player->SetLastBlockActionTime(); //Player tried to interact with a block. Reset last block interation time.
@@ -670,7 +658,9 @@ void cClientHandle::HandlePacket( cPacket* a_Packet )
Kick("You're a baaaaaad boy!");
break;
}
- } else {
+ }
+ else
+ {
m_Player->SetLastBlockActionCnt(0); //reset count
m_Player->SetLastBlockActionTime(); //Player tried to interact with a block. Reset last block interation time.
}
@@ -685,23 +675,20 @@ void cClientHandle::HandlePacket( cPacket* a_Packet )
{
cWorld* World = m_Player->GetWorld();
-
char OldBlock = World->GetBlock(PacketData->m_PosX, PacketData->m_PosY, PacketData->m_PosZ);
char MetaData = World->GetBlockMeta(PacketData->m_PosX, PacketData->m_PosY, PacketData->m_PosZ);
-
bool bBroken = (PacketData->m_Status == 0x02) || g_BlockOneHitDig[(int)OldBlock] || ( (PacketData->m_Status == 0x00) && (m_Player->GetGameMode() == 1) );
- if(bBroken == false) bBroken = (m_Player->GetInventory().GetEquippedItem().m_ItemID == E_ITEM_SHEARS && OldBlock == E_BLOCK_LEAVES);
+ if (bBroken == false) bBroken = (m_Player->GetInventory().GetEquippedItem().m_ItemID == E_ITEM_SHEARS && OldBlock == E_BLOCK_LEAVES);
- if(OldBlock == E_BLOCK_WOODEN_DOOR && !bBroken)
+ if (OldBlock == E_BLOCK_WOODEN_DOOR && !bBroken)
{
cDoors::ChangeDoor(m_Player->GetWorld(), PacketData->m_PosX, PacketData->m_PosY, PacketData->m_PosZ);
}
cItem PickupItem;
- if( bBroken && !(m_Player->GetGameMode() == 1) ) // broken
+ if (bBroken && !(m_Player->GetGameMode() == 1) ) // broken
{
-
ENUM_ITEM_ID PickupID = cBlockToPickup::ToPickup( (ENUM_BLOCK_ID)OldBlock, m_Player->GetInventory().GetEquippedItem().m_ItemID );
PickupItem.m_ItemID = PickupID;
PickupItem.m_ItemHealth = MetaData;
@@ -778,11 +765,11 @@ void cClientHandle::HandlePacket( cPacket* a_Packet )
World->SendBlockTo( PacketData->m_PosX, PacketData->m_PosY, PacketData->m_PosZ, m_Player );
}
}
- }
- break;
- case E_BLOCK_PLACE:
+ break;
+ } // case E_BLOCK_DIG
+
+ case E_BLOCK_PLACE:
{
-
int LastActionCnt = m_Player->GetLastBlockActionCnt();
if ( (cRoot::Get()->GetWorld()->GetTime() - m_Player->GetLastBlockActionTime()) < 0.1 ) { //only allow block interactions every 0.1 seconds
m_Player->SetLastBlockActionTime(); //Player tried to interact with a block. Reset last block interation time.
@@ -792,7 +779,9 @@ void cClientHandle::HandlePacket( cPacket* a_Packet )
Kick("You're a baaaaaad boy!");
break;
}
- } else {
+ }
+ else
+ {
m_Player->SetLastBlockActionCnt(0); //reset count
m_Player->SetLastBlockActionTime(); //Player tried to interact with a block. Reset last block interation time.
}
@@ -800,15 +789,15 @@ void cClientHandle::HandlePacket( cPacket* a_Packet )
cPacket_BlockPlace* PacketData = reinterpret_cast<cPacket_BlockPlace*>(a_Packet);
cItem & Equipped = m_Player->GetInventory().GetEquippedItem();
- if( (Equipped.m_ItemID != PacketData->m_ItemType)) // Not valid
+ if ((Equipped.m_ItemID != PacketData->m_ItemType)) // Not valid
{
LOGWARN("Player %s tried to place a block that was not selected! (could indicate bot)", GetUsername().c_str());
break;
}
- if(cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::E_PLUGIN_BLOCK_PLACE, 2, PacketData, m_Player ) )
+ if (cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::E_PLUGIN_BLOCK_PLACE, 2, PacketData, m_Player ) )
{
- if( PacketData->m_Direction > -1 )
+ if (PacketData->m_Direction > -1)
{
AddDirection( PacketData->m_PosX, PacketData->m_PosY, PacketData->m_PosZ, PacketData->m_Direction );
m_Player->GetWorld()->SendBlockTo( PacketData->m_PosX, PacketData->m_PosY, PacketData->m_PosZ, m_Player );
@@ -1235,9 +1224,10 @@ void cClientHandle::HandlePacket( cPacket* a_Packet )
}
}
*/
- }
- break;
- case E_PICKUP_SPAWN:
+ break;
+ } // case E_BLOCK_PLACE
+
+ case E_PICKUP_SPAWN:
{
LOG("Received packet E_PICKUP_SPAWN");
cPacket_PickupSpawn* PacketData = reinterpret_cast<cPacket_PickupSpawn*>(a_Packet);
@@ -1251,28 +1241,31 @@ void cClientHandle::HandlePacket( cPacket* a_Packet )
cPickup* Pickup = new cPickup( PacketData );
Pickup->Initialize( m_Player->GetWorld() );
}
- }
- break;
- case E_CHAT:
+ break;
+ } // case E_PICKUP_SPAWN
+
+ case E_CHAT:
{
cPacket_Chat* PacketData = reinterpret_cast<cPacket_Chat*>(a_Packet);
- if( !cRoot::Get()->GetServer()->Command( *this, PacketData->m_Message.c_str() ) )
+ if (!cRoot::Get()->GetServer()->Command( *this, PacketData->m_Message.c_str()))
{
- PacketData->m_Message.insert( 0, "<"+m_Player->GetColor() + m_pState->Username + cChatColor::White + "> " );
+ PacketData->m_Message.insert( 0, "<" + m_Player->GetColor() + mUsername + cChatColor::White + "> " );
cRoot::Get()->GetServer()->Broadcast( *PacketData );
}
- }
- break;
- case E_PLAYERLOOK:
+ break;
+ } // case E_CHAT
+
+ case E_PLAYERLOOK:
{
cPacket_PlayerLook* PacketData = reinterpret_cast<cPacket_PlayerLook*>(a_Packet);
m_Player->SetRotation( PacketData->m_Rotation );
m_Player->SetPitch( PacketData->m_Pitch );
m_Player->SetTouchGround( PacketData->m_bFlying );
m_Player->WrapRotation();
- }
- break;
- case E_PLAYERMOVELOOK:
+ break;
+ } // case E_PLAYERLOOK
+
+ case E_PLAYERMOVELOOK:
{
cPacket_PlayerMoveLook* PacketData = reinterpret_cast<cPacket_PlayerMoveLook*>(a_Packet);
m_Player->MoveTo( Vector3d( PacketData->m_PosX, PacketData->m_PosY, PacketData->m_PosZ ) );
@@ -1281,16 +1274,18 @@ void cClientHandle::HandlePacket( cPacket* a_Packet )
m_Player->SetRotation( PacketData->m_Rotation );
m_Player->SetPitch( PacketData->m_Pitch );
m_Player->WrapRotation();
- }
- break;
- case E_ANIMATION:
+ break;
+ } // case E_PLAYERMOVELOOK
+
+ case E_ANIMATION:
{
cPacket_ArmAnim* PacketData = reinterpret_cast<cPacket_ArmAnim*>(a_Packet);
PacketData->m_EntityID = m_Player->GetUniqueID();
cRoot::Get()->GetServer()->Broadcast( *PacketData, this );
- }
- break;
- case E_ITEM_SWITCH:
+ break;
+ } // case E_ANIMATION
+
+ case E_ITEM_SWITCH:
{
cPacket_ItemSwitch* PacketData = reinterpret_cast<cPacket_ItemSwitch*>(a_Packet);
@@ -1301,21 +1296,17 @@ void cClientHandle::HandlePacket( cPacket* a_Packet )
Equipment.m_Slot = 0;
Equipment.m_UniqueID = m_Player->GetUniqueID();
cRoot::Get()->GetServer()->Broadcast( Equipment, this );
- }
- break;
- case E_WINDOW_CLOSE:
+ break;
+ } // case E_ITEM_SWITCH
+
+ case E_WINDOW_CLOSE:
{
cPacket_WindowClose* PacketData = reinterpret_cast<cPacket_WindowClose*>(a_Packet);
m_Player->CloseWindow(PacketData->m_Close);
- /*
- if( PacketData->m_Close > 0 ) // Don't care about closing inventory
- {
- m_Player->CloseWindow();
- }
- */
- }
- break;
- case E_WINDOW_CLICK:
+ break;
+ } // case E_WINDOW_CLOSE
+
+ case E_WINDOW_CLICK:
{
cPacket_WindowClick* PacketData = reinterpret_cast<cPacket_WindowClick*>(a_Packet);
if( PacketData->m_WindowID == 0 )
@@ -1328,9 +1319,10 @@ void cClientHandle::HandlePacket( cPacket* a_Packet )
if( Window ) Window->Clicked( PacketData, *m_Player );
else LOG("No 'other' window! WTF");
}
- }
- break;
- case E_UPDATE_SIGN:
+ break;
+ } // case E_WINDOW_CLICK
+
+ case E_UPDATE_SIGN:
{
cPacket_UpdateSign* PacketData = reinterpret_cast<cPacket_UpdateSign*>(a_Packet);
cWorld* World = m_Player->GetWorld();
@@ -1342,9 +1334,10 @@ void cClientHandle::HandlePacket( cPacket* a_Packet )
Sign->SetLines( PacketData->m_Line1, PacketData->m_Line2, PacketData->m_Line3, PacketData->m_Line4 );
Sign->SendTo( 0 ); // Broadcast to all players in chunk
}
- }
- break;
- case E_USE_ENTITY:
+ break;
+ } // case E_UPDATE_SIGN
+
+ case E_USE_ENTITY:
{
cPacket_UseEntity* PacketData = reinterpret_cast<cPacket_UseEntity*>(a_Packet);
if( PacketData->m_bLeftClick )
@@ -1357,27 +1350,30 @@ void cClientHandle::HandlePacket( cPacket* a_Packet )
Pawn->TakeDamage( 1, m_Player );
}
}
- }
- break;
- case E_RESPAWN:
+ break;
+ } // case E_USE_ENTITY
+
+ case E_RESPAWN:
{
m_Player->Respawn();
- }
- break;
- case E_DISCONNECT:
+ break;
+ } // case E_RESPAWN
+
+ case E_DISCONNECT:
{
- LOG("Received d/c packet from %s", GetUsername().c_str());
+ LOG("Received d/c packet from \"%s\"", GetUsername().c_str());
cPacket_Disconnect* PacketData = reinterpret_cast<cPacket_Disconnect*>(a_Packet);
if( !cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::E_PLUGIN_DISCONNECT, 2, PacketData->m_Reason.c_str(), m_Player ) )
{
- cPacket_Chat DisconnectMessage( m_pState->Username + " disconnected: " + PacketData->m_Reason );
+ cPacket_Chat DisconnectMessage(mUsername + " disconnected: " + PacketData->m_Reason);
cRoot::Get()->GetServer()->Broadcast( DisconnectMessage );
}
Destroy();
return;
- }
- break;
- case E_KEEP_ALIVE:
+ break;
+ } // case E_DISCONNECT
+
+ case E_KEEP_ALIVE:
{
cPacket_KeepAlive *PacketData = reinterpret_cast<cPacket_KeepAlive*>(a_Packet);
if (PacketData->m_KeepAliveID == m_PingID)
@@ -1385,12 +1381,10 @@ void cClientHandle::HandlePacket( cPacket* a_Packet )
cTimer t1;
m_Ping = (short)((t1.GetNowTime() - m_PingStartTime) / 2);
}
- }
- break;
- default:
break;
- }
- }
+ } // case E_KEEP_ALIVE
+ } // switch (Packet type)
+ } // if (normal game)
}
@@ -1400,19 +1394,21 @@ void cClientHandle::HandlePacket( cPacket* a_Packet )
void cClientHandle::Tick(float a_Dt)
{
(void)a_Dt;
- if( cWorld::GetTime() - m_TimeLastPacket > 30.f ) // 30 seconds time-out
+ if (cWorld::GetTime() - m_TimeLastPacket > 30.f) // 30 seconds time-out
{
cPacket_Disconnect DC("Nooooo!! You timed out! D: Come back!");
- DC.Send( m_pState->Socket );
+ DC.Send(mSocket);
- cSleep::MilliSleep( 1000 ); // Give packet some time to be received
+ cSleep::MilliSleep(1000); // Give packet some time to be received
Destroy();
}
cTimer t1;
// Send ping packet
- if (m_LastPingTime + cClientHandle::PING_TIME_MS <= t1.GetNowTime()) {
+ if (m_LastPingTime + cClientHandle::PING_TIME_MS <= t1.GetNowTime())
+ {
+ // TODO: why a random ping ID, can't we just use normal ascending numbers?
MTRand r1;
m_PingID = r1.randInt();
cPacket_KeepAlive Ping(m_PingID);
@@ -1421,7 +1417,7 @@ void cClientHandle::Tick(float a_Dt)
m_LastPingTime = m_PingStartTime;
}
- if( m_bSendLoginResponse )
+ if (m_bSendLoginResponse)
{
m_bSendLoginResponse = false;
@@ -1433,7 +1429,7 @@ void cClientHandle::Tick(float a_Dt)
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
- m_Player->SetIP ( m_pState->Socket.GetIPString() );
+ m_Player->SetIP (mSocket.GetIPString());
cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::E_PLUGIN_PLAYER_SPAWN, 1, m_Player );
@@ -1481,18 +1477,18 @@ void cClientHandle::Send( const cPacket & a_Packet, ENUM_PRIORITY a_Priority /*
if( m_bKicking ) return; // Don't add more packets if player is getting kicked anyway
bool bSignalSemaphore = true;
- m_pState->SendCriticalSection.Lock();
- if( a_Priority == E_PRIORITY_NORMAL )
+ cCSLock Lock(mSendCriticalSection);
+ if (a_Priority == E_PRIORITY_NORMAL)
{
- if( a_Packet.m_PacketID == E_REL_ENT_MOVE_LOOK )
+ if (a_Packet.m_PacketID == E_REL_ENT_MOVE_LOOK)
{
- PacketList & Packets = m_pState->PendingNrmSendPackets;
- for( std::list<cPacket*>::iterator itr = Packets.begin(); itr != Packets.end(); ++itr )
+ PacketList & Packets = mPendingNrmSendPackets;
+ for (PacketList::iterator itr = Packets.begin(); itr != Packets.end(); ++itr)
{
bool bBreak = false;
- switch( (*itr)->m_PacketID )
+ switch ((*itr)->m_PacketID)
{
- case E_REL_ENT_MOVE_LOOK:
+ case E_REL_ENT_MOVE_LOOK:
{
const cPacket_RelativeEntityMoveLook* ThisPacketData = reinterpret_cast< const cPacket_RelativeEntityMoveLook* >(&a_Packet);
cPacket_RelativeEntityMoveLook* PacketData = reinterpret_cast< cPacket_RelativeEntityMoveLook* >(*itr);
@@ -1505,21 +1501,26 @@ void cClientHandle::Send( const cPacket & a_Packet, ENUM_PRIORITY a_Priority /*
delete PacketData;
break;
}
- }
- break;
- default:
+ break;
+ } // case E_REL_END_MOVE_LOOK
+ } // switch (*itr -> Packet type)
+ if (bBreak)
+ {
break;
}
- if( bBreak )
- break;
- }
- }
- m_pState->PendingNrmSendPackets.push_back( a_Packet.Clone() );
+ } // for itr - Packets[]
+ } // if (E_REL_ENT_MOVE_LOOK
+ mPendingNrmSendPackets.push_back(a_Packet.Clone());
+ }
+ else if( a_Priority == E_PRIORITY_LOW )
+ {
+ mPendingLowSendPackets.push_back( a_Packet.Clone() );
+ }
+ Lock.Unlock();
+ if (bSignalSemaphore)
+ {
+ mSemaphore.Signal();
}
- else if( a_Priority == E_PRIORITY_LOW ) m_pState->PendingLowSendPackets.push_back( a_Packet.Clone() );
- m_pState->SendCriticalSection.Unlock();
- if( bSignalSemaphore )
- m_pState->pSemaphore->Signal();
}
@@ -1529,71 +1530,73 @@ void cClientHandle::Send( const cPacket & a_Packet, ENUM_PRIORITY a_Priority /*
void cClientHandle::SendThread( void *lpParam )
{
cClientHandle* self = (cClientHandle*)lpParam;
- sClientHandleState* m_pState = self->m_pState;
- PacketList & NrmSendPackets = m_pState->PendingNrmSendPackets;
- PacketList & LowSendPackets = m_pState->PendingLowSendPackets;
+ PacketList & NrmSendPackets = self->mPendingNrmSendPackets;
+ PacketList & LowSendPackets = self->mPendingLowSendPackets;
- while( self->m_bKeepThreadGoing && m_pState->Socket )
+ while (self->m_bKeepThreadGoing && self->mSocket.IsValid())
{
- m_pState->pSemaphore->Wait();
- m_pState->SendCriticalSection.Lock();
- //LOG("Pending packets: %i", m_PendingPackets.size() );
- if( NrmSendPackets.size() + LowSendPackets.size() > MAX_SEMAPHORES )
+ self->mSemaphore.Wait();
+ cCSLock Lock(self->mSendCriticalSection);
+ if (NrmSendPackets.size() + LowSendPackets.size() > MAX_SEMAPHORES)
{
- LOGERROR("ERROR: Too many packets in queue for player %s !!", self->GetUsername().c_str());
+ LOGERROR("ERROR: Too many packets in queue for player %s !!", self->mUsername.c_str());
cPacket_Disconnect DC("Too many packets in queue.");
- DC.Send( m_pState->Socket );
+ DC.Send(self->mSocket);
cSleep::MilliSleep( 1000 ); // Give packet some time to be received
+ Lock.Unlock();
self->Destroy();
- m_pState->SendCriticalSection.Unlock();
break;
}
- if( NrmSendPackets.size() == 0 && LowSendPackets.size() == 0 )
+
+ if (NrmSendPackets.size() == 0 && LowSendPackets.size() == 0)
{
- if( self->m_bKeepThreadGoing ) LOGERROR("ERROR: Semaphore was signaled while PendingSendPackets.size == 0");
- m_pState->SendCriticalSection.Unlock();
+ assert(!self->m_bKeepThreadGoing);
+ if (self->m_bKeepThreadGoing)
+ {
+ LOGERROR("ERROR: Semaphore was signaled while no packets to send");
+ }
continue;
}
- if( NrmSendPackets.size() > MAX_SEMAPHORES/2 )
+ if (NrmSendPackets.size() > MAX_SEMAPHORES / 2)
{
LOGINFO("Pending packets: %i Last: 0x%02x", NrmSendPackets.size(), (*NrmSendPackets.rbegin())->m_PacketID );
}
- cPacket* Packet = 0;
- if( NrmSendPackets.size() > 0 )
+ cPacket * Packet = NULL;
+ if (!NrmSendPackets.empty())
{
Packet = *NrmSendPackets.begin();
NrmSendPackets.erase( NrmSendPackets.begin() );
}
- else if( LowSendPackets.size() > 0 )
+ else if (!LowSendPackets.empty())
{
Packet = *LowSendPackets.begin();
LowSendPackets.erase( LowSendPackets.begin() );
}
- m_pState->SendCriticalSection.Unlock();
+ Lock.Unlock();
- m_pState->SocketCriticalSection.Lock();
- if( !m_pState->Socket )
+ cCSLock SocketLock(self->mSocketCriticalSection);
+ if (!self->mSocket.IsValid())
{
- m_pState->SocketCriticalSection.Unlock();
break;
}
- //LOG("Send packet: 0x%2x", Packet->m_PacketID );
- bool bSuccess = Packet->Send( m_pState->Socket );
- m_pState->SocketCriticalSection.Unlock();
- if( !bSuccess )
+
+ bool bSuccess = Packet->Send(self->mSocket);
+ SocketLock.Unlock();
+
+ if (!bSuccess)
{
- LOGERROR("ERROR: While sending packet 0x%02x", Packet->m_PacketID );
+ LOGERROR("ERROR: While sending packet 0x%02x to client \"%s\"", Packet->m_PacketID, self->mUsername.c_str());
delete Packet;
self->Destroy();
break;
}
delete Packet;
- if( self->m_bKicking && (NrmSendPackets.size() + LowSendPackets.size() == 0) ) // Disconnect player after all packets have been sent
+ if (self->m_bKicking && (NrmSendPackets.size() + LowSendPackets.size() == 0) ) // Disconnect player after all packets have been sent
{
cSleep::MilliSleep( 1000 ); // Give all packets some time to be received
self->Destroy();
@@ -1630,19 +1633,18 @@ void cClientHandle::ReceiveThread( void *lpParam )
}
else
{
- //LOG("Recv packet: 0x%2x", (unsigned char)temp );
- cPacket* pPacket = self->m_pState->PacketMap[ (unsigned char)temp ];
- if( pPacket )
+ cPacket* pPacket = self->mPacketMap[(unsigned char)temp];
+ if (pPacket)
{
- if( pPacket->Parse( socket ) )
+ if (pPacket->Parse(socket))
{
- self->AddPacket( pPacket );
+ self->AddPacket(pPacket);
//self->HandlePendingPackets();
}
else
{
LOGERROR("Something went wrong during PacketID 0x%02x (%s)", temp, cSocket::GetLastErrorString() );
- LOG("CLIENT %s DISCONNECTED", self->GetUsername().c_str());
+ LOG("CLIENT %s DISCONNECTED", self->mUsername.c_str());
break;
}
}
@@ -1650,7 +1652,6 @@ void cClientHandle::ReceiveThread( void *lpParam )
{
LOG("Unknown packet: 0x%02x \'%c\' %i", (unsigned char)temp, (unsigned char)temp, (unsigned char)temp );
-
AString Reason;
Printf(Reason, "[C->S] Unknown PacketID: 0x%02x", (unsigned char)temp );
cPacket_Disconnect DC(Reason);
@@ -1674,7 +1675,7 @@ void cClientHandle::ReceiveThread( void *lpParam )
const AString & cClientHandle::GetUsername(void) const
{
- return m_pState->Username;
+ return mUsername;
}
@@ -1683,7 +1684,7 @@ const AString & cClientHandle::GetUsername(void) const
const cSocket & cClientHandle::GetSocket()
{
- return m_pState->Socket;
+ return mSocket;
}
diff --git a/source/cClientHandle.h b/source/cClientHandle.h
index 4e7d8ce91..21f97f6c3 100644
--- a/source/cClientHandle.h
+++ b/source/cClientHandle.h
@@ -1,13 +1,32 @@
+
+// cClientHandle.h
+
+// Interfaces to the cClientHandle class representing a client connected to this server. The client need not be a player yet
+
+
+
+
+
#pragma once
+#ifndef CCLIENTHANDLE_H_INCLUDED
+#define CCLIENTHANDLE_H_INCLUDED
+
+#include "Packets/cPacket.h"
+#include "Vector3d.h"
-class cSocket;
-class cSemaphore;
-class cEvent;
-class Game;
-class cPacket;
+
+
+
+
+// class Game;
class cChunk;
class cPlayer;
class cRedstone;
+
+
+
+
+
class cClientHandle // tolua_export
{ // tolua_export
public:
@@ -22,7 +41,7 @@ public:
cClientHandle(const cSocket & a_Socket);
~cClientHandle();
- static const int VIEWDISTANCE = 15; // MUST be odd number or CRASH!
+ static const int VIEWDISTANCE = 17; // MUST be odd number or CRASH!
static const int GENERATEDISTANCE = 2; // Server generates this many chunks AHEAD of player sight.
const cSocket & GetSocket();
@@ -62,12 +81,31 @@ private:
void SendLoginResponse();
- struct sClientHandleState;
- sClientHandleState* m_pState;
+ int mProtocolVersion;
+ AString mUsername;
+ AString mPassword;
+
+ PacketList mPendingParsePackets;
+ PacketList mPendingNrmSendPackets;
+ PacketList mPendingLowSendPackets;
+
+ cThread* pReceiveThread;
+ cThread* pSendThread;
+
+ cSocket mSocket;
- bool m_bDestroyed;
- cPlayer* m_Player;
- bool m_bKicking;
+ cCriticalSection mCriticalSection;
+ cCriticalSection mSendCriticalSection;
+ cCriticalSection mSocketCriticalSection;
+ cSemaphore mSemaphore;
+
+ Vector3d mConfirmPosition;
+
+ cPacket * mPacketMap[256];
+
+ bool m_bDestroyed;
+ cPlayer * m_Player;
+ bool m_bKicking;
float m_TimeLastPacket;
@@ -83,3 +121,12 @@ private:
bool m_bKeepThreadGoing;
}; // tolua_export
+
+
+
+
+#endif // CCLIENTHANDLE_H_INCLUDED
+
+
+
+
diff --git a/source/cPlayer.cpp b/source/cPlayer.cpp
index d336a4616..fa833ff47 100644
--- a/source/cPlayer.cpp
+++ b/source/cPlayer.cpp
@@ -158,16 +158,17 @@ void cPlayer::SpawnOn( cClientHandle* a_Target )
void cPlayer::Tick(float a_Dt)
{
cChunk* InChunk = GetWorld()->GetChunk( m_ChunkX, m_ChunkY, m_ChunkZ );
- if( !InChunk ) return;
+ if ( !InChunk ) return;
cPawn::Tick(a_Dt);
- if(m_bDirtyOrientation && !m_bDirtyPosition)
+ if (m_bDirtyOrientation && !m_bDirtyPosition)
{
cPacket_EntityLook EntityLook( this );
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 );
@@ -242,12 +243,14 @@ void cPlayer::Tick(float a_Dt)
cTimer t1;
// Send Player List (Once per m_LastPlayerListTime/1000 ms)
- if (m_LastPlayerListTime + cPlayer::PLAYER_LIST_TIME_MS <= t1.GetNowTime()) {
+ 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 )
+ for( cWorld::PlayerList::iterator itr = PlayerList.begin(); itr != PlayerList.end(); ++itr)
{
- if ((*itr) && (*itr)->GetClientHandle() && !((*itr)->GetClientHandle()->IsDestroyed())) {
- cPacket_PlayerListItem PlayerListItem(GetColor() + GetName(), true, GetClientHandle()->GetPing());
+ if ((*itr) && (*itr)->GetClientHandle() && !((*itr)->GetClientHandle()->IsDestroyed()))
+ {
+ cPacket_PlayerListItem PlayerListItem(GetColor() + m_pState->PlayerName, true, GetClientHandle()->GetPing());
(*itr)->GetClientHandle()->Send( PlayerListItem );
}
}
diff --git a/source/packets/cPacket.h b/source/packets/cPacket.h
index 7d85afc97..702b3e369 100644
--- a/source/packets/cPacket.h
+++ b/source/packets/cPacket.h
@@ -1,3 +1,4 @@
+
#pragma once
#include "../cSocket.h"
@@ -7,7 +8,6 @@
-class cSocket;
class cPacket
{
public:
@@ -53,6 +53,9 @@ public:
static int RecvAll( cSocket & a_Socket, char* a_Data, unsigned int a_Size, int a_Options );
};
+typedef std::list <cPacket*> PacketList;
+typedef std::deque<cPacket *> PacketQueue;
+