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