1
0

- 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
This commit is contained in:
mtilden@gmail.com 2011-12-27 18:39:06 +00:00
parent 8a21fbf0ce
commit 59af89235b
5 changed files with 38 additions and 10 deletions

View File

@ -24,6 +24,7 @@
#include "cChatColor.h" #include "cChatColor.h"
#include "cThread.h" #include "cThread.h"
#include "cSocket.h" #include "cSocket.h"
#include "cTimer.h"
#include "cTracer.h" #include "cTracer.h"
#include "Vector3f.h" #include "Vector3f.h"
@ -37,6 +38,7 @@
#include "cBlockingTCPLink.h" #include "cBlockingTCPLink.h"
#include "cAuthenticator.h" #include "cAuthenticator.h"
#include "MersenneTwister.h"
#include "packets/cPacket_KeepAlive.h" #include "packets/cPacket_KeepAlive.h"
#include "packets/cPacket_PlayerPosition.h" #include "packets/cPacket_PlayerPosition.h"
@ -126,6 +128,9 @@ cClientHandle::cClientHandle(const cSocket & a_Socket)
, m_Ping(1000) , m_Ping(1000)
{ {
LOG("cClientHandle::cClientHandle"); LOG("cClientHandle::cClientHandle");
cTimer t1;
m_LastPingTime = t1.GetNowTime();
m_pState->Socket = a_Socket; m_pState->Socket = a_Socket;
@ -1203,8 +1208,15 @@ void cClientHandle::HandlePacket( cPacket* a_Packet )
} }
break; break;
case E_KEEP_ALIVE: case E_KEEP_ALIVE:
// TODO: Handle player ping per minecraft {
//cPacket_KeepAlive* PacketData = reinterpret_cast<cPacket_KeepAlive*>(a_Packet); cPacket_KeepAlive *PacketData = reinterpret_cast<cPacket_KeepAlive*>(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; break;
default: default:
break; break;
@ -1238,6 +1250,18 @@ void cClientHandle::Tick(float a_Dt)
Destroy(); 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 ) 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 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(); if( !World ) World = cRoot::Get()->GetDefaultWorld();
World->LockEntities(); 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() ); m_Player->SetIP ( m_pState->Socket.GetIPString() );

View File

@ -54,7 +54,7 @@ public:
static void AuthenticateThread( void* a_Param ); static void AuthenticateThread( void* a_Param );
const char* GetUsername(); const char* GetUsername();
inline short GetPing() { return m_Ping; } inline short GetPing() { return m_Ping; }
private: private:
void HandlePacket( cPacket* a_Packet ); void HandlePacket( cPacket* a_Packet );
@ -71,8 +71,11 @@ private:
float m_TimeLastPacket; float m_TimeLastPacket;
// TODO: ping calculation per minecraft
short m_Ping; 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_bLoggedIn;
bool m_bSendLoginResponse; bool m_bSendLoginResponse;

View File

@ -239,14 +239,14 @@ void cPlayer::Tick(float a_Dt)
} }
cTimer t1; cTimer t1;
// Send Player List (Once per m_LastPlayerListTime/1000 second(s)) // Send Player List (Once per m_LastPlayerListTime/1000 ms)
if (m_LastPlayerListTime + cPlayer::E_PLAYER_LIST_TIME <= t1.GetNowTime()) { if (m_LastPlayerListTime + cPlayer::PLAYER_LIST_TIME_MS <= t1.GetNowTime()) {
cWorld::PlayerList PlayerList = cRoot::Get()->GetWorld()->GetAllPlayers(); 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())) { if ((*itr) && (*itr)->GetClientHandle() && !((*itr)->GetClientHandle()->IsDestroyed())) {
cPacket_PlayerListItem PlayerList(GetColor() + GetName(), true, (*itr)->GetClientHandle()->GetPing()); cPacket_PlayerListItem PlayerListItem(GetColor() + GetName(), true, (*itr)->GetClientHandle()->GetPing());
(*itr)->GetClientHandle()->Send( PlayerList ); (*itr)->GetClientHandle()->Send( PlayerListItem );
} }
} }
m_LastPlayerListTime = t1.GetNowTime(); m_LastPlayerListTime = t1.GetNowTime();

View File

@ -115,7 +115,7 @@ protected:
std::string m_IP; std::string m_IP;
long long m_LastPlayerListTime; 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; cClientHandle* m_ClientHandle;
}; //tolua_export }; //tolua_export

View File

@ -7,6 +7,7 @@ class cPacket_KeepAlive : public cPacket
{ {
public: public:
cPacket_KeepAlive() { m_PacketID = E_KEEP_ALIVE; } 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 cPacket* Clone() const { return new cPacket_KeepAlive(*this); }
virtual bool Parse(cSocket & a_Socket); virtual bool Parse(cSocket & a_Socket);