From 61e761fdc2bfa5c77002d68bb24e0470def37b48 Mon Sep 17 00:00:00 2001 From: Vincent Date: Sat, 29 Nov 2014 00:36:15 -0800 Subject: issue 1253 - prevent multiple logins with same username --- src/ClientHandle.cpp | 18 ++++++++++++++++++ src/Server.cpp | 17 +++++++++++++++++ src/Server.h | 9 +++++++++ src/World.cpp | 12 ++++++++++++ src/World.h | 2 ++ 5 files changed, 58 insertions(+) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index a6cbad32a..ae794d7cb 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1798,6 +1798,24 @@ bool cClientHandle::HandleHandshake(const AString & a_Username) return false; } } + if (!(cRoot::Get()->GetServer()->isAllowMultiLogin())) + { + std::list usernamesServer = cRoot::Get()->GetServer()->GetUsernames(); + std::list usernamesWorld = cRoot::Get()->GetDefaultWorld()-> GetUsernames(); + + usernamesServer.sort(); + usernamesWorld.sort(); + usernamesServer.merge(usernamesWorld); + + for (std::list::iterator itr = usernamesServer.begin(); itr != usernamesServer.end(); ++itr) + { + if ((*itr).compare(a_Username) == 0) + { + Kick("User already logged in."); + return false; + } + } + } return true; } diff --git a/src/Server.cpp b/src/Server.cpp index bbb5ecff3..157bad43e 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -201,6 +201,7 @@ bool cServer::InitServer(cIniFile & a_SettingsIni, bool a_ShouldAuth) m_Description = a_SettingsIni.GetValueSet("Server", "Description", "MCServer - in C++!"); m_MaxPlayers = a_SettingsIni.GetValueSetI("Server", "MaxPlayers", 100); m_bIsHardcore = a_SettingsIni.GetValueSetB("Server", "HardcoreEnabled", false); + m_bAllowMultiLogin = a_SettingsIni.GetValueSetB("Server", "AllowMultiLogin", false); m_PlayerCount = 0; m_PlayerCountDiff = 0; @@ -303,6 +304,22 @@ int cServer::GetNumPlayers(void) const +std::list cServer::GetUsernames() +{ + std::list usernames; + cCSLock Lock(m_CSClients); + for (ClientList::iterator itr = m_Clients.begin(); itr != m_Clients.end(); ++itr) + { + std::string username = (*itr)->GetUsername(); + usernames.insert(usernames.begin(),username); + } + return usernames; +} + + + + + void cServer::PrepareKeys(void) { LOGD("Generating protocol encryption keypair..."); diff --git a/src/Server.h b/src/Server.h index 022794bbc..91e6e5c45 100644 --- a/src/Server.h +++ b/src/Server.h @@ -67,6 +67,12 @@ public: // tolua_export int GetNumPlayers(void) const; void SetMaxPlayers(int a_MaxPlayers) { m_MaxPlayers = a_MaxPlayers; } + // Get the users waiting to be put into the World. + std::list GetUsernames(void); + + // Can login more than once with same username. + bool isAllowMultiLogin(void) { return m_bAllowMultiLogin; } + // Hardcore mode or not: bool IsHardcore(void) const { return m_bIsHardcore; } @@ -216,6 +222,9 @@ private: int m_MaxPlayers; bool m_bIsHardcore; + /** True - allow same username to login more than once False - only once */ + bool m_bAllowMultiLogin; + cTickThread m_TickThread; cEvent m_RestartEvent; diff --git a/src/World.cpp b/src/World.cpp index 0dec0bd96..9ae9e41d9 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -3666,3 +3666,15 @@ void cWorld::cChunkGeneratorCallbacks::CallHookChunkGenerated (cChunkDesc & a_Ch + +std::list cWorld::GetUsernames() +{ + std::list usernames; + cCSLock Lock(m_CSPlayers); + for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) + { + std::string username = (*itr)->GetName(); + usernames.insert(usernames.begin(),username); + } + return usernames; +} diff --git a/src/World.h b/src/World.h index 68d0654ee..81470f869 100644 --- a/src/World.h +++ b/src/World.h @@ -808,6 +808,8 @@ public: as at least one requests is active the chunk will be ticked). */ void SetChunkAlwaysTicked(int a_ChunkX, int a_ChunkZ, bool a_AlwaysTicked = true); // tolua_export + /** Get the usernames from the World. */ + std::list GetUsernames(void); private: friend class cRoot; -- cgit v1.2.3 From a7bf2725c8bd5f8ec3e03584af87a7055cb15a60 Mon Sep 17 00:00:00 2001 From: Vincent Date: Sat, 29 Nov 2014 11:22:03 -0800 Subject: fixed naming of strings and changed from i to I --- src/ClientHandle.cpp | 8 ++++---- src/Server.cpp | 6 +++--- src/Server.h | 4 ++-- src/World.cpp | 10 +++++++--- src/World.h | 3 ++- 5 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index ae794d7cb..3c06f3401 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1798,16 +1798,16 @@ bool cClientHandle::HandleHandshake(const AString & a_Username) return false; } } - if (!(cRoot::Get()->GetServer()->isAllowMultiLogin())) + if (!(cRoot::Get()->GetServer()->IsAllowMultiLogin())) { - std::list usernamesServer = cRoot::Get()->GetServer()->GetUsernames(); - std::list usernamesWorld = cRoot::Get()->GetDefaultWorld()-> GetUsernames(); + std::list usernamesServer = cRoot::Get()->GetServer()->GetUsernames(); + std::list usernamesWorld = cRoot::Get()->GetDefaultWorld()-> GetUsernames(); usernamesServer.sort(); usernamesWorld.sort(); usernamesServer.merge(usernamesWorld); - for (std::list::iterator itr = usernamesServer.begin(); itr != usernamesServer.end(); ++itr) + for (std::list::iterator itr = usernamesServer.begin(); itr != usernamesServer.end(); ++itr) { if ((*itr).compare(a_Username) == 0) { diff --git a/src/Server.cpp b/src/Server.cpp index 157bad43e..ed02500ff 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -304,13 +304,13 @@ int cServer::GetNumPlayers(void) const -std::list cServer::GetUsernames() +std::list cServer::GetUsernames() { - std::list usernames; + std::list usernames; cCSLock Lock(m_CSClients); for (ClientList::iterator itr = m_Clients.begin(); itr != m_Clients.end(); ++itr) { - std::string username = (*itr)->GetUsername(); + AString username = (*itr)->GetUsername(); usernames.insert(usernames.begin(),username); } return usernames; diff --git a/src/Server.h b/src/Server.h index 91e6e5c45..c9741bb7b 100644 --- a/src/Server.h +++ b/src/Server.h @@ -68,10 +68,10 @@ public: // tolua_export void SetMaxPlayers(int a_MaxPlayers) { m_MaxPlayers = a_MaxPlayers; } // Get the users waiting to be put into the World. - std::list GetUsernames(void); + std::list GetUsernames(void); // Can login more than once with same username. - bool isAllowMultiLogin(void) { return m_bAllowMultiLogin; } + bool IsAllowMultiLogin(void) { return m_bAllowMultiLogin; } // Hardcore mode or not: bool IsHardcore(void) const { return m_bIsHardcore; } diff --git a/src/World.cpp b/src/World.cpp index 9ae9e41d9..e6a2f161a 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -3667,14 +3667,18 @@ void cWorld::cChunkGeneratorCallbacks::CallHookChunkGenerated (cChunkDesc & a_Ch -std::list cWorld::GetUsernames() +std::list cWorld::GetUsernames() { - std::list usernames; + std::list usernames; cCSLock Lock(m_CSPlayers); for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { - std::string username = (*itr)->GetName(); + AString username = (*itr)->GetName(); usernames.insert(usernames.begin(),username); } return usernames; } + + + + diff --git a/src/World.h b/src/World.h index 81470f869..a3ad4d1da 100644 --- a/src/World.h +++ b/src/World.h @@ -809,7 +809,8 @@ public: void SetChunkAlwaysTicked(int a_ChunkX, int a_ChunkZ, bool a_AlwaysTicked = true); // tolua_export /** Get the usernames from the World. */ - std::list GetUsernames(void); + std::list GetUsernames(void); + private: friend class cRoot; -- cgit v1.2.3 From 72797b14fe5f83a7a27df17d5b733048d13d5d1b Mon Sep 17 00:00:00 2001 From: Vincent Date: Sat, 29 Nov 2014 15:44:38 -0800 Subject: Uses callback for players already in World. --- src/ClientHandle.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 3c06f3401..f63754aab 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1790,6 +1790,7 @@ void cClientHandle::HandleKeepAlive(int a_KeepAliveID) bool cClientHandle::HandleHandshake(const AString & a_Username) { + if (!cRoot::Get()->GetPluginManager()->CallHookHandshake(*this, a_Username)) { if (cRoot::Get()->GetServer()->GetNumPlayers() >= cRoot::Get()->GetServer()->GetMaxPlayers()) @@ -1801,11 +1802,6 @@ bool cClientHandle::HandleHandshake(const AString & a_Username) if (!(cRoot::Get()->GetServer()->IsAllowMultiLogin())) { std::list usernamesServer = cRoot::Get()->GetServer()->GetUsernames(); - std::list usernamesWorld = cRoot::Get()->GetDefaultWorld()-> GetUsernames(); - - usernamesServer.sort(); - usernamesWorld.sort(); - usernamesServer.merge(usernamesWorld); for (std::list::iterator itr = usernamesServer.begin(); itr != usernamesServer.end(); ++itr) { @@ -1815,6 +1811,17 @@ bool cClientHandle::HandleHandshake(const AString & a_Username) return false; } } + class cCallback : public cPlayerListCallback + { + virtual bool Item(cPlayer * a_Player) override + { + return false; + } + } Callback; + if (cRoot::Get()->GetDefaultWorld()->DoWithPlayer(a_Username, Callback)) + { + Kick("User already logged in."); + } } return true; } -- cgit v1.2.3 From 20dcceb7e6a8810525fd873f29e665759bdde087 Mon Sep 17 00:00:00 2001 From: Vincent Date: Sat, 29 Nov 2014 15:46:31 -0800 Subject: removed GetUsernames() from World --- src/World.cpp | 15 --------------- src/World.h | 3 --- 2 files changed, 18 deletions(-) diff --git a/src/World.cpp b/src/World.cpp index e6a2f161a..100df5742 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -3667,18 +3667,3 @@ void cWorld::cChunkGeneratorCallbacks::CallHookChunkGenerated (cChunkDesc & a_Ch -std::list cWorld::GetUsernames() -{ - std::list usernames; - cCSLock Lock(m_CSPlayers); - for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) - { - AString username = (*itr)->GetName(); - usernames.insert(usernames.begin(),username); - } - return usernames; -} - - - - diff --git a/src/World.h b/src/World.h index a3ad4d1da..ee9b93874 100644 --- a/src/World.h +++ b/src/World.h @@ -807,9 +807,6 @@ public: This function allows nesting and task-concurrency (multiple separate tasks can request ticking and as long as at least one requests is active the chunk will be ticked). */ void SetChunkAlwaysTicked(int a_ChunkX, int a_ChunkZ, bool a_AlwaysTicked = true); // tolua_export - - /** Get the usernames from the World. */ - std::list GetUsernames(void); private: -- cgit v1.2.3 From 9caa3b19c15b257af47a924c68f9b13517447c26 Mon Sep 17 00:00:00 2001 From: vincentleung1 Date: Sat, 29 Nov 2014 15:59:48 -0800 Subject: removed extra space and fixed some formatting in cCallback --- src/ClientHandle.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index f63754aab..54a39cdc2 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1790,7 +1790,6 @@ void cClientHandle::HandleKeepAlive(int a_KeepAliveID) bool cClientHandle::HandleHandshake(const AString & a_Username) { - if (!cRoot::Get()->GetPluginManager()->CallHookHandshake(*this, a_Username)) { if (cRoot::Get()->GetServer()->GetNumPlayers() >= cRoot::Get()->GetServer()->GetMaxPlayers()) @@ -1811,11 +1810,12 @@ bool cClientHandle::HandleHandshake(const AString & a_Username) return false; } } - class cCallback : public cPlayerListCallback + class cCallback : + public cPlayerListCallback { virtual bool Item(cPlayer * a_Player) override { - return false; + return true; } } Callback; if (cRoot::Get()->GetDefaultWorld()->DoWithPlayer(a_Username, Callback)) -- cgit v1.2.3 From 438a9b04cbabcbbab06d9f5bd00ced3342eb97f8 Mon Sep 17 00:00:00 2001 From: vincentleung1 Date: Sat, 29 Nov 2014 16:05:22 -0800 Subject: Changed Kick message --- src/ClientHandle.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 54a39cdc2..1ffb5f04b 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1806,7 +1806,7 @@ bool cClientHandle::HandleHandshake(const AString & a_Username) { if ((*itr).compare(a_Username) == 0) { - Kick("User already logged in."); + Kick("A player of the username is already logged in"); return false; } } @@ -1820,7 +1820,7 @@ bool cClientHandle::HandleHandshake(const AString & a_Username) } Callback; if (cRoot::Get()->GetDefaultWorld()->DoWithPlayer(a_Username, Callback)) { - Kick("User already logged in."); + Kick("A player of the username is already logged in"); } } return true; -- cgit v1.2.3 From 8edfd7829505d43c7d6bf7fcc582e0d7cb29e1d5 Mon Sep 17 00:00:00 2001 From: Vincent Date: Sun, 7 Dec 2014 12:41:42 -0800 Subject: changed from using iterator to auto for server and clienthandle --- src/ClientHandle.cpp | 4 ++-- src/Server.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index f63754aab..94126d496 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1803,9 +1803,9 @@ bool cClientHandle::HandleHandshake(const AString & a_Username) { std::list usernamesServer = cRoot::Get()->GetServer()->GetUsernames(); - for (std::list::iterator itr = usernamesServer.begin(); itr != usernamesServer.end(); ++itr) + for (auto item : usernamesServer) { - if ((*itr).compare(a_Username) == 0) + if ((item).compare(a_Username) == 0) { Kick("User already logged in."); return false; diff --git a/src/Server.cpp b/src/Server.cpp index ed02500ff..15c9521b9 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -308,9 +308,9 @@ std::list cServer::GetUsernames() { std::list usernames; cCSLock Lock(m_CSClients); - for (ClientList::iterator itr = m_Clients.begin(); itr != m_Clients.end(); ++itr) + for (auto client : m_Clients) { - AString username = (*itr)->GetUsername(); + AString username = (client)->GetUsername(); usernames.insert(usernames.begin(),username); } return usernames; -- cgit v1.2.3 From d8d3b9aec5bbb0f6d632d86f1fb7b1e8f58e9063 Mon Sep 17 00:00:00 2001 From: Vincent Date: Mon, 8 Dec 2014 00:12:48 -0800 Subject: Moved the check into a new function and just calls that function and a blank FindAndDoWithPlayer added. --- src/ClientHandle.cpp | 60 +++++++++++++++++++++++++++++++++------------------- src/ClientHandle.h | 2 ++ src/Root.cpp | 9 ++++++++ src/Root.h | 4 +++- 4 files changed, 52 insertions(+), 23 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 3fca48394..025588485 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1788,6 +1788,41 @@ void cClientHandle::HandleKeepAlive(int a_KeepAliveID) +bool cClientHandle::CheckMultiLogin(void) +{ + std::list usernamesServer = cRoot::Get()->GetServer()->GetUsernames(); + + for (auto item : usernamesServer) + { + if ((item).compare(a_Username) == 0) + { + Kick("A player of the username is already logged in"); + return false; + } + } + + class cCallback : + public cPlayerListCallback + { + virtual bool Item(cPlayer * a_Player) override + { + return true; + } + } Callback; + + if (cRoot::Get()->GetDefaultWorld()->DoWithPlayer(a_Username, Callback)) + { + Kick("A player of the username is already logged in"); + return false; + } + + return true; +} + + + + + bool cClientHandle::HandleHandshake(const AString & a_Username) { if (!cRoot::Get()->GetPluginManager()->CallHookHandshake(*this, a_Username)) @@ -1798,31 +1833,12 @@ bool cClientHandle::HandleHandshake(const AString & a_Username) return false; } } + if (!(cRoot::Get()->GetServer()->IsAllowMultiLogin())) { - std::list usernamesServer = cRoot::Get()->GetServer()->GetUsernames(); - - for (auto item : usernamesServer) - { - if ((item).compare(a_Username) == 0) - { - Kick("A player of the username is already logged in"); - return false; - } - } - class cCallback : - public cPlayerListCallback - { - virtual bool Item(cPlayer * a_Player) override - { - return true; - } - } Callback; - if (cRoot::Get()->GetDefaultWorld()->DoWithPlayer(a_Username, Callback)) - { - Kick("A player of the username is already logged in"); - } + return CheckMultiLogin(); } + return true; } diff --git a/src/ClientHandle.h b/src/ClientHandle.h index f195b6be7..880a404da 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -280,6 +280,8 @@ public: void HandleEntityLeaveBed (int a_EntityID); void HandleEntitySprinting (int a_EntityID, bool a_IsSprinting); + /** Kicks the current player if the same username is already logged in. */ + bool CheckMultiLogin(void); /** Called when the protocol handshake has been received (for protocol versions that support it; otherwise the first instant when a username is received). Returns true if the player is to be let in, false if they were disconnected diff --git a/src/Root.cpp b/src/Root.cpp index e309bb174..e51b7a048 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -649,6 +649,15 @@ bool cRoot::DoWithPlayerByUUID(const AString & a_PlayerUUID, cPlayerListCallback +bool cRoot::FindAndDoWithPlayer(const AString & a_PlayerName, cPlayerListCallback & a_Callback) +{ + +} + + + + + AString cRoot::GetProtocolVersionTextFromInt(int a_ProtocolVersion) { return cProtocolRecognizer::GetVersionTextFromInt(a_ProtocolVersion); diff --git a/src/Root.h b/src/Root.h index 29753a47d..b926b36bc 100644 --- a/src/Root.h +++ b/src/Root.h @@ -128,7 +128,9 @@ public: /** Finds the player over his uuid and calls the callback */ bool DoWithPlayerByUUID(const AString & a_PlayerUUID, cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS << - + + bool FindAndDoWithPlayer(const AString & a_PlayerName, cPlayerListCallback & a_Callback); + // tolua_begin /// Sends a chat message to all connected clients (in all worlds) -- cgit v1.2.3 From ed09e76023436c9414356921bc761618b3bb9341 Mon Sep 17 00:00:00 2001 From: Vincent Date: Mon, 8 Dec 2014 00:16:09 -0800 Subject: Changed HandleHandshake to return the result of CheckMultiLogin instead of just true since it already returns true if it finds and kicks the current player. --- src/ClientHandle.cpp | 47 +++++++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 025588485..e60bb5373 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1790,30 +1790,33 @@ void cClientHandle::HandleKeepAlive(int a_KeepAliveID) bool cClientHandle::CheckMultiLogin(void) { - std::list usernamesServer = cRoot::Get()->GetServer()->GetUsernames(); - - for (auto item : usernamesServer) + if (!(cRoot::Get()->GetServer()->IsAllowMultiLogin())) { - if ((item).compare(a_Username) == 0) + std::list usernamesServer = cRoot::Get()->GetServer()->GetUsernames(); + + for (auto item : usernamesServer) { - Kick("A player of the username is already logged in"); - return false; + if ((item).compare(a_Username) == 0) + { + Kick("A player of the username is already logged in"); + return false; + } } - } - class cCallback : - public cPlayerListCallback - { - virtual bool Item(cPlayer * a_Player) override + class cCallback : + public cPlayerListCallback { - return true; - } - } Callback; + virtual bool Item(cPlayer * a_Player) override + { + return true; + } + } Callback; - if (cRoot::Get()->GetDefaultWorld()->DoWithPlayer(a_Username, Callback)) - { - Kick("A player of the username is already logged in"); - return false; + if (cRoot::Get()->GetDefaultWorld()->DoWithPlayer(a_Username, Callback)) + { + Kick("A player of the username is already logged in"); + return false; + } } return true; @@ -1833,13 +1836,9 @@ bool cClientHandle::HandleHandshake(const AString & a_Username) return false; } } + + return CheckMultiLogin(); - if (!(cRoot::Get()->GetServer()->IsAllowMultiLogin())) - { - return CheckMultiLogin(); - } - - return true; } -- cgit v1.2.3 From 656964dc385e4460215d2443724f322cd1bc596d Mon Sep 17 00:00:00 2001 From: Vincent Date: Mon, 8 Dec 2014 00:19:33 -0800 Subject: removed last space in handlehandshake --- src/ClientHandle.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index e60bb5373..4031fa1df 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1838,7 +1838,6 @@ bool cClientHandle::HandleHandshake(const AString & a_Username) } return CheckMultiLogin(); - } -- cgit v1.2.3 From 6de07d4a39096f19c075695824aa87a1907e4edc Mon Sep 17 00:00:00 2001 From: Vincent Date: Mon, 8 Dec 2014 00:45:29 -0800 Subject: Fixed compile errors --- src/ClientHandle.cpp | 11 +++-------- src/ClientHandle.h | 2 +- src/Root.cpp | 2 +- src/Root.h | 2 +- src/Server.cpp | 11 ++++++----- src/Server.h | 4 ++-- 6 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 4031fa1df..6f7bd1faf 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1788,19 +1788,14 @@ void cClientHandle::HandleKeepAlive(int a_KeepAliveID) -bool cClientHandle::CheckMultiLogin(void) +bool cClientHandle::CheckMultiLogin(const AString & a_Username) { if (!(cRoot::Get()->GetServer()->IsAllowMultiLogin())) { - std::list usernamesServer = cRoot::Get()->GetServer()->GetUsernames(); - - for (auto item : usernamesServer) + if (cRoot::Get()->GetServer()->IsPlayerInQueue(a_Username)) { - if ((item).compare(a_Username) == 0) - { Kick("A player of the username is already logged in"); return false; - } } class cCallback : @@ -1837,7 +1832,7 @@ bool cClientHandle::HandleHandshake(const AString & a_Username) } } - return CheckMultiLogin(); + return CheckMultiLogin(a_Username); } diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 880a404da..add004bd5 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -281,7 +281,7 @@ public: void HandleEntitySprinting (int a_EntityID, bool a_IsSprinting); /** Kicks the current player if the same username is already logged in. */ - bool CheckMultiLogin(void); + bool CheckMultiLogin(const AString & a_Username); /** Called when the protocol handshake has been received (for protocol versions that support it; otherwise the first instant when a username is received). Returns true if the player is to be let in, false if they were disconnected diff --git a/src/Root.cpp b/src/Root.cpp index e51b7a048..dddb943a2 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -649,7 +649,7 @@ bool cRoot::DoWithPlayerByUUID(const AString & a_PlayerUUID, cPlayerListCallback -bool cRoot::FindAndDoWithPlayer(const AString & a_PlayerName, cPlayerListCallback & a_Callback) +bool cRoot::DoWithPlayer(const AString & a_PlayerName, cPlayerListCallback & a_Callback) { } diff --git a/src/Root.h b/src/Root.h index b926b36bc..b3cde8748 100644 --- a/src/Root.h +++ b/src/Root.h @@ -129,7 +129,7 @@ public: /** Finds the player over his uuid and calls the callback */ bool DoWithPlayerByUUID(const AString & a_PlayerUUID, cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS << - bool FindAndDoWithPlayer(const AString & a_PlayerName, cPlayerListCallback & a_Callback); + bool DoWithPlayer(const AString & a_PlayerName, cPlayerListCallback & a_Callback); // tolua_begin diff --git a/src/Server.cpp b/src/Server.cpp index 15c9521b9..a1dd27c57 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -304,16 +304,17 @@ int cServer::GetNumPlayers(void) const -std::list cServer::GetUsernames() +bool cServer::IsPlayerInQueue(AString a_Username) { - std::list usernames; cCSLock Lock(m_CSClients); for (auto client : m_Clients) { - AString username = (client)->GetUsername(); - usernames.insert(usernames.begin(),username); + if ((client->GetUsername()).compare(a_Username) == 0) + { + return true; + } } - return usernames; + return false; } diff --git a/src/Server.h b/src/Server.h index c9741bb7b..e329b5c65 100644 --- a/src/Server.h +++ b/src/Server.h @@ -67,8 +67,8 @@ public: // tolua_export int GetNumPlayers(void) const; void SetMaxPlayers(int a_MaxPlayers) { m_MaxPlayers = a_MaxPlayers; } - // Get the users waiting to be put into the World. - std::list GetUsernames(void); + // Check if the player is queued to be transferred to a World. + bool IsPlayerInQueue(AString a_Username); // Can login more than once with same username. bool IsAllowMultiLogin(void) { return m_bAllowMultiLogin; } -- cgit v1.2.3 From e28cc876c4aa4d71f821fca45b5486b8ef6cca4e Mon Sep 17 00:00:00 2001 From: Vincent Date: Mon, 8 Dec 2014 00:57:46 -0800 Subject: created callback in Root and changed CheckMultiLogin() to use the DoWithPlayer function at Root instead of World. --- src/ClientHandle.cpp | 2 +- src/Root.cpp | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 6f7bd1faf..6fe7cbd4a 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1807,7 +1807,7 @@ bool cClientHandle::CheckMultiLogin(const AString & a_Username) } } Callback; - if (cRoot::Get()->GetDefaultWorld()->DoWithPlayer(a_Username, Callback)) + if (cRoot::Get()->DoWithPlayer(a_Username, Callback)) { Kick("A player of the username is already logged in"); return false; diff --git a/src/Root.cpp b/src/Root.cpp index dddb943a2..c59590d95 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -651,7 +651,14 @@ bool cRoot::DoWithPlayerByUUID(const AString & a_PlayerUUID, cPlayerListCallback bool cRoot::DoWithPlayer(const AString & a_PlayerName, cPlayerListCallback & a_Callback) { - + for (WorldMap::iterator itr = m_WorldsByName.begin(); itr != m_WorldsByName.end(); itr++) + { + if (itr->second->DoWithPlayer(a_PlayerName, a_Callback)) + { + return true; + } + } + return false; } -- cgit v1.2.3 From 12c012fa01e719c7c103e36ae0407294a0d11bfb Mon Sep 17 00:00:00 2001 From: Vincent Date: Mon, 8 Dec 2014 14:33:59 -0800 Subject: Changed CheckMultiLogin() to not have main body wrapped in an if statement. Added in indent to cPlayerListCallBack in cCallback class inside CheckMultiLogin(). Added doxy-comment for DoWithPlayer(). Changed comments on IsPlayerInQueue() and IsAllowMultiLogin() to doxy-comments. --- src/ClientHandle.cpp | 41 ++++++++++++++++++++++------------------- src/ClientHandle.h | 1 + src/Root.h | 1 + src/Server.h | 6 ++++-- 4 files changed, 28 insertions(+), 21 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 6fe7cbd4a..3bc17d1a9 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1790,31 +1790,34 @@ void cClientHandle::HandleKeepAlive(int a_KeepAliveID) bool cClientHandle::CheckMultiLogin(const AString & a_Username) { - if (!(cRoot::Get()->GetServer()->IsAllowMultiLogin())) + // If the multilogin is allowed, skip this check entirely: + if ((cRoot::Get()->GetServer()->IsAllowMultiLogin())) { - if (cRoot::Get()->GetServer()->IsPlayerInQueue(a_Username)) - { - Kick("A player of the username is already logged in"); - return false; - } - - class cCallback : - public cPlayerListCallback - { - virtual bool Item(cPlayer * a_Player) override - { - return true; - } - } Callback; + return true; + } - if (cRoot::Get()->DoWithPlayer(a_Username, Callback)) - { + // Check if the player is waiting to be transferred to the World. + if (cRoot::Get()->GetServer()->IsPlayerInQueue(a_Username)) + { Kick("A player of the username is already logged in"); return false; + } + + class cCallback : + public cPlayerListCallback + { + virtual bool Item(cPlayer * a_Player) override + { + return true; } + } Callback; + + // Check if the player is in any World. + if (cRoot::Get()->DoWithPlayer(a_Username, Callback)) + { + Kick("A player of the username is already logged in"); + return false; } - - return true; } diff --git a/src/ClientHandle.h b/src/ClientHandle.h index add004bd5..cd63aa308 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -282,6 +282,7 @@ public: /** Kicks the current player if the same username is already logged in. */ bool CheckMultiLogin(const AString & a_Username); + /** Called when the protocol handshake has been received (for protocol versions that support it; otherwise the first instant when a username is received). Returns true if the player is to be let in, false if they were disconnected diff --git a/src/Root.h b/src/Root.h index b3cde8748..af5a2b47b 100644 --- a/src/Root.h +++ b/src/Root.h @@ -129,6 +129,7 @@ public: /** Finds the player over his uuid and calls the callback */ bool DoWithPlayerByUUID(const AString & a_PlayerUUID, cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS << + /** Finds the player using it's complete username and calls the callback */ bool DoWithPlayer(const AString & a_PlayerName, cPlayerListCallback & a_Callback); // tolua_begin diff --git a/src/Server.h b/src/Server.h index e329b5c65..a93e8df75 100644 --- a/src/Server.h +++ b/src/Server.h @@ -67,10 +67,12 @@ public: // tolua_export int GetNumPlayers(void) const; void SetMaxPlayers(int a_MaxPlayers) { m_MaxPlayers = a_MaxPlayers; } - // Check if the player is queued to be transferred to a World. + /** Check if the player is queued to be transferred to a World. + Returns true is Player is found in queue. */ bool IsPlayerInQueue(AString a_Username); - // Can login more than once with same username. + /** Can login more than once with same username. + Returns false if it is not allowed, true otherwise. */ bool IsAllowMultiLogin(void) { return m_bAllowMultiLogin; } // Hardcore mode or not: -- cgit v1.2.3 From e9a27db028172b5d964cee4421ed5df3af5a1cf0 Mon Sep 17 00:00:00 2001 From: Vincent Date: Mon, 8 Dec 2014 15:58:46 -0800 Subject: Changed DoWithPlayer to auto instead of using iterator. --- src/Root.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Root.cpp b/src/Root.cpp index c59590d95..2234f7fdc 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -651,9 +651,9 @@ bool cRoot::DoWithPlayerByUUID(const AString & a_PlayerUUID, cPlayerListCallback bool cRoot::DoWithPlayer(const AString & a_PlayerName, cPlayerListCallback & a_Callback) { - for (WorldMap::iterator itr = m_WorldsByName.begin(); itr != m_WorldsByName.end(); itr++) + for (auto World : m_WorldsByName) { - if (itr->second->DoWithPlayer(a_PlayerName, a_Callback)) + if (World.second->DoWithPlayer(a_PlayerName, a_Callback)) { return true; } -- cgit v1.2.3 From 4b08ca261bed5ec2fd70f64ee96104ba6bee6927 Mon Sep 17 00:00:00 2001 From: Vincent Date: Tue, 9 Dec 2014 03:06:25 -0800 Subject: Fixed indent problems and added return definitions to CheckMultiLogin(). Changed from IsAllowMultiLogin() to DoesAllowMultiLogin(). Fixed CheckMultiLogin() to not run to the end without returning a value. --- src/ClientHandle.cpp | 6 +++--- src/ClientHandle.h | 3 ++- src/Server.h | 6 +++--- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 3bc17d1a9..6812c06ac 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1799,8 +1799,8 @@ bool cClientHandle::CheckMultiLogin(const AString & a_Username) // Check if the player is waiting to be transferred to the World. if (cRoot::Get()->GetServer()->IsPlayerInQueue(a_Username)) { - Kick("A player of the username is already logged in"); - return false; + Kick("A player of the username is already logged in"); + return false; } class cCallback : @@ -1816,8 +1816,8 @@ bool cClientHandle::CheckMultiLogin(const AString & a_Username) if (cRoot::Get()->DoWithPlayer(a_Username, Callback)) { Kick("A player of the username is already logged in"); - return false; } + return false; } diff --git a/src/ClientHandle.h b/src/ClientHandle.h index cd63aa308..b3aec86f6 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -280,7 +280,8 @@ public: void HandleEntityLeaveBed (int a_EntityID); void HandleEntitySprinting (int a_EntityID, bool a_IsSprinting); - /** Kicks the current player if the same username is already logged in. */ + /** Kicks the current player if the same username is already logged in. + Returns false if a player has been kicked, true otherwise. */ bool CheckMultiLogin(const AString & a_Username); /** Called when the protocol handshake has been received (for protocol versions that support it; diff --git a/src/Server.h b/src/Server.h index a93e8df75..39a5a1a71 100644 --- a/src/Server.h +++ b/src/Server.h @@ -68,12 +68,12 @@ public: // tolua_export void SetMaxPlayers(int a_MaxPlayers) { m_MaxPlayers = a_MaxPlayers; } /** Check if the player is queued to be transferred to a World. - Returns true is Player is found in queue. */ + Returns true is Player is found in queue. */ bool IsPlayerInQueue(AString a_Username); /** Can login more than once with same username. - Returns false if it is not allowed, true otherwise. */ - bool IsAllowMultiLogin(void) { return m_bAllowMultiLogin; } + Returns false if it is not allowed, true otherwise. */ + bool DoesAllowMultiLogin(void) { return m_bAllowMultiLogin; } // Hardcore mode or not: bool IsHardcore(void) const { return m_bIsHardcore; } -- cgit v1.2.3 From 3a2759fdc1a2c7282bd90a1f545fa1effae2728b Mon Sep 17 00:00:00 2001 From: Vincent Date: Tue, 9 Dec 2014 14:23:44 -0800 Subject: Fixed return value in CheckMultiLogin() --- src/ClientHandle.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 6812c06ac..87dc27f8f 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1816,8 +1816,9 @@ bool cClientHandle::CheckMultiLogin(const AString & a_Username) if (cRoot::Get()->DoWithPlayer(a_Username, Callback)) { Kick("A player of the username is already logged in"); + return false; } - return false; + return true; } -- cgit v1.2.3 From 9bba8e4c7d88c0769bb7643a2a8b577a3d12c1af Mon Sep 17 00:00:00 2001 From: Vincent Date: Wed, 10 Dec 2014 00:45:24 -0800 Subject: Changed method call to DoesAllowMultiLogin() instead of IsAllowMultiLogin() Compiles correctly. --- src/ClientHandle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 87dc27f8f..8a39c3ecb 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1791,7 +1791,7 @@ void cClientHandle::HandleKeepAlive(int a_KeepAliveID) bool cClientHandle::CheckMultiLogin(const AString & a_Username) { // If the multilogin is allowed, skip this check entirely: - if ((cRoot::Get()->GetServer()->IsAllowMultiLogin())) + if ((cRoot::Get()->GetServer()->DoesAllowMultiLogin())) { return true; } -- cgit v1.2.3