diff --git a/sql/base/auth_database.sql b/sql/base/auth_database.sql
index 06428af69fa..c88ef20a4f9 100644
--- a/sql/base/auth_database.sql
+++ b/sql/base/auth_database.sql
@@ -952,6 +952,7 @@ INSERT INTO `rbac_linked_permissions` VALUES
(196,773),
(196,775),
(196,777),
+(196,830),
(196,836),
(196,837),
(196,838),
@@ -1824,6 +1825,7 @@ INSERT INTO `rbac_permissions` VALUES
(792,'Command: ahbot reload'),
(793,'Command: ahbot status'),
(794,'Command: guild info'),
+(830,'Command: bnetaccount listgameaccounts'),
(835,'Command: debug loadcells'),
(836,'Command: debug boundary'),
(837,'Command: npc evade'),
@@ -2000,7 +2002,8 @@ INSERT INTO `updates` VALUES
('2019_09_29_00_auth.sql','73C820469E1EF2501C3126CA098D6FE7DD4E0D3C','RELEASED','2019-11-06 00:17:44',85),
('2019_10_03_00_auth.sql','A0D27DAFDE2F7F1F7FAAACF1E13FA104A50D603A','RELEASED','2019-11-06 00:17:44',80),
('2019_10_06_00_auth.sql','0E25F5CB2CEDAB52B899085EEC9EEB37B8236F20','RELEASED','2019-11-06 00:17:44',64),
-('2019_10_08_00_auth.sql','1CD55291FED15182C2E71F8695E4B304EDB3F35E','RELEASED','2019-11-06 00:17:44',63);
+('2019_10_08_00_auth.sql','1CD55291FED15182C2E71F8695E4B304EDB3F35E','RELEASED','2019-11-06 00:17:44',63),
+('9999_99_99_99_auth.sql','B3738FB3FA1C75E430EC64B5E9635A5E52E3AB36','RELEASED','2020-02-13 16:37:42',37);
/*!40000 ALTER TABLE `updates` ENABLE KEYS */;
UNLOCK TABLES;
diff --git a/sql/updates/auth/4.3.4/9999_99_99_99_auth.sql b/sql/updates/auth/4.3.4/9999_99_99_99_auth.sql
new file mode 100644
index 00000000000..dcdaf999553
--- /dev/null
+++ b/sql/updates/auth/4.3.4/9999_99_99_99_auth.sql
@@ -0,0 +1,7 @@
+DELETE FROM `rbac_permissions` WHERE `id`=830;
+INSERT INTO `rbac_permissions` (`id`,`name`) VALUES
+(830,'Command: bnetaccount listgameaccounts');
+
+DELETE FROM `rbac_linked_permissions` WHERE `id`=196 AND `linkedId`=830;
+INSERT INTO `rbac_linked_permissions` (`id`, `linkedId`) VALUES
+(196, 830);
diff --git a/sql/updates/world/custom/custom_9999_99_99_99_world.sql b/sql/updates/world/custom/custom_9999_99_99_99_world.sql
new file mode 100644
index 00000000000..2e45b7d2b83
--- /dev/null
+++ b/sql/updates/world/custom/custom_9999_99_99_99_world.sql
@@ -0,0 +1,11 @@
+DELETE FROM `command` WHERE `name`='bnetaccount listgameaccounts';
+INSERT INTO `command` (`name`,`permission`,`help`) VALUES
+('bnetaccount listgameaccounts', 830, 'Syntax: .bnetaccount listgameaccounts $email $password\nLists all game accounts linked to battle.net $email');
+
+DELETE FROM `trinity_string` WHERE `entry` IN (1030, 1032, 1033, 1034, 1035);
+INSERT INTO `trinity_string` (`entry`, `content_default`) VALUES
+(1030, 'You are attempting to create a battle.net account with wrong command, use .bnetaccount create'),
+(1032, 'Battle.net account created: %s with game account %s'),
+(1033, 'Battle.net account created: %s'),
+(1034, '| Account Id | Internal name | Display name |'),
+(1035, 'Battle.net account %s has no linked game accounts.');
diff --git a/src/common/Utilities/Util.cpp b/src/common/Utilities/Util.cpp
index 82232bb36d5..e5d56114687 100644
--- a/src/common/Utilities/Util.cpp
+++ b/src/common/Utilities/Util.cpp
@@ -579,7 +579,7 @@ void HexStrToByteArray(std::string const& str, uint8* out, bool reverse /*= fals
bool StringToBool(std::string const& str)
{
std::string lowerStr = str;
- std::transform(str.begin(), str.end(), lowerStr.begin(), ::tolower);
+ std::transform(str.begin(), str.end(), lowerStr.begin(), [](char c) { return char(::tolower(c)); });
return lowerStr == "1" || lowerStr == "true" || lowerStr == "yes";
}
diff --git a/src/server/database/Database/Implementation/LoginDatabase.cpp b/src/server/database/Database/Implementation/LoginDatabase.cpp
index d55d66eddf6..91a21d03d07 100644
--- a/src/server/database/Database/Implementation/LoginDatabase.cpp
+++ b/src/server/database/Database/Implementation/LoginDatabase.cpp
@@ -148,6 +148,7 @@ void LoginDatabaseConnection::DoPrepareStatements()
PrepareStatement(LOGIN_SEL_BNET_ACCOUNT_ID_BY_GAME_ACCOUNT, "SELECT battlenet_account FROM account WHERE id = ?", CONNECTION_SYNCH);
PrepareStatement(LOGIN_UPD_BNET_GAME_ACCOUNT_LINK, "UPDATE account SET battlenet_account = ?, battlenet_index = ? WHERE id = ?", CONNECTION_ASYNC);
PrepareStatement(LOGIN_SEL_BNET_MAX_ACCOUNT_INDEX, "SELECT MAX(battlenet_index) FROM account WHERE battlenet_account = ?", CONNECTION_SYNCH);
+ PrepareStatement(LOGIN_SEL_BNET_GAME_ACCOUNT_LIST, "SELECT a.id, a.username FROM account a LEFT JOIN battlenet_accounts ba ON a.battlenet_account = ba.id WHERE ba.email = ?", CONNECTION_SYNCH);
}
LoginDatabaseConnection::LoginDatabaseConnection(MySQLConnectionInfo& connInfo) : MySQLConnection(connInfo)
diff --git a/src/server/database/Database/Implementation/LoginDatabase.h b/src/server/database/Database/Implementation/LoginDatabase.h
index 0ed20093f0e..593be33ab9d 100644
--- a/src/server/database/Database/Implementation/LoginDatabase.h
+++ b/src/server/database/Database/Implementation/LoginDatabase.h
@@ -130,6 +130,7 @@ enum LoginDatabaseStatements : uint32
LOGIN_SEL_BNET_ACCOUNT_ID_BY_GAME_ACCOUNT,
LOGIN_UPD_BNET_GAME_ACCOUNT_LINK,
LOGIN_SEL_BNET_MAX_ACCOUNT_INDEX,
+ LOGIN_SEL_BNET_GAME_ACCOUNT_LIST,
MAX_LOGINDATABASE_STATEMENTS
};
diff --git a/src/server/game/Accounts/BattlenetAccountMgr.cpp b/src/server/game/Accounts/BattlenetAccountMgr.cpp
index aa176f438ff..54f4113f0d0 100644
--- a/src/server/game/Accounts/BattlenetAccountMgr.cpp
+++ b/src/server/game/Accounts/BattlenetAccountMgr.cpp
@@ -15,15 +15,15 @@
* with this program. If not, see .
*/
-#include "AccountMgr.h"
#include "BattlenetAccountMgr.h"
+#include "AccountMgr.h"
#include "DatabaseEnv.h"
#include "Util.h"
#include "SHA256.h"
using GameAccountMgr = AccountMgr;
-AccountOpResult Battlenet::AccountMgr::CreateBattlenetAccount(std::string email, std::string password)
+AccountOpResult Battlenet::AccountMgr::CreateBattlenetAccount(std::string email, std::string password, bool withGameAccount, std::string* gameAccountName)
{
if (utf8length(email) > MAX_BNET_EMAIL_STR)
return AccountOpResult::AOR_NAME_TOO_LONG;
@@ -35,7 +35,7 @@ AccountOpResult Battlenet::AccountMgr::CreateBattlenetAccount(std::string email,
Utf8ToUpperOnlyLatin(password);
if (GetId(email))
- return AccountOpResult::AOR_NAME_ALREADY_EXIST;
+ return AccountOpResult::AOR_NAME_ALREADY_EXIST;
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_BNET_ACCOUNT);
stmt->setString(0, email);
@@ -45,7 +45,11 @@ AccountOpResult Battlenet::AccountMgr::CreateBattlenetAccount(std::string email,
uint32 newAccountId = GetId(email);
ASSERT(newAccountId);
- GameAccountMgr::instance()->CreateAccount(std::to_string(newAccountId) + "#1", password, email, newAccountId, 1);
+ if (withGameAccount)
+ {
+ *gameAccountName = std::to_string(newAccountId) + "#1";
+ GameAccountMgr::instance()->CreateAccount(*gameAccountName, password, email, newAccountId, 1);
+ }
return AccountOpResult::AOR_OK;
}
diff --git a/src/server/game/Accounts/BattlenetAccountMgr.h b/src/server/game/Accounts/BattlenetAccountMgr.h
index 5a169374cd7..fb2e333d4b5 100644
--- a/src/server/game/Accounts/BattlenetAccountMgr.h
+++ b/src/server/game/Accounts/BattlenetAccountMgr.h
@@ -29,7 +29,7 @@ namespace Battlenet
{
namespace AccountMgr
{
- TC_GAME_API AccountOpResult CreateBattlenetAccount(std::string email, std::string password);
+ TC_GAME_API AccountOpResult CreateBattlenetAccount(std::string email, std::string password, bool withGameAccount, std::string* gameAccountName);
TC_GAME_API AccountOpResult ChangePassword(uint32 accountId, std::string newPassword);
TC_GAME_API bool CheckPassword(uint32 accountId, std::string password);
TC_GAME_API AccountOpResult LinkWithGameAccount(std::string const& email, std::string const& gameAccountName);
diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h
index d9522b2334f..756b5f9184b 100644
--- a/src/server/game/Accounts/RBAC.h
+++ b/src/server/game/Accounts/RBAC.h
@@ -727,7 +727,7 @@ enum RBACPermissions
RBAC_PERM_COMMAND_TICKET_SUGGESTION_UNASSIGN = 827, // not on 3.3.5a or 4.3.4
RBAC_PERM_COMMAND_TICKET_SUGGESTION_VIEW = 828, // not on 3.3.5a or 4.3.4
RBAC_PERM_COMMAND_TICKET_RESET_ALL = 829, // not on 3.3.5a or 4.3.4
- RBAC_PERM_COMMAND_BNET_ACCOUNT_LIST_GAME_ACCOUTNS = 830, // not on 3.3.5a or 4.3.4
+ RBAC_PERM_COMMAND_BNET_ACCOUNT_LIST_GAME_ACCOUNTS = 830,
RBAC_PERM_COMMAND_TICKET_RESET_BUG = 831, // not on 3.3.5a or 4.3.4
RBAC_PERM_COMMAND_TICKET_RESET_COMPLAINT = 832, // not on 3.3.5a or 4.3.4
RBAC_PERM_COMMAND_TICKET_RESET_SUGGESTION = 833, // not on 3.3.5a or 4.3.4
diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h
index 71b2e802e65..95d5535d28c 100644
--- a/src/server/game/Miscellaneous/Language.h
+++ b/src/server/game/Miscellaneous/Language.h
@@ -829,13 +829,13 @@ enum TrinityStrings
LANG_CHARACTER_DELETED_LIST_LINE_CHAT = 1026,
LANG_SQLDRIVER_QUERY_LOGGING_ENABLED = 1027,
LANG_SQLDRIVER_QUERY_LOGGING_DISABLED = 1028,
- LANG_ACCOUNT_INVALID_BNET_NAME = 1029, // 6.x ONLY
- LANG_ACCOUNT_USE_BNET_COMMANDS = 1030, // 6.x enum value name but different text in DB
+ LANG_ACCOUNT_INVALID_BNET_NAME = 1029,
+ LANG_ACCOUNT_USE_BNET_COMMANDS = 1030,
LANG_ACCOUNT_PASS_TOO_LONG = 1031,
- LANG_ACCOUNT_CREATED_BNET_WITH_GAME = 1032, // master branch ONLY
- LANG_ACCOUNT_CREATED_BNET = 1033, // master branch ONLY
- LANG_ACCOUNT_BNET_LIST_HEADER = 1034, // master branch ONLY
- LANG_ACCOUNT_BNET_LIST_NO_ACCOUNTS = 1035, // master branch ONLY
+ LANG_ACCOUNT_CREATED_BNET_WITH_GAME = 1032,
+ LANG_ACCOUNT_CREATED_BNET = 1033,
+ LANG_ACCOUNT_BNET_LIST_HEADER = 1034,
+ LANG_ACCOUNT_BNET_LIST_NO_ACCOUNTS = 1035,
LANG_ACCOUNT_BNET_LINKED = 1036,
LANG_ACCOUNT_OR_BNET_DOES_NOT_EXIST = 1037,
LANG_ACCOUNT_ALREADY_LINKED = 1038,
diff --git a/src/server/scripts/Commands/cs_battlenet_account.cpp b/src/server/scripts/Commands/cs_battlenet_account.cpp
index f3a1444ceab..93bb7497c7d 100644
--- a/src/server/scripts/Commands/cs_battlenet_account.cpp
+++ b/src/server/scripts/Commands/cs_battlenet_account.cpp
@@ -15,9 +15,9 @@
* with this program. If not, see .
*/
-#include "ScriptMgr.h"
#include "AccountMgr.h"
#include "BattlenetAccountMgr.h"
+#include "BigNumber.h"
#include "Chat.h"
#include "DatabaseEnv.h"
#include "IpAddress.h"
@@ -25,7 +25,8 @@
#include "Language.h"
#include "Log.h"
#include "Player.h"
-#include "RBAC.h"
+#include "ScriptMgr.h"
+#include "Util.h"
#include "WorldSession.h"
class battlenet_account_commandscript : public CommandScript
@@ -48,13 +49,14 @@ public:
static std::vector accountCommandTable =
{
- { "create", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_CREATE, true, &HandleAccountCreateCommand, "" },
- { "gameaccountcreate", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_CREATE_GAME, true, &HandleGameAccountCreateCommand, "", },
- { "lock", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT, false, nullptr, "", accountLockCommandTable },
- { "set", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_SET, true, nullptr, "", accountSetCommandTable },
- { "password", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_PASSWORD, false, &HandleAccountPasswordCommand, "" },
- { "link", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_LINK, true, &HandleAccountLinkCommand, "", },
- { "unlink", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_UNLINK, true, &HandleAccountUnlinkCommand, "", },
+ { "create", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_CREATE, true, &HandleAccountCreateCommand, "" },
+ { "gameaccountcreate", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_CREATE_GAME, true, &HandleGameAccountCreateCommand, "", },
+ { "lock", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT, false, nullptr, "", accountLockCommandTable },
+ { "set", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_SET, true, nullptr, "", accountSetCommandTable },
+ { "password", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_PASSWORD, false, &HandleAccountPasswordCommand, "" },
+ { "link", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_LINK, true, &HandleAccountLinkCommand, "", },
+ { "unlink", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_UNLINK, true, &HandleAccountUnlinkCommand, "", },
+ { "listgameaccounts", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_LIST_GAME_ACCOUNTS, true, &HandleListGameAccountsCommand, "" }
};
static std::vector commandTable =
@@ -71,8 +73,6 @@ public:
if (!*args)
return false;
- std::string email;
-
///- %Parse the command line arguments
char* accountName = strtok((char*)args, " ");
char* password = strtok(nullptr, " ");
@@ -86,32 +86,44 @@ public:
return false;
}
- switch (Battlenet::AccountMgr::CreateBattlenetAccount(std::string(accountName), std::string(password)))
+ char* createGameAccountParam = strtok(nullptr, " ");
+ bool createGameAccount = true;
+ if (createGameAccountParam)
+ createGameAccount = StringToBool(createGameAccountParam);
+
+ std::string gameAccountName;
+ switch (Battlenet::AccountMgr::CreateBattlenetAccount(std::string(accountName), std::string(password), createGameAccount, &gameAccountName))
{
case AccountOpResult::AOR_OK:
- handler->PSendSysMessage(LANG_ACCOUNT_CREATED, accountName);
+ {
+ if (createGameAccount)
+ handler->PSendSysMessage(LANG_ACCOUNT_CREATED_BNET_WITH_GAME, accountName, gameAccountName.c_str());
+ else
+ handler->PSendSysMessage(LANG_ACCOUNT_CREATED_BNET, accountName);
+
if (handler->GetSession())
{
- TC_LOG_INFO("entities.player.character", "Battle.net account: %d (IP: %s) Character:[%s] (GUID: %u) created Account %s",
+ TC_LOG_INFO("entities.player.character", "Account: %u (IP: %s) Character:[%s] (%s) created Battle.net account %s%s%s",
handler->GetSession()->GetAccountId(), handler->GetSession()->GetRemoteAddress().c_str(),
- handler->GetSession()->GetPlayer()->GetName().c_str(), handler->GetSession()->GetPlayer()->GetGUID().GetCounter(),
- accountName);
+ handler->GetSession()->GetPlayer()->GetName().c_str(), handler->GetSession()->GetPlayer()->GetGUID().ToString().c_str(),
+ accountName, createGameAccount ? " with game account " : "", createGameAccount ? gameAccountName.c_str() : "");
}
break;
+ }
case AccountOpResult::AOR_NAME_TOO_LONG:
handler->SendSysMessage(LANG_ACCOUNT_NAME_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:
+ case AccountOpResult::AOR_NAME_ALREADY_EXIST:
+ handler->SendSysMessage(LANG_ACCOUNT_ALREADY_EXIST);
+ handler->SetSentErrorMessage(true);
return false;
+ default:
+ break;
}
return true;
@@ -224,12 +236,12 @@ public:
}
// 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)))
+ if (!Battlenet::AccountMgr::CheckPassword(handler->GetSession()->GetBattlenetAccountId(), 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()->GetBattlenetAccountId(), handler->GetSession()->GetRemoteAddress().c_str(),
handler->GetSession()->GetPlayer()->GetName().c_str(), handler->GetSession()->GetPlayer()->GetGUID().GetCounter());
return false;
}
@@ -412,38 +424,80 @@ public:
uint8 index = Battlenet::AccountMgr::GetMaxIndex(accountId) + 1;
std::string accountName = std::to_string(accountId) + '#' + std::to_string(uint32(index));
- switch (sAccountMgr->CreateAccount(accountName, "DUMMY", bnetAccountName, accountId, index))
+ // Generate random hex string for password, these accounts must not be logged on with GRUNT
+ BigNumber randPassword;
+ randPassword.SetRand(8 * 16);
+
+ switch (sAccountMgr->CreateAccount(accountName, ByteArrayToHexStr(randPassword.AsByteArray().get(), randPassword.GetNumBytes()), bnetAccountName, accountId, index))
{
- case AccountOpResult::AOR_OK:
- handler->PSendSysMessage(LANG_ACCOUNT_CREATED, accountName.c_str());
- if (handler->GetSession())
- {
- TC_LOG_INFO("entities.player.character", "Account: %u (IP: %s) Character:[%s] (%s) created Account %s (Email: '%s')",
- handler->GetSession()->GetAccountId(), handler->GetSession()->GetRemoteAddress().c_str(),
- handler->GetSession()->GetPlayer()->GetName().c_str(), handler->GetSession()->GetPlayer()->GetGUID().ToString().c_str(),
- accountName.c_str(), bnetAccountName.c_str());
- }
- break;
- case AccountOpResult::AOR_NAME_TOO_LONG:
- handler->SendSysMessage(LANG_ACCOUNT_NAME_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_DB_INTERNAL_ERROR:
- handler->PSendSysMessage(LANG_ACCOUNT_NOT_CREATED_SQL_ERROR, accountName.c_str());
- handler->SetSentErrorMessage(true);
- return false;
- default:
- handler->PSendSysMessage(LANG_ACCOUNT_NOT_CREATED, accountName.c_str());
- handler->SetSentErrorMessage(true);
- return false;
+ case AccountOpResult::AOR_OK:
+ handler->PSendSysMessage(LANG_ACCOUNT_CREATED, accountName.c_str());
+ if (handler->GetSession())
+ {
+ TC_LOG_INFO("entities.player.character", "Account: %u (IP: %s) Character:[%s] (%s) created Account %s (Email: '%s')",
+ handler->GetSession()->GetAccountId(), handler->GetSession()->GetRemoteAddress().c_str(),
+ handler->GetSession()->GetPlayer()->GetName().c_str(), handler->GetSession()->GetPlayer()->GetGUID().ToString().c_str(),
+ accountName.c_str(), bnetAccountName.c_str());
+ }
+ break;
+ case AccountOpResult::AOR_NAME_TOO_LONG:
+ handler->SendSysMessage(LANG_ACCOUNT_NAME_TOO_LONG);
+ handler->SetSentErrorMessage(true);
+ return false;
+ case AccountOpResult::AOR_PASS_TOO_LONG:
+ handler->SendSysMessage(LANG_ACCOUNT_PASS_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_DB_INTERNAL_ERROR:
+ handler->PSendSysMessage(LANG_ACCOUNT_NOT_CREATED_SQL_ERROR, accountName.c_str());
+ handler->SetSentErrorMessage(true);
+ return false;
+ default:
+ handler->PSendSysMessage(LANG_ACCOUNT_NOT_CREATED, accountName.c_str());
+ handler->SetSentErrorMessage(true);
+ return false;
}
return true;
}
+
+ static bool HandleListGameAccountsCommand(ChatHandler* handler, char const* args)
+ {
+ if (!*args)
+ return false;
+
+ char* battlenetAccountName = strtok((char*)args, " ");
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_GAME_ACCOUNT_LIST);
+ stmt->setString(0, battlenetAccountName);
+ if (PreparedQueryResult accountList = LoginDatabase.Query(stmt))
+ {
+ auto formatDisplayName = [](char const* name) -> std::string
+ {
+ if (char const* hashPos = strchr(name, '#'))
+ return std::string("WoW") + ++hashPos;
+ else
+ return name;
+ };
+
+ handler->SendSysMessage("----------------------------------------------------");
+ handler->SendSysMessage(LANG_ACCOUNT_BNET_LIST_HEADER);
+ handler->SendSysMessage("----------------------------------------------------");
+ do
+ {
+ Field* fields = accountList->Fetch();
+ handler->PSendSysMessage("| %10u | %-16.16s | %-16.16s |", fields[0].GetUInt32(), fields[1].GetCString(), formatDisplayName(fields[1].GetCString()).c_str());
+ } while (accountList->NextRow());
+ handler->SendSysMessage("----------------------------------------------------");
+ }
+ else
+ handler->PSendSysMessage(LANG_ACCOUNT_BNET_LIST_NO_ACCOUNTS, battlenetAccountName);
+
+ return true;
+ }
};
void AddSC_battlenet_account_commandscript()