Removed cServer::m_pState, dissolved into direct member variables.
The server tick thread is now in the cServer::cTickThread object.master
parent
2baa6634ec
commit
c59d80a2af
|
@ -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"),
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue