diff options
Diffstat (limited to 'src/trinitycore/CliRunnable.cpp')
-rw-r--r-- | src/trinitycore/CliRunnable.cpp | 1177 |
1 files changed, 132 insertions, 1045 deletions
diff --git a/src/trinitycore/CliRunnable.cpp b/src/trinitycore/CliRunnable.cpp index 33544435e3b..9c464fde9ef 100644 --- a/src/trinitycore/CliRunnable.cpp +++ b/src/trinitycore/CliRunnable.cpp @@ -27,7 +27,6 @@ #include "Log.h" #include "World.h" #include "ScriptCalls.h" -#include "GlobalEvents.h" #include "ObjectMgr.h" #include "WorldSession.h" #include "SystemConfig.h" @@ -36,254 +35,109 @@ #include "AccountMgr.h" #include "CliRunnable.h" #include "MapManager.h" -#include "PlayerDump.h" #include "Player.h" +#include "Chat.h" -//CliCommand and CliCommandHolder are defined in World.h to avoid cyclic deps - -//func prototypes must be defined - -void CliHelp(char*,pPrintf); -void CliInfo(char*,pPrintf); -void CliBan(char*,pPrintf); -void CliBanList(char*,pPrintf); -void CliRemoveBan(char*,pPrintf); -void CliSetGM(char*,pPrintf); -void CliListGM(char*,pPrintf); -void CliVersion(char*,pPrintf); -void CliExit(char*,pPrintf); -void CliIdleRestart(char*,pPrintf zprintf); -void CliRestart(char*,pPrintf zprintf); -void CliIdleShutdown(char*,pPrintf zprintf); -void CliShutdown(char*,pPrintf zprintf); -void CliBroadcast(char*,pPrintf); -void CliCreate(char*,pPrintf); -void CliDelete(char*,pPrintf); -void CliCharDelete(char *,pPrintf); -void CliLoadScripts(char*,pPrintf); -void CliKick(char*,pPrintf); -void CliTele(char*,pPrintf); -void CliMotd(char*,pPrintf); -void CliCorpses(char*,pPrintf); -void CliSetLogLevel(char*,pPrintf); -void CliUpTime(char*,pPrintf); -void CliSetAddon(char*,pPrintf); -void CliWritePlayerDump(char*,pPrintf); -void CliLoadPlayerDump(char*,pPrintf); -void CliSave(char*,pPrintf); -void CliSend(char*,pPrintf); -void CliPLimit(char*,pPrintf); -void CliSetPassword(char*,pPrintf); -/// Table of known commands -const CliCommand Commands[]= +void utf8print(const char* str) { - {"help", & CliHelp,"Display this help message"}, - {"broadcast", & CliBroadcast,"Announce in-game message"}, - {"create", & CliCreate,"Create account"}, - {"delete", & CliDelete,"Delete account and characters"}, - {"chardelete", & CliCharDelete,"Delete character"}, - {"info", & CliInfo,"Display Server infomation"}, - {"uptime", & CliUpTime, "Displays the server uptime"}, - {"motd", & CliMotd,"Change or display motd"}, - {"kick", & CliKick,"Kick user"}, - {"ban", & CliBan,"Ban account|ip"}, - {"listbans", & CliBanList,"List bans"}, - {"unban", & CliRemoveBan,"Remove ban from account|ip"}, - {"setgm", & CliSetGM,"Edit user privileges"}, - {"setpass", & CliSetPassword,"Set password for account"}, - {"setaddon", & CliSetAddon,"Set user expansion addon level allowed"}, - {"listgm", & CliListGM,"Display user privileges"}, - {"loadscripts", & CliLoadScripts,"Load script library"}, - {"setloglevel", & CliSetLogLevel,"Set Log Level"}, - {"corpses", & CliCorpses,"Manually call corpses erase global even code"}, - {"version", & CliVersion,"Display server version"}, - {"idlerestart", & CliIdleRestart,"Restart server with some delay when there are no active connections remaining"}, - {"restart", & CliRestart,"Restart server with some delay"}, - {"idleshutdown", & CliIdleShutdown,"Shutdown server with some delay when there are no active connections remaining"}, - {"shutdown", & CliShutdown,"Shutdown server with some delay"}, - {"exit", & CliExit,"Shutdown server NOW"}, - {"writepdump", &CliWritePlayerDump,"Write a player dump to a file"}, - {"loadpdump", &CliLoadPlayerDump,"Load a player dump from a file"}, - {"saveall", &CliSave,"Save all players"}, - {"send", &CliSend,"Send message to a player"}, - {"tele", &CliTele,"Teleport player to location"}, - {"plimit", &CliPLimit,"Show or set player login limitations"} -}; -/// \todo Need some pragma pack? Else explain why in a comment. -#define CliTotalCmds sizeof(Commands)/sizeof(CliCommand) - #if PLATFORM == PLATFORM_WINDOWS -int utf8printf(const char* str,...) -{ - UTF8PRINTF(stdout,str,1); - return 0; -} #define UTF8ZPRINTF utf8printf + wchar_t wtemp_buf[6000]; + size_t wtemp_len = 6000-1; + if(!Utf8toWStr(str,strlen(str),wtemp_buf,wtemp_len)) + return; + + char temp_buf[6000]; + CharToOemBuffW(&wtemp_buf[0],&temp_buf[0],wtemp_len+1); + printf(temp_buf); #else -#define UTF8ZPRINTF printf + printf(str); #endif +} -/// Create a character dump file -void CliWritePlayerDump(char*command,pPrintf zprintf) +/// Delete a user account and all associated characters in this realm +/// \todo This function has to be enhanced to respect the login/realm split (delete char, delete account chars in realm, delete account chars in realm then delete account +bool ChatHandler::HandleAccountDeleteCommand(const char* args) { - char * file = strtok(command, " "); - char * p2 = strtok(NULL, " "); - if(!file || !p2) - { - zprintf("Syntax is: writepdump $filename $playerNameOrGUID\r\n"); - return; - } - - std::string name; - if(!consoleToUtf8(p2,name)) // convert from console encoding to utf8 - return; - - if(!normalizePlayerName(name)) - { - zprintf("Syntax is: writepdump $filename $playerNameOrGUID\r\n"); - return; - } - - uint32 guid = objmgr.GetPlayerGUIDByName(name); - if(!guid) - guid = atoi(p2); - - if(!guid) - { - zprintf("Syntax is: writepdump $filename $playerNameOrGUID\r\n"); - return; - } + if(!*args) + return false; - PlayerDumpWriter().WriteDump(file, guid); -} + ///- Get the account name from the command line + char *account_name_str=strtok ((char*)args," "); + if (!account_name_str) + return false; -/// Load a character from a dump file -void CliLoadPlayerDump(char*command,pPrintf zprintf) -{ - char * file = strtok(command, " "); - char * acc = strtok(NULL, " "); - if (!file ||!acc) + std::string account_name = account_name_str; + if(!AccountMgr::normilizeString(account_name)) { - zprintf("Syntax is: loadpdump $filename $account ($newname) ($newguid)\r\n"); - return; + PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); + SetSentErrorMessage(true); + return false; } - uint32 account_id = accmgr.GetId(acc); + uint32 account_id = accmgr.GetId(account_name); if(!account_id) { - account_id = atoi(acc); - if(account_id) - { - std::string acc_name; - if(!accmgr.GetName(account_id,acc_name)) - { - zprintf("Failed to load the character! Account not exist.\r\n"); - return; - } - } - else - { - zprintf("Failed to load the character! Account not exist.\r\n"); - return; - } + PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); + SetSentErrorMessage(true); + return false; } - char * name_str = strtok(NULL, " "); - char * guid_str = name_str ? strtok(NULL, " ") : NULL; - - uint32 guid = guid_str ? atoi(guid_str) : 0; - - std::string name; - if(name_str) + /// Commands not recommended call from chat, but support anyway + if(m_session) { - if(!consoleToUtf8(name_str,name)) // convert from console encoding to utf8 - return; + uint32 targetSecurity = accmgr.GetSecurity(account_id); - if(!normalizePlayerName(name)) + /// can delete only for account with less security + /// This is also reject self apply in fact + if (targetSecurity >= m_session->GetSecurity()) { - zprintf("Syntax is: loadpdump $filename $account ($newname) ($newguid)\r\n"); - return; + SendSysMessage (LANG_YOURS_SECURITY_IS_LOW); + SetSentErrorMessage (true); + return false; } } - if(PlayerDumpReader().LoadDump(file, account_id, name, guid)) - zprintf("Character loaded successfully!\r\n"); - else - zprintf("Failed to load the character!\r\n"); -} - -/// Reload the scripts and notify the players -void CliLoadScripts(char*command,pPrintf zprintf) -{ - char const *del=strtok(command," "); - if (!del) - del=""; - if(!LoadScriptingModule(del)) // Error report is already done by LoadScriptingModule - return; - - sWorld.SendWorldText(LANG_SCRIPTS_RELOADED); -} - -/// Delete a user account and all associated characters in this realm -/// \todo This function has to be enhanced to respect the login/realm split (delete char, delete account chars in realm, delete account chars in realm then delete account -void CliDelete(char*command,pPrintf zprintf) -{ - ///- Get the account name from the command line - char *account_name_str=strtok(command," "); - if(!account_name_str) - { - // \r\n is used because this function can also be called from RA - zprintf("Syntax is: delete $account\r\n"); - return; - } - - std::string account_name; - if(!consoleToUtf8(account_name_str,account_name)) // convert from console encoding to utf8 - return; - - AccountOpResult result = accmgr.DeleteAccount(accmgr.GetId(account_name)); + AccountOpResult result = accmgr.DeleteAccount(account_id); switch(result) { case AOR_OK: - zprintf("We deleted account: %s\r\n",account_name.c_str()); + PSendSysMessage(LANG_ACCOUNT_DELETED,account_name.c_str()); break; case AOR_NAME_NOT_EXIST: - zprintf("User %s does not exist\r\n",account_name.c_str()); - break; + PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); + SetSentErrorMessage(true); + return false; case AOR_DB_INTERNAL_ERROR: - zprintf("User %s NOT deleted (probably sql file format was updated)\r\n",account_name.c_str()); - break; + PSendSysMessage(LANG_ACCOUNT_NOT_DELETED_SQL_ERROR,account_name.c_str()); + SetSentErrorMessage(true); + return false; default: - zprintf("User %s NOT deleted (unknown error)\r\n",account_name.c_str()); - break; + PSendSysMessage(LANG_ACCOUNT_NOT_DELETED,account_name.c_str()); + SetSentErrorMessage(true); + return false; } + + return true; } -void CliCharDelete(char*command,pPrintf zprintf) +bool ChatHandler::HandleCharacterDeleteCommand(const char* args) { - char *character_name_str = strtok(command," "); + if(!*args) + return false; + char *character_name_str = strtok((char*)args," "); if(!character_name_str) - { - zprintf("Syntax is: chardelete $character_name\r\n"); - return; - } - - std::string character_name; - if(!consoleToUtf8(character_name_str,character_name)) // convert from console encoding to utf8 - return; + return false; + std::string character_name = character_name_str; if(!normalizePlayerName(character_name)) - { - zprintf("Syntax is: chardelete $character_name\r\n"); - return; - } - - Player *player = objmgr.GetPlayer(character_name.c_str()); + return false; uint64 character_guid; uint32 account_id; + Player *player = objmgr.GetPlayer(character_name.c_str()); if(player) { character_guid = player->GetGUID(); @@ -295,185 +149,42 @@ void CliCharDelete(char*command,pPrintf zprintf) character_guid = objmgr.GetPlayerGUIDByName(character_name); if(!character_guid) { - zprintf("Player %s not found!\r\n",character_name.c_str()); - return; + PSendSysMessage(LANG_NO_PLAYER,character_name.c_str()); + SetSentErrorMessage(true); + return false; } account_id = objmgr.GetPlayerAccountIdByGUID(character_guid); } - Player::DeleteFromDB(character_guid, account_id, true); - zprintf("Player %s (Guid: %u AccountId: %u) deleted\r\n",character_name.c_str(),GUID_LOPART(character_guid),account_id); -} - -/// Broadcast a message to the World -void CliBroadcast(char *text,pPrintf zprintf) -{ - std::string textUtf8; - if(!consoleToUtf8(text,textUtf8)) // convert from console encoding to utf8 - return; + std::string account_name; + accmgr.GetName (account_id,account_name); - sWorld.SendWorldText(LANG_SYSTEMMESSAGE,textUtf8.c_str()); - zprintf("Broadcasting to the world: %s\r\n",textUtf8.c_str()); -} - -/// Print the list of commands and associated description -void CliHelp(char*,pPrintf zprintf) -{ - for (unsigned int x=0;x<CliTotalCmds;x++) - zprintf("%-13s - %s.\r\n",Commands[x].cmd ,Commands[x].description); + Player::DeleteFromDB(character_guid, account_id, true); + PSendSysMessage(LANG_CHARACTER_DELETED,character_name.c_str(),GUID_LOPART(character_guid),account_name.c_str(), account_id); + return true; } /// Exit the realm -void CliExit(char*,pPrintf zprintf) +bool ChatHandler::HandleServerExitCommand(const char* args) { - zprintf( "Exiting daemon...\r\n" ); + SendSysMessage(LANG_COMMAND_EXIT); World::m_stopEvent = true; -} - -/// Restart the server (with some delay) as soon as no active connections remain on the server -void CliIdleRestart(char* command,pPrintf zprintf) -{ - char *args = strtok(command," "); - - if(!args) - { - zprintf("Syntax is: idlerestart $seconds|cancel\r\n"); - return; - } - - if(std::string(args)=="cancel") - { - sWorld.ShutdownCancel(); - } - else - { - - uint32 time = atoi(args); - - ///- Prevent interpret wrong arg value as 0 secs shutdown time - if(time==0 && (args[0]!='0' || args[1]!='\0') || time < 0) - { - zprintf("Syntax is: idlerestart $seconds|cancel\r\n"); - return; - } - - sWorld.ShutdownServ(time,SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE); - } -} - -/// Restart the server with some delay -void CliRestart(char* command,pPrintf zprintf) -{ - char *args = strtok(command," "); - - if(!args) - { - zprintf("Syntax is: restart $seconds|cancel\r\n"); - return; - } - - if(std::string(args)=="cancel") - { - sWorld.ShutdownCancel(); - } - else - { - int32 time = atoi(args); - - ///- Prevent interpret wrong arg value as 0 secs shutdown time - if(time==0 && (args[0]!='0' || args[1]!='\0') || time < 0) - { - zprintf("Syntax is: restart $seconds|cancel\r\n"); - return; - } - - sWorld.ShutdownServ(time,SHUTDOWN_MASK_RESTART); - } -} - -/// Shutdown the server (with some delay) as soon as no active connections remain on the server -void CliIdleShutdown(char* command,pPrintf zprintf) -{ - char *args = strtok(command," "); - - if(!args) - { - zprintf("Syntax is: idleshutdown $seconds|cancel\r\n"); - return; - } - - if(std::string(args)=="cancel") - { - sWorld.ShutdownCancel(); - } - else - { - - uint32 time = atoi(args); - - ///- Prevent interpret wrong arg value as 0 secs shutdown time - if(time==0 && (args[0]!='0' || args[1]!='\0') || time < 0) - { - zprintf("Syntax is: idleshutdown $seconds|cancel\r\n"); - return; - } - - sWorld.ShutdownServ(time,SHUTDOWN_MASK_IDLE); - } -} - -/// Shutdown the server with some delay -void CliShutdown(char* command,pPrintf zprintf) -{ - char *args = strtok(command," "); - - if(!args) - { - zprintf("Syntax is: shutdown $seconds|cancel\r\n"); - return; - } - - if(std::string(args)=="cancel") - { - sWorld.ShutdownCancel(); - } - else - { - int32 time = atoi(args); - - ///- Prevent interpret wrong arg value as 0 secs shutdown time - if(time==0 && (args[0]!='0' || args[1]!='\0') || time < 0) - { - zprintf("Syntax is: shutdown $seconds|cancel\r\n"); - return; - } - - sWorld.ShutdownServ(time); - } + return true; } /// Display info on users currently in the realm -void CliInfo(char*,pPrintf zprintf) +bool ChatHandler::HandleAccountOnlineListCommand(const char* args) { - uint32 activeClientsNum = sWorld.GetActiveSessionCount(); - uint32 queuedClientsNum = sWorld.GetQueuedSessionCount(); - uint32 maxActiveClientsNum = sWorld.GetMaxActiveSessionCount(); - uint32 maxQueuedClientsNum = sWorld.GetMaxQueuedSessionCount(); - std::string timeStr = secsToTimeString(sWorld.GetUptime(),true); - - zprintf("Online players: %u (max: %u) queued: %u (max: %u) Uptime: %s\r\n",activeClientsNum,maxActiveClientsNum,queuedClientsNum,maxQueuedClientsNum,timeStr.c_str()); - ///- Get the list of accounts ID logged to the realm QueryResult *resultDB = CharacterDatabase.Query("SELECT name,account FROM characters WHERE online > 0"); - if (!resultDB) - return; + return true; ///- Display the list of account/characters online - zprintf("=====================================================================\r\n"); - zprintf("| Account | Character | IP | GM | Exp |\r\n"); - zprintf("=====================================================================\r\n"); + SendSysMessage("====================================================================="); + SendSysMessage(LANG_ACCOUNT_LIST_HEADER); + SendSysMessage("====================================================================="); ///- Circle through accounts do @@ -490,708 +201,77 @@ void CliInfo(char*,pPrintf zprintf) if(resultLogin) { Field *fieldsLogin = resultLogin->Fetch(); - zprintf("|%15s| %20s | %15s |%4d|%5d|\r\n", + PSendSysMessage("|%15s| %20s | %15s |%4d|%5d|", fieldsLogin[0].GetString(),name.c_str(),fieldsLogin[1].GetString(),fieldsLogin[2].GetUInt32(),fieldsLogin[3].GetUInt32()); delete resultLogin; } else - zprintf("|<Error> | %20s |<Error> |<Er>|<Err>|\r\n",name.c_str()); + PSendSysMessage(LANG_ACCOUNT_LIST_ERROR,name.c_str()); }while(resultDB->NextRow()); delete resultDB; - zprintf("=====================================================================\r\n"); -} - -/// Display a list of banned accounts and ip addresses -void CliBanList(char*,pPrintf zprintf) -{ - bool found = false; - ///- Get the list of banned accounts and display them - QueryResult *result = loginDatabase.Query("SELECT id,username FROM account WHERE id IN (SELECT id FROM account_banned WHERE active = 1)"); - if(result) - { - found = true; - - zprintf("Currently Banned Accounts:\r\n"); - zprintf("===============================================================================\r\n"); - zprintf("| Account | BanDate | UnbanDate | Banned By | Ban Reason |\r\n"); - do - { - zprintf("-------------------------------------------------------------------------------\r\n"); - Field *fields = result->Fetch(); - // No SQL injection. id is uint32. - QueryResult *banInfo = loginDatabase.PQuery("SELECT bandate,unbandate,bannedby,banreason FROM account_banned WHERE id = %u AND active = 1 ORDER BY unbandate", fields[0].GetUInt32()); - if (banInfo) - { - Field *fields2 = banInfo->Fetch(); - do - { - time_t t_ban = fields2[0].GetUInt64(); - tm* aTm_ban = localtime(&t_ban); - zprintf("|%-15.15s|", fields[1].GetString()); - zprintf("%02d-%02d-%02d %02d:%02d|", aTm_ban->tm_year%100, aTm_ban->tm_mon+1, aTm_ban->tm_mday, aTm_ban->tm_hour, aTm_ban->tm_min); - if ( fields2[0].GetUInt64() == fields2[1].GetUInt64() ) - zprintf(" permanent |"); - else - { - time_t t_unban = fields2[1].GetUInt64(); - tm* aTm_unban = localtime(&t_unban); - zprintf("%02d-%02d-%02d %02d:%02d|",aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min); - } - zprintf("%-15.15s|%-15.15s|\r\n",fields2[2].GetString(),fields2[3].GetString()); - }while ( banInfo->NextRow() ); - delete banInfo; - } - }while( result->NextRow() ); - zprintf("===============================================================================\r\n"); - delete result; - } - - ///- Get the list of banned IP addresses and display them - result = loginDatabase.Query( "SELECT ip,bandate,unbandate,bannedby,banreason FROM ip_banned WHERE (bandate=unbandate OR unbandate>UNIX_TIMESTAMP()) ORDER BY unbandate" ); - if(result) - { - found = true; - - zprintf("Currently Banned IPs:\r\n"); - zprintf("===============================================================================\r\n"); - zprintf("| IP | BanDate | UnbanDate | Banned By | Ban Reason |\r\n"); - do - { - zprintf("-------------------------------------------------------------------------------\r\n"); - Field *fields = result->Fetch(); - time_t t_ban = fields[1].GetUInt64(); - tm* aTm_ban = localtime(&t_ban); - zprintf("|%-15.15s|", fields[0].GetString()); - zprintf("%02d-%02d-%02d %02d:%02d|", aTm_ban->tm_year%100, aTm_ban->tm_mon+1, aTm_ban->tm_mday, aTm_ban->tm_hour, aTm_ban->tm_min); - if ( fields[1].GetUInt64() == fields[2].GetUInt64() ) - zprintf(" permanent |"); - else - { - time_t t_unban = fields[2].GetUInt64(); - tm* aTm_unban = localtime(&t_unban); - zprintf("%02d-%02d-%02d %02d:%02d|", aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min); - } - zprintf("%-15.15s|%-15.15s|\r\n", fields[3].GetString(), fields[4].GetString()); - }while( result->NextRow() ); - zprintf("===============================================================================\r\n"); - delete result; - } - - if(!found) - zprintf("We do not have banned users\r\n"); -} - -/// Ban an IP address or a user account -void CliBan(char*command,pPrintf zprintf) -{ - ///- Get the command parameter - char* type_str = strtok((char*)command, " "); - char* nameOrIP_str = strtok(NULL, " "); - char* duration_str = strtok(NULL," "); - char* reason_str = strtok(NULL,""); - - if(!type_str||!nameOrIP_str||!duration_str||!reason_str)// ?!? input of single char "0"-"9" wouldn't detect when with: || !atoi(duration) - { - zprintf("Syntax: ban account|ip|character $AccountOrIpOrCharacter $duration[s|m|h|d] $reason \r\n"); - return; - } - - std::string type; - if(!consoleToUtf8(type_str,type)) // convert from console encoding to utf8 - return; - - std::string nameOrIP; - if(!consoleToUtf8(nameOrIP_str,nameOrIP)) // convert from console encoding to utf8 - return; - - std::string duration; - if(!consoleToUtf8(duration_str,duration)) // convert from console encoding to utf8 - return; - - std::string reason; - if(!consoleToUtf8(reason_str,reason)) // convert from console encoding to utf8 - return; - - switch (sWorld.BanAccount(type, nameOrIP, duration, reason, "Set by console.")) - { - case BAN_SUCCESS: - if(atoi(duration_str)>0) - zprintf("%s is banned for %s. Reason: %s.\r\n",nameOrIP.c_str(),secsToTimeString(TimeStringToSecs(duration_str),true,false).c_str(),reason.c_str()); - else - zprintf("%s is banned permanently. Reason: %s.\r\n",nameOrIP.c_str(),reason.c_str()); - break; - case BAN_NOTFOUND: - zprintf("%s %s not found\r\n", type.c_str(), nameOrIP.c_str()); - break; - case BAN_SYNTAX_ERROR: - zprintf("Syntax: ban account|ip|character $AccountOrIpOrCharacter $duration[s|m|h|d] $reason \r\n"); - break; - } -} - -/// Display %TrinIty version -void CliVersion(char*,pPrintf zprintf) -{ - //<--maybe better append to info cmd - zprintf( "%s (world-daemon)\r\n", _FULLVERSION ); -} - -/// Unban an IP adress or a user account -void CliRemoveBan(char *command,pPrintf zprintf) -{ - ///- Get the command parameter - char *type_str = strtok(command," "); - char *nameorip_str = strtok(NULL," "); - if(!nameorip_str||!type_str) - { - zprintf("Syntax is: unban account|ip|character $nameorip\r\n"); - return; - } - - std::string type; - if(!consoleToUtf8(type_str,type)) // convert from console encoding to utf8 - return; - - std::string nameorip; - if(!consoleToUtf8(nameorip_str,nameorip)) // convert from console encoding to utf8 - return; - - if (!sWorld.RemoveBanAccount(type, nameorip)) - zprintf("%s %s not found\r\n", type.c_str(), nameorip.c_str()); - else - zprintf("We removed ban from %s: %s\r\n",type_str,nameorip.c_str()); -} - -/// Display the list of GMs -void CliListGM(char*,pPrintf zprintf) -{ - - ///- Get the accounts with GM Level >0 - Field *fields; - - QueryResult *result = loginDatabase.Query( "SELECT username,gmlevel FROM account WHERE gmlevel > 0" ); - if(result) - { - - zprintf("Current gamemasters:\r\n"); - zprintf("========================\r\n"); - zprintf("| Account | GM |\r\n"); - zprintf("========================\r\n"); - - ///- Circle through them. Display username and GM level - do - { - fields = result->Fetch(); - zprintf("|%15s|", fields[0].GetString()); - zprintf("%6s|\r\n",fields[1].GetString()); - }while( result->NextRow() ); - - zprintf("========================\r\n"); - delete result; - } - else - { - zprintf("No gamemasters\r\n"); - } -} - -/// Set the GM level of an account -void CliSetGM(char *command,pPrintf zprintf) -{ - ///- Get the command line arguments - char *szAcc = strtok(command," "); - char *szLevel = strtok(NULL," "); - - if(!szAcc||!szLevel) //wrong syntax 'setgm' without name - { - zprintf("Syntax is: setgm $account $number (0 - normal, 3 - gamemaster)>\r\n"); - return; - } - - //wow it's ok,let's hope it was integer given - int lev=atoi(szLevel); //get int anyway (0 if error) - - std::string safe_account_name; - if(!consoleToUtf8(szAcc,safe_account_name)) // convert from console encoding to utf8 - return; - - ///- Convert Account name to Upper Format - AccountMgr::normilizeString(safe_account_name); - - ///- Escape the account name to allow quotes in names - loginDatabase.escape_string(safe_account_name); - - ///- Try to find the account, then update the GM level - // No SQL injection (account name is escaped) - QueryResult *result = loginDatabase.PQuery("SELECT id FROM account WHERE username = '%s'",safe_account_name.c_str()); - - if (result) - { - Field *fields = result->Fetch(); - uint32 account_id = fields[0].GetUInt32(); - delete result; - - WorldSession* session = sWorld.FindSession(account_id); - if(session) - session->SetSecurity(lev); - - // No SQL injection (account name is escaped) - loginDatabase.PExecute("UPDATE account SET gmlevel = '%d' WHERE username = '%s'",lev,safe_account_name.c_str()); - zprintf("We set %s gmlevel %d\r\n",safe_account_name.c_str(),lev); - } - else - { - zprintf("No account %s found\r\n",safe_account_name.c_str()); - } -} - -/// Set password for account -void CliSetPassword(char *command,pPrintf zprintf) -{ - ///- Get the command line arguments - char *szAcc = strtok(command," "); - char *szPassword1 = strtok(NULL," "); - char *szPassword2 = strtok(NULL," "); - - if(!szAcc||!szPassword1 || !szPassword2) - { - zprintf("Syntax is: setpass $account $password $password\r\n"); - return; - } - - std::string account_name; - if(!consoleToUtf8(szAcc,account_name)) // convert from console encoding to utf8 - return; - - std::string pass1; - if(!consoleToUtf8(szPassword1,pass1)) // convert from console encoding to utf8 - return; - - std::string pass2; - if(!consoleToUtf8(szPassword2,pass2)) // convert from console encoding to utf8 - return; - - uint32 acc_id = accmgr.GetId(szAcc); - if (!acc_id) - { - zprintf("Account '%s' does not exist!\r\n", account_name.c_str()); - return; - } - - if (pass1 != pass2) - { - zprintf("Password does not match the confirm password, password not changed!\r\n"); - return; - } - - AccountOpResult result = accmgr.ChangePassword(acc_id, pass1); - - switch(result) - { - case AOR_OK: - zprintf("The password was changed for account '%s' (ID: %u).\r\n",account_name.c_str(),acc_id); - break; - case AOR_PASS_TOO_LONG: - zprintf("Password can't be longer than 16 characters (client limit), password not changed!\r\n"); - break; - case AOR_NAME_NOT_EXIST: - zprintf("Account '%s' does not exist!\r\n", account_name.c_str()); - break; - case AOR_DB_INTERNAL_ERROR: - zprintf("Password not changed! (probably sql file format was updated)\r\n"); - break; - default: - zprintf("Password not changed! (unknown error\r\n"); - break; - } + SendSysMessage("====================================================================="); + return true; } /// Create an account -void CliCreate(char *command,pPrintf zprintf) +bool ChatHandler::HandleAccountCreateCommand(const char* args) { - //I see no need in this function (why would an admin personally create accounts - //instead of using account registration page or accessing db directly?) - //but still let it be + if(!*args) + return false; ///- %Parse the command line arguments - char *szAcc = strtok(command, " "); + char *szAcc = strtok((char*)args, " "); char *szPassword = strtok(NULL, " "); if(!szAcc || !szPassword) - { - zprintf("Syntax is: create $username $password\r\n"); - return; - } + return false; - std::string account_name; - if(!consoleToUtf8(szAcc,account_name)) // convert from console encoding to utf8 - return; - - std::string password; - if(!consoleToUtf8(szPassword,password)) // convert from console encoding to utf8 - return; + // normilized in accmgr.CreateAccount + std::string account_name = szAcc; + std::string password = szPassword; AccountOpResult result = accmgr.CreateAccount(account_name, password); switch(result) { case AOR_OK: - zprintf("User %s with password %s created successfully\r\n",account_name.c_str(),password.c_str()); + PSendSysMessage(LANG_ACCOUNT_CREATED,account_name.c_str()); break; case AOR_NAME_TOO_LONG: - zprintf("Username %s is too long\r\n", account_name.c_str()); - break; + SendSysMessage(LANG_ACCOUNT_TOO_LONG); + SetSentErrorMessage(true); + return false; case AOR_NAME_ALREDY_EXIST: - zprintf("User %s already exists\r\n",account_name.c_str()); - break; + SendSysMessage(LANG_ACCOUNT_ALREADY_EXIST); + SetSentErrorMessage(true); + return false; case AOR_DB_INTERNAL_ERROR: - zprintf("User %s with password %s NOT created (probably sql file format was updated)\r\n",account_name.c_str(),password.c_str()); - break; + PSendSysMessage(LANG_ACCOUNT_NOT_CREATED_SQL_ERROR,account_name.c_str()); + SetSentErrorMessage(true); + return false; default: - zprintf("User %s with password %s NOT created (unknown error)\r\n",account_name.c_str(),password.c_str()); - break; - } -} - -/// Command parser and dispatcher -void ParseCommand( pPrintf zprintf, char* input) -{ - unsigned int x; - bool bSuccess=false; - if (!input) - return; - - unsigned int l=strlen(input); - char *supposedCommand=NULL,* arguments=(char*)(""); - if(l) - { - ///- Get the command and the arguments - supposedCommand = strtok(input," "); - if (supposedCommand) - { - if (l>strlen(supposedCommand)) - arguments=&input[strlen(supposedCommand)+1]; - - ///- Circle through the command table and, if found, put the command in the queue - for ( x=0;x<CliTotalCmds;x++) - if(!strcmp(Commands[x].cmd,supposedCommand)) - { - sWorld.QueueCliCommand(new CliCommandHolder(&Commands[x], arguments, zprintf)); - bSuccess=true; - break; - } - - ///- Display an error message if the command is unknown - if(x==CliTotalCmds) - zprintf("Unknown command: %s\r\n", input); - } + PSendSysMessage(LANG_ACCOUNT_NOT_CREATED,account_name.c_str()); + SetSentErrorMessage(true); + return false; } - if (!bSuccess) - zprintf("TC>"); -} - -/// Kick a character out of the realm -void CliKick(char*command,pPrintf zprintf) -{ - char *kickName = strtok(command, " "); - - if (!kickName) - { - zprintf("Syntax is: kick $charactername\r\n"); - return; - } - - std::string name; - if(!consoleToUtf8(kickName,name)) // convert from console encoding to utf8 - return; - - if(!normalizePlayerName(name)) - return; - - sWorld.KickPlayer(name); -} - -/// Teleport a character to location -void CliTele(char*command,pPrintf zprintf) -{ - char *charName = strtok(command, " "); - char *locName = strtok(NULL, " "); - - if (!charName || !locName) - { - zprintf("Syntax is: tele $charactername $location\r\n"); - return; - } - - std::string name = charName; - if(!consoleToUtf8(charName,name)) // convert from console encoding to utf8 - return; - - if(!normalizePlayerName(name)) - return; - - std::string location; - if(!consoleToUtf8(locName,location)) // convert from console encoding to utf8 - return; - - WorldDatabase.escape_string(location); - QueryResult *result = WorldDatabase.PQuery("SELECT position_x,position_y,position_z,orientation,map FROM game_tele WHERE name = '%s'",location.c_str()); - if (!result) - { - zprintf(objmgr.GetTrinityStringForDBCLocale(LANG_COMMAND_TELE_NOTFOUND),"\r\n"); - return; - } - - Field *fields = result->Fetch(); - float x = fields[0].GetFloat(); - float y = fields[1].GetFloat(); - float z = fields[2].GetFloat(); - float ort = fields[3].GetFloat(); - int mapid = fields[4].GetUInt16(); - delete result; - - if(!MapManager::IsValidMapCoord(mapid,x,y,z,ort)) - { - zprintf(objmgr.GetTrinityStringForDBCLocale(LANG_INVALID_TARGET_COORD),"\r\n",x,y,mapid); - return; - } - - Player *chr = objmgr.GetPlayer(name.c_str()); - if (chr) - { - - if(chr->IsBeingTeleported()==true) - { - zprintf(objmgr.GetTrinityStringForDBCLocale(LANG_IS_TELEPORTED),"\r\n",chr->GetName()); - return; - } - - if(chr->isInFlight()) - { - zprintf(objmgr.GetTrinityStringForDBCLocale(LANG_CHAR_IN_FLIGHT),"\r\n",chr->GetName()); - return; - } - - zprintf(objmgr.GetTrinityStringForDBCLocale(LANG_TELEPORTING_TO),"\r\n",chr->GetName(),"", location.c_str()); - - chr->SaveRecallPosition(); - - chr->TeleportTo(mapid,x,y,z,chr->GetOrientation()); - } - else if (uint64 guid = objmgr.GetPlayerGUIDByName(name.c_str())) - { - zprintf(objmgr.GetTrinityStringForDBCLocale(LANG_TELEPORTING_TO),"\r\n",name.c_str(), objmgr.GetTrinityStringForDBCLocale(LANG_OFFLINE), location.c_str()); - Player::SavePositionInDB(mapid,x,y,z,ort,MapManager::Instance().GetZoneId(mapid,x,y),guid); - } - else - zprintf(objmgr.GetTrinityStringForDBCLocale(LANG_NO_PLAYER),"\r\n",name.c_str()); -} - -/// Display/Define the 'Message of the day' for the realm -void CliMotd(char*command,pPrintf zprintf) -{ - - if (strlen(command) == 0) - { - zprintf("Current Message of the day: \r\n%s\r\n", sWorld.GetMotd()); - return; - } - else - { - std::string commandUtf8; - if(!consoleToUtf8(command,commandUtf8)) // convert from console encoding to utf8 - return; - - sWorld.SetMotd(commandUtf8); - zprintf("Message of the day changed to:\r\n%s\r\n", commandUtf8.c_str()); - } -} - -/// Comment me -/// \todo What is CorpsesErase for? -void CliCorpses(char*,pPrintf) -{ - CorpsesErase(); + + return true; } /// Set the level of logging -void CliSetLogLevel(char*command,pPrintf zprintf) -{ - char *NewLevel = strtok(command, " "); - if (!NewLevel) - { - zprintf("Syntax is: setloglevel $loglevel\r\n"); - return; - } - sLog.SetLogLevel(NewLevel); -} - -/// Display the server uptime -void CliUpTime(char*,pPrintf zprintf) -{ - uint32 uptime = sWorld.GetUptime(); - std::string suptime = secsToTimeString(uptime,true,(uptime > 86400)); - zprintf("Server has been up for: %s\r\n", suptime.c_str()); -} - -/// Set/Unset the TBC flag for an account -void CliSetAddon(char *command,pPrintf zprintf) -{ - ///- Get the command line arguments - char *szAcc = strtok(command," "); - char *szExp = strtok(NULL," "); - - if(!szAcc||!szExp) - { - zprintf("Syntax is: setbc $account $number (0 - normal, 1 - tbc, 2 - wotlk)>\r\n"); - return; - } - - int lev=atoi(szExp); //get int anyway (0 if error) - - if(lev < 0) - { - zprintf("Syntax is: setbc $account $number (0 - normal, 1 - tbc, 2 - wotlk)>\r\n"); - return; - } - - ///- Escape the account name to allow quotes in names - std::string safe_account_name; - if(!consoleToUtf8(szAcc,safe_account_name)) // convert from console encoding to utf8 - return; - - ///- Convert Account name to Upper Format - AccountMgr::normilizeString(safe_account_name); - - ///- Escape the account name to allow quotes in names - loginDatabase.escape_string(safe_account_name); - - // No SQL injection (account name is escaped) - QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE username = '%s'",safe_account_name.c_str()); - - if (result) - { - // No SQL injection (account name is escaped) - loginDatabase.PExecute("UPDATE account SET expansion = '%d' WHERE username = '%s'",lev,safe_account_name.c_str()); - zprintf("We set %s to expansion allowed %d\r\n",safe_account_name.c_str(),lev); - - delete result; - } - else - { - zprintf("No account %s found\r\n",safe_account_name.c_str()); - } -} - -/// Save all players -void CliSave(char*,pPrintf zprintf) -{ - ///- Save players - ObjectAccessor::Instance().SaveAllPlayers(); - zprintf( objmgr.GetTrinityStringForDBCLocale(LANG_PLAYERS_SAVED) ); - - ///- Send a message - sWorld.SendWorldText(LANG_PLAYERS_SAVED); -} - -/// Send a message to a player in game -void CliSend(char *playerN,pPrintf zprintf) +bool ChatHandler::HandleServerSetLogLevelCommand(const char *args) { - ///- Get the command line arguments - char* name_str = strtok((char*)playerN, " "); - char* msg_str = strtok(NULL, ""); - - if(!name_str || !msg_str) - { - zprintf("Syntax: send $player $message (Player name is case sensitive)\r\n"); - return; - } - - std::string name; - if(!consoleToUtf8(name_str,name)) // convert from console encoding to utf8 - return; - - std::string msg; - if(!consoleToUtf8(msg_str,msg)) // convert from console encoding to utf8 - return; - - if(!normalizePlayerName(name)) - { - zprintf("Syntax: send $player $message (Player name is case sensitive)\r\n"); - return; - } + if(!*args) + return false; - ///- Find the player and check that he is not logging out. - Player *rPlayer = objmgr.GetPlayer(name.c_str()); - if(!rPlayer) - { - zprintf("Player %s not found!\r\n", name.c_str()); - return; - } - - if (rPlayer->GetSession()->isLogingOut()) - { - zprintf("Cannot send message while player %s is logging out!\r\n",name.c_str()); - return; - } - - ///- Send the message - //Use SendAreaTriggerMessage for fastest delivery. - rPlayer->GetSession()->SendAreaTriggerMessage("%s", msg.c_str()); - rPlayer->GetSession()->SendAreaTriggerMessage("|cffff0000[Message from administrator]:|r"); - - //Confirmation message - zprintf("Message '%s' sent to %s\r\n",msg.c_str(), name.c_str()); -} - -void CliPLimit(char *args,pPrintf zprintf) -{ - if(*args) - { - char* param = strtok((char*)args, " "); - if(!param || !*param) - return; - - int l = strlen(param); - - if( strncmp(param,"player",l) == 0 ) - sWorld.SetPlayerLimit(-SEC_PLAYER); - else if(strncmp(param,"moderator",l) == 0 ) - sWorld.SetPlayerLimit(-SEC_MODERATOR); - else if(strncmp(param,"gamemaster",l) == 0 ) - sWorld.SetPlayerLimit(-SEC_GAMEMASTER); - else if(strncmp(param,"administrator",l) == 0 ) - sWorld.SetPlayerLimit(-SEC_ADMINISTRATOR); - else if(strncmp(param,"reset",l) == 0 ) - sWorld.SetPlayerLimit(sConfig.GetIntDefault("PlayerLimit", DEFAULT_PLAYER_LIMIT)); - else - { - int val = atoi(param); - if(val < -SEC_ADMINISTRATOR) val = -SEC_ADMINISTRATOR; - - sWorld.SetPlayerLimit(val); - } - - // kick all low security level players - if(sWorld.GetPlayerAmountLimit() > SEC_PLAYER) - sWorld.KickAllLess(sWorld.GetPlayerSecurityLimit()); - } - - uint32 pLimit = sWorld.GetPlayerAmountLimit(); - AccountTypes allowedAccountType = sWorld.GetPlayerSecurityLimit(); - char const* secName = ""; - switch(allowedAccountType) - { - case SEC_PLAYER: secName = "Player"; break; - case SEC_MODERATOR: secName = "Moderator"; break; - case SEC_GAMEMASTER: secName = "Gamemaster"; break; - case SEC_ADMINISTRATOR: secName = "Administrator"; break; - default: secName = "<unknown>"; break; - } + char *NewLevel = strtok((char*)args, " "); + if (!NewLevel) + return false; - zprintf("Player limits: amount %u, min. security level %s.\r\n",pLimit,secName); + sLog.SetLogLevel(NewLevel); + return true; } /// @} @@ -1221,13 +301,9 @@ void CliRunnable::run() ///- Display the list of available CLI functions then beep sLog.outString(); - /// \todo Shoudn't we use here also the sLog singleton? - CliHelp(NULL,&UTF8ZPRINTF); if(sConfig.GetBoolDefault("BeepAtStart", true)) - { printf("\a"); // \a = Alert - } // print this here the first time // later it will be printed after command queue updates @@ -1244,22 +320,33 @@ void CliRunnable::run() if (World::m_stopEvent) break; #endif - char *command = fgets(commandbuf,sizeof(commandbuf),stdin); - if (command != NULL) + char *command_str = fgets(commandbuf,sizeof(commandbuf),stdin); + if (command_str != NULL) { - for(int x=0;command[x];x++) - if(command[x]=='\r'||command[x]=='\n') + for(int x=0;command_str[x];x++) + if(command_str[x]=='\r'||command_str[x]=='\n') + { + command_str[x]=0; + break; + } + + if(!*command_str) { - command[x]=0; - break; + printf("TC>"); + continue; } - //// \todo Shoudn't we use here also the sLog singleton? - ParseCommand(&UTF8ZPRINTF,command); + + std::string command; + if(!consoleToUtf8(command_str,command)) // convert from console encoding to utf8 + { + printf("TC>"); + continue; + } + + sWorld.QueueCliCommand(&utf8print,command.c_str()); } else if (feof(stdin)) - { World::m_stopEvent = true; - } } ///- End the database thread |