[9794] Implement ".account characters" command

Console/chat command output characters list for specific account.
This commit is contained in:
VladimirMangos 2010-04-26 06:55:16 +04:00
parent 26cbb01556
commit 7ee25008d3
13 changed files with 210 additions and 173 deletions

View file

@ -72,6 +72,7 @@ ChatCommand * ChatHandler::getCommandTable()
static ChatCommand accountCommandTable[] =
{
{ "characters", SEC_CONSOLE, true, &ChatHandler::HandleAccountCharactersCommand, "", NULL },
{ "create", SEC_CONSOLE, true, &ChatHandler::HandleAccountCreateCommand, "", NULL },
{ "delete", SEC_CONSOLE, true, &ChatHandler::HandleAccountDeleteCommand, "", NULL },
{ "onlinelist", SEC_CONSOLE, true, &ChatHandler::HandleAccountOnlineListCommand, "", NULL },
@ -2248,6 +2249,83 @@ char* ChatHandler::extractQuotedArg( char* args )
}
}
uint32 ChatHandler::extractAccountId(char* args, std::string* accountName /*= NULL*/, Player** targetIfNullArg /*= NULL*/)
{
uint32 account_id = 0;
///- Get the account name from the command line
char* account_str = args ? strtok (args," ") : NULL;
if (!account_str)
{
if (!targetIfNullArg)
return 0;
/// only target player different from self allowed (if targetPlayer!=NULL then not console)
Player* targetPlayer = getSelectedPlayer();
if (!targetPlayer)
return 0;
account_id = targetPlayer->GetSession()->GetAccountId();
if (accountName)
sAccountMgr.GetName(account_id, *accountName);
if (targetIfNullArg)
*targetIfNullArg = targetPlayer;
return account_id;
}
std::string account_name;
if (isNumeric(account_str))
{
long id = atol(account_str);
if (id <= 0 || ((unsigned long)id) >= std::numeric_limits<uint32>::max())
{
PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_str);
SetSentErrorMessage(true);
return 0;
}
account_id = uint32(id);
if (!sAccountMgr.GetName(account_id, account_name))
{
PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_str);
SetSentErrorMessage(true);
return 0;
}
}
else
{
account_name = account_str;
if (!AccountMgr::normalizeString(account_name))
{
PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
SetSentErrorMessage(true);
return 0;
}
account_id = sAccountMgr.GetId(account_name);
if (!account_id)
{
PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
SetSentErrorMessage(true);
return 0;
}
}
if (accountName)
*accountName = account_name;
if (targetIfNullArg)
*targetIfNullArg = NULL;
return account_id;
}
bool ChatHandler::needReportToTarget(Player* chr) const
{
Player* pl = m_session->GetPlayer();

View file

@ -99,6 +99,7 @@ class ChatHandler
ChatCommand* getCommandTable();
bool HandleAccountCommand(const char* args);
bool HandleAccountCharactersCommand(const char* args);
bool HandleAccountCreateCommand(const char* args);
bool HandleAccountDeleteCommand(const char* args);
bool HandleAccountLockCommand(const char* args);
@ -537,6 +538,8 @@ class ChatHandler
std::string playerLink(std::string const& name) const { return m_session ? "|cffffffff|Hplayer:"+name+"|h["+name+"]|h|r" : name; }
std::string GetNameLink(Player* chr) const { return playerLink(chr->GetName()); }
uint32 extractAccountId(char* args, std::string* accountName = NULL, Player** targetIfNullArg = NULL);
GameObject* GetObjectGlobalyWithGuidOrNearWithDbGuid(uint32 lowguid,uint32 entry);
// Utility methods for commands

View file

@ -635,9 +635,9 @@ struct ChrClassesEntry
uint32 ClassID; // 0
//uint32 flags; // 1, unused
uint32 powerType; // 2
// 3-4, unused
//char* name[16]; // 5-20 unused
// 21 string flag, unused
// 3, unused
char const* name[16]; // 4-19 unused
// 20 string flag, unused
//char* nameFemale[16]; // 21-36 unused, if different from base (male) case
// 37 string flag, unused
//char* nameNeutralGender[16]; // 38-53 unused, if different from base (male) case

View file

@ -32,7 +32,7 @@ const char CharStartOutfitEntryfmt[]="diiiiiiiiiiiiiiiiiiiiiiiiixxxxxxxxxxxxxxxx
const char CharTitlesEntryfmt[]="nxssssssssssssssssxxxxxxxxxxxxxxxxxxi";
const char ChatChannelsEntryfmt[]="iixssssssssssssssssxxxxxxxxxxxxxxxxxx";
// ChatChannelsEntryfmt, index not used (more compact store)
const char ChrClassesEntryfmt[]="nxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixii";
const char ChrClassesEntryfmt[]="nxixssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixii";
const char ChrRacesEntryfmt[]="nxixiixixxxxixssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxi";
const char CinematicSequencesEntryfmt[]="nxxxxxxxxx";
const char CreatureDisplayInfofmt[]="nxxxfxxxxxxxxxxx";

View file

@ -833,7 +833,11 @@ enum MangosStrings
LANG_LIST_TALENTS_TITLE = 1135,
LANG_LIST_TALENTS_COUNT = 1136,
LANG_GO_LIST_CHAT = 1137,
// Room for more level 3 1138-1199 not used
LANG_ACCOUNT_CHARACTERS_LIST_BAR = 1138,
LANG_ACCOUNT_CHARACTERS_LIST_HEADER = 1139,
LANG_ACCOUNT_CHARACTERS_LIST_LINE_CONSOLE = 1140,
LANG_ACCOUNT_CHARACTERS_LIST_LINE_CHAT = 1141,
// Room for more level 3 1142-1199 not used
// Debug commands
LANG_CINEMATIC_NOT_EXIST = 1200,

View file

@ -901,52 +901,20 @@ bool ChatHandler::HandleLoadScriptsCommand(const char* args)
bool ChatHandler::HandleAccountSetGmLevelCommand(const char* args)
{
char* arg1 = strtok((char*)args, " ");
if( !arg1 )
return false;
char* arg1;
char* arg2;
/// must be NULL if targeted syntax and must be not nULL if not targeted
char* arg2 = strtok(NULL, " ");
extractOptFirstArg((char*)args, &arg1, &arg2);
std::string targetAccountName;
uint32 targetAccountId = 0;
Player* targetPlayer = NULL;
uint32 targetAccountId = extractAccountId(arg1,&targetAccountName,&targetPlayer);
if (!targetAccountId)
return false;
/// only target player different from self allowed (if targetPlayer!=NULL then not console)
Player* targetPlayer = getSelectedPlayer();
if(targetPlayer && m_session->GetPlayer()!=targetPlayer)
{
/// wrong command syntax or unexpected targeting
if(arg2)
return false;
/// security level expected in arg2 after this if.
arg2 = arg1;
targetAccountId = targetPlayer->GetSession()->GetAccountId();
sAccountMgr.GetName(targetAccountId, targetAccountName);
}
else
{
/// wrong command syntax (second arg expected)
if(!arg2)
return false;
targetAccountName = arg1;
if (!AccountMgr::normalizeString(targetAccountName))
{
PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,targetAccountName.c_str());
SetSentErrorMessage(true);
return false;
}
targetAccountId = sAccountMgr.GetId(targetAccountName);
if(!targetAccountId)
{
PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,targetAccountName.c_str());
SetSentErrorMessage(true);
return false;
}
}
/// only target player different from self allowed
if (GetAccountId() == targetAccountId)
return false;
int32 gm = (int32)atoi(arg2);
if ( gm < SEC_PLAYER || gm > SEC_ADMINISTRATOR )
@ -970,8 +938,7 @@ bool ChatHandler::HandleAccountSetGmLevelCommand(const char* args)
return false;
}
// This will prevent self apply by self target or no target
if(targetPlayer && m_session->GetPlayer()!=targetPlayer)
if (targetPlayer)
{
ChatHandler(targetPlayer).PSendSysMessage(LANG_YOURS_SECURITY_CHANGED,GetNameLink().c_str(), gm);
targetPlayer->GetSession()->SetSecurity(AccountTypes(gm));
@ -990,29 +957,16 @@ bool ChatHandler::HandleAccountSetPasswordCommand(const char* args)
return false;
///- Get the command line arguments
char *szAccount = strtok ((char*)args," ");
std::string account_name;
uint32 targetAccountId = extractAccountId((char*)args, &account_name);
if (!targetAccountId)
return false;
char *szPassword1 = strtok (NULL," ");
char *szPassword2 = strtok (NULL," ");
if (!szAccount||!szPassword1 || !szPassword2)
if (!szPassword1 || !szPassword2)
return false;
std::string account_name = szAccount;
if (!AccountMgr::normalizeString(account_name))
{
PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
SetSentErrorMessage(true);
return false;
}
uint32 targetAccountId = sAccountMgr.GetId(account_name);
if (!targetAccountId)
{
PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
SetSentErrorMessage(true);
return false;
}
/// can set password only for target with less security
/// This is also reject self apply in fact
if(HasLowerSecurityAccount (NULL,targetAccountId,true))
@ -5148,24 +5102,10 @@ bool ChatHandler::HandleBanInfoAccountCommand(const char* args)
if (!*args)
return false;
char* cname = strtok((char*)args, "");
if (!cname)
return false;
std::string account_name = cname;
if (!AccountMgr::normalizeString(account_name))
{
PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
SetSentErrorMessage(true);
return false;
}
uint32 accountid = sAccountMgr.GetId(account_name);
std::string account_name;
uint32 accountid = extractAccountId((char*)args, &account_name);
if (!accountid)
{
PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
return true;
}
return false;
return HandleBanInfoHelper(accountid,account_name.c_str());
}
@ -5508,43 +5448,22 @@ bool ChatHandler::HandlePDumpLoadCommand(const char *args)
if (!*args)
return false;
char * file = strtok((char*)args, " ");
char* file = strtok((char*)args, " ");
if (!file)
return false;
char * account = strtok(NULL, " ");
char* account = strtok(NULL, " ");
if (!account)
return false;
std::string account_name = account;
if (!AccountMgr::normalizeString(account_name))
{
PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
SetSentErrorMessage(true);
return false;
}
char* name_str = strtok(NULL, " ");
uint32 account_id = sAccountMgr.GetId(account_name);
std::string account_name;
uint32 account_id = extractAccountId(account, &account_name);
if (!account_id)
{
account_id = atoi(account); // use original string
if (!account_id)
{
PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
SetSentErrorMessage(true);
return false;
}
}
if (!sAccountMgr.GetName(account_id,account_name))
{
PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
SetSentErrorMessage(true);
return false;
}
char* guid_str = NULL;
char* name_str = strtok(NULL, " ");
std::string name;
if (name_str)
@ -6217,49 +6136,73 @@ bool ChatHandler::HandleServerSetMotdCommand(const char* args)
return true;
}
/// Output list of character for account
bool ChatHandler::HandleAccountCharactersCommand(const char* args)
{
///- Get the command line arguments
std::string account_name;
Player* target = NULL; // only for triggering use targeted player account
uint32 account_id = extractAccountId((char*)args, &account_name, &target);
if (!account_id )
return false;
///- Get the characters for account id
QueryResult *result = CharacterDatabase.PQuery( "SELECT guid, name, race, class, level FROM characters WHERE account = %u", account_id);
if (!m_session)
{
SendSysMessage(LANG_ACCOUNT_CHARACTERS_LIST_BAR);
SendSysMessage(LANG_ACCOUNT_CHARACTERS_LIST_HEADER);
SendSysMessage(LANG_ACCOUNT_CHARACTERS_LIST_BAR);
}
if (result)
{
///- Circle through them. Display username and GM level
do
{
Field *fields = result->Fetch();
uint32 guid = fields[0].GetUInt32();
std::string name = fields[1].GetCppString();
uint8 race = fields[2].GetUInt8();
uint8 class_ = fields[3].GetUInt8();
uint32 level = fields[4].GetUInt32();
ChrRacesEntry const* raceEntry = sChrRacesStore.LookupEntry(race);
ChrClassesEntry const* classEntry = sChrClassesStore.LookupEntry(class_);
char const* race_name = raceEntry ? raceEntry->name[GetSessionDbcLocale()] : "<?>";
char const* class_name = classEntry ? classEntry->name[GetSessionDbcLocale()] : "<?>";
if (!m_session)
PSendSysMessage(LANG_ACCOUNT_CHARACTERS_LIST_LINE_CONSOLE, guid, name.c_str(), race_name, class_name, level);
else
PSendSysMessage(LANG_ACCOUNT_CHARACTERS_LIST_LINE_CHAT, guid, name.c_str(), name.c_str(), race_name, class_name, level);
}while( result->NextRow() );
delete result;
}
if (!m_session)
SendSysMessage(LANG_ACCOUNT_CHARACTERS_LIST_BAR);
return true;
}
/// Set/Unset the expansion level for an account
bool ChatHandler::HandleAccountSetAddonCommand(const char* args)
{
///- Get the command line arguments
char *szAcc = strtok((char*)args," ");
char *szExp = strtok(NULL," ");
char* arg1;
char* arg2;
if(!szAcc)
return false;
extractOptFirstArg((char*)args, &arg1, &arg2);
std::string account_name;
uint32 account_id;
if (!szExp)
{
Player* player = getSelectedPlayer();
if (!player)
return false;
account_id = player->GetSession()->GetAccountId();
sAccountMgr.GetName(account_id,account_name);
szExp = szAcc;
}
else
{
///- Convert Account name to Upper Format
account_name = szAcc;
if (!AccountMgr::normalizeString(account_name))
{
PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
SetSentErrorMessage(true);
return false;
}
account_id = sAccountMgr.GetId(account_name);
if (!account_id)
{
PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
SetSentErrorMessage(true);
return false;
}
}
uint32 account_id = extractAccountId(arg1, &account_name);
if (!account_id )
return false;
// Let set addon state only for lesser (strong) security level
// or to self account
@ -6267,8 +6210,8 @@ bool ChatHandler::HandleAccountSetAddonCommand(const char* args)
HasLowerSecurityAccount (NULL,account_id,true))
return false;
int lev=atoi(szExp); //get int anyway (0 if error)
if(lev < 0)
int lev=atoi(arg2); //get int anyway (0 if error)
if (lev < 0)
return false;
// No SQL injection

View file

@ -64,26 +64,10 @@ bool ChatHandler::HandleAccountDeleteCommand(const char* args)
if (!*args)
return false;
///- Get the account name from the command line
char *account_name_str=strtok ((char*)args," ");
if (!account_name_str)
return false;
std::string account_name = account_name_str;
if (!AccountMgr::normalizeString(account_name))
{
PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
SetSentErrorMessage(true);
return false;
}
uint32 account_id = sAccountMgr.GetId(account_name);
std::string account_name;
uint32 account_id = extractAccountId((char*)args,&account_name);
if (!account_id)
{
PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
SetSentErrorMessage(true);
return false;
}
/// Commands not recommended call from chat, but support anyway
/// can delete only for account with less security

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "9793"
#define REVISION_NR "9794"
#endif // __REVISION_NR_H__

View file

@ -1,6 +1,6 @@
#ifndef __REVISION_SQL_H__
#define __REVISION_SQL_H__
#define REVISION_DB_CHARACTERS "required_9767_03_characters_characters"
#define REVISION_DB_MANGOS "required_9768_01_mangos_command"
#define REVISION_DB_MANGOS "required_9794_02_mangos_command"
#define REVISION_DB_REALMD "required_9748_01_realmd_realmlist"
#endif // __REVISION_SQL_H__