parent
b65a91dde3
commit
8c3837987b
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
** Lua binding: AllToLua
|
** Lua binding: AllToLua
|
||||||
** Generated automatically by tolua++-1.0.92 on 08/13/13 23:07:52.
|
** Generated automatically by tolua++-1.0.92 on 08/14/13 08:14:03.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __cplusplus
|
#ifndef __cplusplus
|
||||||
@ -11295,14 +11295,14 @@ static int tolua_AllToLua_cServer_GetNumPlayers00(lua_State* tolua_S)
|
|||||||
#ifndef TOLUA_RELEASE
|
#ifndef TOLUA_RELEASE
|
||||||
tolua_Error tolua_err;
|
tolua_Error tolua_err;
|
||||||
if (
|
if (
|
||||||
!tolua_isusertype(tolua_S,1,"const cServer",0,&tolua_err) ||
|
!tolua_isusertype(tolua_S,1,"cServer",0,&tolua_err) ||
|
||||||
!tolua_isnoobj(tolua_S,2,&tolua_err)
|
!tolua_isnoobj(tolua_S,2,&tolua_err)
|
||||||
)
|
)
|
||||||
goto tolua_lerror;
|
goto tolua_lerror;
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
const cServer* self = (const cServer*) tolua_tousertype(tolua_S,1,0);
|
cServer* self = (cServer*) tolua_tousertype(tolua_S,1,0);
|
||||||
#ifndef TOLUA_RELEASE
|
#ifndef TOLUA_RELEASE
|
||||||
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetNumPlayers'", NULL);
|
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetNumPlayers'", NULL);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
** Lua binding: AllToLua
|
** Lua binding: AllToLua
|
||||||
** Generated automatically by tolua++-1.0.92 on 08/13/13 23:07:53.
|
** Generated automatically by tolua++-1.0.92 on 08/14/13 08:14:04.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Exported function */
|
/* Exported function */
|
||||||
|
@ -275,7 +275,7 @@ void cClientHandle::Authenticate(void)
|
|||||||
|
|
||||||
void cClientHandle::StreamChunks(void)
|
void cClientHandle::StreamChunks(void)
|
||||||
{
|
{
|
||||||
if ((m_State < csAuthenticating) || (m_State >= csDestroying))
|
if ((m_State < csAuthenticated) || (m_State >= csDestroying))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1314,6 +1314,42 @@ void cClientHandle::SendData(const char * a_Data, int a_Size)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cClientHandle::MoveToWorld(cWorld & a_World, bool a_SendRespawnPacket)
|
||||||
|
{
|
||||||
|
ASSERT(m_Player != NULL);
|
||||||
|
|
||||||
|
if (a_SendRespawnPacket)
|
||||||
|
{
|
||||||
|
SendRespawn();
|
||||||
|
}
|
||||||
|
|
||||||
|
cWorld * World = m_Player->GetWorld();
|
||||||
|
|
||||||
|
// Remove all associated chunks:
|
||||||
|
cChunkCoordsList Chunks;
|
||||||
|
{
|
||||||
|
cCSLock Lock(m_CSChunkLists);
|
||||||
|
std::swap(Chunks, m_LoadedChunks);
|
||||||
|
m_ChunksToSend.clear();
|
||||||
|
}
|
||||||
|
for (cChunkCoordsList::iterator itr = Chunks.begin(), end = Chunks.end(); itr != end; ++itr)
|
||||||
|
{
|
||||||
|
World->RemoveChunkClient(itr->m_ChunkX, itr->m_ChunkZ, this);
|
||||||
|
m_Protocol->SendUnloadChunk(itr->m_ChunkX, itr->m_ChunkZ);
|
||||||
|
} // for itr - Chunks[]
|
||||||
|
|
||||||
|
// Do NOT stream new chunks, the new world runs its own tick thread and may deadlock
|
||||||
|
// Instead, the chunks will be streamed when the client is moved to the new world's Tick list,
|
||||||
|
// by setting state to csAuthenticated
|
||||||
|
m_State = csAuthenticated;
|
||||||
|
m_LastStreamedChunkX = 0x7fffffff;
|
||||||
|
m_LastStreamedChunkZ = 0x7fffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cClientHandle::CheckBlockInteractionsRate(void)
|
bool cClientHandle::CheckBlockInteractionsRate(void)
|
||||||
{
|
{
|
||||||
ASSERT(m_Player != NULL);
|
ASSERT(m_Player != NULL);
|
||||||
|
@ -32,6 +32,7 @@ class cRedstone;
|
|||||||
class cWindow;
|
class cWindow;
|
||||||
class cFallingBlock;
|
class cFallingBlock;
|
||||||
class cItemHandler;
|
class cItemHandler;
|
||||||
|
class cWorld;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -194,6 +195,9 @@ public:
|
|||||||
|
|
||||||
void SendData(const char * a_Data, int a_Size);
|
void SendData(const char * a_Data, int a_Size);
|
||||||
|
|
||||||
|
/// Called when the player moves into a different world; queues sreaming the new chunks
|
||||||
|
void MoveToWorld(cWorld & a_World, bool a_SendRespawnPacket);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
int m_ViewDistance; // Number of chunks the player can see in each direction; 4 is the minimum ( http://wiki.vg/Protocol_FAQ#.E2.80.A6all_connecting_clients_spasm_and_jerk_uncontrollably.21 )
|
int m_ViewDistance; // Number of chunks the player can see in each direction; 4 is the minimum ( http://wiki.vg/Protocol_FAQ#.E2.80.A6all_connecting_clients_spasm_and_jerk_uncontrollably.21 )
|
||||||
|
@ -100,6 +100,8 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName)
|
|||||||
m_LastJumpHeight = (float)(GetPosY());
|
m_LastJumpHeight = (float)(GetPosY());
|
||||||
m_LastGroundHeight = (float)(GetPosY());
|
m_LastGroundHeight = (float)(GetPosY());
|
||||||
m_Stance = GetPosY() + 1.62;
|
m_Stance = GetPosY() + 1.62;
|
||||||
|
|
||||||
|
cRoot::Get()->GetServer()->PlayerCreated(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1120,20 +1122,15 @@ bool cPlayer::MoveToWorld(const char * a_WorldName)
|
|||||||
m_ClientHandle->RemoveFromAllChunks();
|
m_ClientHandle->RemoveFromAllChunks();
|
||||||
m_World->RemoveEntity(this);
|
m_World->RemoveEntity(this);
|
||||||
|
|
||||||
|
// If the dimension is different, we can send the respawn packet
|
||||||
|
// http://wiki.vg/Protocol#0x09 says "don't send if dimension is the same" as of 2013_07_02
|
||||||
|
m_ClientHandle->MoveToWorld(*World, (OldDimension != World->GetDimension()));
|
||||||
|
|
||||||
// Add player to all the necessary parts of the new world
|
// Add player to all the necessary parts of the new world
|
||||||
SetWorld(World);
|
SetWorld(World);
|
||||||
World->AddEntity(this);
|
World->AddEntity(this);
|
||||||
World->AddPlayer(this);
|
World->AddPlayer(this);
|
||||||
|
|
||||||
// If the dimension is different, we can send the respawn packet
|
|
||||||
// http://wiki.vg/Protocol#0x09 says "don't send if dimension is the same" as of 2013_07_02
|
|
||||||
if (OldDimension != World->GetDimension())
|
|
||||||
{
|
|
||||||
m_ClientHandle->SendRespawn();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stream the new chunks:
|
|
||||||
m_ClientHandle->StreamChunks();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,10 +172,34 @@ void cServer::ClientMovedToWorld(const cClientHandle * a_Client)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cServer::PlayerCreated(const cPlayer * a_Player)
|
||||||
|
{
|
||||||
|
// To avoid deadlocks, the player count is not handled directly, but rather posted onto the tick thread
|
||||||
|
cCSLock Lock(m_CSPlayerCountDiff);
|
||||||
|
m_PlayerCountDiff += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cServer::PlayerDestroyed(const cPlayer * a_Player)
|
||||||
|
{
|
||||||
|
// To avoid deadlocks, the player count is not handled directly, but rather posted onto the tick thread
|
||||||
|
cCSLock Lock(m_CSPlayerCountDiff);
|
||||||
|
m_PlayerCountDiff -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cServer::InitServer(cIniFile & a_SettingsIni)
|
bool cServer::InitServer(cIniFile & a_SettingsIni)
|
||||||
{
|
{
|
||||||
m_Description = a_SettingsIni.GetValue ("Server", "Description", "MCServer! - In C++!").c_str();
|
m_Description = a_SettingsIni.GetValue ("Server", "Description", "MCServer! - In C++!").c_str();
|
||||||
m_MaxPlayers = a_SettingsIni.GetValueI("Server", "MaxPlayers", 100);
|
m_MaxPlayers = a_SettingsIni.GetValueI("Server", "MaxPlayers", 100);
|
||||||
|
m_PlayerCount = 0;
|
||||||
|
m_PlayerCountDiff = 0;
|
||||||
|
|
||||||
if (m_bIsConnected)
|
if (m_bIsConnected)
|
||||||
{
|
{
|
||||||
@ -254,6 +278,16 @@ bool cServer::InitServer(cIniFile & a_SettingsIni)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int cServer::GetNumPlayers(void)
|
||||||
|
{
|
||||||
|
cCSLock Lock(m_CSPlayerCount);
|
||||||
|
return m_PlayerCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cServer::PrepareKeys(void)
|
void cServer::PrepareKeys(void)
|
||||||
{
|
{
|
||||||
// TODO: Save and load key for persistence across sessions
|
// TODO: Save and load key for persistence across sessions
|
||||||
@ -310,6 +344,17 @@ void cServer::OnConnectionAccepted(cSocket & a_Socket)
|
|||||||
|
|
||||||
bool cServer::Tick(float a_Dt)
|
bool cServer::Tick(float a_Dt)
|
||||||
{
|
{
|
||||||
|
// Apply the queued playercount adjustments (postponed to avoid deadlocks)
|
||||||
|
int PlayerCountDiff = 0;
|
||||||
|
{
|
||||||
|
cCSLock Lock(m_CSPlayerCountDiff);
|
||||||
|
std::swap(PlayerCountDiff, m_PlayerCountDiff);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
cCSLock Lock(m_CSPlayerCount);
|
||||||
|
m_PlayerCount += PlayerCountDiff;
|
||||||
|
}
|
||||||
|
|
||||||
cRoot::Get()->TickCommands();
|
cRoot::Get()->TickCommands();
|
||||||
|
|
||||||
TickClients(a_Dt);
|
TickClients(a_Dt);
|
||||||
|
@ -43,7 +43,7 @@ public: // tolua_export
|
|||||||
|
|
||||||
// Player counts:
|
// Player counts:
|
||||||
int GetMaxPlayers(void) const {return m_MaxPlayers; }
|
int GetMaxPlayers(void) const {return m_MaxPlayers; }
|
||||||
int GetNumPlayers(void) const { return m_NumPlayers; }
|
int GetNumPlayers(void);
|
||||||
void SetMaxPlayers(int a_MaxPlayers) { m_MaxPlayers = a_MaxPlayers; }
|
void SetMaxPlayers(int a_MaxPlayers) { m_MaxPlayers = a_MaxPlayers; }
|
||||||
|
|
||||||
// tolua_end
|
// tolua_end
|
||||||
@ -78,6 +78,12 @@ public: // tolua_export
|
|||||||
/// Don't tick a_Client anymore, it will be ticked from its cPlayer instead
|
/// Don't tick a_Client anymore, it will be ticked from its cPlayer instead
|
||||||
void ClientMovedToWorld(const cClientHandle * a_Client);
|
void ClientMovedToWorld(const cClientHandle * a_Client);
|
||||||
|
|
||||||
|
/// Notifies the server that a player was created; the server uses this to adjust the number of players
|
||||||
|
void PlayerCreated(const cPlayer * a_Player);
|
||||||
|
|
||||||
|
/// Notifies the server that a player was destroyed; the server uses this to adjust the number of players
|
||||||
|
void PlayerDestroyed(const cPlayer * a_Player);
|
||||||
|
|
||||||
CryptoPP::RSA::PrivateKey & GetPrivateKey(void) { return m_PrivateKey; }
|
CryptoPP::RSA::PrivateKey & GetPrivateKey(void) { return m_PrivateKey; }
|
||||||
CryptoPP::RSA::PublicKey & GetPublicKey (void) { return m_PublicKey; }
|
CryptoPP::RSA::PublicKey & GetPublicKey (void) { return m_PublicKey; }
|
||||||
|
|
||||||
@ -135,6 +141,11 @@ private:
|
|||||||
cClientHandleList m_Clients; ///< Clients that are connected to the server and not yet assigned to a cWorld
|
cClientHandleList m_Clients; ///< Clients that are connected to the server and not yet assigned to a cWorld
|
||||||
cClientHandleList m_ClientsToRemove; ///< Clients that have just been moved into a world and are to be removed from m_Clients in the next Tick()
|
cClientHandleList m_ClientsToRemove; ///< Clients that have just been moved into a world and are to be removed from m_Clients in the next Tick()
|
||||||
|
|
||||||
|
cCriticalSection m_CSPlayerCount; ///< Locks the m_PlayerCount
|
||||||
|
int m_PlayerCount; ///< Number of players currently playing in the server
|
||||||
|
cCriticalSection m_CSPlayerCountDiff; ///< Locks the m_PlayerCountDiff
|
||||||
|
int m_PlayerCountDiff; ///< Adjustment to m_PlayerCount to be applied in the Tick thread
|
||||||
|
|
||||||
cSocketThreads m_SocketThreads;
|
cSocketThreads m_SocketThreads;
|
||||||
|
|
||||||
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
|
||||||
@ -150,7 +161,6 @@ private:
|
|||||||
|
|
||||||
AString m_Description;
|
AString m_Description;
|
||||||
int m_MaxPlayers;
|
int m_MaxPlayers;
|
||||||
int m_NumPlayers;
|
|
||||||
|
|
||||||
cTickThread m_TickThread;
|
cTickThread m_TickThread;
|
||||||
cEvent m_RestartEvent;
|
cEvent m_RestartEvent;
|
||||||
|
Loading…
Reference in New Issue
Block a user