diff --git a/sql/mangos.sql b/sql/mangos.sql index 53e11d79d..30c3353e3 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -24,7 +24,7 @@ CREATE TABLE `db_version` ( `version` varchar(120) default NULL, `creature_ai_version` varchar(120) default NULL, `cache_id` int(10) default '0', - `required_9883_01_mangos_scripts` bit(1) default NULL + `required_9886_02_mangos_command` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -632,6 +632,9 @@ INSERT INTO `command` VALUES ('list object',3,'Syntax: .list object #gameobject_id [#max_count]\r\n\r\nOutput gameobjects with gameobject id #gameobject_id found in world. Output gameobject guids and coordinates sorted by distance from character. Will be output maximum #max_count gameobject. If #max_count not provided use 10 as default value.'), ('list talents',3,'Syntax: .list talents\r\n\r\nShow list all really known (as learned spells) talent rank spells for selected player or self.'), ('loadscripts',3,'Syntax: .loadscripts $scriptlibraryname\r\n\r\nUnload current and load the script library $scriptlibraryname or reload current if $scriptlibraryname omitted, in case you changed it while the server was running.'), +('lookup account email',2,'Syntax: .lookup account email $emailpart [#limit] \r\n\r\n Searchs accounts, which email including $emailpart with optional parametr #limit of results. If #limit not provided expected 100.'), +('lookup account ip',2,'Syntax: lookup account ip $ippart [#limit] \r\n\r\n Searchs accounts, which last used ip inluding $ippart (textual) with optional parametr #$limit of results. If #limit not provided expected 100.'), +('lookup account name',2,'Syntax: .lookup account name $accountpart [#limit] \r\n\r\n Searchs accounts, which username including $accountpart with optional parametr #limit of results. If #limit not provided expected 100.'), ('lookup area',1,'Syntax: .lookup area $namepart\r\n\r\nLooks up an area by $namepart, and returns all matches with their area ID\'s.'), ('lookup creature',3,'Syntax: .lookup creature $namepart\r\n\r\nLooks up a creature by $namepart, and returns all matches with their creature ID\'s.'), ('lookup event',2,'Syntax: .lookup event $name\r\nAttempts to find the ID of the event with the provided $name.'), @@ -639,9 +642,9 @@ INSERT INTO `command` VALUES ('lookup item',3,'Syntax: .lookup item $itemname\r\n\r\nLooks up an item by $itemname, and returns all matches with their Item ID\'s.'), ('lookup itemset',3,'Syntax: .lookup itemset $itemname\r\n\r\nLooks up an item set by $itemname, and returns all matches with their Item set ID\'s.'), ('lookup object',3,'Syntax: .lookup object $objname\r\n\r\nLooks up an gameobject by $objname, and returns all matches with their Gameobject ID\'s.'), -('lookup player account',2,'Syntax: .lookup player account $account ($limit) \r\n\r\n Searchs players, which account username is $account with optional parametr $limit of results.'), -('lookup player ip',2,'Syntax: .lookup player ip $ip ($limit) \r\n\r\n Searchs players, which account ast_ip is $ip with optional parametr $limit of results.'), -('lookup player email',2,'Syntax: .lookup player email $email ($limit) \r\n\r\n Searchs players, which account email is $email with optional parametr $limit of results.'), +('lookup player account',2,'Syntax: .lookup player account $accountpart [#limit] \r\n\r\n Searchs players, which account username including $accountpart with optional parametr #limit of results. If #limit not provided expected 100.'), +('lookup player email',2,'Syntax: .lookup player email $emailpart [#limit] \r\n\r\n Searchs players, which account email including $emailpart with optional parametr #limit of results. If #limit not provided expected 100.'), +('lookup player ip',2,'Syntax: .lookup player ip $ippart [#limit] \r\n\r\n Searchs players, which account last used ip inluding $ippart (textual) with optional parametr #limit of results. If #limit not provided expected 100.'), ('lookup quest',3,'Syntax: .lookup quest $namepart\r\n\r\nLooks up a quest by $namepart, and returns all matches with their quest ID\'s.'), ('lookup skill',3,'Syntax: .lookup skill $$namepart\r\n\r\nLooks up a skill by $namepart, and returns all matches with their skill ID\'s.'), ('lookup spell',3,'Syntax: .lookup spell $namepart\r\n\r\nLooks up a spell by $namepart, and returns all matches with their spell ID\'s.'), @@ -3585,10 +3588,9 @@ INSERT INTO `mangos_string` VALUES (1007,'Account %s NOT created (probably sql file format was updated)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (1008,'Account %s NOT created (unknown error)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (1009,'Player %s (Guid: %u) Account %s (Id: %u) deleted.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), -(1010,'| Account | Character | IP | GM | Expansion |',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), -(1011,'| | %20s | || |',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), -(1012,'===========================================================================',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), -(1013,'|%15s| %20s | %15s |%4d| %9d |',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1010,'| ID | Account | Character | IP | GM | Expansion |',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1012,'========================================================================================',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1013,'| %10u |%15s| %20s | %15s |%4d| %9d |',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (1014,'No online players.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (1015,'Used not fully typed quit command, need type it fully (quit), or command used not in RA command line.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (1016, '| GUID | Name | Account | Delete Date |',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), @@ -3644,6 +3646,7 @@ INSERT INTO `mangos_string` VALUES (1139, '| GUID | Name | Race | Class | Level |',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (1140, '| %10u | %20s | %15s | %15s | %5u |',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (1141, '%u - |cffffffff|Hplayer:%s|h[%s]|h|r %s %s %u',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1142,'%u - %s (Online:%s IP:%s GM:%u Expansion:%u)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (1200,'You try to view cinemitic %u but it doesn\'t exist.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (1201,'You try to view movie %u but it doesn\'t exist.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); /*!40000 ALTER TABLE `mangos_string` ENABLE KEYS */; diff --git a/sql/updates/9886_01_mangos_mangos_string.sql b/sql/updates/9886_01_mangos_mangos_string.sql new file mode 100644 index 000000000..126aaf779 --- /dev/null +++ b/sql/updates/9886_01_mangos_mangos_string.sql @@ -0,0 +1,8 @@ +ALTER TABLE db_version CHANGE COLUMN required_9883_01_mangos_scripts required_9886_01_mangos_mangos_string bit; + +DELETE FROM mangos_string WHERE entry IN (1011,1010,1012,1013,1142); +INSERT INTO mangos_string VALUES +(1010,'| ID | Account | Character | IP | GM | Expansion |',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1012,'========================================================================================',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1013,'| %10u |%15s| %20s | %15s |%4d| %9d |',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1142,'%u - %s (Online:%s IP:%s GM:%u Expansion:%u)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); diff --git a/sql/updates/9886_02_mangos_command.sql b/sql/updates/9886_02_mangos_command.sql new file mode 100644 index 000000000..7d3c9c8de --- /dev/null +++ b/sql/updates/9886_02_mangos_command.sql @@ -0,0 +1,10 @@ +ALTER TABLE db_version CHANGE COLUMN required_9886_01_mangos_mangos_string required_9886_02_mangos_command bit; + +DELETE FROM command WHERE name IN('lookup account email','lookup account ip','lookup account name','lookup player account','lookup player ip','lookup player email'); +INSERT INTO command (name, security, help) VALUES +('lookup account email',2,'Syntax: .lookup account email $emailpart [#limit] \r\n\r\n Searchs accounts, which email including $emailpart with optional parametr #limit of results. If #limit not provided expected 100.'), +('lookup account ip',2,'Syntax: lookup account ip $ippart [#limit] \r\n\r\n Searchs accounts, which last used ip inluding $ippart (textual) with optional parametr #$limit of results. If #limit not provided expected 100.'), +('lookup account name',2,'Syntax: .lookup account name $accountpart [#limit] \r\n\r\n Searchs accounts, which username including $accountpart with optional parametr #limit of results. If #limit not provided expected 100.'), +('lookup player account',2,'Syntax: .lookup player account $accountpart [#limit] \r\n\r\n Searchs players, which account username including $accountpart with optional parametr #limit of results. If #limit not provided expected 100.'), +('lookup player email',2,'Syntax: .lookup player email $emailpart [#limit] \r\n\r\n Searchs players, which account email including $emailpart with optional parametr #limit of results. If #limit not provided expected 100.'), +('lookup player ip',2,'Syntax: .lookup player ip $ippart [#limit] \r\n\r\n Searchs players, which account last used ip inluding $ippart (textual) with optional parametr #limit of results. If #limit not provided expected 100.'); diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index e1244127b..f55e50d2a 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -60,6 +60,8 @@ pkgdata_DATA = \ 9854_01_mangos_spell_bonus_data.sql \ 9881_01_mangos_scripts.sql \ 9883_01_mangos_scripts.sql \ + 9886_01_mangos_mangos_string.sql \ + 9886_02_mangos_command.sql \ README ## Additional files to include when running 'make dist' @@ -100,4 +102,6 @@ EXTRA_DIST = \ 9854_01_mangos_spell_bonus_data.sql \ 9881_01_mangos_scripts.sql \ 9883_01_mangos_scripts.sql \ + 9886_01_mangos_mangos_string.sql \ + 9886_02_mangos_command.sql \ README diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp index 1047447c2..3aa0f330b 100644 --- a/src/game/Chat.cpp +++ b/src/game/Chat.cpp @@ -285,16 +285,25 @@ ChatCommand * ChatHandler::getCommandTable() { NULL, 0, false, NULL, "", NULL } }; + static ChatCommand lookupAccountCommandTable[] = + { + { "email", SEC_GAMEMASTER, true, &ChatHandler::HandleLookupAccountEmailCommand, "", NULL }, + { "ip", SEC_GAMEMASTER, true, &ChatHandler::HandleLookupAccountIpCommand, "", NULL }, + { "name", SEC_GAMEMASTER, true, &ChatHandler::HandleLookupAccountNameCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + static ChatCommand lookupPlayerCommandTable[] = { - { "ip", SEC_GAMEMASTER, true, &ChatHandler::HandleLookupPlayerIpCommand, "", NULL }, - { "account", SEC_GAMEMASTER, true, &ChatHandler::HandleLookupPlayerAccountCommand, "", NULL }, - { "email", SEC_GAMEMASTER, true, &ChatHandler::HandleLookupPlayerEmailCommand, "", NULL }, - { NULL, 0, false, NULL, "", NULL } + { "account", SEC_GAMEMASTER, true, &ChatHandler::HandleLookupPlayerAccountCommand, "", NULL }, + { "email", SEC_GAMEMASTER, true, &ChatHandler::HandleLookupPlayerEmailCommand, "", NULL }, + { "ip", SEC_GAMEMASTER, true, &ChatHandler::HandleLookupPlayerIpCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } }; static ChatCommand lookupCommandTable[] = { + { "account", SEC_GAMEMASTER, true, NULL, "", lookupAccountCommandTable }, { "area", SEC_MODERATOR, true, &ChatHandler::HandleLookupAreaCommand, "", NULL }, { "creature", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLookupCreatureCommand, "", NULL }, { "event", SEC_GAMEMASTER, true, &ChatHandler::HandleLookupEventCommand, "", NULL }, diff --git a/src/game/Chat.h b/src/game/Chat.h index 88c24e92f..288725daa 100644 --- a/src/game/Chat.h +++ b/src/game/Chat.h @@ -233,6 +233,9 @@ class ChatHandler bool HandleListObjectCommand(const char* args); bool HandleListTalentsCommand(const char * args); + bool HandleLookupAccountEmailCommand(const char* args); + bool HandleLookupAccountIpCommand(const char* args); + bool HandleLookupAccountNameCommand(const char* args); bool HandleLookupAreaCommand(const char* args); bool HandleLookupCreatureCommand(const char* args); bool HandleLookupEventCommand(const char* args); @@ -544,7 +547,9 @@ class ChatHandler // Utility methods for commands void ShowTicket(uint64 guid, char const* text, char const* time); - bool LookupPlayerSearchCommand(QueryResult* result, int32 limit); + bool ShowAccountListHelper(QueryResult* result, uint32* limit = NULL, bool title = true, bool error = true); + bool ShowPlayerListHelper(QueryResult* result, uint32* limit = NULL, bool title = true, bool error = true); + bool LookupPlayerSearchCommand(QueryResult* result, uint32* limit = NULL); bool HandleBanListHelper(QueryResult* result); bool HandleBanHelper(BanMode mode,char const* args); bool HandleBanInfoHelper(uint32 accountid, char const* accountname); diff --git a/src/game/Language.h b/src/game/Language.h index d845f3700..1fab0ec32 100644 --- a/src/game/Language.h +++ b/src/game/Language.h @@ -776,9 +776,9 @@ enum MangosStrings LANG_ACCOUNT_NOT_CREATED = 1008, LANG_CHARACTER_DELETED = 1009, LANG_ACCOUNT_LIST_HEADER = 1010, - LANG_ACCOUNT_LIST_ERROR = 1011, + // = 1011, not used LANG_ACCOUNT_LIST_BAR = 1012, - LANG_ACCOUNT_LIST_LINE = 1013, + LANG_ACCOUNT_LIST_LINE_CONSOLE = 1013, LANG_ACCOUNT_LIST_EMPTY = 1014, LANG_QUIT_WRONG_USE_ERROR = 1015, LANG_CHARACTER_DELETED_LIST_HEADER = 1016, @@ -833,11 +833,12 @@ enum MangosStrings LANG_LIST_TALENTS_TITLE = 1135, LANG_LIST_TALENTS_COUNT = 1136, LANG_GO_LIST_CHAT = 1137, - 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 + LANG_CHARACTERS_LIST_BAR = 1138, + LANG_CHARACTERS_LIST_HEADER = 1139, + LANG_CHARACTERS_LIST_LINE_CONSOLE = 1140, + LANG_CHARACTERS_LIST_LINE_CHAT = 1141, + LANG_ACCOUNT_LIST_LINE_CHAT = 1142, + // Room for more level 3 1143-1199 not used // Debug commands LANG_CINEMATIC_NOT_EXIST = 1200, diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp index 0f4beb3b1..ad9682fde 100644 --- a/src/game/Level2.cpp +++ b/src/game/Level2.cpp @@ -4092,6 +4092,112 @@ bool ChatHandler::HandleLearnAllRecipesCommand(const char* args) return true; } +bool ChatHandler::HandleLookupAccountEmailCommand(const char* args) +{ + + if (!*args) + return false; + + std::string email = strtok ((char*)args, " "); + char* limit_str = strtok (NULL, " "); + uint32 limit = limit_str ? atoi (limit_str) : 100; + + loginDatabase.escape_string (email); + // 0 1 2 3 4 + QueryResult *result = loginDatabase.PQuery("SELECT id, username, last_ip, gmlevel, expansion FROM account WHERE email "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'"), email.c_str ()); + + return ShowAccountListHelper(result,&limit); +} + +bool ChatHandler::HandleLookupAccountIpCommand(const char* args) +{ + + if (!*args) + return false; + + std::string ip = strtok ((char*)args, " "); + char* limit_str = strtok (NULL, " "); + uint32 limit = limit_str ? atoi (limit_str) : 100; + + loginDatabase.escape_string (ip); + + // 0 1 2 3 4 + QueryResult *result = loginDatabase.PQuery("SELECT id, username, last_ip, gmlevel, expansion FROM account WHERE last_ip "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'"), ip.c_str ()); + + return ShowAccountListHelper(result,&limit); +} + +bool ChatHandler::HandleLookupAccountNameCommand(const char* args) +{ + if (!*args) + return false; + + std::string account = strtok ((char*)args, " "); + char* limit_str = strtok (NULL, " "); + uint32 limit = limit_str ? atoi (limit_str) : 100; + + if (!AccountMgr::normalizeString (account)) + return false; + + loginDatabase.escape_string (account); + // 0 1 2 3 4 + QueryResult *result = loginDatabase.PQuery("SELECT id, username, last_ip, gmlevel, expansion FROM account WHERE username "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'"), account.c_str ()); + + return ShowAccountListHelper(result,&limit); +} + +bool ChatHandler::ShowAccountListHelper(QueryResult* result, uint32* limit, bool title, bool error) +{ + if (!result) + { + if (error) + SendSysMessage(LANG_ACCOUNT_LIST_EMPTY); + return true; + } + + ///- Display the list of account/characters online + if (!m_session && title) // not output header for online case + { + SendSysMessage(LANG_ACCOUNT_LIST_BAR); + SendSysMessage(LANG_ACCOUNT_LIST_HEADER); + SendSysMessage(LANG_ACCOUNT_LIST_BAR); + } + + ///- Circle through accounts + do + { + // check limit + if (limit) + { + if(*limit == 0) + break; + --*limit; + } + + Field *fields = result->Fetch(); + uint32 account = fields[0].GetUInt32(); + + WorldSession* session = sWorld.FindSession(account); + Player* player = session ? session->GetPlayer() : NULL; + char const* char_name = player ? player->GetName() : " - "; + + if(m_session) + PSendSysMessage(LANG_ACCOUNT_LIST_LINE_CHAT, + account,fields[1].GetString(),char_name,fields[2].GetString(),fields[3].GetUInt32(),fields[4].GetUInt32()); + else + PSendSysMessage(LANG_ACCOUNT_LIST_LINE_CONSOLE, + account,fields[1].GetString(),char_name,fields[2].GetString(),fields[3].GetUInt32(),fields[4].GetUInt32()); + + }while(result->NextRow()); + + delete result; + + if (!m_session) // not output header for online case + SendSysMessage(LANG_ACCOUNT_LIST_BAR); + + return true; +} + bool ChatHandler::HandleLookupPlayerIpCommand(const char* args) { @@ -4100,13 +4206,13 @@ bool ChatHandler::HandleLookupPlayerIpCommand(const char* args) std::string ip = strtok ((char*)args, " "); char* limit_str = strtok (NULL, " "); - int32 limit = limit_str ? atoi (limit_str) : -1; + uint32 limit = limit_str ? atoi (limit_str) : 100; loginDatabase.escape_string (ip); - QueryResult* result = loginDatabase.PQuery ("SELECT id,username FROM account WHERE last_ip = '%s'", ip.c_str ()); + QueryResult* result = loginDatabase.PQuery ("SELECT id,username FROM account WHERE last_ip "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'"), ip.c_str ()); - return LookupPlayerSearchCommand (result,limit); + return LookupPlayerSearchCommand (result,&limit); } bool ChatHandler::HandleLookupPlayerAccountCommand(const char* args) @@ -4116,16 +4222,16 @@ bool ChatHandler::HandleLookupPlayerAccountCommand(const char* args) std::string account = strtok ((char*)args, " "); char* limit_str = strtok (NULL, " "); - int32 limit = limit_str ? atoi (limit_str) : -1; + uint32 limit = limit_str ? atoi (limit_str) : 100; if (!AccountMgr::normalizeString (account)) return false; loginDatabase.escape_string (account); - QueryResult* result = loginDatabase.PQuery ("SELECT id,username FROM account WHERE username = '%s'", account.c_str ()); + QueryResult* result = loginDatabase.PQuery ("SELECT id,username FROM account WHERE username "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'"), account.c_str ()); - return LookupPlayerSearchCommand (result,limit); + return LookupPlayerSearchCommand (result,&limit); } bool ChatHandler::HandleLookupPlayerEmailCommand(const char* args) @@ -4136,57 +4242,57 @@ bool ChatHandler::HandleLookupPlayerEmailCommand(const char* args) std::string email = strtok ((char*)args, " "); char* limit_str = strtok (NULL, " "); - int32 limit = limit_str ? atoi (limit_str) : -1; + uint32 limit = limit_str ? atoi (limit_str) : 100; loginDatabase.escape_string (email); - QueryResult* result = loginDatabase.PQuery ("SELECT id,username FROM account WHERE email = '%s'", email.c_str ()); + QueryResult* result = loginDatabase.PQuery ("SELECT id,username FROM account WHERE email "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'"), email.c_str ()); - return LookupPlayerSearchCommand (result,limit); + return LookupPlayerSearchCommand (result,&limit); } -bool ChatHandler::LookupPlayerSearchCommand(QueryResult* result, int32 limit) +bool ChatHandler::LookupPlayerSearchCommand(QueryResult* result, uint32* limit) { - if(!result) + if (!result) { PSendSysMessage(LANG_NO_PLAYERS_FOUND); SetSentErrorMessage(true); return false; } - int i =0; + uint32 limit_original = limit ? *limit : 100; + + uint32 limit_local = limit_original; + + if (!limit) + limit = &limit_local; + do { + if (limit && *limit == 0) + break; + Field* fields = result->Fetch(); uint32 acc_id = fields[0].GetUInt32(); std::string acc_name = fields[1].GetCppString(); - QueryResult* chars = CharacterDatabase.PQuery("SELECT guid,name FROM characters WHERE account = '%u'", acc_id); - if(chars) + ///- Get the characters for account id + QueryResult *chars = CharacterDatabase.PQuery( "SELECT guid, name, race, class, level FROM characters WHERE account = %u", acc_id); + if (chars) { - PSendSysMessage(LANG_LOOKUP_PLAYER_ACCOUNT,acc_name.c_str(),acc_id); - - uint64 guid = 0; - std::string name; - - do + if (chars->GetRowCount()) { - Field* charfields = chars->Fetch(); - guid = charfields[0].GetUInt64(); - name = charfields[1].GetCppString(); - - PSendSysMessage(LANG_LOOKUP_PLAYER_CHARACTER,name.c_str(),guid); - ++i; - - } while( chars->NextRow() && ( limit == -1 || i < limit ) ); - - delete chars; + PSendSysMessage(LANG_LOOKUP_PLAYER_ACCOUNT,acc_name.c_str(),acc_id); + ShowPlayerListHelper(chars,limit,true,false); + } + else + delete chars; } } while(result->NextRow()); delete result; - if(i==0) // empty accounts only + if (*limit==limit_original) // empty accounts only { PSendSysMessage(LANG_NO_PLAYERS_FOUND); SetSentErrorMessage(true); diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index e9e77ff1c..efb73972e 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -6136,24 +6136,23 @@ bool ChatHandler::HandleServerSetMotdCommand(const char* args) return true; } -/// Output list of character for account -bool ChatHandler::HandleAccountCharactersCommand(const char* args) +bool ChatHandler::ShowPlayerListHelper(QueryResult* result, uint32* limit, bool title, bool error) { - ///- 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) + if (!result) { - SendSysMessage(LANG_ACCOUNT_CHARACTERS_LIST_BAR); - SendSysMessage(LANG_ACCOUNT_CHARACTERS_LIST_HEADER); - SendSysMessage(LANG_ACCOUNT_CHARACTERS_LIST_BAR); + if (error) + { + PSendSysMessage(LANG_NO_PLAYERS_FOUND); + SetSentErrorMessage(true); + } + return false; + } + + if (!m_session && title) + { + SendSysMessage(LANG_CHARACTERS_LIST_BAR); + SendSysMessage(LANG_CHARACTERS_LIST_HEADER); + SendSysMessage(LANG_CHARACTERS_LIST_BAR); } if (result) @@ -6161,6 +6160,14 @@ bool ChatHandler::HandleAccountCharactersCommand(const char* args) ///- Circle through them. Display username and GM level do { + // check limit + if (limit) + { + if(*limit == 0) + break; + --*limit; + } + Field *fields = result->Fetch(); uint32 guid = fields[0].GetUInt32(); std::string name = fields[1].GetCppString(); @@ -6175,9 +6182,9 @@ bool ChatHandler::HandleAccountCharactersCommand(const char* args) 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); + PSendSysMessage(LANG_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); + PSendSysMessage(LANG_CHARACTERS_LIST_LINE_CHAT, guid, name.c_str(), name.c_str(), race_name, class_name, level); }while( result->NextRow() ); @@ -6185,11 +6192,28 @@ bool ChatHandler::HandleAccountCharactersCommand(const char* args) } if (!m_session) - SendSysMessage(LANG_ACCOUNT_CHARACTERS_LIST_BAR); + SendSysMessage(LANG_CHARACTERS_LIST_BAR); 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); + + return ShowPlayerListHelper(result); +} + /// Set/Unset the expansion level for an account bool ChatHandler::HandleAccountSetAddonCommand(const char* args) { diff --git a/src/mangosd/CliRunnable.cpp b/src/mangosd/CliRunnable.cpp index d93b3419d..1f11037e7 100644 --- a/src/mangosd/CliRunnable.cpp +++ b/src/mangosd/CliRunnable.cpp @@ -476,50 +476,16 @@ bool ChatHandler::HandleServerExitCommand(const char* /*args*/) } /// Display info on users currently in the realm -bool ChatHandler::HandleAccountOnlineListCommand(const char* /*args*/) +bool ChatHandler::HandleAccountOnlineListCommand(const char* args) { + char* limit_str = *args ? strtok((char*)args, " ") : NULL; + uint32 limit = limit_str ? atoi (limit_str) : 100; + ///- Get the list of accounts ID logged to the realm - QueryResult *resultDB = CharacterDatabase.Query("SELECT name,account FROM characters WHERE online > 0"); - if (!resultDB) - { - SendSysMessage(LANG_ACCOUNT_LIST_EMPTY); - return true; - } + // 0 1 2 3 4 + QueryResult *result = loginDatabase.PQuery("SELECT id, username, last_ip, gmlevel, expansion FROM account WHERE realm = %u", realmID); - ///- Display the list of account/characters online - SendSysMessage(LANG_ACCOUNT_LIST_BAR); - SendSysMessage(LANG_ACCOUNT_LIST_HEADER); - SendSysMessage(LANG_ACCOUNT_LIST_BAR); - - ///- Circle through accounts - do - { - Field *fieldsDB = resultDB->Fetch(); - std::string name = fieldsDB[0].GetCppString(); - uint32 account = fieldsDB[1].GetUInt32(); - - ///- Get the username, last IP and GM level of each account - // No SQL injection. account is uint32. - // 0 1 2 3 - QueryResult *resultLogin = loginDatabase.PQuery("SELECT username, last_ip, gmlevel, expansion FROM account WHERE id = '%u'",account); - - if(resultLogin) - { - Field *fieldsLogin = resultLogin->Fetch(); - PSendSysMessage(LANG_ACCOUNT_LIST_LINE, - fieldsLogin[0].GetString(),name.c_str(),fieldsLogin[1].GetString(),fieldsLogin[2].GetUInt32(),fieldsLogin[3].GetUInt32()); - - delete resultLogin; - } - else - PSendSysMessage(LANG_ACCOUNT_LIST_ERROR,name.c_str()); - - }while(resultDB->NextRow()); - - delete resultDB; - - SendSysMessage(LANG_ACCOUNT_LIST_BAR); - return true; + return ShowAccountListHelper(result,&limit); } /// Create an account diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 461a473d9..da1bb2af7 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "9885" + #define REVISION_NR "9886" #endif // __REVISION_NR_H__ diff --git a/src/shared/revision_sql.h b/src/shared/revision_sql.h index 1dfd48da9..49604d255 100644 --- a/src/shared/revision_sql.h +++ b/src/shared/revision_sql.h @@ -1,6 +1,6 @@ #ifndef __REVISION_SQL_H__ #define __REVISION_SQL_H__ #define REVISION_DB_CHARACTERS "required_9849_01_characters_saved_variables" - #define REVISION_DB_MANGOS "required_9883_01_mangos_scripts" + #define REVISION_DB_MANGOS "required_9886_02_mangos_command" #define REVISION_DB_REALMD "required_9748_01_realmd_realmlist" #endif // __REVISION_SQL_H__