aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2014-06-08 17:58:28 +0200
committerShauren <shauren.trinity@gmail.com>2014-06-08 17:58:28 +0200
commit434b3a80e1ef4ccef3d66661e6a260b6328eabe5 (patch)
treeac51417a1fc3cc9a70be0109252d717961e4a191 /src
parent7dd552c8261be9d1c9c8e45628e5aca5cdae405d (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.cpp9
-rw-r--r--src/server/game/Accounts/BattlenetAccountMgr.cpp32
-rw-r--r--src/server/game/Accounts/BattlenetAccountMgr.h1
-rw-r--r--src/server/game/Accounts/RBAC.h14
-rw-r--r--src/server/game/Miscellaneous/Language.h3
-rw-r--r--src/server/game/Scripting/ScriptLoader.cpp2
-rw-r--r--src/server/game/Server/WorldSession.cpp3
-rw-r--r--src/server/game/Server/WorldSession.h4
-rw-r--r--src/server/game/Server/WorldSocket.cpp6
-rw-r--r--src/server/scripts/Commands/cs_account.cpp8
-rw-r--r--src/server/scripts/Commands/cs_battlenet_account.cpp335
-rw-r--r--src/server/shared/Database/Implementation/LoginDatabase.cpp4
-rw-r--r--src/server/shared/Database/Implementation/LoginDatabase.h2
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
};