diff --git a/loginserver/client.cpp b/loginserver/client.cpp index 2c2f3ae2b..b5ae59b48 100644 --- a/loginserver/client.cpp +++ b/loginserver/client.cpp @@ -590,6 +590,7 @@ void Client::DoSuccessfulLogin(const std::string &user, int db_account_id, const in.s_addr = connection->GetRemoteIP(); server.db->UpdateLSAccountData(db_account_id, std::string(inet_ntoa(in))); + GenerateKey(); account_id = db_account_id; @@ -674,6 +675,11 @@ void Client::CreateEQEmuAccount(const std::string &user, const std::string &pass auto mode = server.options.GetEncryptionMode(); auto hash = eqcrypt_hash(user, pass, mode); + if (server.db->DoesLoginServerAccountExist(user, hash, "eqemu", id)) { + DoSuccessfulLogin(user, id, "eqemu"); + return; + } + if (!server.db->CreateLoginDataWithID(user, hash, "eqemu", id)) { DoFailedLogin(); } diff --git a/loginserver/database_mysql.cpp b/loginserver/database_mysql.cpp index c8696c019..c961d9b6f 100644 --- a/loginserver/database_mysql.cpp +++ b/loginserver/database_mysql.cpp @@ -322,6 +322,39 @@ bool DatabaseMySQL::CreateLoginDataWithID( return true; } +/** + * @param name + * @param password + * @param loginserver + * @param id + * @return + */ +bool DatabaseMySQL::DoesLoginServerAccountExist( + const std::string &name, + const std::string &password, + const std::string &loginserver, + unsigned int id +) +{ + if (id == 0) { + return false; + } + + auto query = fmt::format( + "SELECT AccountName FROM {0} WHERE AccountName = '{1}' AND AccountLoginserver = '{2}'", + server.options.GetAccountTable(), + EscapeString(name), + EscapeString(loginserver) + ); + + auto results = QueryDatabase(query); + if (!results.Success() || results.RowCount() != 1) { + return false; + } + + return true; +} + /** * @param name * @param loginserver diff --git a/loginserver/database_mysql.h b/loginserver/database_mysql.h index b45ee9c2f..5f1c31779 100644 --- a/loginserver/database_mysql.h +++ b/loginserver/database_mysql.h @@ -87,8 +87,16 @@ public: const std::string &loginserver, unsigned int id ); + virtual void UpdateLoginHash(const std::string &name, const std::string &loginserver, const std::string &hash); + virtual bool DoesLoginServerAccountExist( + const std::string &name, + const std::string &password, + const std::string &loginserver, + unsigned int id + ); + /** * Retrieves the world registration from the long and short names provided * Needed for world login procedure diff --git a/loginserver/login_server.h b/loginserver/login_server.h index ba03bfd52..bc257ddef 100644 --- a/loginserver/login_server.h +++ b/loginserver/login_server.h @@ -39,7 +39,7 @@ public: LoginServer() : db(nullptr), server_manager(nullptr) { } EQ::JsonConfigFile config; - Database *db; + DatabaseMySQL *db; Options options; ServerManager *server_manager; ClientManager *client_manager; diff --git a/loginserver/main.cpp b/loginserver/main.cpp index 04d61d702..70b48ca54 100644 --- a/loginserver/main.cpp +++ b/loginserver/main.cpp @@ -133,7 +133,7 @@ int main() */ Log(Logs::General, Logs::Login_Server, "MySQL Database Init."); - server.db = (Database *) new DatabaseMySQL( + server.db = new DatabaseMySQL( server.config.GetVariableString("database", "user", "root"), server.config.GetVariableString("database", "password", ""), server.config.GetVariableString("database", "host", "localhost"), diff --git a/loginserver/world_server.cpp b/loginserver/world_server.cpp index b1abfa2a5..1d6c0d2d3 100644 --- a/loginserver/world_server.cpp +++ b/loginserver/world_server.cpp @@ -159,7 +159,7 @@ void WorldServer::ProcessLSStatus(uint16_t opcode, const EQ::Net::Packet &p) Logs::Error, "Received application packet from server that had opcode ServerOP_LSStatus, but was too small. Discarded to avoid buffer overrun" ); - + return; }