diff --git a/source/cClientHandle.cpp b/source/cClientHandle.cpp index d99ff04d0..d1c924064 100644 --- a/source/cClientHandle.cpp +++ b/source/cClientHandle.cpp @@ -24,6 +24,7 @@ #include "cChatColor.h" #include "cThread.h" #include "cSocket.h" +#include "cTimer.h" #include "cTracer.h" #include "Vector3f.h" @@ -37,6 +38,7 @@ #include "cBlockingTCPLink.h" #include "cAuthenticator.h" +#include "MersenneTwister.h" #include "packets/cPacket_KeepAlive.h" #include "packets/cPacket_PlayerPosition.h" @@ -126,6 +128,9 @@ cClientHandle::cClientHandle(const cSocket & a_Socket) , m_Ping(1000) { LOG("cClientHandle::cClientHandle"); + + cTimer t1; + m_LastPingTime = t1.GetNowTime(); m_pState->Socket = a_Socket; @@ -1203,8 +1208,15 @@ void cClientHandle::HandlePacket( cPacket* a_Packet ) } break; case E_KEEP_ALIVE: - // TODO: Handle player ping per minecraft - //cPacket_KeepAlive* PacketData = reinterpret_cast(a_Packet); + { + cPacket_KeepAlive *PacketData = reinterpret_cast(a_Packet); + if (PacketData->m_KeepAliveID == m_PingID) + { + cTimer t1; + m_Ping = (short)(t1.GetNowTime() - m_PingStartTime); + LOG("%s ping: %d\n", m_Player->GetName(), m_Ping); + } + } break; default: break; @@ -1238,6 +1250,18 @@ void cClientHandle::Tick(float a_Dt) Destroy(); } + + cTimer t1; + // Send ping packet + if (m_LastPingTime + cClientHandle::PING_TIME_MS <= t1.GetNowTime()) { + MTRand r1; + m_PingID = r1.randInt(); + cPacket_KeepAlive Ping(m_PingID); + m_PingStartTime = t1.GetNowTime(); + Send(Ping); + m_Ping = 1000; // default if it's > 1 second or they're timed out + m_LastPingTime = m_PingStartTime; + } if( m_bSendLoginResponse ) { @@ -1249,7 +1273,7 @@ void cClientHandle::Tick(float a_Dt) 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 if( !World ) World = cRoot::Get()->GetDefaultWorld(); World->LockEntities(); - m_Player->LoginSetGameMode ( World->GetGameMode() ); //set player's gamemode to server's gamemode at login. + 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() ); diff --git a/source/cClientHandle.h b/source/cClientHandle.h index 4f8981b78..abb0c14c6 100644 --- a/source/cClientHandle.h +++ b/source/cClientHandle.h @@ -54,7 +54,7 @@ public: static void AuthenticateThread( void* a_Param ); const char* GetUsername(); - + inline short GetPing() { return m_Ping; } private: void HandlePacket( cPacket* a_Packet ); @@ -71,8 +71,11 @@ private: float m_TimeLastPacket; - // TODO: ping calculation per minecraft short m_Ping; + int m_PingID; + long long m_PingStartTime; + long long m_LastPingTime; + static const unsigned short PING_TIME_MS = 1000; //minecraft sends 1 per 20 ticks (1 second or every 1000 ms) bool m_bLoggedIn; bool m_bSendLoginResponse; diff --git a/source/cPlayer.cpp b/source/cPlayer.cpp index dcc9de177..4e743a2fe 100644 --- a/source/cPlayer.cpp +++ b/source/cPlayer.cpp @@ -239,14 +239,14 @@ void cPlayer::Tick(float a_Dt) } cTimer t1; - // Send Player List (Once per m_LastPlayerListTime/1000 second(s)) - if (m_LastPlayerListTime + cPlayer::E_PLAYER_LIST_TIME <= t1.GetNowTime()) { + // 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 PlayerList(GetColor() + GetName(), true, (*itr)->GetClientHandle()->GetPing()); - (*itr)->GetClientHandle()->Send( PlayerList ); + cPacket_PlayerListItem PlayerListItem(GetColor() + GetName(), true, (*itr)->GetClientHandle()->GetPing()); + (*itr)->GetClientHandle()->Send( PlayerListItem ); } } m_LastPlayerListTime = t1.GetNowTime(); diff --git a/source/cPlayer.h b/source/cPlayer.h index 17e575e91..621b1031c 100644 --- a/source/cPlayer.h +++ b/source/cPlayer.h @@ -115,7 +115,7 @@ protected: std::string m_IP; long long m_LastPlayerListTime; - static const unsigned short E_PLAYER_LIST_TIME = 1000; // 1000 = once per second + static const unsigned short PLAYER_LIST_TIME_MS = 1000; // 1000 = once per second cClientHandle* m_ClientHandle; }; //tolua_export diff --git a/source/packets/cPacket_KeepAlive.h b/source/packets/cPacket_KeepAlive.h index 833947bfb..85bd14083 100644 --- a/source/packets/cPacket_KeepAlive.h +++ b/source/packets/cPacket_KeepAlive.h @@ -7,6 +7,7 @@ class cPacket_KeepAlive : public cPacket { public: cPacket_KeepAlive() { m_PacketID = E_KEEP_ALIVE; } + cPacket_KeepAlive(int a_PingID) { m_KeepAliveID = a_PingID; } virtual cPacket* Clone() const { return new cPacket_KeepAlive(*this); } virtual bool Parse(cSocket & a_Socket);