diff options
author | Shauren <shauren.trinity@gmail.com> | 2014-06-08 14:54:37 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2014-06-08 14:54:37 +0200 |
commit | 05c0524bf3d97ba29496fa13e93acd3b8d7d37a4 (patch) | |
tree | c7781f1cedac93cd2f7dba51bd716dcd759699fa | |
parent | 372f043a68788f1903232392546c0d386b9fc248 (diff) |
Core/Battle.net: Refactored handling multiple game accounts
-rw-r--r-- | sql/base/auth_database.sql | 2 | ||||
-rw-r--r-- | sql/updates/auth/2014_06_08_00_auth_account_434.sql | 3 | ||||
-rw-r--r-- | src/server/authserver/Server/BattlenetPackets.cpp | 6 | ||||
-rw-r--r-- | src/server/authserver/Server/BattlenetPackets.h | 4 | ||||
-rw-r--r-- | src/server/authserver/Server/BattlenetSocket.cpp | 30 | ||||
-rw-r--r-- | src/server/authserver/Server/BattlenetSocket.h | 1 | ||||
-rw-r--r-- | src/server/game/Server/WorldSocket.cpp | 17 | ||||
-rw-r--r-- | src/server/shared/Database/Implementation/LoginDatabase.cpp | 8 |
8 files changed, 52 insertions, 19 deletions
diff --git a/sql/base/auth_database.sql b/sql/base/auth_database.sql index 7ab0c855f45..6dca9aa1e14 100644 --- a/sql/base/auth_database.sql +++ b/sql/base/auth_database.sql @@ -47,8 +47,10 @@ CREATE TABLE `account` ( `os` varchar(3) NOT NULL DEFAULT '', `recruiter` int(10) unsigned NOT NULL DEFAULT '0', `battlenet_account` int(10) unsigned DEFAULT NULL, + `battlenet_index` tinyint(3) unsigned DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `idx_username` (`username`), + UNIQUE KEY `uk_bnet_acc` (`battlenet_account`, `battlenet_index`), CONSTRAINT `fk_bnet_acc` FOREIGN KEY (`battlenet_account`) REFERENCES `battlenet_accounts` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Account System'; /*!40101 SET character_set_client = @saved_cs_client */; diff --git a/sql/updates/auth/2014_06_08_00_auth_account_434.sql b/sql/updates/auth/2014_06_08_00_auth_account_434.sql new file mode 100644 index 00000000000..bc57136dc07 --- /dev/null +++ b/sql/updates/auth/2014_06_08_00_auth_account_434.sql @@ -0,0 +1,3 @@ +ALTER TABLE `account` + ADD `battlenet_index` tinyint(3) unsigned DEFAULT NULL AFTER `battlenet_account`, + ADD UNIQUE KEY `uk_bnet_acc` (`battlenet_account`, `battlenet_index`); diff --git a/src/server/authserver/Server/BattlenetPackets.cpp b/src/server/authserver/Server/BattlenetPackets.cpp index 9997ea8d259..6a8e09090ef 100644 --- a/src/server/authserver/Server/BattlenetPackets.cpp +++ b/src/server/authserver/Server/BattlenetPackets.cpp @@ -202,7 +202,7 @@ void Battlenet::AuthComplete::Write() _stream.WriteString(FirstName, 8); // First name _stream.WriteString(LastName, 8); // Last name - not set for WoW - _stream.Write(GameAccountId, 32); + _stream.Write(AccountId, 32); _stream.Write(Region, 8); _stream.Write(0, 64); @@ -236,7 +236,7 @@ std::string Battlenet::AuthComplete::ToString() const { std::ostringstream stream; stream << "Battlenet::AuthComplete AuthResult " << Result << " PingTimeout " << PingTimeout << " Threshold " << Threshold << " Rate " << Rate - << " FirstName " << FirstName << " LastName " << LastName << " GameAccountId " << GameAccountId << " GameAccountName " << GameAccountName + << " FirstName " << FirstName << " LastName " << LastName << " AccountId " << AccountId << " Region " << uint32(Region) << " GameAccountName " << GameAccountName << " GameAccountFlags " << GameAccountFlags << " Modules " << Modules.size(); for (ModuleInfo const* module : Modules) @@ -441,7 +441,7 @@ void Battlenet::RealmJoinResult::Write() std::string Battlenet::RealmJoinResult::ToString() const { std::ostringstream stream; - stream << "Battlenet::RealmJoinResult ServerSeed " << ServerSeed << " Addresses (IPv4)" << IPv4.size(); + stream << "Battlenet::RealmJoinResult ServerSeed " << ServerSeed << " IPv4 Addresses " << IPv4.size(); for (ACE_INET_Addr const& addr : IPv4) stream << std::endl << "Battlenet::RealmJoinResult::Address " << GetAddressString(addr); diff --git a/src/server/authserver/Server/BattlenetPackets.h b/src/server/authserver/Server/BattlenetPackets.h index 3fa628c2ba3..54fb50184a0 100644 --- a/src/server/authserver/Server/BattlenetPackets.h +++ b/src/server/authserver/Server/BattlenetPackets.h @@ -208,7 +208,7 @@ namespace Battlenet public: AuthComplete() : ServerPacket(PacketHeader(SMSG_AUTH_COMPLETE, AUTHENTICATION)), Result(AUTH_OK), ErrorType(0), PingTimeout(120000), Threshold(25000000), Rate(1000), - FirstName(""), LastName(""), Region(2), GameAccountId(0), GameAccountRegion(2), GameAccountName("") + FirstName(""), LastName(""), AccountId(0), Region(2), GameAccountRegion(2), GameAccountName("") { } @@ -227,8 +227,8 @@ namespace Battlenet uint32 Rate; std::string FirstName; std::string LastName; + uint32 AccountId; uint8 Region; - uint32 GameAccountId; uint8 GameAccountRegion; std::string GameAccountName; uint64 GameAccountFlags; diff --git a/src/server/authserver/Server/BattlenetSocket.cpp b/src/server/authserver/Server/BattlenetSocket.cpp index 56744784167..eb8dc1158f0 100644 --- a/src/server/authserver/Server/BattlenetSocket.cpp +++ b/src/server/authserver/Server/BattlenetSocket.cpp @@ -59,7 +59,7 @@ Battlenet::Socket::ModuleHandler const Battlenet::Socket::ModuleHandlers[MODULE_ }; Battlenet::Socket::Socket(RealmSocket& socket) : _socket(socket), _accountId(0), _accountName(), _locale(), - _os(), _build(0), _gameAccountId(0), _accountSecurityLevel(SEC_PLAYER), I(), s(), v(), b(), B(), K(), + _os(), _build(0), _gameAccountId(0), _gameAccountIndex(0), _accountSecurityLevel(SEC_PLAYER), I(), s(), v(), b(), B(), K(), _reconnectProof(), _crypt(), _authed(false) { static uint8 const N_Bytes[] = @@ -323,10 +323,12 @@ bool Battlenet::Socket::HandleAuthReconnect(PacketHeader& header, BitStream& pac if (baseComponent != reconnect.Components.end()) _build = baseComponent->Build; + uint8 accountIndex = atol(reconnect.GameAccountName.substr(reconnect.GameAccountName.find_last_of('#') + 1).c_str()); + Utf8ToUpperOnlyLatin(_accountName); PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_RECONNECT_INFO); stmt->setString(0, _accountName); - stmt->setString(1, reconnect.GameAccountName.c_str()); + stmt->setUInt8(1, accountIndex); PreparedQueryResult result = LoginDatabase.Query(stmt); if (!result) { @@ -341,6 +343,7 @@ bool Battlenet::Socket::HandleAuthReconnect(PacketHeader& header, BitStream& pac _accountId = fields[0].GetUInt32(); K.SetHexStr(fields[1].GetString().c_str()); _gameAccountId = fields[2].GetUInt32(); + _gameAccountIndex = accountIndex; ModuleInfo* thumbprint = sBattlenetMgr->CreateModule(_os, "Thumbprint"); ModuleInfo* resume = sBattlenetMgr->CreateModule(_os, "Resume"); @@ -768,8 +771,10 @@ bool Battlenet::Socket::HandlePasswordModule(BitStream* dataStream, ServerPacket do { fields = result->Fetch(); + std::ostringstream name; + name << "WoW" << uint32(fields[0].GetUInt8()); accounts.Write(2, 8); - accounts.WriteString(fields[0].GetString(), 8); + accounts.WriteString(name.str(), 8); } while (result->NextRow()); ModuleInfo* selectGameAccount = sBattlenetMgr->CreateModule(_os, "SelectGameAccount"); @@ -801,7 +806,8 @@ bool Battlenet::Socket::HandlePasswordModule(BitStream* dataStream, ServerPacket return false; } - _gameAccountId = (*result)[1].GetUInt32(); + _gameAccountId = fields[1].GetUInt32(); + _gameAccountIndex = fields[0].GetUInt8(); request->Modules.push_back(sBattlenetMgr->CreateModule(_os, "RiskFingerprint")); _modulesWaitingForData.push(MODULE_RISK_FINGERPRINT); @@ -823,9 +829,18 @@ bool Battlenet::Socket::HandleSelectGameAccountModule(BitStream* dataStream, Ser dataStream->Read<uint8>(8); std::string account = dataStream->ReadString(8); + if (account.length() < 4) + { + AuthComplete* complete = new AuthComplete(); + complete->SetAuthResult(LOGIN_NO_GAME_ACCOUNT); + ReplaceResponse(response, complete); + return false; + } + + uint8 accountIndex = atol(account.substr(3).c_str()); PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_GAME_ACCOUNT); - stmt->setString(0, account); + stmt->setUInt8(0, accountIndex); stmt->setUInt32(1, _accountId); PreparedQueryResult result = LoginDatabase.Query(stmt); if (!result) @@ -856,6 +871,7 @@ bool Battlenet::Socket::HandleSelectGameAccountModule(BitStream* dataStream, Ser } _gameAccountId = fields[0].GetUInt32(); + _gameAccountIndex = accountIndex; ProofRequest* request = new ProofRequest(); request->Modules.push_back(sBattlenetMgr->CreateModule(_os, "RiskFingerprint")); @@ -871,9 +887,9 @@ bool Battlenet::Socket::HandleRiskFingerprintModule(BitStream* dataStream, Serve if (dataStream->Read<uint8>(8) == 1) { std::ostringstream str; - str << _gameAccountId << "#1"; + str << _accountId << "#" << uint32(_gameAccountIndex); - complete->GameAccountId = _gameAccountId; + complete->AccountId = _accountId; complete->GameAccountName = str.str(); complete->GameAccountFlags = GAMEACCOUNT_FLAG_PROPASS_LOCK; diff --git a/src/server/authserver/Server/BattlenetSocket.h b/src/server/authserver/Server/BattlenetSocket.h index c634a81b517..ee399e26b09 100644 --- a/src/server/authserver/Server/BattlenetSocket.h +++ b/src/server/authserver/Server/BattlenetSocket.h @@ -92,6 +92,7 @@ namespace Battlenet std::string _os; uint32 _build; uint32 _gameAccountId; + uint8 _gameAccountIndex; AccountTypes _accountSecurityLevel; BigNumber N; diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index cc839b5281c..1a93e7ae1d5 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -856,9 +856,20 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket) // Get the account information from the realmd database // 0 1 2 3 4 5 6 7 8 // SELECT id, sessionkey, last_ip, locked, expansion, mutetime, locale, recruiter, os FROM account WHERE username = ? - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(account.find('#') == std::string::npos ? LOGIN_SEL_ACCOUNT_INFO_BY_NAME : LOGIN_SEL_ACCOUNT_INFO_BY_BNET); - - stmt->setString(0, account); + size_t hashPos = account.find_last_of('#'); + PreparedStatement* stmt; + if (hashPos != std::string::npos) + { + Tokenizer tokens(account, '#', 2); + stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_INFO_BY_BNET); + stmt->setUInt32(0, atol(tokens[0])); + stmt->setUInt8(1, atol(tokens[1])); + } + else + { + stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_INFO_BY_NAME); + stmt->setString(0, account); + } PreparedQueryResult result = LoginDatabase.Query(stmt); diff --git a/src/server/shared/Database/Implementation/LoginDatabase.cpp b/src/server/shared/Database/Implementation/LoginDatabase.cpp index abe733e55e2..1da8088ed36 100644 --- a/src/server/shared/Database/Implementation/LoginDatabase.cpp +++ b/src/server/shared/Database/Implementation/LoginDatabase.cpp @@ -44,7 +44,7 @@ void LoginDatabaseConnection::DoPrepareStatements() PrepareStatement(LOGIN_SEL_ACCOUNT_ID_BY_NAME, "SELECT id FROM account WHERE username = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_ACCOUNT_LIST_BY_NAME, "SELECT id, username FROM account WHERE username = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_ACCOUNT_INFO_BY_NAME, "SELECT id, sessionkey, last_ip, locked, expansion, mutetime, locale, recruiter, os FROM account WHERE username = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_ACCOUNT_INFO_BY_BNET, "SELECT id, sessionkey, last_ip, locked, expansion, mutetime, locale, recruiter, os FROM account WHERE id = SUBSTRING_INDEX(?, '#', 1)", CONNECTION_SYNCH); + PrepareStatement(LOGIN_SEL_ACCOUNT_INFO_BY_BNET, "SELECT id, sessionkey, last_ip, locked, expansion, mutetime, locale, recruiter, os FROM account WHERE battlenet_account = ? AND battlenet_index = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_ACCOUNT_LIST_BY_EMAIL, "SELECT id, username FROM account WHERE email = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_NUM_CHARS_ON_REALM, "SELECT numchars FROM realmcharacters WHERE realmid = ? AND acctid= ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_ACCOUNT_BY_IP, "SELECT id, username FROM account WHERE last_ip = ?", CONNECTION_SYNCH); @@ -108,9 +108,9 @@ void LoginDatabaseConnection::DoPrepareStatements() PrepareStatement(LOGIN_SEL_BNET_ACTIVE_ACCOUNT_BAN, "SELECT bandate, unbandate FROM battlenet_account_bans WHERE id = ? AND active = 1", CONNECTION_SYNCH); PrepareStatement(LOGIN_UPD_BNET_VS_FIELDS, "UPDATE battlenet_accounts SET v = ?, s = ? WHERE email = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_UPD_BNET_SESSION_KEY, "UPDATE battlenet_accounts SET sessionKey = ? WHERE id = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_SEL_BNET_RECONNECT_INFO, "SELECT ba.id, ba.sessionKey, a.id FROM battlenet_accounts ba LEFT JOIN account a ON ba.id = a.battlenet_account WHERE ba.email = ? AND a.id = SUBSTRING_INDEX(?, '#', 1)", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_BNET_GAME_ACCOUNTS, "SELECT a.username, a.id, ab.bandate, ab.unbandate, ab.active FROM account a LEFT JOIN account_banned ab ON a.id = ab.id WHERE battlenet_account = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_BNET_GAME_ACCOUNT, "SELECT a.id, ab.bandate, ab.unbandate, ab.active FROM account a LEFT JOIN account_banned ab ON a.id = ab.id WHERE username = ? AND battlenet_account = ?", CONNECTION_SYNCH); + PrepareStatement(LOGIN_SEL_BNET_RECONNECT_INFO, "SELECT ba.id, ba.sessionKey, a.id FROM battlenet_accounts ba LEFT JOIN account a ON ba.id = a.battlenet_account WHERE ba.email = ? AND a.battlenet_index = ?", CONNECTION_SYNCH); + PrepareStatement(LOGIN_SEL_BNET_GAME_ACCOUNTS, "SELECT a.battlenet_index, a.id, ab.bandate, ab.unbandate, ab.active FROM account a LEFT JOIN account_banned ab ON a.id = ab.id WHERE battlenet_account = ?", CONNECTION_SYNCH); + PrepareStatement(LOGIN_SEL_BNET_GAME_ACCOUNT, "SELECT a.id, ab.bandate, ab.unbandate, ab.active FROM account a LEFT JOIN account_banned ab ON a.id = ab.id WHERE battlenet_index = ? AND battlenet_account = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_UPD_BNET_LAST_LOGIN_INFO, "UPDATE battlenet_accounts SET last_ip = ?, last_login = NOW(), locale = ?, failed_logins = 0, os = ? WHERE id = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_SEL_BNET_CHARACTER_COUNTS, "SELECT rc.numchars, r.id, r.Region, r.Battlegroup, r.gamebuild FROM realmcharacters rc INNER JOIN realmlist r ON rc.realmid = r.id WHERE rc.acctid = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_INS_BNET_ACCOUNT, "INSERT INTO battlenet_accounts (`email`,`sha_pass_hash`) VALUES (?, ?)", CONNECTION_ASYNC); |