From 59af89235bfb9189dec1fcee40a9231d03690d27 Mon Sep 17 00:00:00 2001 From: "mtilden@gmail.com" Date: Tue, 27 Dec 2011 18:39:06 +0000 Subject: - Added basic ping handling. Not sure what's up with the MC client, though. It doesn't seem to end up giving good results like the KA packet return is hanging and waiting for other things to process instead of being handled on its own to give a true result. Feel free to update if there's any way to deliver truer results. git-svn-id: http://mc-server.googlecode.com/svn/trunk@133 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/cClientHandle.cpp | 30 +++++++++++++++++++++++++++--- source/cClientHandle.h | 7 +++++-- source/cPlayer.cpp | 8 ++++---- source/cPlayer.h | 2 +- source/packets/cPacket_KeepAlive.h | 1 + 5 files changed, 38 insertions(+), 10 deletions(-) (limited to 'source') 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); -- cgit v1.2.3