diff options
author | Shauren <shauren.trinity@gmail.com> | 2014-06-08 17:58:28 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2014-06-08 17:58:28 +0200 |
commit | 434b3a80e1ef4ccef3d66661e6a260b6328eabe5 (patch) | |
tree | ac51417a1fc3cc9a70be0109252d717961e4a191 /src | |
parent | 7dd552c8261be9d1c9c8e45628e5aca5cdae405d (diff) |
Core/Commands: Added a set of commands to manage battle.net accounts
TODO: Ban commands, linking game accounts to battle.net accounts
Diffstat (limited to 'src')
-rw-r--r-- | src/server/authserver/Server/BattlenetSocket.cpp | 9 | ||||
-rw-r--r-- | src/server/game/Accounts/BattlenetAccountMgr.cpp | 32 | ||||
-rw-r--r-- | src/server/game/Accounts/BattlenetAccountMgr.h | 1 | ||||
-rw-r--r-- | src/server/game/Accounts/RBAC.h | 14 | ||||
-rw-r--r-- | src/server/game/Miscellaneous/Language.h | 3 | ||||
-rw-r--r-- | src/server/game/Scripting/ScriptLoader.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Server/WorldSession.cpp | 3 | ||||
-rw-r--r-- | src/server/game/Server/WorldSession.h | 4 | ||||
-rw-r--r-- | src/server/game/Server/WorldSocket.cpp | 6 | ||||
-rw-r--r-- | src/server/scripts/Commands/cs_account.cpp | 8 | ||||
-rw-r--r-- | src/server/scripts/Commands/cs_battlenet_account.cpp | 335 | ||||
-rw-r--r-- | src/server/shared/Database/Implementation/LoginDatabase.cpp | 4 | ||||
-rw-r--r-- | src/server/shared/Database/Implementation/LoginDatabase.h | 2 |
13 files changed, 371 insertions, 52 deletions
diff --git a/src/server/authserver/Server/BattlenetSocket.cpp b/src/server/authserver/Server/BattlenetSocket.cpp index 4ee3c8e9b3d..dad52f64877 100644 --- a/src/server/authserver/Server/BattlenetSocket.cpp +++ b/src/server/authserver/Server/BattlenetSocket.cpp @@ -421,7 +421,8 @@ bool Battlenet::Socket::HandleDisconnect(PacketHeader& /*header*/, BitStream& /* { PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_SESSION_KEY); stmt->setString(0, ""); - stmt->setUInt32(1, _accountId); + stmt->setBool(1, false); + stmt->setUInt32(2, _accountId); LoginDatabase.Execute(stmt); return true; } @@ -908,7 +909,8 @@ bool Battlenet::Socket::HandleRiskFingerprintModule(BitStream* dataStream, Serve stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_SESSION_KEY); stmt->setString(0, K.AsHexStr()); - stmt->setUInt32(1, _accountId); + stmt->setBool(1, true); + stmt->setUInt32(2, _accountId); trans->Append(stmt); LoginDatabase.CommitTransaction(trans); @@ -975,7 +977,8 @@ bool Battlenet::Socket::HandleResumeModule(BitStream* dataStream, ServerPacket** PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_SESSION_KEY); stmt->setString(0, K.AsHexStr()); - stmt->setUInt32(1, _accountId); + stmt->setBool(1, true); + stmt->setUInt32(2, _accountId); LoginDatabase.Execute(stmt); HmacSha256 serverProof(64, newSessionKey); diff --git a/src/server/game/Accounts/BattlenetAccountMgr.cpp b/src/server/game/Accounts/BattlenetAccountMgr.cpp index 8b73ba19a97..4f4d78591f9 100644 --- a/src/server/game/Accounts/BattlenetAccountMgr.cpp +++ b/src/server/game/Accounts/BattlenetAccountMgr.cpp @@ -23,9 +23,12 @@ AccountOpResult Battlenet::AccountMgr::CreateBattlenetAccount(std::string email, std::string password) { - if (utf8length(email) > 64) + if (utf8length(email) > MAX_BNET_EMAIL_STR) return AccountOpResult::AOR_NAME_TOO_LONG; + if (utf8length(password) > MAX_PASS_STR) + return AccountOpResult::AOR_PASS_TOO_LONG; + Utf8ToUpperOnlyLatin(email); Utf8ToUpperOnlyLatin(password); @@ -40,33 +43,6 @@ AccountOpResult Battlenet::AccountMgr::CreateBattlenetAccount(std::string email, return AccountOpResult::AOR_OK; } -AccountOpResult Battlenet::AccountMgr::ChangeUsername(uint32 accountId, std::string newUsername, std::string newPassword) -{ - // Check if accounts exists - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_ACCOUNT_EMAIL_BY_ID); - stmt->setUInt32(0, accountId); - PreparedQueryResult result = LoginDatabase.Query(stmt); - - if (!result) - return AccountOpResult::AOR_NAME_NOT_EXIST; - - Utf8ToUpperOnlyLatin(newUsername); - if (utf8length(newUsername) > MAX_ACCOUNT_STR) - return AccountOpResult::AOR_NAME_TOO_LONG; - - Utf8ToUpperOnlyLatin(newPassword); - if (utf8length(newPassword) > MAX_PASS_STR) - return AccountOpResult::AOR_PASS_TOO_LONG; - - stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_PASSWORD); - stmt->setString(0, newUsername); - stmt->setString(1, CalculateShaPassHash(newUsername, newPassword)); - stmt->setUInt32(2, accountId); - LoginDatabase.Execute(stmt); - - return AccountOpResult::AOR_OK; -} - AccountOpResult Battlenet::AccountMgr::ChangePassword(uint32 accountId, std::string newPassword) { std::string username; diff --git a/src/server/game/Accounts/BattlenetAccountMgr.h b/src/server/game/Accounts/BattlenetAccountMgr.h index 07191d24313..1565c1aeee1 100644 --- a/src/server/game/Accounts/BattlenetAccountMgr.h +++ b/src/server/game/Accounts/BattlenetAccountMgr.h @@ -31,7 +31,6 @@ namespace Battlenet namespace AccountMgr { AccountOpResult CreateBattlenetAccount(std::string email, std::string password); - AccountOpResult ChangeUsername(uint32 accountId, std::string newUsername, std::string newPassword); AccountOpResult ChangePassword(uint32 accountId, std::string newPassword); bool CheckPassword(uint32 accountId, std::string password); diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h index 9ce1f9bb67a..f8d967c3e3a 100644 --- a/src/server/game/Accounts/RBAC.h +++ b/src/server/game/Accounts/RBAC.h @@ -110,13 +110,13 @@ enum RBACPermissions RBAC_PERM_COMMAND_RBAC_ACC_PERM_DENY = 204, RBAC_PERM_COMMAND_RBAC_ACC_PERM_REVOKE = 205, RBAC_PERM_COMMAND_RBAC_LIST = 206, - // 207 - reuse - // 208 - reuse - // 209 - reuse - // 210 - reuse - // 211 - reuse - // 212 - reuse - // 213 - reuse + RBAC_PERM_COMMAND_BNET_ACCOUNT = 207, + RBAC_PERM_COMMAND_BNET_ACCOUNT_CREATE = 208, + RBAC_PERM_COMMAND_BNET_ACCOUNT_LOCK_COUNTRY = 209, + RBAC_PERM_COMMAND_BNET_ACCOUNT_LOCK_IP = 210, + RBAC_PERM_COMMAND_BNET_ACCOUNT_PASSWORD = 211, + RBAC_PERM_COMMAND_BNET_ACCOUNT_SET = 212, + RBAC_PERM_COMMAND_BNET_ACCOUNT_SET_PASSWORD = 213, // 214 - reuse // 215 - reuse // 216 - reuse diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h index 97834d3e444..b841b1195af 100644 --- a/src/server/game/Miscellaneous/Language.h +++ b/src/server/game/Miscellaneous/Language.h @@ -889,7 +889,8 @@ enum TrinityStrings LANG_CHARACTER_DELETED_LIST_LINE_CHAT = 1026, LANG_SQLDRIVER_QUERY_LOGGING_ENABLED = 1027, LANG_SQLDRIVER_QUERY_LOGGING_DISABLED = 1028, - // Room for more level 4 1029-1099 not used + LANG_ACCOUNT_INVALID_BNET_NAME = 1029, + // Room for more level 4 1030-1099 not used // Level 3 (continue) LANG_ACCOUNT_SETADDON = 1100, diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp index a744915a25a..1b8f0ff9f2c 100644 --- a/src/server/game/Scripting/ScriptLoader.cpp +++ b/src/server/game/Scripting/ScriptLoader.cpp @@ -48,6 +48,7 @@ void AddSC_account_commandscript(); void AddSC_achievement_commandscript(); void AddSC_arena_commandscript(); void AddSC_ban_commandscript(); +void AddSC_battlenet_account_commandscript(); void AddSC_bf_commandscript(); void AddSC_cast_commandscript(); void AddSC_character_commandscript(); @@ -759,6 +760,7 @@ void AddCommandScripts() AddSC_achievement_commandscript(); AddSC_arena_commandscript(); AddSC_ban_commandscript(); + AddSC_battlenet_account_commandscript(); AddSC_bf_commandscript(); AddSC_cast_commandscript(); AddSC_character_commandscript(); diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 201235b4a40..28e87de0468 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -99,7 +99,7 @@ bool WorldSessionFilter::Process(WorldPacket* packet) } /// WorldSession constructor -WorldSession::WorldSession(uint32 id, WorldSocket* sock, AccountTypes sec, uint8 expansion, time_t mute_time, LocaleConstant locale, uint32 recruiter, bool isARecruiter): +WorldSession::WorldSession(uint32 id, uint32 battlenetAccountId, WorldSocket* sock, AccountTypes sec, uint8 expansion, time_t mute_time, LocaleConstant locale, uint32 recruiter, bool isARecruiter): m_muteTime(mute_time), m_timeOutTime(0), AntiDOS(this), @@ -108,6 +108,7 @@ WorldSession::WorldSession(uint32 id, WorldSocket* sock, AccountTypes sec, uint8 m_Socket(sock), _security(sec), _accountId(id), + _battlenetAccountId(battlenetAccountId), m_expansion(expansion), _warden(NULL), _logoutTime(0), diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 3c5e27f6f52..f7fe3a967e2 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -215,7 +215,7 @@ struct PacketCounter class WorldSession { public: - WorldSession(uint32 id, WorldSocket* sock, AccountTypes sec, uint8 expansion, time_t mute_time, LocaleConstant locale, uint32 recruiter, bool isARecruiter); + WorldSession(uint32 id, uint32 battlenetAccountId, WorldSocket* sock, AccountTypes sec, uint8 expansion, time_t mute_time, LocaleConstant locale, uint32 recruiter, bool isARecruiter); ~WorldSession(); bool PlayerLoading() const { return m_playerLoading; } @@ -246,6 +246,7 @@ class WorldSession AccountTypes GetSecurity() const { return _security; } uint32 GetAccountId() const { return _accountId; } + uint32 GetBattlenetAccountId() const { return _accountId; } Player* GetPlayer() const { return _player; } std::string const& GetPlayerName() const; std::string GetPlayerInfo() const; @@ -1055,6 +1056,7 @@ class WorldSession AccountTypes _security; uint32 _accountId; + uint32 _battlenetAccountId; uint8 m_expansion; typedef std::list<AddonInfo> AddonsList; diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index 1a93e7ae1d5..5905ec6a704 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -858,11 +858,13 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket) // SELECT id, sessionkey, last_ip, locked, expansion, mutetime, locale, recruiter, os FROM account WHERE username = ? size_t hashPos = account.find_last_of('#'); PreparedStatement* stmt; + uint32 battlenetAccountId = 0; if (hashPos != std::string::npos) { Tokenizer tokens(account, '#', 2); + battlenetAccountId = atol(tokens[0]); stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_INFO_BY_BNET); - stmt->setUInt32(0, atol(tokens[0])); + stmt->setUInt32(0, battlenetAccountId); stmt->setUInt8(1, atol(tokens[1])); } else @@ -1018,7 +1020,7 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket) LoginDatabase.Execute(stmt); // NOTE ATM the socket is single-threaded, have this in mind ... - ACE_NEW_RETURN(m_Session, WorldSession(id, this, AccountTypes(security), expansion, mutetime, locale, recruiter, isRecruiter), -1); + ACE_NEW_RETURN(m_Session, WorldSession(id, battlenetAccountId, this, AccountTypes(security), expansion, mutetime, locale, recruiter, isRecruiter), -1); m_Crypt.Init(&k); diff --git a/src/server/scripts/Commands/cs_account.cpp b/src/server/scripts/Commands/cs_account.cpp index a438cd995e7..13402018508 100644 --- a/src/server/scripts/Commands/cs_account.cpp +++ b/src/server/scripts/Commands/cs_account.cpp @@ -127,13 +127,7 @@ public: if (!accountName || !password) return false; - AccountOpResult result; - if (strchr(accountName, '@')) - result = Battlenet::AccountMgr::CreateBattlenetAccount(std::string(accountName), std::string(password)); - else - result = sAccountMgr->CreateAccount(std::string(accountName), std::string(password), email); - - switch (result) + switch (sAccountMgr->CreateAccount(std::string(accountName), std::string(password), email)) { case AccountOpResult::AOR_OK: handler->PSendSysMessage(LANG_ACCOUNT_CREATED, accountName); diff --git a/src/server/scripts/Commands/cs_battlenet_account.cpp b/src/server/scripts/Commands/cs_battlenet_account.cpp new file mode 100644 index 00000000000..ebfcd8acbe3 --- /dev/null +++ b/src/server/scripts/Commands/cs_battlenet_account.cpp @@ -0,0 +1,335 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "BattlenetAccountMgr.h" +#include "Chat.h" +#include "Language.h" +#include "Player.h" +#include "ScriptMgr.h" + +class battlenet_account_commandscript : public CommandScript +{ +public: + battlenet_account_commandscript() : CommandScript("battlenet_account_commandscript") { } + + ChatCommand* GetCommands() const override + { + static ChatCommand accountSetCommandTable[] = + { + { "password", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_SET_PASSWORD, true, &HandleAccountSetPasswordCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + + static ChatCommand accountLockCommandTable[] = + { + { "country", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_LOCK_COUNTRY, true, &HandleAccountLockCountryCommand, "", NULL }, + { "ip", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_LOCK_IP, true, &HandleAccountLockIpCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + + static ChatCommand accountCommandTable[] = + { + { "create", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_CREATE, true, &HandleAccountCreateCommand, "", NULL }, + { "lock", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT, false, NULL, "", accountLockCommandTable }, + { "set", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_SET, true, NULL, "", accountSetCommandTable }, + { "password", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_PASSWORD, false, &HandleAccountPasswordCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + + static ChatCommand commandTable[] = + { + { "battlenetaccount", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT, true, NULL, "", accountCommandTable }, + { NULL, 0, false, NULL, "", NULL } + }; + + return commandTable; + } + + /// Create an account + static bool HandleAccountCreateCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + std::string email; + + ///- %Parse the command line arguments + char* accountName = strtok((char*)args, " "); + char* password = strtok(NULL, " "); + if (!accountName || !password) + return false; + + if (!strchr(accountName, '@')) + { + handler->SendSysMessage(LANG_ACCOUNT_INVALID_BNET_NAME); + handler->SetSentErrorMessage(true); + return false; + } + + switch (Battlenet::AccountMgr::CreateBattlenetAccount(std::string(accountName), std::string(password))) + { + case AccountOpResult::AOR_OK: + handler->PSendSysMessage(LANG_ACCOUNT_CREATED, accountName); + if (handler->GetSession()) + { + TC_LOG_INFO("entities.player.character", "Battle.net account: %d (IP: %s) Character:[%s] (GUID: %u) created Account %s", + handler->GetSession()->GetAccountId(), handler->GetSession()->GetRemoteAddress().c_str(), + handler->GetSession()->GetPlayer()->GetName().c_str(), handler->GetSession()->GetPlayer()->GetGUIDLow(), + accountName); + } + break; + case AccountOpResult::AOR_NAME_TOO_LONG: + handler->SendSysMessage(LANG_ACCOUNT_TOO_LONG); + handler->SetSentErrorMessage(true); + return false; + case AccountOpResult::AOR_NAME_ALREADY_EXIST: + handler->SendSysMessage(LANG_ACCOUNT_ALREADY_EXIST); + handler->SetSentErrorMessage(true); + return false; + case AccountOpResult::AOR_PASS_TOO_LONG: + handler->SendSysMessage(LANG_PASSWORD_TOO_LONG); + handler->SetSentErrorMessage(true); + return false; + default: + break; + } + + return true; + } + + // Sets country lock on own account + static bool HandleAccountLockCountryCommand(ChatHandler* handler, char const* args) + { + if (!*args) + { + handler->SendSysMessage(LANG_USE_BOL); + handler->SetSentErrorMessage(true); + return false; + } + + std::string param = (char*)args; + if (!param.empty()) + { + if (param == "on") + { + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_LOGON_COUNTRY); + uint32 ip = inet_addr(handler->GetSession()->GetRemoteAddress().c_str()); + EndianConvertReverse(ip); + stmt->setUInt32(0, ip); + PreparedQueryResult result = LoginDatabase.Query(stmt); + if (result) + { + Field* fields = result->Fetch(); + std::string country = fields[0].GetString(); + stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_ACCOUNT_LOCK_CONTRY); + stmt->setString(0, country); + stmt->setUInt32(1, handler->GetSession()->GetBattlenetAccountId()); + LoginDatabase.Execute(stmt); + handler->PSendSysMessage(LANG_COMMAND_ACCLOCKLOCKED); + } + else + { + handler->PSendSysMessage("[IP2NATION] Table empty"); + TC_LOG_DEBUG("server.authserver", "[IP2NATION] Table empty"); + } + } + else if (param == "off") + { + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_ACCOUNT_LOCK_CONTRY); + stmt->setString(0, "00"); + stmt->setUInt32(1, handler->GetSession()->GetBattlenetAccountId()); + LoginDatabase.Execute(stmt); + handler->PSendSysMessage(LANG_COMMAND_ACCLOCKUNLOCKED); + } + return true; + } + + handler->SendSysMessage(LANG_USE_BOL); + handler->SetSentErrorMessage(true); + return false; + } + + // Sets ip lock on own account + static bool HandleAccountLockIpCommand(ChatHandler* handler, char const* args) + { + if (!*args) + { + handler->SendSysMessage(LANG_USE_BOL); + handler->SetSentErrorMessage(true); + return false; + } + + std::string param = (char*)args; + + if (!param.empty()) + { + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_ACCOUNT_LOCK); + + if (param == "on") + { + stmt->setBool(0, true); // locked + handler->PSendSysMessage(LANG_COMMAND_ACCLOCKLOCKED); + } + else if (param == "off") + { + stmt->setBool(0, false); // unlocked + handler->PSendSysMessage(LANG_COMMAND_ACCLOCKUNLOCKED); + } + + stmt->setUInt32(1, handler->GetSession()->GetBattlenetAccountId()); + + LoginDatabase.Execute(stmt); + return true; + } + + handler->SendSysMessage(LANG_USE_BOL); + handler->SetSentErrorMessage(true); + return false; + } + + static bool HandleAccountPasswordCommand(ChatHandler* handler, char const* args) + { + // If no args are given at all, we can return false right away. + if (!*args) + { + handler->SendSysMessage(LANG_CMD_SYNTAX); + handler->SetSentErrorMessage(true); + return false; + } + + // Command is supposed to be: .account password [$oldpassword] [$newpassword] [$newpasswordconfirmation] [$emailconfirmation] + char* oldPassword = strtok((char*)args, " "); // This extracts [$oldpassword] + char* newPassword = strtok(NULL, " "); // This extracts [$newpassword] + char* passwordConfirmation = strtok(NULL, " "); // This extracts [$newpasswordconfirmation] + + //Is any of those variables missing for any reason ? We return false. + if (!oldPassword || !newPassword || !passwordConfirmation) + { + handler->SendSysMessage(LANG_CMD_SYNTAX); + handler->SetSentErrorMessage(true); + return false; + } + + // We compare the old, saved password to the entered old password - no chance for the unauthorized. + if (!Battlenet::AccountMgr::CheckPassword(handler->GetSession()->GetAccountId(), std::string(oldPassword))) + { + handler->SendSysMessage(LANG_COMMAND_WRONGOLDPASSWORD); + handler->SetSentErrorMessage(true); + TC_LOG_INFO("entities.player.character", "Battle.net account: %u (IP: %s) Character:[%s] (GUID: %u) Tried to change password, but the provided old password is wrong.", + handler->GetSession()->GetAccountId(), handler->GetSession()->GetRemoteAddress().c_str(), + handler->GetSession()->GetPlayer()->GetName().c_str(), handler->GetSession()->GetPlayer()->GetGUIDLow()); + return false; + } + + // Making sure that newly entered password is correctly entered. + if (strcmp(newPassword, passwordConfirmation) != 0) + { + handler->SendSysMessage(LANG_NEW_PASSWORDS_NOT_MATCH); + handler->SetSentErrorMessage(true); + return false; + } + + // Changes password and prints result. + AccountOpResult result = Battlenet::AccountMgr::ChangePassword(handler->GetSession()->GetBattlenetAccountId(), std::string(newPassword)); + switch (result) + { + case AccountOpResult::AOR_OK: + handler->SendSysMessage(LANG_COMMAND_PASSWORD); + TC_LOG_INFO("entities.player.character", "Battle.net account: %u (IP: %s) Character:[%s] (GUID: %u) Changed Password.", + handler->GetSession()->GetBattlenetAccountId(), handler->GetSession()->GetRemoteAddress().c_str(), + handler->GetSession()->GetPlayer()->GetName().c_str(), handler->GetSession()->GetPlayer()->GetGUIDLow()); + break; + case AccountOpResult::AOR_PASS_TOO_LONG: + handler->SendSysMessage(LANG_PASSWORD_TOO_LONG); + handler->SetSentErrorMessage(true); + return false; + default: + handler->SendSysMessage(LANG_COMMAND_NOTCHANGEPASSWORD); + handler->SetSentErrorMessage(true); + return false; + } + + return true; + } + + /// Set password for account + static bool HandleAccountSetPasswordCommand(ChatHandler* handler, char const* args) + { + if (!*args) + { + handler->SendSysMessage(LANG_CMD_SYNTAX); + handler->SetSentErrorMessage(true); + return false; + } + + ///- Get the command line arguments + char* account = strtok((char*)args, " "); + char* password = strtok(NULL, " "); + char* passwordConfirmation = strtok(NULL, " "); + + if (!account || !password || !passwordConfirmation) + return false; + + std::string accountName = account; + if (!Utf8ToUpperOnlyLatin(accountName)) + { + handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + + uint32 targetAccountId = Battlenet::AccountMgr::GetId(accountName); + if (!targetAccountId) + { + handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + + if (strcmp(password, passwordConfirmation)) + { + handler->SendSysMessage(LANG_NEW_PASSWORDS_NOT_MATCH); + handler->SetSentErrorMessage(true); + return false; + } + + AccountOpResult result = Battlenet::AccountMgr::ChangePassword(targetAccountId, password); + + switch (result) + { + case AccountOpResult::AOR_OK: + handler->SendSysMessage(LANG_COMMAND_PASSWORD); + break; + case AccountOpResult::AOR_NAME_NOT_EXIST: + handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str()); + handler->SetSentErrorMessage(true); + return false; + case AccountOpResult::AOR_PASS_TOO_LONG: + handler->SendSysMessage(LANG_PASSWORD_TOO_LONG); + handler->SetSentErrorMessage(true); + return false; + default: + break; + } + return true; + } +}; + +void AddSC_battlenet_account_commandscript() +{ + new battlenet_account_commandscript(); +} diff --git a/src/server/shared/Database/Implementation/LoginDatabase.cpp b/src/server/shared/Database/Implementation/LoginDatabase.cpp index bccbe41a6ec..df9ab6fcf29 100644 --- a/src/server/shared/Database/Implementation/LoginDatabase.cpp +++ b/src/server/shared/Database/Implementation/LoginDatabase.cpp @@ -107,7 +107,7 @@ void LoginDatabaseConnection::DoPrepareStatements() PrepareStatement(LOGIN_DEL_BNET_EXPIRED_BANS, "UPDATE battlenet_account_bans SET active = 0 WHERE active = 1 AND unbandate <> bandate AND unbandate <= UNIX_TIMESTAMP()", CONNECTION_SYNCH); 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_UPD_BNET_SESSION_KEY, "UPDATE battlenet_accounts SET sessionKey = ?, online = ? 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.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); @@ -118,4 +118,6 @@ void LoginDatabaseConnection::DoPrepareStatements() PrepareStatement(LOGIN_SEL_BNET_ACCOUNT_ID_BY_EMAIL, "SELECT id FROM battlenet_accounts WHERE email = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_UPD_BNET_PASSWORD, "UPDATE account SET v = '', s = '', username = ?, sha_pass_hash = ? WHERE id = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_SEL_BNET_CHECK_PASSWORD, "SELECT 1 FROM battlenet_accounts WHERE id = ? AND sha_pass_hash = ?", CONNECTION_ASYNC); + PrepareStatement(LOGIN_UPD_BNET_ACCOUNT_LOCK, "UPDATE battlenet_accounts SET locked = ? WHERE id = ?", CONNECTION_ASYNC); + PrepareStatement(LOGIN_UPD_BNET_ACCOUNT_LOCK_CONTRY, "UPDATE battlenet_accounts SET lock_country = ? WHERE id = ?", CONNECTION_ASYNC); } diff --git a/src/server/shared/Database/Implementation/LoginDatabase.h b/src/server/shared/Database/Implementation/LoginDatabase.h index 64264984e29..4fdfb91fed3 100644 --- a/src/server/shared/Database/Implementation/LoginDatabase.h +++ b/src/server/shared/Database/Implementation/LoginDatabase.h @@ -137,6 +137,8 @@ enum LoginDatabaseStatements LOGIN_SEL_BNET_ACCOUNT_ID_BY_EMAIL, LOGIN_UPD_BNET_PASSWORD, LOGIN_SEL_BNET_CHECK_PASSWORD, + LOGIN_UPD_BNET_ACCOUNT_LOCK, + LOGIN_UPD_BNET_ACCOUNT_LOCK_CONTRY, MAX_LOGINDATABASE_STATEMENTS }; |