Fixed cClientHandle::Tick() being called from two threads.
When the player was initialized, the Tick() function continued to stream chunk, while the cWorld called Tick() from its tick thread. Final fix for #187.
This commit is contained in:
parent
e024278b02
commit
f521cbeb31
@ -1476,12 +1476,6 @@ void cClientHandle::Tick(float a_Dt)
|
|||||||
}
|
}
|
||||||
m_Protocol->DataReceived(IncomingData.data(), IncomingData.size());
|
m_Protocol->DataReceived(IncomingData.data(), IncomingData.size());
|
||||||
|
|
||||||
if (m_State == csAuthenticated)
|
|
||||||
{
|
|
||||||
StreamChunks();
|
|
||||||
m_State = csDownloadingWorld;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_TimeSinceLastPacket += a_Dt;
|
m_TimeSinceLastPacket += a_Dt;
|
||||||
if (m_TimeSinceLastPacket > 30000.f) // 30 seconds time-out
|
if (m_TimeSinceLastPacket > 30000.f) // 30 seconds time-out
|
||||||
{
|
{
|
||||||
@ -1536,6 +1530,49 @@ void cClientHandle::Tick(float a_Dt)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cClientHandle::ServerTick(float a_Dt)
|
||||||
|
{
|
||||||
|
// Handle clients that are waiting for final close while destroyed:
|
||||||
|
if (m_State == csDestroyedWaiting)
|
||||||
|
{
|
||||||
|
// Do not wait while the client is not in the world, simply cut them off.
|
||||||
|
m_State = csDestroyed;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process received network data:
|
||||||
|
AString IncomingData;
|
||||||
|
{
|
||||||
|
cCSLock Lock(m_CSIncomingData);
|
||||||
|
std::swap(IncomingData, m_IncomingData);
|
||||||
|
}
|
||||||
|
m_Protocol->DataReceived(IncomingData.data(), IncomingData.size());
|
||||||
|
|
||||||
|
if (m_State == csAuthenticated)
|
||||||
|
{
|
||||||
|
StreamChunks();
|
||||||
|
|
||||||
|
// Remove the client handle from the server, it will be ticked from its cPlayer object from now on
|
||||||
|
cRoot::Get()->GetServer()->ClientMovedToWorld(this);
|
||||||
|
|
||||||
|
// Add the player to the world (start ticking from there):
|
||||||
|
m_State = csDownloadingWorld;
|
||||||
|
m_Player->GetWorld()->AddPlayer(m_Player);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_TimeSinceLastPacket += a_Dt;
|
||||||
|
if (m_TimeSinceLastPacket > 30000.f) // 30 seconds time-out
|
||||||
|
{
|
||||||
|
SendDisconnect("Nooooo!! You timed out! D: Come back!");
|
||||||
|
Destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cClientHandle::SendAttachEntity(const cEntity & a_Entity, const cEntity * a_Vehicle)
|
void cClientHandle::SendAttachEntity(const cEntity & a_Entity, const cEntity * a_Vehicle)
|
||||||
{
|
{
|
||||||
m_Protocol->SendAttachEntity(a_Entity, a_Vehicle);
|
m_Protocol->SendAttachEntity(a_Entity, a_Vehicle);
|
||||||
|
@ -79,8 +79,12 @@ public:
|
|||||||
|
|
||||||
inline bool IsLoggedIn(void) const { return (m_State >= csAuthenticating); }
|
inline bool IsLoggedIn(void) const { return (m_State >= csAuthenticating); }
|
||||||
|
|
||||||
|
/// Called while the client is being ticked from the world via its cPlayer object
|
||||||
void Tick(float a_Dt);
|
void Tick(float a_Dt);
|
||||||
|
|
||||||
|
/// Called while the client is being ticked from the cServer object
|
||||||
|
void ServerTick(float a_Dt);
|
||||||
|
|
||||||
void Destroy(void);
|
void Destroy(void);
|
||||||
|
|
||||||
bool IsPlaying (void) const { return (m_State == csPlaying); }
|
bool IsPlaying (void) const { return (m_State == csPlaying); }
|
||||||
|
@ -137,28 +137,6 @@ cPlayer::~cPlayer(void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cPlayer::Initialize(cWorld * a_World)
|
|
||||||
{
|
|
||||||
ASSERT(a_World != NULL);
|
|
||||||
|
|
||||||
if (super::Initialize(a_World))
|
|
||||||
{
|
|
||||||
// Remove the client handle from the server, it will be ticked from this object from now on
|
|
||||||
if (m_ClientHandle != NULL)
|
|
||||||
{
|
|
||||||
cRoot::Get()->GetServer()->ClientMovedToWorld(m_ClientHandle);
|
|
||||||
}
|
|
||||||
|
|
||||||
GetWorld()->AddPlayer(this);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cPlayer::Destroyed()
|
void cPlayer::Destroyed()
|
||||||
{
|
{
|
||||||
CloseWindow(false);
|
CloseWindow(false);
|
||||||
|
@ -41,8 +41,6 @@ public:
|
|||||||
cPlayer(cClientHandle * a_Client, const AString & a_PlayerName);
|
cPlayer(cClientHandle * a_Client, const AString & a_PlayerName);
|
||||||
virtual ~cPlayer();
|
virtual ~cPlayer();
|
||||||
|
|
||||||
virtual bool Initialize(cWorld * a_World) override;
|
|
||||||
|
|
||||||
virtual void SpawnOn(cClientHandle & a_Client) override;
|
virtual void SpawnOn(cClientHandle & a_Client) override;
|
||||||
|
|
||||||
virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
|
virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
|
||||||
|
@ -402,7 +402,7 @@ void cServer::TickClients(float a_Dt)
|
|||||||
itr = m_Clients.erase(itr);
|
itr = m_Clients.erase(itr);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
(*itr)->Tick(a_Dt);
|
(*itr)->ServerTick(a_Dt);
|
||||||
++itr;
|
++itr;
|
||||||
} // for itr - m_Clients[]
|
} // for itr - m_Clients[]
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user