Removed cServer::m_pState, dissolved into direct member variables.

The server tick thread is now in the cServer::cTickThread object.
master
madmaxoft 2013-08-11 19:46:27 +02:00
parent 2baa6634ec
commit c59d80a2af
2 changed files with 75 additions and 101 deletions

View File

@ -59,18 +59,42 @@ typedef std::list< cClientHandle* > ClientList;
struct cServer::sServerState ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cServer::cTickThread:
cServer::cTickThread::cTickThread(cServer & a_Server) :
super("ServerTickThread"),
m_Server(a_Server)
{ {
sServerState() }
: pTickThread(NULL)
, bStopTickThread(false)
{}
cThread* pTickThread; bool bStopTickThread;
cEvent RestartEvent;
std::string ServerID;
};
void cServer::cTickThread::Execute(void)
{
cTimer Timer;
long long msPerTick = 50; // TODO - Put this in server config file
long long LastTime = Timer.GetNowTime();
while (!m_ShouldTerminate)
{
long long NowTime = Timer.GetNowTime();
float DeltaTime = (float)(NowTime-LastTime);
m_ShouldTerminate = !m_Server.Tick(DeltaTime);
long long TickTime = Timer.GetNowTime() - NowTime;
if (TickTime < msPerTick)
{
// Stretch tick time until it's at least msPerTick
cSleep::MilliSleep((unsigned int)(msPerTick - TickTime));
}
LastTime = NowTime;
}
}
@ -80,14 +104,12 @@ struct cServer::sServerState
// cServer: // cServer:
cServer::cServer(void) : cServer::cServer(void) :
m_pState(new sServerState),
m_ListenThreadIPv4(*this, cSocket::IPv4, "Client"), m_ListenThreadIPv4(*this, cSocket::IPv4, "Client"),
m_ListenThreadIPv6(*this, cSocket::IPv6, "Client"), m_ListenThreadIPv6(*this, cSocket::IPv6, "Client"),
m_Millisecondsf(0),
m_Milliseconds(0),
m_bIsConnected(false), m_bIsConnected(false),
m_bRestarting(false), m_bRestarting(false),
m_RCONServer(*this) m_RCONServer(*this),
m_TickThread(*this)
{ {
} }
@ -95,19 +117,6 @@ cServer::cServer(void) :
cServer::~cServer()
{
// TODO: Shut down the server gracefully
m_pState->bStopTickThread = true;
delete m_pState->pTickThread; m_pState->pTickThread = NULL;
delete m_pState;
}
void cServer::ClientDestroying(const cClientHandle * a_Client) void cServer::ClientDestroying(const cClientHandle * a_Client)
{ {
m_SocketThreads.StopReading(a_Client); m_SocketThreads.StopReading(a_Client);
@ -199,7 +208,7 @@ bool cServer::InitServer(cIniFile & a_SettingsIni)
m_bIsConnected = true; m_bIsConnected = true;
m_pState->ServerID = "-"; m_ServerID = "-";
if (a_SettingsIni.GetValueSetB("Authentication", "Authenticate", true)) if (a_SettingsIni.GetValueSetB("Authentication", "Authenticate", true))
{ {
MTRand mtrand1; MTRand mtrand1;
@ -208,9 +217,8 @@ bool cServer::InitServer(cIniFile & a_SettingsIni)
std::ostringstream sid; std::ostringstream sid;
sid << std::hex << r1; sid << std::hex << r1;
sid << std::hex << r2; sid << std::hex << r2;
std::string ServerID = sid.str(); m_ServerID = sid.str();
ServerID.resize(16, '0'); m_ServerID.resize(16, '0');
m_pState->ServerID = ServerID;
} }
m_ClientViewDistance = a_SettingsIni.GetValueSetI("Server", "DefaultViewDistance", cClientHandle::DEFAULT_VIEW_DISTANCE); m_ClientViewDistance = a_SettingsIni.GetValueSetI("Server", "DefaultViewDistance", cClientHandle::DEFAULT_VIEW_DISTANCE);
@ -309,14 +317,7 @@ void cServer::BroadcastChat(const AString & a_Message, const cClientHandle * a_E
bool cServer::Tick(float a_Dt) bool cServer::Tick(float a_Dt)
{ {
m_Millisecondsf += a_Dt; cRoot::Get()->TickWorlds(a_Dt);
if (m_Millisecondsf > 1.f)
{
m_Milliseconds += (int)m_Millisecondsf;
m_Millisecondsf = m_Millisecondsf - (int)m_Millisecondsf;
}
cRoot::Get()->TickWorlds(a_Dt); // TODO - Maybe give all worlds their own thread?
cClientHandleList RemoveClients; cClientHandleList RemoveClients;
{ {
@ -338,8 +339,6 @@ bool cServer::Tick(float a_Dt)
delete *itr; delete *itr;
} // for itr - RemoveClients[] } // for itr - RemoveClients[]
cRoot::Get()->GetPluginManager()->Tick(a_Dt);
if (!m_bRestarting) if (!m_bRestarting)
{ {
return true; return true;
@ -347,7 +346,7 @@ bool cServer::Tick(float a_Dt)
else else
{ {
m_bRestarting = false; m_bRestarting = false;
m_pState->RestartEvent.Set(); m_RestartEvent.Set();
return false; return false;
} }
} }
@ -356,42 +355,8 @@ bool cServer::Tick(float a_Dt)
void ServerTickThread( void * a_Param )
{
LOG("ServerTickThread");
cServer *CServerObj = (cServer*)a_Param;
cTimer Timer;
long long msPerTick = 50; // TODO - Put this in server config file
long long LastTime = Timer.GetNowTime();
bool bKeepGoing = true;
while( bKeepGoing )
{
long long NowTime = Timer.GetNowTime();
float DeltaTime = (float)(NowTime-LastTime);
bKeepGoing = CServerObj->Tick( DeltaTime );
long long TickTime = Timer.GetNowTime() - NowTime;
if( TickTime < msPerTick ) // Stretch tick time until it's at least msPerTick
{
cSleep::MilliSleep( (unsigned int)( msPerTick - TickTime ) );
}
LastTime = NowTime;
}
LOG("TICK THREAD STOPPED");
}
bool cServer::Start(void) bool cServer::Start(void)
{ {
m_pState->pTickThread = new cThread( ServerTickThread, this, "cServer::ServerTickThread" );
if (!m_ListenThreadIPv4.Start()) if (!m_ListenThreadIPv4.Start())
{ {
return false; return false;
@ -400,7 +365,10 @@ bool cServer::Start(void)
{ {
return false; return false;
} }
m_pState->pTickThread->Start( true ); if (!m_TickThread.Start())
{
return false;
}
return true; return true;
} }
@ -503,13 +471,13 @@ void cServer::SendMessage(const AString & a_Message, cPlayer * a_Player /* = NUL
void cServer::Shutdown() void cServer::Shutdown(void)
{ {
m_ListenThreadIPv4.Stop(); m_ListenThreadIPv4.Stop();
m_ListenThreadIPv6.Stop(); m_ListenThreadIPv6.Stop();
m_bRestarting = true; m_bRestarting = true;
m_pState->RestartEvent.Wait(); m_RestartEvent.Wait();
cRoot::Get()->SaveAllChunks(); cRoot::Get()->SaveAllChunks();
@ -526,15 +494,6 @@ void cServer::Shutdown()
const AString & cServer::GetServerID(void) const
{
return m_pState->ServerID;
}
void cServer::KickUser(int a_ClientID, const AString & a_Reason) void cServer::KickUser(int a_ClientID, const AString & a_Reason)
{ {
cCSLock Lock(m_CSClients); cCSLock Lock(m_CSClients);
@ -568,7 +527,7 @@ void cServer::AuthenticateUser(int a_ClientID)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cServer::cClientPacketThread: // cServer::cNotifyWriteThread:
cServer::cNotifyWriteThread::cNotifyWriteThread(void) : cServer::cNotifyWriteThread::cNotifyWriteThread(void) :
super("ClientPacketThread"), super("ClientPacketThread"),

View File

@ -52,8 +52,6 @@ public: // tolua_export
void BroadcastChat(const AString & a_Message, const cClientHandle * a_Exclude = NULL); // tolua_export void BroadcastChat(const AString & a_Message, const cClientHandle * a_Exclude = NULL); // tolua_export
bool Tick(float a_Dt);
bool Start(void); bool Start(void);
bool Command(cClientHandle & a_Client, AString & a_Cmd); bool Command(cClientHandle & a_Client, AString & a_Cmd);
@ -71,7 +69,7 @@ public: // tolua_export
void KickUser(int a_ClientID, const AString & a_Reason); void KickUser(int a_ClientID, const AString & a_Reason);
void AuthenticateUser(int a_ClientID); // Called by cAuthenticator to auth the specified user void AuthenticateUser(int a_ClientID); // Called by cAuthenticator to auth the specified user
const AString & GetServerID(void) const; // tolua_export const AString & GetServerID(void) const { return m_ServerID; } // tolua_export
void ClientDestroying(const cClientHandle * a_Client); // Called by cClientHandle::Destroy(); stop m_SocketThreads from calling back into a_Client void ClientDestroying(const cClientHandle * a_Client); // Called by cClientHandle::Destroy(); stop m_SocketThreads from calling back into a_Client
@ -114,8 +112,22 @@ private:
void NotifyClientWrite(const cClientHandle * a_Client); void NotifyClientWrite(const cClientHandle * a_Client);
} ; } ;
struct sServerState; /// The server tick thread takes care of the players who aren't yet spawned in a world
sServerState * m_pState; class cTickThread :
public cIsThread
{
typedef cIsThread super;
public:
cTickThread(cServer & a_Server);
protected:
cServer & m_Server;
// cIsThread overrides:
virtual void Execute(void) override;
} ;
cNotifyWriteThread m_NotifyWriteThread; cNotifyWriteThread m_NotifyWriteThread;
@ -129,10 +141,6 @@ private:
int m_ClientViewDistance; // The default view distance for clients; settable in Settings.ini int m_ClientViewDistance; // The default view distance for clients; settable in Settings.ini
// Time since server was started
float m_Millisecondsf;
unsigned int m_Milliseconds;
bool m_bIsConnected; // true - connected false - not connected bool m_bIsConnected; // true - connected false - not connected
bool m_bRestarting; bool m_bRestarting;
@ -146,13 +154,20 @@ private:
int m_MaxPlayers; int m_MaxPlayers;
int m_NumPlayers; int m_NumPlayers;
cTickThread m_TickThread;
cEvent m_RestartEvent;
/// The server ID used for client authentication
AString m_ServerID;
cServer(void); cServer(void);
~cServer();
/// Loads, or generates, if missing, RSA keys for protocol encryption /// Loads, or generates, if missing, RSA keys for protocol encryption
void PrepareKeys(void); void PrepareKeys(void);
bool Tick(float a_Dt);
// cListenThread::cCallback overrides: // cListenThread::cCallback overrides:
virtual void OnConnectionAccepted(cSocket & a_Socket) override; virtual void OnConnectionAccepted(cSocket & a_Socket) override;
}; // tolua_export }; // tolua_export