diff options
Diffstat (limited to 'src/server/scripts/Commands')
| -rw-r--r-- | src/server/scripts/Commands/CMakeLists.txt | 101 | ||||
| -rw-r--r-- | src/server/scripts/Commands/cs_account.cpp | 555 | ||||
| -rw-r--r-- | src/server/scripts/Commands/cs_achievement.cpp | 80 | ||||
| -rw-r--r-- | src/server/scripts/Commands/cs_debug.cpp | 1231 | ||||
| -rw-r--r-- | src/server/scripts/Commands/cs_gm.cpp | 243 | ||||
| -rw-r--r-- | src/server/scripts/Commands/cs_go.cpp | 617 | ||||
| -rw-r--r-- | src/server/scripts/Commands/cs_learn.cpp | 1113 | ||||
| -rw-r--r-- | src/server/scripts/Commands/cs_modify.cpp | 1418 | ||||
| -rw-r--r-- | src/server/scripts/Commands/cs_npc.cpp | 1433 |
9 files changed, 6791 insertions, 0 deletions
diff --git a/src/server/scripts/Commands/CMakeLists.txt b/src/server/scripts/Commands/CMakeLists.txt new file mode 100644 index 00000000000..b16cb182169 --- /dev/null +++ b/src/server/scripts/Commands/CMakeLists.txt @@ -0,0 +1,101 @@ +set(scripts_STAT_SRCS + ${scripts_STAT_SRCS} + Commands/cs_account.cpp + Commands/cs_achievement.cpp + Commands/cs_gm.cpp + Commands/cs_npc.cpp + Commands/cs_go.cpp + Commands/cs_learn.cpp + Commands/cs_modify.cpp + Commands/cs_debug.cpp +# Commands/cs_tele.cpp +# Commands/cs_character.cpp +# Commands/cs_event.cpp +# Commands/cs_gobject.cpp +# Commands/cs_honor.cpp +# Commands/cs_wp.cpp +# Commands/cs_titles.cpp +# Commands/cs_quest.cpp +# Commands/cs_reload.cpp +# Commands/cs_list.cpp +# Commands/cs_lookup.cpp +# Commands/cs_pdump.cpp +# Commands/cs_guild.cpp +# Commands/cs_cast.cpp +# Commands/cs_reset.cpp +# Commands/cs_instance.cpp +# Commands/cs_server.cpp +# Commands/cs_channel.cpp +# Commands/cs_pet.cpp +# Commands/cs_loadpath.cpp +# Commands/cs_ticket.cpp +# Commands/cs_aura.cpp +# Commands/cs_unaura.cpp +# Commands/cs_nameannounce.cpp +# Commands/cs_gmnameannounce.cpp +# Commands/cs_announce.cpp +# Commands/cs_gmannounce.cpp +# Commands/cs_notify.cpp +# Commands/cs_gmnotify.cpp +# Commands/cs_appear.cpp +# Commands/cs_summon.cpp +# Commands/cs_groupsummon.cpp +# Commands/cs_commands.cpp +# Commands/cs_demorph.cpp +# Commands/cs_die.cpp +# Commands/cs_revive.cpp +# Commands/cs_dismount.cpp +# Commands/cs_gps.cpp +# Commands/cs_guid.cpp +# Commands/cs_help.cpp +# Commands/cs_itemmove.cpp +# Commands/cs_cooldown.cpp +# Commands/cs_unlearn.cpp +# Commands/cs_distance.cpp +# Commands/cs_recall.cpp +# Commands/cs_save.cpp +# Commands/cs_saveall.cpp +# Commands/cs_kick.cpp +# Commands/cs_ban.cpp +# Commands/cs_unban.cpp +# Commands/cs_baninfo.cpp +# Commands/cs_banlist.cpp +# Commands/cs_start.cpp +# Commands/cs_taxicheat.cpp +# Commands/cs_linkgrave.cpp +# Commands/cs_neargrave.cpp +# Commands/cs_explorecheat.cpp +# Commands/cs_hover.cpp +# Commands/cs_levelup.cpp +# Commands/cs_showarea.cpp +# Commands/cs_hidearea.cpp +# Commands/cs_additem.cpp +# Commands/cs_additemset.cpp +# Commands/cs_bank.cpp +# Commands/cs_wchange.cpp +# Commands/cs_maxskill.cpp +# Commands/cs_setskill.cpp +# Commands/cs_whispers.cpp +# Commands/cs_pinfo.cpp +# Commands/cs_respawn.cpp +# Commands/cs_send.cpp +# Commands/cs_mute.cpp +# Commands/cs_unmute.cpp +# Commands/cs_movegens.cpp +# Commands/cs_cometome.cpp +# Commands/cs_damage.cpp +# Commands/cs_combatstop.cpp +# Commands/cs_flusharenapoints.cpp +# Commands/cs_repairitems.cpp +# Commands/cs_waterwalk.cpp +# Commands/cs_freeze.cpp +# Commands/cs_unfreeze.cpp +# Commands/cs_listfreeze.cpp +# Commands/cs_possess.cpp +# Commands/cs_unpossess.cpp +# Commands/cs_bindsight.cpp +# Commands/cs_unbindsight.cpp +# Commands/cs_playall.cpp +) + +message(" -> Prepared: Commands") diff --git a/src/server/scripts/Commands/cs_account.cpp b/src/server/scripts/Commands/cs_account.cpp new file mode 100644 index 00000000000..1c6bd03f8a4 --- /dev/null +++ b/src/server/scripts/Commands/cs_account.cpp @@ -0,0 +1,555 @@ +/* + * Copyright (C) 2008-2010 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* ScriptData +Name: account_commandscript +%Complete: 100 +Comment: All account related commands +Category: commandscripts +EndScriptData */ + +#include "ScriptPCH.h" +#include "AccountMgr.h" + +class account_commandscript : public CommandScript +{ + public: + account_commandscript() : CommandScript("account_commandscript") { } + + ChatCommand* GetCommands() const + { + static ChatCommand accountSetCommandTable[] = + { + { "addon", SEC_ADMINISTRATOR, true, &HandleAccountSetAddonCommand, "", NULL }, + { "gmlevel", SEC_CONSOLE, true, &HandleAccountSetGmLevelCommand, "", NULL }, + { "password", SEC_CONSOLE, true, &HandleAccountSetPasswordCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + static ChatCommand accountCommandTable[] = + { + { "addon", SEC_MODERATOR, false, &HandleAccountAddonCommand, "", NULL }, + { "create", SEC_CONSOLE, true, &HandleAccountCreateCommand, "", NULL }, + { "delete", SEC_CONSOLE, true, &HandleAccountDeleteCommand, "", NULL }, + { "onlinelist", SEC_CONSOLE, true, &HandleAccountOnlineListCommand, "", NULL }, + { "lock", SEC_PLAYER, false, &HandleAccountLockCommand, "", NULL }, + { "set", SEC_ADMINISTRATOR, true, NULL, "", accountSetCommandTable }, + { "password", SEC_PLAYER, false, &HandleAccountPasswordCommand, "", NULL }, + { "", SEC_PLAYER, false, &HandleAccountCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + static ChatCommand commandTable[] = + { + { "account", SEC_PLAYER, true, NULL, "", accountCommandTable }, + { NULL, 0, false, NULL, "", NULL } + }; + return commandTable; + } + + static bool HandleAccountAddonCommand(ChatHandler* handler, const char* args) + { + if (!*args) + { + handler->SendSysMessage(LANG_CMD_SYNTAX); + handler->SetSentErrorMessage(true); + return false; + } + + char *szExp = strtok((char*)args, " "); + + uint32 account_id = handler->GetSession()->GetAccountId(); + + int expansion = atoi(szExp); //get int anyway (0 if error) + if (expansion < 0 || uint8(expansion) > sWorld.getIntConfig(CONFIG_EXPANSION)) + { + handler->SendSysMessage(LANG_IMPROPER_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + + // No SQL injection + LoginDatabase.PExecute("UPDATE account SET expansion = '%d' WHERE id = '%u'", expansion, account_id); + handler->PSendSysMessage(LANG_ACCOUNT_ADDON, expansion); + return true; + } + + /// Create an account + static bool HandleAccountCreateCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + ///- %Parse the command line arguments + char *szAcc = strtok((char*)args, " "); + char *szPassword = strtok(NULL, " "); + if (!szAcc || !szPassword) + return false; + + // normalized in sAccountMgr.CreateAccount + std::string account_name = szAcc; + std::string password = szPassword; + + AccountOpResult result = sAccountMgr.CreateAccount(account_name, password); + switch(result) + { + case AOR_OK: + handler->PSendSysMessage(LANG_ACCOUNT_CREATED,account_name.c_str()); + break; + case AOR_NAME_TOO_LONG: + handler->SendSysMessage(LANG_ACCOUNT_TOO_LONG); + handler->SetSentErrorMessage(true); + return false; + case AOR_NAME_ALREDY_EXIST: + handler->SendSysMessage(LANG_ACCOUNT_ALREADY_EXIST); + handler->SetSentErrorMessage(true); + return false; + case AOR_DB_INTERNAL_ERROR: + handler->PSendSysMessage(LANG_ACCOUNT_NOT_CREATED_SQL_ERROR,account_name.c_str()); + handler->SetSentErrorMessage(true); + return false; + default: + handler->PSendSysMessage(LANG_ACCOUNT_NOT_CREATED,account_name.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + + return true; + } + + /// 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 + static bool HandleAccountDeleteCommand(ChatHandler* handler, 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)) + { + handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + + uint32 account_id = sAccountMgr.GetId(account_name); + if (!account_id) + { + handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + + /// Commands not recommended call from chat, but support anyway + /// can delete only for account with less security + /// This is also reject self apply in fact + if (handler->HasLowerSecurityAccount (NULL,account_id,true)) + return false; + + AccountOpResult result = sAccountMgr.DeleteAccount(account_id); + switch(result) + { + case AOR_OK: + handler->PSendSysMessage(LANG_ACCOUNT_DELETED,account_name.c_str()); + break; + case AOR_NAME_NOT_EXIST: + handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); + handler->SetSentErrorMessage(true); + return false; + case AOR_DB_INTERNAL_ERROR: + handler->PSendSysMessage(LANG_ACCOUNT_NOT_DELETED_SQL_ERROR,account_name.c_str()); + handler->SetSentErrorMessage(true); + return false; + default: + handler->PSendSysMessage(LANG_ACCOUNT_NOT_DELETED,account_name.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + + return true; + } + + /// Display info on users currently in the realm + static bool HandleAccountOnlineListCommand(ChatHandler* handler, const char* /*args*/) + { + ///- Get the list of accounts ID logged to the realm + QueryResult resultDB = CharacterDatabase.Query("SELECT name,account,map,zone FROM characters WHERE online > 0"); + if (!resultDB) + { + handler->SendSysMessage(LANG_ACCOUNT_LIST_EMPTY); + return true; + } + + ///- Display the list of account/characters online + handler->SendSysMessage(LANG_ACCOUNT_LIST_BAR_HEADER); + handler->SendSysMessage(LANG_ACCOUNT_LIST_HEADER); + handler->SendSysMessage(LANG_ACCOUNT_LIST_BAR); + + ///- Circle through accounts + do + { + Field *fieldsDB = resultDB->Fetch(); + std::string name = fieldsDB[0].GetString(); + uint32 account = fieldsDB[1].GetUInt32(); + + ///- Get the username, last IP and GM level of each account + // No SQL injection. account is uint32. + QueryResult resultLogin = + LoginDatabase.PQuery("SELECT a.username, a.last_ip, aa.gmlevel, a.expansion " + "FROM account a " + "LEFT JOIN account_access aa " + "ON (a.id = aa.id) " + "WHERE a.id = '%u'", account); + if (resultLogin) + { + Field *fieldsLogin = resultLogin->Fetch(); + handler->PSendSysMessage(LANG_ACCOUNT_LIST_LINE, + fieldsLogin[0].GetCString(),name.c_str(),fieldsLogin[1].GetCString(),fieldsDB[2].GetInt32(),fieldsDB[3].GetInt32(),fieldsLogin[3].GetUInt32(),fieldsLogin[2].GetUInt32()); + } + else + handler->PSendSysMessage(LANG_ACCOUNT_LIST_ERROR,name.c_str()); + + }while (resultDB->NextRow()); + + handler->SendSysMessage(LANG_ACCOUNT_LIST_BAR); + return true; + } + + static bool HandleAccountLockCommand(ChatHandler* handler, const char* args) + { + if (!*args) + { + handler->SendSysMessage(LANG_USE_BOL); + handler->SetSentErrorMessage(true); + return false; + } + + std::string argstr = (char*)args; + if (argstr == "on") + { + LoginDatabase.PExecute("UPDATE account SET locked = '1' WHERE id = '%d'",handler->GetSession()->GetAccountId()); + handler->PSendSysMessage(LANG_COMMAND_ACCLOCKLOCKED); + return true; + } + + if (argstr == "off") + { + LoginDatabase.PExecute("UPDATE account SET locked = '0' WHERE id = '%d'",handler->GetSession()->GetAccountId()); + handler->PSendSysMessage(LANG_COMMAND_ACCLOCKUNLOCKED); + return true; + } + + handler->SendSysMessage(LANG_USE_BOL); + handler->SetSentErrorMessage(true); + return false; + } + + static bool HandleAccountPasswordCommand(ChatHandler* handler, const char* args) + { + if (!*args) + { + handler->SendSysMessage(LANG_CMD_SYNTAX); + handler->SetSentErrorMessage(true); + return false; + } + + char *old_pass = strtok((char*)args, " "); + char *new_pass = strtok(NULL, " "); + char *new_pass_c = strtok(NULL, " "); + + if (!old_pass || !new_pass || !new_pass_c) + { + handler->SendSysMessage(LANG_CMD_SYNTAX); + handler->SetSentErrorMessage(true); + return false; + } + + std::string password_old = old_pass; + std::string password_new = new_pass; + std::string password_new_c = new_pass_c; + + if (!sAccountMgr.CheckPassword(handler->GetSession()->GetAccountId(), password_old)) + { + handler->SendSysMessage(LANG_COMMAND_WRONGOLDPASSWORD); + handler->SetSentErrorMessage(true); + return false; + } + + if (strcmp(new_pass, new_pass_c) != 0) + { + handler->SendSysMessage(LANG_NEW_PASSWORDS_NOT_MATCH); + handler->SetSentErrorMessage(true); + return false; + } + + AccountOpResult result = sAccountMgr.ChangePassword(handler->GetSession()->GetAccountId(), password_new); + switch(result) + { + case AOR_OK: + handler->SendSysMessage(LANG_COMMAND_PASSWORD); + break; + case AOR_PASS_TOO_LONG: + handler->SendSysMessage(LANG_PASSWORD_TOO_LONG); + handler->SetSentErrorMessage(true); + return false; + default: + handler->SendSysMessage(LANG_COMMAND_NOTCHANGEPASSWORD); + handler->SetSentErrorMessage(true); + return false; + } + + return true; + } + + static bool HandleAccountCommand(ChatHandler* handler, const char* /*args*/) + { + AccountTypes gmlevel = handler->GetSession()->GetSecurity(); + handler->PSendSysMessage(LANG_ACCOUNT_LEVEL, uint32(gmlevel)); + return true; + } + + /// Set/Unset the expansion level for an account + static bool HandleAccountSetAddonCommand(ChatHandler* handler, const char *args) + { + ///- Get the command line arguments + char *szAcc = strtok((char*)args," "); + char *szExp = strtok(NULL," "); + + if (!szAcc) + return false; + + std::string account_name; + uint32 account_id; + + if (!szExp) + { + Player* player = handler->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)) + { + handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + + account_id = sAccountMgr.GetId(account_name); + if (!account_id) + { + handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + + } + + // Let set addon state only for lesser (strong) security level + // or to self account + if (handler->GetSession() && handler->GetSession()->GetAccountId () != account_id && + handler->HasLowerSecurityAccount (NULL,account_id,true)) + return false; + + int expansion = atoi(szExp); //get int anyway (0 if error) + if (expansion < 0 || uint8(expansion) > sWorld.getIntConfig(CONFIG_EXPANSION)) + return false; + + // No SQL injection + LoginDatabase.PExecute("UPDATE account SET expansion = '%d' WHERE id = '%u'",expansion,account_id); + handler->PSendSysMessage(LANG_ACCOUNT_SETADDON,account_name.c_str(),account_id,expansion); + return true; + } + + static bool HandleAccountSetGmLevelCommand(ChatHandler* handler, const char *args) + { + if (!*args) + return false; + + std::string targetAccountName; + uint32 targetAccountId = 0; + uint32 targetSecurity = 0; + uint32 gm = 0; + char* arg1 = strtok((char*)args, " "); + char* arg2 = strtok(NULL, " "); + char* arg3 = strtok(NULL, " "); + bool isAccountNameGiven = true; + + if (arg1 && !arg3) + { + if (!handler->getSelectedPlayer()) + return false; + isAccountNameGiven = false; + } + + // Check for second parameter + if (!isAccountNameGiven && !arg2) + return false; + + // Check for account + if (isAccountNameGiven) + { + targetAccountName = arg1; + if (!AccountMgr::normalizeString(targetAccountName)) + { + handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,targetAccountName.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + } + + // Check for invalid specified GM level. + gm = (isAccountNameGiven) ? atoi(arg2) : atoi(arg1); + if (gm > SEC_CONSOLE) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + + // handler->getSession() == NULL only for console + targetAccountId = (isAccountNameGiven) ? sAccountMgr.GetId(targetAccountName) : handler->getSelectedPlayer()->GetSession()->GetAccountId(); + int32 gmRealmID = (isAccountNameGiven) ? atoi(arg3) : atoi(arg2); + uint32 plSecurity; + if (handler->GetSession()) + plSecurity = sAccountMgr.GetSecurity(handler->GetSession()->GetAccountId(), gmRealmID); + else + plSecurity = SEC_CONSOLE; + + // can set security level only for target with less security and to less security that we have + // This is also reject self apply in fact + targetSecurity = sAccountMgr.GetSecurity(targetAccountId, gmRealmID); + if (targetSecurity >= plSecurity || gm >= plSecurity) + { + handler->SendSysMessage(LANG_YOURS_SECURITY_IS_LOW); + handler->SetSentErrorMessage(true); + return false; + } + + // Check and abort if the target gm has a higher rank on one of the realms and the new realm is -1 + if (gmRealmID == -1) + { + QueryResult result = LoginDatabase.PQuery("SELECT * FROM account_access WHERE id = '%u' AND gmlevel > '%d'", targetAccountId, gm); + if (result) + { + handler->SendSysMessage(LANG_YOURS_SECURITY_IS_LOW); + handler->SetSentErrorMessage(true); + return false; + } + } + + // Check if provided realmID has a negative value other than -1 + if (gmRealmID < -1) + { + handler->SendSysMessage(LANG_INVALID_REALMID); + handler->SetSentErrorMessage(true); + return false; + } + + // If gmRealmID is -1, delete all values for the account id, else, insert values for the specific realmID + if (gmRealmID == -1) + LoginDatabase.PExecute("DELETE FROM account_access WHERE id = '%u'", targetAccountId); + else + LoginDatabase.PExecute("DELETE FROM account_access WHERE id = '%u' AND (RealmID = '%d' OR RealmID = '-1')", targetAccountId, realmID); + + if (gm != 0) + LoginDatabase.PExecute("INSERT INTO account_access VALUES ('%u','%d','%d')", targetAccountId, gm, realmID); + handler->PSendSysMessage(LANG_YOU_CHANGE_SECURITY, targetAccountName.c_str(), gm); + return true; + } + + /// Set password for account + static bool HandleAccountSetPasswordCommand(ChatHandler* handler, const char *args) + { + if (!*args) + return false; + + ///- Get the command line arguments + char *szAccount = strtok ((char*)args," "); + char *szPassword1 = strtok (NULL," "); + char *szPassword2 = strtok (NULL," "); + + if (!szAccount||!szPassword1 || !szPassword2) + return false; + + std::string account_name = szAccount; + if (!AccountMgr::normalizeString(account_name)) + { + handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + + uint32 targetAccountId = sAccountMgr.GetId(account_name); + if (!targetAccountId) + { + handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + + /// can set password only for target with less security + /// This is also reject self apply in fact + if (handler->HasLowerSecurityAccount (NULL,targetAccountId,true)) + return false; + + if (strcmp(szPassword1,szPassword2)) + { + handler->SendSysMessage (LANG_NEW_PASSWORDS_NOT_MATCH); + handler->SetSentErrorMessage (true); + return false; + } + + AccountOpResult result = sAccountMgr.ChangePassword(targetAccountId, szPassword1); + + switch (result) + { + case AOR_OK: + handler->SendSysMessage(LANG_COMMAND_PASSWORD); + break; + case AOR_NAME_NOT_EXIST: + handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); + handler->SetSentErrorMessage(true); + return false; + case AOR_PASS_TOO_LONG: + handler->SendSysMessage(LANG_PASSWORD_TOO_LONG); + handler->SetSentErrorMessage(true); + return false; + default: + handler->SendSysMessage(LANG_COMMAND_NOTCHANGEPASSWORD); + handler->SetSentErrorMessage(true); + return false; + } + + return true; + } +}; + +void AddSC_account_commandscript() +{ + new account_commandscript(); +} diff --git a/src/server/scripts/Commands/cs_achievement.cpp b/src/server/scripts/Commands/cs_achievement.cpp new file mode 100644 index 00000000000..f3bf0381ecf --- /dev/null +++ b/src/server/scripts/Commands/cs_achievement.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2008-2010 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* ScriptData +Name: achievement_commandscript +%Complete: 100 +Comment: All achievement related commands +Category: commandscripts +EndScriptData */ + +#include "ScriptPCH.h" +#include "Chat.h" + +class achievement_commandscript : public CommandScript +{ + public: + achievement_commandscript() : CommandScript("achievement_commandscript") { } + + ChatCommand* GetCommands() const + { + static ChatCommand achievementCommandTable[] = + { + { "add", SEC_ADMINISTRATOR, false, &HandleAchievementAddCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + static ChatCommand commandTable[] = + { + { "achievement", SEC_ADMINISTRATOR, false, NULL, "", achievementCommandTable }, + { NULL, 0, false, NULL, "", NULL } + }; + return commandTable; + } + + static bool HandleAchievementAddCommand(ChatHandler* handler, const char *args) + { + if (!*args) + return false; + + uint32 achievementId = atoi((char*)args); + if (!achievementId) + { + if (char* cId = handler->extractKeyFromLink((char*)args, "Hachievement")) + achievementId = atoi(cId); + if (!achievementId) + return false; + } + + Player* target = handler->getSelectedPlayer(); + if (!target) + { + handler->SendSysMessage(LANG_NO_CHAR_SELECTED); + handler->SetSentErrorMessage(true); + return false; + } + + if (AchievementEntry const* pAE = GetAchievementStore()->LookupEntry(achievementId)) + target->CompletedAchievement(pAE, true); + + return true; + } +}; + +void AddSC_achievement_commandscript() +{ + new achievement_commandscript(); +} diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp new file mode 100644 index 00000000000..027f9d91aab --- /dev/null +++ b/src/server/scripts/Commands/cs_debug.cpp @@ -0,0 +1,1231 @@ +/* + * Copyright (C) 2008-2010 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* ScriptData +Name: debug_commandscript +%Complete: 100 +Comment: All debug related commands +Category: commandscripts +EndScriptData */ + +#include "ScriptPCH.h" +#include <fstream> +#include "BattlegroundMgr.h" + +class debug_commandscript : public CommandScript +{ + public: + debug_commandscript() : CommandScript("debug_commandscript") { } + + ChatCommand* GetCommands() const + { + static ChatCommand debugPlayCommandTable[] = + { + { "cinematic", SEC_MODERATOR, false, &HandleDebugPlayCinematicCommand, "", NULL }, + { "movie", SEC_MODERATOR, false, &HandleDebugPlayMovieCommand, "", NULL }, + { "sound", SEC_MODERATOR, false, &HandleDebugPlaySoundCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + static ChatCommand debugSendCommandTable[] = + { + { "buyerror", SEC_ADMINISTRATOR, false, &HandleDebugSendBuyErrorCommand, "", NULL }, + { "channelnotify", SEC_ADMINISTRATOR, false, &HandleDebugSendChannelNotifyCommand, "", NULL }, + { "chatmmessage", SEC_ADMINISTRATOR, false, &HandleDebugSendChatMsgCommand, "", NULL }, + { "equiperror", SEC_ADMINISTRATOR, false, &HandleDebugSendEquipErrorCommand, "", NULL }, + { "largepacket", SEC_ADMINISTRATOR, false, &HandleDebugSendLargePacketCommand, "", NULL }, + { "opcode", SEC_ADMINISTRATOR, false, &HandleDebugSendOpcodeCommand, "", NULL }, + { "poi", SEC_ADMINISTRATOR, false, &HandleDebugSendPoiCommand, "", NULL }, + { "qpartymsg", SEC_ADMINISTRATOR, false, &HandleDebugSendQuestPartyMsgCommand, "", NULL }, + { "qinvalidmsg", SEC_ADMINISTRATOR, false, &HandleDebugSendQuestInvalidMsgCommand,"", NULL }, + { "sellerror", SEC_ADMINISTRATOR, false, &HandleDebugSendSellErrorCommand, "", NULL }, + { "setphaseshift", SEC_ADMINISTRATOR, false, &HandleDebugSendSetPhaseShiftCommand, "", NULL }, + { "spellfail", SEC_ADMINISTRATOR, false, &HandleDebugSendSpellFailCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + static ChatCommand debugCommandTable[] = + { + { "setbit", SEC_ADMINISTRATOR, false, &HandleDebugSet32BitCommand, "", NULL }, + { "threat", SEC_ADMINISTRATOR, false, &HandleDebugThreatListCommand, "", NULL }, + { "hostil", SEC_ADMINISTRATOR, false, &HandleDebugHostileRefListCommand, "", NULL }, + { "anim", SEC_GAMEMASTER, false, &HandleDebugAnimCommand, "", NULL }, + { "arena", SEC_ADMINISTRATOR, false, &HandleDebugArenaCommand, "", NULL }, + { "bg", SEC_ADMINISTRATOR, false, &HandleDebugBattlegroundCommand, "", NULL }, + { "getitemstate", SEC_ADMINISTRATOR, false, &HandleDebugGetItemStateCommand, "", NULL }, + { "lootrecipient", SEC_GAMEMASTER, false, &HandleDebugGetLootRecipientCommand,"", NULL }, + { "getvalue", SEC_ADMINISTRATOR, false, &HandleDebugGetValueCommand, "", NULL }, + { "getitemvalue", SEC_ADMINISTRATOR, false, &HandleDebugGetItemValueCommand, "", NULL }, + { "Mod32Value", SEC_ADMINISTRATOR, false, &HandleDebugMod32ValueCommand, "", NULL }, + { "play", SEC_MODERATOR, false, NULL, "", debugPlayCommandTable }, + { "send", SEC_ADMINISTRATOR, false, NULL, "", debugSendCommandTable }, + { "setaurastate", SEC_ADMINISTRATOR, false, &HandleDebugSetAuraStateCommand, "", NULL }, + { "setitemvalue", SEC_ADMINISTRATOR, false, &HandleDebugSetItemValueCommand, "", NULL }, + { "setvalue", SEC_ADMINISTRATOR, false, &HandleDebugSetValueCommand, "", NULL }, + { "spawnvehicle", SEC_ADMINISTRATOR, false, &HandleDebugSpawnVehicleCommand, "", NULL }, + { "setvid", SEC_ADMINISTRATOR, false, &HandleDebugSetVehicleIdCommand, "", NULL }, + { "entervehicle", SEC_ADMINISTRATOR, false, &HandleDebugEnterVehicleCommand, "", NULL }, + { "uws", SEC_ADMINISTRATOR, false, &HandleDebugUpdateWorldStateCommand,"", NULL }, + { "update", SEC_ADMINISTRATOR, false, &HandleDebugUpdateCommand, "", NULL }, + { "itemexpire", SEC_ADMINISTRATOR, false, &HandleDebugItemExpireCommand, "", NULL }, + { "areatriggers", SEC_ADMINISTRATOR, false, &HandleDebugAreaTriggersCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + static ChatCommand commandTable[] = + { + { "debug", SEC_MODERATOR, true, NULL, "", debugCommandTable }, + { NULL, 0, false, NULL, "", NULL } + }; + return commandTable; + } + + static bool HandleDebugPlayCinematicCommand(ChatHandler* handler, const char* args) + { + // USAGE: .debug play cinematic #cinematicid + // #cinematicid - ID decimal number from CinemaicSequences.dbc (1st column) + if (!*args) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + + uint32 dwId = atoi((char*)args); + + if (!sCinematicSequencesStore.LookupEntry(dwId)) + { + handler->PSendSysMessage(LANG_CINEMATIC_NOT_EXIST, dwId); + handler->SetSentErrorMessage(true); + return false; + } + + handler->GetSession()->GetPlayer()->SendCinematicStart(dwId); + return true; + } + + static bool HandleDebugPlayMovieCommand(ChatHandler* handler, const char* args) + { + // USAGE: .debug play movie #movieid + // #movieid - ID decimal number from Movie.dbc (1st column) + if (!*args) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + + uint32 dwId = atoi((char*)args); + + if (!sMovieStore.LookupEntry(dwId)) + { + handler->PSendSysMessage(LANG_MOVIE_NOT_EXIST, dwId); + handler->SetSentErrorMessage(true); + return false; + } + + handler->GetSession()->GetPlayer()->SendMovieStart(dwId); + return true; + } + + //Play sound + static bool HandleDebugPlaySoundCommand(ChatHandler* handler, const char* args) + { + // USAGE: .debug playsound #soundid + // #soundid - ID decimal number from SoundEntries.dbc (1st column) + if (!*args) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + + uint32 dwSoundId = atoi((char*)args); + + if (!sSoundEntriesStore.LookupEntry(dwSoundId)) + { + handler->PSendSysMessage(LANG_SOUND_NOT_EXIST, dwSoundId); + handler->SetSentErrorMessage(true); + return false; + } + + Unit* unit = handler->getSelectedUnit(); + if (!unit) + { + handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + if (handler->GetSession()->GetPlayer()->GetSelection()) + unit->PlayDistanceSound(dwSoundId,handler->GetSession()->GetPlayer()); + else + unit->PlayDirectSound(dwSoundId,handler->GetSession()->GetPlayer()); + + handler->PSendSysMessage(LANG_YOU_HEAR_SOUND, dwSoundId); + return true; + } + + static bool HandleDebugSendSpellFailCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + char* px = strtok((char*)args, " "); + if (!px) + return false; + + uint8 failnum = (uint8)atoi(px); + if (failnum == 0 && *px != '0') + return false; + + char* p1 = strtok(NULL, " "); + uint8 failarg1 = p1 ? (uint8)atoi(p1) : 0; + + char* p2 = strtok(NULL, " "); + uint8 failarg2 = p2 ? (uint8)atoi(p2) : 0; + + WorldPacket data(SMSG_CAST_FAILED, 5); + data << uint8(0); + data << uint32(133); + data << uint8(failnum); + if (p1 || p2) + data << uint32(failarg1); + if (p2) + data << uint32(failarg2); + + handler->GetSession()->SendPacket(&data); + + return true; + } + + static bool HandleDebugSendPoiCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + Player *pPlayer = handler->GetSession()->GetPlayer(); + Unit* target = handler->getSelectedUnit(); + if (!target) + { + handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + return true; + } + + char* icon_text = strtok((char*)args, " "); + char* flags_text = strtok(NULL, " "); + if (!icon_text || !flags_text) + return false; + + uint32 icon = atol(icon_text); + uint32 flags = atol(flags_text); + + sLog.outDetail("Command : POI, NPC = %u, icon = %u flags = %u", target->GetGUIDLow(), icon,flags); + pPlayer->PlayerTalkClass->SendPointOfInterest(target->GetPositionX(), target->GetPositionY(), Poi_Icon(icon), flags, 30, "Test POI"); + return true; + } + + static bool HandleDebugSendEquipErrorCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + uint8 msg = atoi(args); + handler->GetSession()->GetPlayer()->SendEquipError(msg, NULL, NULL); + return true; + } + + static bool HandleDebugSendSellErrorCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + uint8 msg = atoi(args); + handler->GetSession()->GetPlayer()->SendSellError(msg, 0, 0, 0); + return true; + } + + static bool HandleDebugSendBuyErrorCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + uint8 msg = atoi(args); + handler->GetSession()->GetPlayer()->SendBuyError(msg, 0, 0, 0); + return true; + } + + static bool HandleDebugSendOpcodeCommand(ChatHandler* handler, const char* /*args*/) + { + Unit *unit = handler->getSelectedUnit(); + Player *player = NULL; + if (!unit || (unit->GetTypeId() != TYPEID_PLAYER)) + player = handler->GetSession()->GetPlayer(); + else + player = (Player*)unit; + if (!unit) unit = player; + + std::ifstream ifs("opcode.txt"); + if (ifs.bad()) + return false; + + uint32 opcode; + ifs >> opcode; + + WorldPacket data(opcode, 0); + + while (!ifs.eof()) + { + std::string type; + ifs >> type; + + if (type == "") + break; + + if (type == "uint8") + { + uint16 val1; + ifs >> val1; + data << uint8(val1); + } + else if (type == "uint16") + { + uint16 val2; + ifs >> val2; + data << val2; + } + else if (type == "uint32") + { + uint32 val3; + ifs >> val3; + data << val3; + } + else if (type == "uint64") + { + uint64 val4; + ifs >> val4; + data << val4; + } + else if (type == "float") + { + float val5; + ifs >> val5; + data << val5; + } + else if (type == "string") + { + std::string val6; + ifs >> val6; + data << val6; + } + else if (type == "appitsguid") + { + data.append(unit->GetPackGUID()); + } + else if (type == "appmyguid") + { + data.append(player->GetPackGUID()); + } + else if (type == "appgoguid") + { + GameObject *obj = handler->GetNearbyGameObject(); + if (!obj) + { + handler->PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, 0); + handler->SetSentErrorMessage(true); + ifs.close(); + return false; + } + data.append(obj->GetPackGUID()); + } + else if (type == "goguid") + { + GameObject *obj = handler->GetNearbyGameObject(); + if (!obj) + { + handler->PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, 0); + handler->SetSentErrorMessage(true); + ifs.close(); + return false; + } + data << uint64(obj->GetGUID()); + } + else if (type == "myguid") + { + data << uint64(player->GetGUID()); + } + else if (type == "itsguid") + { + data << uint64(unit->GetGUID()); + } + else if (type == "pos") + { + data << unit->GetPositionX(); + data << unit->GetPositionY(); + data << unit->GetPositionZ(); + } + else if (type == "mypos") + { + data << player->GetPositionX(); + data << player->GetPositionY(); + data << player->GetPositionZ(); + } + else + { + sLog.outDebug("Sending opcode: unknown type '%s'", type.c_str()); + break; + } + } + ifs.close(); + sLog.outDebug("Sending opcode %u", data.GetOpcode()); + data.hexlike(); + player->GetSession()->SendPacket(&data); + handler->PSendSysMessage(LANG_COMMAND_OPCODESENT, data.GetOpcode(), unit->GetName()); + return true; + } + + static bool HandleDebugUpdateWorldStateCommand(ChatHandler* handler, const char* args) + { + char* w = strtok((char*)args, " "); + char* s = strtok(NULL, " "); + + if (!w || !s) + return false; + + uint32 world = (uint32)atoi(w); + uint32 state = (uint32)atoi(s); + handler->GetSession()->GetPlayer()->SendUpdateWorldState(world, state); + return true; + } + + static bool HandleDebugAreaTriggersCommand(ChatHandler* handler, const char* /*args*/) + { + Player* plr = handler->GetSession()->GetPlayer(); + if (!plr->isDebugAreaTriggers) + { + handler->PSendSysMessage(LANG_DEBUG_AREATRIGGER_ON); + plr->isDebugAreaTriggers = true; + } else { + handler->PSendSysMessage(LANG_DEBUG_AREATRIGGER_OFF); + plr->isDebugAreaTriggers = false; + } + return true; + } + + //Send notification in channel + static bool HandleDebugSendChannelNotifyCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + const char *name = "test"; + uint8 code = atoi(args); + + WorldPacket data(SMSG_CHANNEL_NOTIFY, (1+10)); + data << code; // notify type + data << name; // channel name + data << uint32(0); + data << uint32(0); + handler->GetSession()->SendPacket(&data); + return true; + } + + //Send notification in chat + static bool HandleDebugSendChatMsgCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + const char *msg = "testtest"; + uint8 type = atoi(args); + WorldPacket data; + ChatHandler::FillMessageData(&data, handler->GetSession(), type, 0, "chan", handler->GetSession()->GetPlayer()->GetGUID(), msg, handler->GetSession()->GetPlayer()); + handler->GetSession()->SendPacket(&data); + return true; + } + + static bool HandleDebugSendQuestPartyMsgCommand(ChatHandler* handler, const char* args) + { + uint32 msg = atol((char*)args); + handler->GetSession()->GetPlayer()->SendPushToPartyResponse(handler->GetSession()->GetPlayer(), msg); + return true; + } + + static bool HandleDebugGetLootRecipientCommand(ChatHandler* handler, const char* /*args*/) + { + Creature* target = handler->getSelectedCreature(); + if (!target) + return false; + + handler->PSendSysMessage("loot recipient: %s", target->hasLootRecipient()?(target->GetLootRecipient()?target->GetLootRecipient()->GetName():"offline"):"no loot recipient"); + return true; + } + + static bool HandleDebugSendQuestInvalidMsgCommand(ChatHandler* handler, const char* args) + { + uint32 msg = atol((char*)args); + handler->GetSession()->GetPlayer()->SendCanTakeQuestResponse(msg); + return true; + } + + static bool HandleDebugGetItemStateCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + std::string state_str = args; + + ItemUpdateState state = ITEM_UNCHANGED; + bool list_queue = false, check_all = false; + if (state_str == "unchanged") state = ITEM_UNCHANGED; + else if (state_str == "changed") state = ITEM_CHANGED; + else if (state_str == "new") state = ITEM_NEW; + else if (state_str == "removed") state = ITEM_REMOVED; + else if (state_str == "queue") list_queue = true; + else if (state_str == "check_all") check_all = true; + else return false; + + Player* player = handler->getSelectedPlayer(); + if (!player) player = handler->GetSession()->GetPlayer(); + + if (!list_queue && !check_all) + { + state_str = "The player has the following " + state_str + " items: "; + handler->SendSysMessage(state_str.c_str()); + for (uint8 i = PLAYER_SLOT_START; i < PLAYER_SLOT_END; ++i) + { + if (i >= BUYBACK_SLOT_START && i < BUYBACK_SLOT_END) + continue; + + Item *item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, i); + if (!item) continue; + if (!item->IsBag()) + { + if (item->GetState() == state) + handler->PSendSysMessage("bag: 255 slot: %d guid: %d owner: %d", item->GetSlot(), item->GetGUIDLow(), GUID_LOPART(item->GetOwnerGUID())); + } + else + { + Bag *bag = (Bag*)item; + for (uint8 j = 0; j < bag->GetBagSize(); ++j) + { + Item* item2 = bag->GetItemByPos(j); + if (item2 && item2->GetState() == state) + handler->PSendSysMessage("bag: 255 slot: %d guid: %d owner: %d", item2->GetSlot(), item2->GetGUIDLow(), GUID_LOPART(item2->GetOwnerGUID())); + } + } + } + } + + if (list_queue) + { + std::vector<Item *> &updateQueue = player->GetItemUpdateQueue(); + for (size_t i = 0; i < updateQueue.size(); ++i) + { + Item *item = updateQueue[i]; + if (!item) continue; + + Bag *container = item->GetContainer(); + uint8 bag_slot = container ? container->GetSlot() : uint8(INVENTORY_SLOT_BAG_0); + + std::string st; + switch(item->GetState()) + { + case ITEM_UNCHANGED: st = "unchanged"; break; + case ITEM_CHANGED: st = "changed"; break; + case ITEM_NEW: st = "new"; break; + case ITEM_REMOVED: st = "removed"; break; + } + + handler->PSendSysMessage("bag: %d slot: %d guid: %d - state: %s", bag_slot, item->GetSlot(), item->GetGUIDLow(), st.c_str()); + } + if (updateQueue.empty()) + handler->PSendSysMessage("updatequeue empty"); + } + + if (check_all) + { + bool error = false; + std::vector<Item *> &updateQueue = player->GetItemUpdateQueue(); + for (uint8 i = PLAYER_SLOT_START; i < PLAYER_SLOT_END; ++i) + { + if (i >= BUYBACK_SLOT_START && i < BUYBACK_SLOT_END) + continue; + + Item *item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, i); + if (!item) continue; + + if (item->GetSlot() != i) + { + handler->PSendSysMessage("item at slot %d, guid %d has an incorrect slot value: %d", i, item->GetGUIDLow(), item->GetSlot()); + error = true; continue; + } + + if (item->GetOwnerGUID() != player->GetGUID()) + { + handler->PSendSysMessage("for the item at slot %d and itemguid %d, owner's guid (%d) and player's guid (%d) don't match!", item->GetSlot(), item->GetGUIDLow(), GUID_LOPART(item->GetOwnerGUID()), player->GetGUIDLow()); + error = true; continue; + } + + if (Bag *container = item->GetContainer()) + { + handler->PSendSysMessage("item at slot: %d guid: %d has a container (slot: %d, guid: %d) but shouldnt!", item->GetSlot(), item->GetGUIDLow(), container->GetSlot(), container->GetGUIDLow()); + error = true; continue; + } + + if (item->IsInUpdateQueue()) + { + uint16 qp = item->GetQueuePos(); + if (qp > updateQueue.size()) + { + handler->PSendSysMessage("item at slot: %d guid: %d has a queuepos (%d) larger than the update queue size! ", item->GetSlot(), item->GetGUIDLow(), qp); + error = true; continue; + } + + if (updateQueue[qp] == NULL) + { + handler->PSendSysMessage("item at slot: %d guid: %d has a queuepos (%d) that points to NULL in the queue!", item->GetSlot(), item->GetGUIDLow(), qp); + error = true; continue; + } + + if (updateQueue[qp] != item) + { + handler->PSendSysMessage("item at slot: %d guid: %d has has a queuepos (%d) that points to another item in the queue (bag: %d, slot: %d, guid: %d)", item->GetSlot(), item->GetGUIDLow(), qp, updateQueue[qp]->GetBagSlot(), updateQueue[qp]->GetSlot(), updateQueue[qp]->GetGUIDLow()); + error = true; continue; + } + } + else if (item->GetState() != ITEM_UNCHANGED) + { + handler->PSendSysMessage("item at slot: %d guid: %d is not in queue but should be (state: %d)!", item->GetSlot(), item->GetGUIDLow(), item->GetState()); + error = true; continue; + } + + if (item->IsBag()) + { + Bag *bag = (Bag*)item; + for (uint8 j = 0; j < bag->GetBagSize(); ++j) + { + Item* item2 = bag->GetItemByPos(j); + if (!item2) continue; + + if (item2->GetSlot() != j) + { + handler->PSendSysMessage("the item in bag %d slot %d, guid %d has an incorrect slot value: %d", bag->GetSlot(), j, item2->GetGUIDLow(), item2->GetSlot()); + error = true; continue; + } + + if (item2->GetOwnerGUID() != player->GetGUID()) + { + handler->PSendSysMessage("for the item in bag %d at slot %d and itemguid %d, owner's guid (%d) and player's guid (%d) don't match!", bag->GetSlot(), item2->GetSlot(), item2->GetGUIDLow(), GUID_LOPART(item2->GetOwnerGUID()), player->GetGUIDLow()); + error = true; continue; + } + + Bag *container = item2->GetContainer(); + if (!container) + { + handler->PSendSysMessage("the item in bag %d at slot %d with guid %d has no container!", bag->GetSlot(), item2->GetSlot(), item2->GetGUIDLow()); + error = true; continue; + } + + if (container != bag) + { + handler->PSendSysMessage("the item in bag %d at slot %d with guid %d has a different container(slot %d guid %d)!", bag->GetSlot(), item2->GetSlot(), item2->GetGUIDLow(), container->GetSlot(), container->GetGUIDLow()); + error = true; continue; + } + + if (item2->IsInUpdateQueue()) + { + uint16 qp = item2->GetQueuePos(); + if (qp > updateQueue.size()) + { + handler->PSendSysMessage("item in bag: %d at slot: %d guid: %d has a queuepos (%d) larger than the update queue size! ", bag->GetSlot(), item2->GetSlot(), item2->GetGUIDLow(), qp); + error = true; continue; + } + + if (updateQueue[qp] == NULL) + { + handler->PSendSysMessage("item in bag: %d at slot: %d guid: %d has a queuepos (%d) that points to NULL in the queue!", bag->GetSlot(), item2->GetSlot(), item2->GetGUIDLow(), qp); + error = true; continue; + } + + if (updateQueue[qp] != item2) + { + handler->PSendSysMessage("item in bag: %d at slot: %d guid: %d has has a queuepos (%d) that points to another item in the queue (bag: %d, slot: %d, guid: %d)", bag->GetSlot(), item2->GetSlot(), item2->GetGUIDLow(), qp, updateQueue[qp]->GetBagSlot(), updateQueue[qp]->GetSlot(), updateQueue[qp]->GetGUIDLow()); + error = true; continue; + } + } + else if (item2->GetState() != ITEM_UNCHANGED) + { + handler->PSendSysMessage("item in bag: %d at slot: %d guid: %d is not in queue but should be (state: %d)!", bag->GetSlot(), item2->GetSlot(), item2->GetGUIDLow(), item2->GetState()); + error = true; continue; + } + } + } + } + + for (size_t i = 0; i < updateQueue.size(); ++i) + { + Item *item = updateQueue[i]; + if (!item) continue; + + if (item->GetOwnerGUID() != player->GetGUID()) + { + handler->PSendSysMessage("queue(" SIZEFMTD "): for the an item (guid %d), the owner's guid (%d) and player's guid (%d) don't match!", i, item->GetGUIDLow(), GUID_LOPART(item->GetOwnerGUID()), player->GetGUIDLow()); + error = true; continue; + } + + if (item->GetQueuePos() != i) + { + handler->PSendSysMessage("queue(" SIZEFMTD "): for the an item (guid %d), the queuepos doesn't match it's position in the queue!", i, item->GetGUIDLow()); + error = true; continue; + } + + if (item->GetState() == ITEM_REMOVED) continue; + Item *test = player->GetItemByPos(item->GetBagSlot(), item->GetSlot()); + + if (test == NULL) + { + handler->PSendSysMessage("queue(" SIZEFMTD "): the bag(%d) and slot(%d) values for the item with guid %d are incorrect, the player doesn't have an item at that position!", i, item->GetBagSlot(), item->GetSlot(), item->GetGUIDLow()); + error = true; continue; + } + + if (test != item) + { + handler->PSendSysMessage("queue(" SIZEFMTD "): the bag(%d) and slot(%d) values for the item with guid %d are incorrect, the item with guid %d is there instead!", i, item->GetBagSlot(), item->GetSlot(), item->GetGUIDLow(), test->GetGUIDLow()); + error = true; continue; + } + } + if (!error) + handler->SendSysMessage("All OK!"); + } + + return true; + } + + static bool HandleDebugBattlegroundCommand(ChatHandler* handler, const char* /*args*/) + { + sBattlegroundMgr.ToggleTesting(); + return true; + } + + static bool HandleDebugArenaCommand(ChatHandler* handler, const char* /*args*/) + { + sBattlegroundMgr.ToggleArenaTesting(); + return true; + } + + static bool HandleDebugThreatListCommand(ChatHandler* handler, const char* /*args*/) + { + Creature* target = handler->getSelectedCreature(); + if (!target || target->isTotem() || target->isPet()) + return false; + + std::list<HostileReference*>& tlist = target->getThreatManager().getThreatList(); + std::list<HostileReference*>::iterator itr; + uint32 cnt = 0; + handler->PSendSysMessage("Threat list of %s (guid %u)",target->GetName(), target->GetGUIDLow()); + for (itr = tlist.begin(); itr != tlist.end(); ++itr) + { + Unit* unit = (*itr)->getTarget(); + if (!unit) + continue; + ++cnt; + handler->PSendSysMessage(" %u. %s (guid %u) - threat %f",cnt,unit->GetName(), unit->GetGUIDLow(), (*itr)->getThreat()); + } + handler->SendSysMessage("End of threat list."); + return true; + } + + static bool HandleDebugHostileRefListCommand(ChatHandler* handler, const char* /*args*/) + { + Unit* target = handler->getSelectedUnit(); + if (!target) + target = handler->GetSession()->GetPlayer(); + HostileReference* ref = target->getHostileRefManager().getFirst(); + uint32 cnt = 0; + handler->PSendSysMessage("Hostil reference list of %s (guid %u)",target->GetName(), target->GetGUIDLow()); + while (ref) + { + if (Unit * unit = ref->getSource()->getOwner()) + { + ++cnt; + handler->PSendSysMessage(" %u. %s (guid %u) - threat %f",cnt,unit->GetName(), unit->GetGUIDLow(), ref->getThreat()); + } + ref = ref->next(); + } + handler->SendSysMessage("End of hostil reference list."); + return true; + } + + static bool HandleDebugSetVehicleIdCommand(ChatHandler* handler, const char* args) + { + Unit* target = handler->getSelectedUnit(); + if (!target || target->IsVehicle()) + return false; + + if (!args) + return false; + + char* i = strtok((char*)args, " "); + if (!i) + return false; + + uint32 id = (uint32)atoi(i); + //target->SetVehicleId(id); + handler->PSendSysMessage("Vehicle id set to %u", id); + return true; + } + + static bool HandleDebugEnterVehicleCommand(ChatHandler* handler, const char* args) + { + Unit* target = handler->getSelectedUnit(); + if (!target || !target->IsVehicle()) + return false; + + if (!args) + return false; + + char* i = strtok((char*)args, " "); + if (!i) + return false; + + char* j = strtok(NULL, " "); + + uint32 entry = (uint32)atoi(i); + int8 seatId = j ? (int8)atoi(j) : -1; + + if (!entry) + handler->GetSession()->GetPlayer()->EnterVehicle(target, seatId); + else + { + Creature *passenger = NULL; + Trinity::AllCreaturesOfEntryInRange check(handler->GetSession()->GetPlayer(), entry, 20.0f); + Trinity::CreatureSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(handler->GetSession()->GetPlayer(), passenger, check); + handler->GetSession()->GetPlayer()->VisitNearbyObject(30.0f, searcher); + if (!passenger || passenger == target) + return false; + passenger->EnterVehicle(target, seatId); + } + + handler->PSendSysMessage("Unit %u entered vehicle %d", entry, (int32)seatId); + return true; + } + + static bool HandleDebugSpawnVehicleCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + char* e = strtok((char*)args, " "); + char* i = strtok(NULL, " "); + + if (!e) + return false; + + uint32 entry = (uint32)atoi(e); + + float x, y, z, o = handler->GetSession()->GetPlayer()->GetOrientation(); + handler->GetSession()->GetPlayer()->GetClosePoint(x, y, z, handler->GetSession()->GetPlayer()->GetObjectSize()); + + if (!i) + return handler->GetSession()->GetPlayer()->SummonCreature(entry, x, y, z, o); + + uint32 id = (uint32)atoi(i); + + CreatureInfo const *ci = sObjectMgr.GetCreatureTemplate(entry); + + if (!ci) + return false; + + VehicleEntry const *ve = sVehicleStore.LookupEntry(id); + + if (!ve) + return false; + + Creature *v = new Creature; + + Map *map = handler->GetSession()->GetPlayer()->GetMap(); + + if (!v->Create(sObjectMgr.GenerateLowGuid(HIGHGUID_VEHICLE), map, handler->GetSession()->GetPlayer()->GetPhaseMask(), entry, id, handler->GetSession()->GetPlayer()->GetTeam(), x, y, z, o)) + { + delete v; + return false; + } + + map->Add(v->ToCreature()); + + return true; + } + + static bool HandleDebugSendLargePacketCommand(ChatHandler* handler, const char* /*args*/) + { + const char* stuffingString = "This is a dummy string to push the packet's size beyond 128000 bytes. "; + std::ostringstream ss; + while (ss.str().size() < 128000) + ss << stuffingString; + handler->SendSysMessage(ss.str().c_str()); + return true; + } + + static bool HandleDebugSendSetPhaseShiftCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + uint32 PhaseShift = atoi(args); + handler->GetSession()->SendSetPhaseShift(PhaseShift); + return true; + } + + static bool HandleDebugGetItemValueCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + char* e = strtok((char*)args, " "); + char* f = strtok(NULL, " "); + + if (!e || !f) + return false; + + uint32 guid = (uint32)atoi(e); + uint32 index = (uint32)atoi(f); + + Item *i = handler->GetSession()->GetPlayer()->GetItemByGuid(MAKE_NEW_GUID(guid, 0, HIGHGUID_ITEM)); + + if (!i) + return false; + + if (index >= i->GetValuesCount()) + return false; + + uint32 value = i->GetUInt32Value(index); + + handler->PSendSysMessage("Item %u: value at %u is %u", guid, index, value); + + return true; + } + + static bool HandleDebugSetItemValueCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + char* e = strtok((char*)args, " "); + char* f = strtok(NULL, " "); + char* g = strtok(NULL, " "); + + if (!e || !f || !g) + return false; + + uint32 guid = (uint32)atoi(e); + uint32 index = (uint32)atoi(f); + uint32 value = (uint32)atoi(g); + + Item *i = handler->GetSession()->GetPlayer()->GetItemByGuid(MAKE_NEW_GUID(guid, 0, HIGHGUID_ITEM)); + + if (!i) + return false; + + if (index >= i->GetValuesCount()) + return false; + + i->SetUInt32Value(index, value); + + return true; + } + + static bool HandleDebugItemExpireCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + char* e = strtok((char*)args, " "); + if (!e) + return false; + + uint32 guid = (uint32)atoi(e); + + Item *i = handler->GetSession()->GetPlayer()->GetItemByGuid(MAKE_NEW_GUID(guid, 0, HIGHGUID_ITEM)); + + if (!i) + return false; + + handler->GetSession()->GetPlayer()->DestroyItem(i->GetBagSlot(), i->GetSlot(), true); + sScriptMgr.OnItemExpire(handler->GetSession()->GetPlayer(), i->GetProto()); + + return true; + } + + //show animation + static bool HandleDebugAnimCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + uint32 anim_id = atoi((char*)args); + handler->GetSession()->GetPlayer()->HandleEmoteCommand(anim_id); + return true; + } + + static bool HandleDebugSetAuraStateCommand(ChatHandler* handler, const char* args) + { + if (!*args) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + + Unit* unit = handler->getSelectedUnit(); + if (!unit) + { + handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + int32 state = atoi((char*)args); + if (!state) + { + // reset all states + for (int i = 1; i <= 32; ++i) + unit->ModifyAuraState(AuraState(i),false); + return true; + } + + unit->ModifyAuraState(AuraState(abs(state)),state > 0); + return true; + } + + static bool HandleDebugSetValueCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + char* px = strtok((char*)args, " "); + char* py = strtok(NULL, " "); + char* pz = strtok(NULL, " "); + + if (!px || !py) + return false; + + WorldObject* target = handler->getSelectedObject(); + if (!target) + { + handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + uint64 guid = target->GetGUID(); + + uint32 Opcode = (uint32)atoi(px); + if (Opcode >= target->GetValuesCount()) + { + handler->PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, GUID_LOPART(guid), target->GetValuesCount()); + return false; + } + uint32 iValue; + float fValue; + bool isint32 = true; + if (pz) + isint32 = (bool)atoi(pz); + if (isint32) + { + iValue = (uint32)atoi(py); + sLog.outDebug(handler->GetTrinityString(LANG_SET_UINT), GUID_LOPART(guid), Opcode, iValue); + target->SetUInt32Value(Opcode , iValue); + handler->PSendSysMessage(LANG_SET_UINT_FIELD, GUID_LOPART(guid), Opcode,iValue); + } + else + { + fValue = (float)atof(py); + sLog.outDebug(handler->GetTrinityString(LANG_SET_FLOAT), GUID_LOPART(guid), Opcode, fValue); + target->SetFloatValue(Opcode , fValue); + handler->PSendSysMessage(LANG_SET_FLOAT_FIELD, GUID_LOPART(guid), Opcode,fValue); + } + + return true; + } + + static bool HandleDebugGetValueCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + char* px = strtok((char*)args, " "); + char* pz = strtok(NULL, " "); + + if (!px) + return false; + + Unit* target = handler->getSelectedUnit(); + if (!target) + { + handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + uint64 guid = target->GetGUID(); + + uint32 Opcode = (uint32)atoi(px); + if (Opcode >= target->GetValuesCount()) + { + handler->PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, GUID_LOPART(guid), target->GetValuesCount()); + return false; + } + uint32 iValue; + float fValue; + bool isint32 = true; + if (pz) + isint32 = (bool)atoi(pz); + + if (isint32) + { + iValue = target->GetUInt32Value(Opcode); + sLog.outDebug(handler->GetTrinityString(LANG_GET_UINT), GUID_LOPART(guid), Opcode, iValue); + handler->PSendSysMessage(LANG_GET_UINT_FIELD, GUID_LOPART(guid), Opcode, iValue); + } + else + { + fValue = target->GetFloatValue(Opcode); + sLog.outDebug(handler->GetTrinityString(LANG_GET_FLOAT), GUID_LOPART(guid), Opcode, fValue); + handler->PSendSysMessage(LANG_GET_FLOAT_FIELD, GUID_LOPART(guid), Opcode, fValue); + } + + return true; + } + + static bool HandleDebugMod32ValueCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + char* px = strtok((char*)args, " "); + char* py = strtok(NULL, " "); + + if (!px || !py) + return false; + + uint32 Opcode = (uint32)atoi(px); + int Value = atoi(py); + + if (Opcode >= handler->GetSession()->GetPlayer()->GetValuesCount()) + { + handler->PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, handler->GetSession()->GetPlayer()->GetGUIDLow(), handler->GetSession()->GetPlayer()->GetValuesCount()); + return false; + } + + sLog.outDebug(handler->GetTrinityString(LANG_CHANGE_32BIT), Opcode, Value); + + int CurrentValue = (int)handler->GetSession()->GetPlayer()->GetUInt32Value(Opcode); + + CurrentValue += Value; + handler->GetSession()->GetPlayer()->SetUInt32Value(Opcode , (uint32)CurrentValue); + + handler->PSendSysMessage(LANG_CHANGE_32BIT_FIELD, Opcode,CurrentValue); + + return true; + } + + static bool HandleDebugUpdateCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + uint32 updateIndex; + uint32 value; + + char* pUpdateIndex = strtok((char*)args, " "); + + Unit* chr = handler->getSelectedUnit(); + if (chr == NULL) + { + handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + if (!pUpdateIndex) + { + return true; + } + updateIndex = atoi(pUpdateIndex); + //check updateIndex + if (chr->GetTypeId() == TYPEID_PLAYER) + { + if (updateIndex >= PLAYER_END) return true; + } + else + { + if (updateIndex >= UNIT_END) return true; + } + + char* pvalue = strtok(NULL, " "); + if (!pvalue) + { + value=chr->GetUInt32Value(updateIndex); + + handler->PSendSysMessage(LANG_UPDATE, chr->GetGUIDLow(),updateIndex,value); + return true; + } + + value=atoi(pvalue); + + handler->PSendSysMessage(LANG_UPDATE_CHANGE, chr->GetGUIDLow(),updateIndex,value); + + chr->SetUInt32Value(updateIndex,value); + + return true; + } +static bool HandleDebugSet32BitCommand(ChatHandler* handler, const char* args) +{ + if (!*args) + return false; + + WorldObject* target = handler->getSelectedObject(); + if (!target) + { + handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + char* px = strtok((char*)args, " "); + char* py = strtok(NULL, " "); + + if (!px || !py) + return false; + + uint32 Opcode = (uint32)atoi(px); + uint32 Value = (uint32)atoi(py); + if (Value > 32) //uint32 = 32 bits + return false; + + sLog.outDebug(handler->GetTrinityString(LANG_SET_32BIT), Opcode, Value); + + uint32 iValue = Value ? 1 << (Value - 1) : 0; + target->SetUInt32Value(Opcode , iValue); + + handler->PSendSysMessage(LANG_SET_32BIT_FIELD, Opcode, iValue); + return true; +} +}; + +void AddSC_debug_commandscript() +{ + new debug_commandscript(); +} diff --git a/src/server/scripts/Commands/cs_gm.cpp b/src/server/scripts/Commands/cs_gm.cpp new file mode 100644 index 00000000000..41fa7a3b4d7 --- /dev/null +++ b/src/server/scripts/Commands/cs_gm.cpp @@ -0,0 +1,243 @@ +/* + * Copyright (C) 2008-2010 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* ScriptData +Name: gm_commandscript +%Complete: 100 +Comment: All gm related commands +Category: commandscripts +EndScriptData */ + +#include "ScriptPCH.h" + +class gm_commandscript : public CommandScript +{ + public: + gm_commandscript() : CommandScript("gm_commandscript") { } + + ChatCommand* GetCommands() const + { + static ChatCommand gmCommandTable[] = + { + { "chat", SEC_MODERATOR, false, &HandleGMChatCommand, "", NULL }, + { "fly", SEC_ADMINISTRATOR, false, &HandleGMFlyCommand, "", NULL }, + { "ingame", SEC_PLAYER, true, &HandleGMListIngameCommand, "", NULL }, + { "list", SEC_ADMINISTRATOR, true, &HandleGMListFullCommand, "", NULL }, + { "visible", SEC_MODERATOR, false, &HandleGMVisibleCommand, "", NULL }, + { "", SEC_MODERATOR, false, &HandleGMCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + static ChatCommand commandTable[] = + { + { "gm", SEC_MODERATOR, true, NULL, "", gmCommandTable }, + { NULL, 0, false, NULL, "", NULL } + }; + return commandTable; + } + + // Enables or disables hiding of the staff badge + static bool HandleGMChatCommand(ChatHandler* handler, const char* args) + { + if (!*args) + { + if (handler->GetSession()->GetPlayer()->isGMChat()) + handler->GetSession()->SendNotification(LANG_GM_CHAT_ON); + else + handler->GetSession()->SendNotification(LANG_GM_CHAT_OFF); + return true; + } + + std::string argstr = (char*)args; + + if (argstr == "on") + { + handler->GetSession()->GetPlayer()->SetGMChat(true); + handler->GetSession()->SendNotification(LANG_GM_CHAT_ON); + return true; + } + + if (argstr == "off") + { + handler->GetSession()->GetPlayer()->SetGMChat(false); + handler->GetSession()->SendNotification(LANG_GM_CHAT_OFF); + return true; + } + + handler->SendSysMessage(LANG_USE_BOL); + handler->SetSentErrorMessage(true); + return false; + } + + static bool HandleGMFlyCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + Player *target = handler->getSelectedPlayer(); + if (!target) + target = handler->GetSession()->GetPlayer(); + + WorldPacket data(12); + if (strncmp(args, "on", 3) == 0) + data.SetOpcode(SMSG_MOVE_SET_CAN_FLY); + else if (strncmp(args, "off", 4) == 0) + data.SetOpcode(SMSG_MOVE_UNSET_CAN_FLY); + else + { + handler->SendSysMessage(LANG_USE_BOL); + return false; + } + data.append(target->GetPackGUID()); + data << uint32(0); // unknown + target->SendMessageToSet(&data, true); + handler->PSendSysMessage(LANG_COMMAND_FLYMODE_STATUS, handler->GetNameLink(target).c_str(), args); + return true; + } + + static bool HandleGMListIngameCommand(ChatHandler* handler, const char* /*args*/) + { + bool first = true; + + ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, *HashMapHolder<Player>::GetLock(), true); + HashMapHolder<Player>::MapType &m = sObjectAccessor.GetPlayers(); + for (HashMapHolder<Player>::MapType::const_iterator itr = m.begin(); itr != m.end(); ++itr) + { + AccountTypes itr_sec = itr->second->GetSession()->GetSecurity(); + if ((itr->second->isGameMaster() || (itr_sec > SEC_PLAYER && itr_sec <= AccountTypes(sWorld.getIntConfig(CONFIG_GM_LEVEL_IN_GM_LIST)))) && + (!handler->GetSession() || itr->second->IsVisibleGloballyFor(handler->GetSession()->GetPlayer()))) + { + if (first) + { + handler->SendSysMessage(LANG_GMS_ON_SRV); + first = false; + } + + handler->SendSysMessage(handler->GetNameLink(itr->second).c_str()); + } + } + + if (first) + handler->SendSysMessage(LANG_GMS_NOT_LOGGED); + + return true; + } + + /// Display the list of GMs + static bool HandleGMListFullCommand(ChatHandler* handler, const char* /*args*/) + { + ///- Get the accounts with GM Level >0 + QueryResult result = LoginDatabase.Query("SELECT a.username,aa.gmlevel FROM account a, account_access aa WHERE a.id=aa.id AND aa.gmlevel > 0"); + if (result) + { + handler->SendSysMessage(LANG_GMLIST); + handler->SendSysMessage(" ======================== "); + handler->SendSysMessage(LANG_GMLIST_HEADER); + handler->SendSysMessage(" ======================== "); + + ///- Cycle through them. Display username and GM level + do + { + Field *fields = result->Fetch(); + handler->PSendSysMessage("|%15s|%6s|", fields[0].GetCString(),fields[1].GetCString()); + } + while (result->NextRow()); + + handler->PSendSysMessage(" ======================== "); + } + else + handler->PSendSysMessage(LANG_GMLIST_EMPTY); + return true; + } + + //Enable\Disable Invisible mode + static bool HandleGMVisibleCommand(ChatHandler* handler, const char* args) + { + if (!*args) + { + handler->PSendSysMessage(LANG_YOU_ARE, handler->GetSession()->GetPlayer()->isGMVisible() ? handler->GetTrinityString(LANG_VISIBLE) : handler->GetTrinityString(LANG_INVISIBLE)); + return true; + } + + std::string argstr = (char*)args; + + if (argstr == "on") + { + handler->GetSession()->GetPlayer()->SetGMVisible(true); + handler->GetSession()->SendNotification(LANG_INVISIBLE_VISIBLE); + return true; + } + + if (argstr == "off") + { + handler->GetSession()->SendNotification(LANG_INVISIBLE_INVISIBLE); + handler->GetSession()->GetPlayer()->SetGMVisible(false); + return true; + } + + handler->SendSysMessage(LANG_USE_BOL); + handler->SetSentErrorMessage(true); + return false; + } + + //Enable\Disable GM Mode + static bool HandleGMCommand(ChatHandler* handler, const char* args) + { + if (!*args) + { + if (handler->GetSession()->GetPlayer()->isGameMaster()) + handler->GetSession()->SendNotification(LANG_GM_ON); + else + handler->GetSession()->SendNotification(LANG_GM_OFF); + return true; + } + + std::string argstr = (char*)args; + + if (argstr == "on") + { + handler->GetSession()->GetPlayer()->SetGameMaster(true); + handler->GetSession()->SendNotification(LANG_GM_ON); + handler->GetSession()->GetPlayer()->UpdateTriggerVisibility(); + #ifdef _DEBUG_VMAPS + VMAP::IVMapManager *vMapManager = VMAP::VMapFactory::createOrGetVMapManager(); + vMapManager->processCommand("stoplog"); + #endif + return true; + } + + if (argstr == "off") + { + handler->GetSession()->GetPlayer()->SetGameMaster(false); + handler->GetSession()->SendNotification(LANG_GM_OFF); + handler->GetSession()->GetPlayer()->UpdateTriggerVisibility(); + #ifdef _DEBUG_VMAPS + VMAP::IVMapManager *vMapManager = VMAP::VMapFactory::createOrGetVMapManager(); + vMapManager->processCommand("startlog"); + #endif + return true; + } + + handler->SendSysMessage(LANG_USE_BOL); + handler->SetSentErrorMessage(true); + return false; + } +}; + +void AddSC_gm_commandscript() +{ + new gm_commandscript(); +} diff --git a/src/server/scripts/Commands/cs_go.cpp b/src/server/scripts/Commands/cs_go.cpp new file mode 100644 index 00000000000..27cfc5c3268 --- /dev/null +++ b/src/server/scripts/Commands/cs_go.cpp @@ -0,0 +1,617 @@ +/* + * Copyright (C) 2008-2010 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* ScriptData +Name: go_commandscript +%Complete: 100 +Comment: All go related commands +Category: commandscripts +EndScriptData */ + +#include "ScriptPCH.h" +#include "MapManager.h" +#include "TicketMgr.h" + +class go_commandscript : public CommandScript +{ + public: + go_commandscript() : CommandScript("go_commandscript") { } + + ChatCommand* GetCommands() const + { + static ChatCommand goCommandTable[] = + { + { "creature", SEC_MODERATOR, false, &HandleGoCreatureCommand, "", NULL }, + { "graveyard", SEC_MODERATOR, false, &HandleGoGraveyardCommand, "", NULL }, + { "grid", SEC_MODERATOR, false, &HandleGoGridCommand, "", NULL }, + { "object", SEC_MODERATOR, false, &HandleGoObjectCommand, "", NULL }, + { "taxinode", SEC_MODERATOR, false, &HandleGoTaxinodeCommand, "", NULL }, + { "trigger", SEC_MODERATOR, false, &HandleGoTriggerCommand, "", NULL }, + { "zonexy", SEC_MODERATOR, false, &HandleGoZoneXYCommand, "", NULL }, + { "xy", SEC_MODERATOR, false, &HandleGoXYCommand, "", NULL }, + { "xyz", SEC_MODERATOR, false, &HandleGoXYZCommand, "", NULL }, + { "ticket", SEC_MODERATOR, false, &HandleGoTicketCommand, "", NULL }, + { "", SEC_MODERATOR, false, &HandleGoXYZCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + + static ChatCommand commandTable[] = + { + { "go", SEC_MODERATOR, false, NULL, "", goCommandTable }, + { NULL, 0, false, NULL, "", NULL } + }; + return commandTable; + } + + /** \brief Teleport the GM to the specified creature + * + * .gocreature <GUID> --> TP using creature.guid + * .gocreature azuregos --> TP player to the mob with this name + * Warning: If there is more than one mob with this name + * you will be teleported to the first one that is found. + * .gocreature id 6109 --> TP player to the mob, that has this creature_template.entry + * Warning: If there is more than one mob with this "id" + * you will be teleported to the first one that is found. + */ + //teleport to creature + static bool HandleGoCreatureCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + Player* _player = handler->GetSession()->GetPlayer(); + + // "id" or number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r + char* pParam1 = handler->extractKeyFromLink((char*)args,"Hcreature"); + if (!pParam1) + return false; + + std::ostringstream whereClause; + + // User wants to teleport to the NPC's template entry + if (strcmp(pParam1, "id") == 0) + { + //sLog.outError("DEBUG: ID found"); + + // Get the "creature_template.entry" + // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r + char* tail = strtok(NULL,""); + if (!tail) + return false; + char* cId = handler->extractKeyFromLink(tail,"Hcreature_entry"); + if (!cId) + return false; + + int32 tEntry = atoi(cId); + //sLog.outError("DEBUG: ID value: %d", tEntry); + if (!tEntry) + return false; + + whereClause << "WHERE id = '" << tEntry << "'"; + } + else + { + //sLog.outError("DEBUG: ID *not found*"); + + int32 guid = atoi(pParam1); + + // Number is invalid - maybe the user specified the mob's name + if (!guid) + { + std::string name = pParam1; + WorldDatabase.escape_string(name); + whereClause << ", creature_template WHERE creature.id = creature_template.entry AND creature_template.name "_LIKE_" '" << name << "'"; + } + else + { + whereClause << "WHERE guid = '" << guid << "'"; + } + } + //sLog.outError("DEBUG: %s", whereClause.c_str()); + + QueryResult result = WorldDatabase.PQuery("SELECT position_x,position_y,position_z,orientation,map FROM creature %s", whereClause.str().c_str()); + if (!result) + { + handler->SendSysMessage(LANG_COMMAND_GOCREATNOTFOUND); + handler->SetSentErrorMessage(true); + return false; + } + if (result->GetRowCount() > 1) + handler->SendSysMessage(LANG_COMMAND_GOCREATMULTIPLE); + + 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(); + + if (!MapManager::IsValidMapCoord(mapid,x,y,z,ort)) + { + handler->PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid); + handler->SetSentErrorMessage(true); + return false; + } + + // stop flight if need + if (_player->isInFlight()) + { + _player->GetMotionMaster()->MovementExpired(); + _player->CleanupAfterTaxiFlight(); + } + // save only in non-flight case + else + _player->SaveRecallPosition(); + + _player->TeleportTo(mapid, x, y, z, ort); + return true; + } + + static bool HandleGoGraveyardCommand(ChatHandler* handler, const char* args) + { + Player* _player = handler->GetSession()->GetPlayer(); + + if (!*args) + return false; + + char *gyId = strtok((char*)args, " "); + if (!gyId) + return false; + + int32 i_gyId = atoi(gyId); + + if (!i_gyId) + return false; + + WorldSafeLocsEntry const* gy = sWorldSafeLocsStore.LookupEntry(i_gyId); + if (!gy) + { + handler->PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST,i_gyId); + handler->SetSentErrorMessage(true); + return false; + } + + if (!MapManager::IsValidMapCoord(gy->map_id,gy->x,gy->y,gy->z)) + { + handler->PSendSysMessage(LANG_INVALID_TARGET_COORD,gy->x,gy->y,gy->map_id); + handler->SetSentErrorMessage(true); + return false; + } + + // stop flight if need + if (_player->isInFlight()) + { + _player->GetMotionMaster()->MovementExpired(); + _player->CleanupAfterTaxiFlight(); + } + // save only in non-flight case + else + _player->SaveRecallPosition(); + + _player->TeleportTo(gy->map_id, gy->x, gy->y, gy->z, _player->GetOrientation()); + return true; + } + + //teleport to grid + static bool HandleGoGridCommand(ChatHandler* handler, const char* args) + { + if (!*args) return false; + Player* _player = handler->GetSession()->GetPlayer(); + + char* px = strtok((char*)args, " "); + char* py = strtok(NULL, " "); + char* pmapid = strtok(NULL, " "); + + if (!px || !py) + return false; + + float grid_x = (float)atof(px); + float grid_y = (float)atof(py); + uint32 mapid; + if (pmapid) + mapid = (uint32)atoi(pmapid); + else mapid = _player->GetMapId(); + + // center of grid + float x = (grid_x-CENTER_GRID_ID+0.5f)*SIZE_OF_GRIDS; + float y = (grid_y-CENTER_GRID_ID+0.5f)*SIZE_OF_GRIDS; + + if (!MapManager::IsValidMapCoord(mapid,x,y)) + { + handler->PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid); + handler->SetSentErrorMessage(true); + return false; + } + + // stop flight if need + if (_player->isInFlight()) + { + _player->GetMotionMaster()->MovementExpired(); + _player->CleanupAfterTaxiFlight(); + } + // save only in non-flight case + else + _player->SaveRecallPosition(); + + Map const *map = sMapMgr.CreateBaseMap(mapid); + float z = std::max(map->GetHeight(x, y, MAX_HEIGHT), map->GetWaterLevel(x, y)); + _player->TeleportTo(mapid, x, y, z, _player->GetOrientation()); + + return true; + } + + //teleport to gameobject + static bool HandleGoObjectCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + Player* _player = handler->GetSession()->GetPlayer(); + + // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r + char* cId = handler->extractKeyFromLink((char*)args,"Hgameobject"); + if (!cId) + return false; + + int32 guid = atoi(cId); + if (!guid) + return false; + + float x, y, z, ort; + int mapid; + + // by DB guid + if (GameObjectData const* go_data = sObjectMgr.GetGOData(guid)) + { + x = go_data->posX; + y = go_data->posY; + z = go_data->posZ; + ort = go_data->orientation; + mapid = go_data->mapid; + } + else + { + handler->SendSysMessage(LANG_COMMAND_GOOBJNOTFOUND); + handler->SetSentErrorMessage(true); + return false; + } + + if (!MapManager::IsValidMapCoord(mapid,x,y,z,ort)) + { + handler->PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid); + handler->SetSentErrorMessage(true); + return false; + } + + // stop flight if need + if (_player->isInFlight()) + { + _player->GetMotionMaster()->MovementExpired(); + _player->CleanupAfterTaxiFlight(); + } + // save only in non-flight case + else + _player->SaveRecallPosition(); + + _player->TeleportTo(mapid, x, y, z, ort); + return true; + } + + static bool HandleGoTaxinodeCommand(ChatHandler* handler, const char* args) + { + Player* _player = handler->GetSession()->GetPlayer(); + + if (!*args) + return false; + + char* cNodeId = handler->extractKeyFromLink((char*)args,"Htaxinode"); + if (!cNodeId) + return false; + + int32 i_nodeId = atoi(cNodeId); + if (!i_nodeId) + return false; + + TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(i_nodeId); + if (!node) + { + handler->PSendSysMessage(LANG_COMMAND_GOTAXINODENOTFOUND,i_nodeId); + handler->SetSentErrorMessage(true); + return false; + } + + if ((node->x == 0.0f && node->y == 0.0f && node->z == 0.0f) || + !MapManager::IsValidMapCoord(node->map_id,node->x,node->y,node->z)) + { + handler->PSendSysMessage(LANG_INVALID_TARGET_COORD,node->x,node->y,node->map_id); + handler->SetSentErrorMessage(true); + return false; + } + + // stop flight if need + if (_player->isInFlight()) + { + _player->GetMotionMaster()->MovementExpired(); + _player->CleanupAfterTaxiFlight(); + } + // save only in non-flight case + else + _player->SaveRecallPosition(); + + _player->TeleportTo(node->map_id, node->x, node->y, node->z, _player->GetOrientation()); + return true; + } + + static bool HandleGoTriggerCommand(ChatHandler* handler, const char* args) + { + Player* _player = handler->GetSession()->GetPlayer(); + + if (!*args) + return false; + + char *atId = strtok((char*)args, " "); + if (!atId) + return false; + + int32 i_atId = atoi(atId); + + if (!i_atId) + return false; + + AreaTriggerEntry const* at = sAreaTriggerStore.LookupEntry(i_atId); + if (!at) + { + handler->PSendSysMessage(LANG_COMMAND_GOAREATRNOTFOUND,i_atId); + handler->SetSentErrorMessage(true); + return false; + } + + if (!MapManager::IsValidMapCoord(at->mapid,at->x,at->y,at->z)) + { + handler->PSendSysMessage(LANG_INVALID_TARGET_COORD,at->x,at->y,at->mapid); + handler->SetSentErrorMessage(true); + return false; + } + + // stop flight if need + if (_player->isInFlight()) + { + _player->GetMotionMaster()->MovementExpired(); + _player->CleanupAfterTaxiFlight(); + } + // save only in non-flight case + else + _player->SaveRecallPosition(); + + _player->TeleportTo(at->mapid, at->x, at->y, at->z, _player->GetOrientation()); + return true; + } + + //teleport at coordinates + static bool HandleGoZoneXYCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + Player* _player = handler->GetSession()->GetPlayer(); + + char* px = strtok((char*)args, " "); + char* py = strtok(NULL, " "); + char* tail = strtok(NULL,""); + + char* cAreaId = handler->extractKeyFromLink(tail,"Harea"); // string or [name] Shift-click form |color|Harea:area_id|h[name]|h|r + + if (!px || !py) + return false; + + float x = (float)atof(px); + float y = (float)atof(py); + + // prevent accept wrong numeric args + if ((x == 0.0f && *px != '0') || (y == 0.0f && *py != '0')) + return false; + + uint32 areaid = cAreaId ? (uint32)atoi(cAreaId) : _player->GetZoneId(); + + AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(areaid); + + if (x < 0 || x > 100 || y < 0 || y > 100 || !areaEntry) + { + handler->PSendSysMessage(LANG_INVALID_ZONE_COORD,x,y,areaid); + handler->SetSentErrorMessage(true); + return false; + } + + // update to parent zone if exist (client map show only zones without parents) + AreaTableEntry const* zoneEntry = areaEntry->zone ? GetAreaEntryByAreaID(areaEntry->zone) : areaEntry; + + Map const *map = sMapMgr.CreateBaseMap(zoneEntry->mapid); + + if (map->Instanceable()) + { + handler->PSendSysMessage(LANG_INVALID_ZONE_MAP,areaEntry->ID,areaEntry->area_name[handler->GetSessionDbcLocale()],map->GetId(),map->GetMapName()); + handler->SetSentErrorMessage(true); + return false; + } + + Zone2MapCoordinates(x,y,zoneEntry->ID); + + if (!MapManager::IsValidMapCoord(zoneEntry->mapid,x,y)) + { + handler->PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,zoneEntry->mapid); + handler->SetSentErrorMessage(true); + return false; + } + + // stop flight if need + if (_player->isInFlight()) + { + _player->GetMotionMaster()->MovementExpired(); + _player->CleanupAfterTaxiFlight(); + } + // save only in non-flight case + else + _player->SaveRecallPosition(); + + float z = std::max(map->GetHeight(x, y, MAX_HEIGHT), map->GetWaterLevel(x, y)); + _player->TeleportTo(zoneEntry->mapid, x, y, z, _player->GetOrientation()); + + return true; + } + + //teleport at coordinates + static bool HandleGoXYCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + Player* _player = handler->GetSession()->GetPlayer(); + + char* px = strtok((char*)args, " "); + char* py = strtok(NULL, " "); + char* pmapid = strtok(NULL, " "); + + if (!px || !py) + return false; + + float x = (float)atof(px); + float y = (float)atof(py); + uint32 mapid; + if (pmapid) + mapid = (uint32)atoi(pmapid); + else + mapid = _player->GetMapId(); + + if (!MapManager::IsValidMapCoord(mapid,x,y)) + { + handler->PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid); + handler->SetSentErrorMessage(true); + return false; + } + + // stop flight if need + if (_player->isInFlight()) + { + _player->GetMotionMaster()->MovementExpired(); + _player->CleanupAfterTaxiFlight(); + } + // save only in non-flight case + else + _player->SaveRecallPosition(); + + Map const *map = sMapMgr.CreateBaseMap(mapid); + float z = std::max(map->GetHeight(x, y, MAX_HEIGHT), map->GetWaterLevel(x, y)); + + _player->TeleportTo(mapid, x, y, z, _player->GetOrientation()); + + return true; + } + + //teleport at coordinates, including Z + static bool HandleGoXYZCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + Player* _player = handler->GetSession()->GetPlayer(); + + char* px = strtok((char*)args, " "); + char* py = strtok(NULL, " "); + char* pz = strtok(NULL, " "); + char* pmapid = strtok(NULL, " "); + + if (!px || !py || !pz) + return false; + + float x = (float)atof(px); + float y = (float)atof(py); + float z = (float)atof(pz); + uint32 mapid; + if (pmapid) + mapid = (uint32)atoi(pmapid); + else + mapid = _player->GetMapId(); + + if (!MapManager::IsValidMapCoord(mapid,x,y,z)) + { + handler->PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid); + handler->SetSentErrorMessage(true); + return false; + } + + // stop flight if need + if (_player->isInFlight()) + { + _player->GetMotionMaster()->MovementExpired(); + _player->CleanupAfterTaxiFlight(); + } + // save only in non-flight case + else + _player->SaveRecallPosition(); + + _player->TeleportTo(mapid, x, y, z, _player->GetOrientation()); + + return true; + } + + static bool HandleGoTicketCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + char *cstrticket_id = strtok((char*)args, " "); + + if (!cstrticket_id) + return false; + + uint64 ticket_id = atoi(cstrticket_id); + if (!ticket_id) + return false; + + GM_Ticket *ticket = sTicketMgr.GetGMTicket(ticket_id); + if (!ticket) + { + handler->SendSysMessage(LANG_COMMAND_TICKETNOTEXIST); + return true; + } + + float x, y, z; + int mapid; + + x = ticket->pos_x; + y = ticket->pos_y; + z = ticket->pos_z; + mapid = ticket->map; + + Player* _player = handler->GetSession()->GetPlayer(); + if (_player->isInFlight()) + { + _player->GetMotionMaster()->MovementExpired(); + _player->CleanupAfterTaxiFlight(); + } + else + _player->SaveRecallPosition(); + + _player->TeleportTo(mapid, x, y, z, 1, 0); + return true; + } + +}; + +void AddSC_go_commandscript() +{ + new go_commandscript(); +} diff --git a/src/server/scripts/Commands/cs_learn.cpp b/src/server/scripts/Commands/cs_learn.cpp new file mode 100644 index 00000000000..4ac6c98564b --- /dev/null +++ b/src/server/scripts/Commands/cs_learn.cpp @@ -0,0 +1,1113 @@ +/* + * Copyright (C) 2008-2010 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* ScriptData +Name: learn_commandscript +%Complete: 100 +Comment: All learn related commands +Category: commandscripts +EndScriptData */ + +#include "ScriptPCH.h" + +class learn_commandscript : public CommandScript +{ + public: + learn_commandscript() : CommandScript("learn_commandscript") { } + + ChatCommand* GetCommands() const + { + static ChatCommand learnAllMyCommandTable[] = + { + { "class", SEC_ADMINISTRATOR, false, &HandleLearnAllMyClassCommand, "", NULL }, + { "pettalents", SEC_ADMINISTRATOR, false, &HandleLearnAllMyPetTalentsCommand,"", NULL }, + { "spells", SEC_ADMINISTRATOR, false, &HandleLearnAllMySpellsCommand, "", NULL }, + { "talents", SEC_ADMINISTRATOR, false, &HandleLearnAllMyTalentsCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + static ChatCommand learnAllCommandTable[] = + { + { "my", SEC_ADMINISTRATOR, false, NULL, "", learnAllMyCommandTable }, + { "gm", SEC_GAMEMASTER, false, &HandleLearnAllGMCommand, "", NULL }, + { "crafts", SEC_GAMEMASTER, false, &HandleLearnAllCraftsCommand, "", NULL }, + { "default", SEC_MODERATOR, false, &HandleLearnAllDefaultCommand, "", NULL }, + { "lang", SEC_MODERATOR, false, &HandleLearnAllLangCommand, "", NULL }, + { "recipes", SEC_GAMEMASTER, false, &HandleLearnAllRecipesCommand, "", NULL }, + { "", SEC_ADMINISTRATOR, false, &HandleLearnAllCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + + static ChatCommand learnCommandTable[] = + { + { "all", SEC_ADMINISTRATOR, false, NULL, "", learnAllCommandTable }, + { "", SEC_ADMINISTRATOR, false, &HandleLearnCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + + static ChatCommand commandTable[] = + { + { "learn", SEC_MODERATOR, false, NULL, "", learnCommandTable }, + { NULL, 0, false, NULL, "", NULL } + }; + return commandTable; + } + static bool HandleLearnCommand(ChatHandler* handler, const char* args) + { + Player* targetPlayer = handler->getSelectedPlayer(); + + if (!targetPlayer) + { + handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); + handler->SetSentErrorMessage(true); + return false; + } + + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form + uint32 spell = handler->extractSpellIdFromLink((char*)args); + if (!spell || !sSpellStore.LookupEntry(spell)) + return false; + + char const* allStr = strtok(NULL," "); + bool allRanks = allStr ? (strncmp(allStr, "all", strlen(allStr)) == 0) : false; + + SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell); + if (!spellInfo || !SpellMgr::IsSpellValid(spellInfo,handler->GetSession()->GetPlayer())) + { + handler->PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell); + handler->SetSentErrorMessage(true); + return false; + } + + if (!allRanks && targetPlayer->HasSpell(spell)) + { + if (targetPlayer == handler->GetSession()->GetPlayer()) + handler->SendSysMessage(LANG_YOU_KNOWN_SPELL); + else + handler->PSendSysMessage(LANG_TARGET_KNOWN_SPELL,handler->GetNameLink(targetPlayer).c_str()); + handler->SetSentErrorMessage(true); + return false; + } + + if (allRanks) + targetPlayer->learnSpellHighRank(spell); + else + targetPlayer->learnSpell(spell, false); + + uint32 first_spell = sSpellMgr.GetFirstSpellInChain(spell); + if (GetTalentSpellCost(first_spell)) + targetPlayer->SendTalentsInfoData(false); + + return true; + } + + static bool HandleLearnAllCommand(ChatHandler* handler, const char* /*args*/) + { + static const char *allSpellList[] = + { + "3365", + "6233", + "6247", + "6246", + "6477", + "6478", + "22810", + "8386", + "21651", + "21652", + "522", + "7266", + "8597", + "2479", + "22027", + "6603", + "5019", + "133", + "168", + "227", + "5009", + "9078", + "668", + "203", + "20599", + "20600", + "81", + "20597", + "20598", + "20864", + "1459", + "5504", + "587", + "5143", + "118", + "5505", + "597", + "604", + "1449", + "1460", + "2855", + "1008", + "475", + "5506", + "1463", + "12824", + "8437", + "990", + "5145", + "8450", + "1461", + "759", + "8494", + "8455", + "8438", + "6127", + "8416", + "6129", + "8451", + "8495", + "8439", + "3552", + "8417", + "10138", + "12825", + "10169", + "10156", + "10144", + "10191", + "10201", + "10211", + "10053", + "10173", + "10139", + "10145", + "10192", + "10170", + "10202", + "10054", + "10174", + "10193", + "12826", + "2136", + "143", + "145", + "2137", + "2120", + "3140", + "543", + "2138", + "2948", + "8400", + "2121", + "8444", + "8412", + "8457", + "8401", + "8422", + "8445", + "8402", + "8413", + "8458", + "8423", + "8446", + "10148", + "10197", + "10205", + "10149", + "10215", + "10223", + "10206", + "10199", + "10150", + "10216", + "10207", + "10225", + "10151", + "116", + "205", + "7300", + "122", + "837", + "10", + "7301", + "7322", + "6143", + "120", + "865", + "8406", + "6141", + "7302", + "8461", + "8407", + "8492", + "8427", + "8408", + "6131", + "7320", + "10159", + "8462", + "10185", + "10179", + "10160", + "10180", + "10219", + "10186", + "10177", + "10230", + "10181", + "10161", + "10187", + "10220", + "2018", + "2663", + "12260", + "2660", + "3115", + "3326", + "2665", + "3116", + "2738", + "3293", + "2661", + "3319", + "2662", + "9983", + "8880", + "2737", + "2739", + "7408", + "3320", + "2666", + "3323", + "3324", + "3294", + "22723", + "23219", + "23220", + "23221", + "23228", + "23338", + "10788", + "10790", + "5611", + "5016", + "5609", + "2060", + "10963", + "10964", + "10965", + "22593", + "22594", + "596", + "996", + "499", + "768", + "17002", + "1448", + "1082", + "16979", + "1079", + "5215", + "20484", + "5221", + "15590", + "17007", + "6795", + "6807", + "5487", + "1446", + "1066", + "5421", + "3139", + "779", + "6811", + "6808", + "1445", + "5216", + "1737", + "5222", + "5217", + "1432", + "6812", + "9492", + "5210", + "3030", + "1441", + "783", + "6801", + "20739", + "8944", + "9491", + "22569", + "5226", + "6786", + "1433", + "8973", + "1828", + "9495", + "9006", + "6794", + "8993", + "5203", + "16914", + "6784", + "9635", + "22830", + "20722", + "9748", + "6790", + "9753", + "9493", + "9752", + "9831", + "9825", + "9822", + "5204", + "5401", + "22831", + "6793", + "9845", + "17401", + "9882", + "9868", + "20749", + "9893", + "9899", + "9895", + "9832", + "9902", + "9909", + "22832", + "9828", + "9851", + "9883", + "9869", + "17406", + "17402", + "9914", + "20750", + "9897", + "9848", + "3127", + "107", + "204", + "9116", + "2457", + "78", + "18848", + "331", + "403", + "2098", + "1752", + "11278", + "11288", + "11284", + "6461", + "2344", + "2345", + "6463", + "2346", + "2352", + "775", + "1434", + "1612", + "71", + "2468", + "2458", + "2467", + "7164", + "7178", + "7367", + "7376", + "7381", + "21156", + "5209", + "3029", + "5201", + "9849", + "9850", + "20719", + "22568", + "22827", + "22828", + "22829", + "6809", + "8972", + "9005", + "9823", + "9827", + "6783", + "9913", + "6785", + "6787", + "9866", + "9867", + "9894", + "9896", + "6800", + "8992", + "9829", + "9830", + "780", + "769", + "6749", + "6750", + "9755", + "9754", + "9908", + "20745", + "20742", + "20747", + "20748", + "9746", + "9745", + "9880", + "9881", + "5391", + "842", + "3025", + "3031", + "3287", + "3329", + "1945", + "3559", + "4933", + "4934", + "4935", + "4936", + "5142", + "5390", + "5392", + "5404", + "5420", + "6405", + "7293", + "7965", + "8041", + "8153", + "9033", + "9034", + //"9036", problems with ghost state + "16421", + "21653", + "22660", + "5225", + "9846", + "2426", + "5916", + "6634", + //"6718", phasing stealth, annoying for learn all case. + "6719", + "8822", + "9591", + "9590", + "10032", + "17746", + "17747", + "8203", + "11392", + "12495", + "16380", + "23452", + "4079", + "4996", + "4997", + "4998", + "4999", + "5000", + "6348", + "6349", + "6481", + "6482", + "6483", + "6484", + "11362", + "11410", + "11409", + "12510", + "12509", + "12885", + "13142", + "21463", + "23460", + "11421", + "11416", + "11418", + "1851", + "10059", + "11423", + "11417", + "11422", + "11419", + "11424", + "11420", + "27", + "31", + "33", + "34", + "35", + "15125", + "21127", + "22950", + "1180", + "201", + "12593", + "16770", + "6057", + "12051", + "18468", + "12606", + "12605", + "18466", + "12502", + "12043", + "15060", + "12042", + "12341", + "12848", + "12344", + "12353", + "18460", + "11366", + "12350", + "12352", + "13043", + "11368", + "11113", + "12400", + "11129", + "16766", + "12573", + "12580", + "12472", + "12953", + "12488", + "11189", + "12985", + "12519", + "16758", + "11958", + "12490", + "11426", + "3565", + "3562", + "18960", + "3567", + "3561", + "3566", + "3563", + "1953", + "2139", + "12505", + "13018", + "12522", + "12523", + "5146", + "5144", + "5148", + "8419", + "8418", + "10213", + "10212", + "10157", + "12524", + "13019", + "12525", + "13020", + "12526", + "13021", + "18809", + "13031", + "13032", + "13033", + "4036", + "3920", + "3919", + "3918", + "7430", + "3922", + "3923", + "7411", + "7418", + "7421", + "13262", + "7412", + "7415", + "7413", + "7416", + "13920", + "13921", + "7745", + "7779", + "7428", + "7457", + "7857", + "7748", + "7426", + "13421", + "7454", + "13378", + "7788", + "14807", + "14293", + "7795", + "6296", + "20608", + "755", + "444", + "427", + "428", + "442", + "447", + "3578", + "3581", + "19027", + "3580", + "665", + "3579", + "3577", + "6755", + "3576", + "2575", + "2577", + "2578", + "2579", + "2580", + "2656", + "2657", + "2576", + "3564", + "10248", + "8388", + "2659", + "14891", + "3308", + "3307", + "10097", + "2658", + "3569", + "16153", + "3304", + "10098", + "4037", + "3929", + "3931", + "3926", + "3924", + "3930", + "3977", + "3925", + "136", + "228", + "5487", + "43", + "202", + "0" + }; + + int loop = 0; + while (strcmp(allSpellList[loop], "0")) + { + uint32 spell = atol((char*)allSpellList[loop++]); + + if (handler->GetSession()->GetPlayer()->HasSpell(spell)) + continue; + + SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell); + if (!spellInfo || !SpellMgr::IsSpellValid(spellInfo,handler->GetSession()->GetPlayer())) + { + handler->PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell); + continue; + } + + handler->GetSession()->GetPlayer()->learnSpell(spell, false); + } + + handler->SendSysMessage(LANG_COMMAND_LEARN_MANY_SPELLS); + + return true; + } + + static bool HandleLearnAllGMCommand(ChatHandler* handler, const char* /*args*/) + { + static const char *gmSpellList[] = + { + "24347", // Become A Fish, No Breath Bar + "35132", // Visual Boom + "38488", // Attack 4000-8000 AOE + "38795", // Attack 2000 AOE + Slow Down 90% + "15712", // Attack 200 + "1852", // GM Spell Silence + "31899", // Kill + "31924", // Kill + "29878", // Kill My Self + "26644", // More Kill + + "28550", //Invisible 24 + "23452", //Invisible + Target + "0" + }; + + uint16 gmSpellIter = 0; + while (strcmp(gmSpellList[gmSpellIter], "0")) + { + uint32 spell = atol((char*)gmSpellList[gmSpellIter++]); + + SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell); + if (!spellInfo || !SpellMgr::IsSpellValid(spellInfo,handler->GetSession()->GetPlayer())) + { + handler->PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell); + continue; + } + + handler->GetSession()->GetPlayer()->learnSpell(spell, false); + } + + handler->SendSysMessage(LANG_LEARNING_GM_SKILLS); + return true; + } + + static bool HandleLearnAllMyClassCommand(ChatHandler* handler, const char* /*args*/) + { + HandleLearnAllMySpellsCommand(handler, ""); + HandleLearnAllMyTalentsCommand(handler, ""); + return true; + } + + static bool HandleLearnAllMySpellsCommand(ChatHandler* handler, const char* /*args*/) + { + ChrClassesEntry const* clsEntry = sChrClassesStore.LookupEntry(handler->GetSession()->GetPlayer()->getClass()); + if (!clsEntry) + return true; + uint32 family = clsEntry->spellfamily; + + for (uint32 i = 0; i < sSpellStore.GetNumRows(); ++i) + { + SpellEntry const *spellInfo = sSpellStore.LookupEntry(i); + if (!spellInfo) + continue; + + // skip server-side/triggered spells + if (spellInfo->spellLevel == 0) + continue; + + // skip wrong class/race skills + if (!handler->GetSession()->GetPlayer()->IsSpellFitByClassAndRace(spellInfo->Id)) + continue; + + // skip other spell families + if (spellInfo->SpellFamilyName != family) + continue; + + // skip spells with first rank learned as talent (and all talents then also) + uint32 first_rank = sSpellMgr.GetFirstSpellInChain(spellInfo->Id); + if (GetTalentSpellCost(first_rank) > 0) + continue; + + // skip broken spells + if (!SpellMgr::IsSpellValid(spellInfo,handler->GetSession()->GetPlayer(),false)) + continue; + + handler->GetSession()->GetPlayer()->learnSpell(i, false); + } + + handler->SendSysMessage(LANG_COMMAND_LEARN_CLASS_SPELLS); + return true; + } + + static bool HandleLearnAllMyTalentsCommand(ChatHandler* handler, const char* /*args*/) + { + Player* player = handler->GetSession()->GetPlayer(); + uint32 classMask = player->getClassMask(); + + for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i) + { + TalentEntry const *talentInfo = sTalentStore.LookupEntry(i); + if (!talentInfo) + continue; + + TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry(talentInfo->TalentTab); + if (!talentTabInfo) + continue; + + if ((classMask & talentTabInfo->ClassMask) == 0) + continue; + + // search highest talent rank + uint32 spellId = 0; + for (int8 rank = MAX_TALENT_RANK-1; rank >= 0; --rank) + { + if (talentInfo->RankID[rank] != 0) + { + spellId = talentInfo->RankID[rank]; + break; + } + } + + if (!spellId) // ??? none spells in talent + continue; + + SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellId); + if (!spellInfo || !SpellMgr::IsSpellValid(spellInfo,handler->GetSession()->GetPlayer(),false)) + continue; + + // learn highest rank of talent and learn all non-talent spell ranks (recursive by tree) + player->learnSpellHighRank(spellId); + player->AddTalent(spellId, player->GetActiveSpec(), true); + } + + player->SetFreeTalentPoints(0); + + handler->SendSysMessage(LANG_COMMAND_LEARN_CLASS_TALENTS); + return true; + } + + static bool HandleLearnAllMyPetTalentsCommand(ChatHandler* handler, const char* /*args*/) + { + Player* player = handler->GetSession()->GetPlayer(); + + Pet* pet = player->GetPet(); + if (!pet) + { + handler->SendSysMessage(LANG_NO_PET_FOUND); + handler->SetSentErrorMessage(true); + return false; + } + + CreatureInfo const *ci = pet->GetCreatureInfo(); + if (!ci) + { + handler->SendSysMessage(LANG_WRONG_PET_TYPE); + handler->SetSentErrorMessage(true); + return false; + } + + CreatureFamilyEntry const *pet_family = sCreatureFamilyStore.LookupEntry(ci->family); + if (!pet_family) + { + handler->SendSysMessage(LANG_WRONG_PET_TYPE); + handler->SetSentErrorMessage(true); + return false; + } + + if (pet_family->petTalentType < 0) // not hunter pet + { + handler->SendSysMessage(LANG_WRONG_PET_TYPE); + handler->SetSentErrorMessage(true); + return false; + } + + for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i) + { + TalentEntry const *talentInfo = sTalentStore.LookupEntry(i); + if (!talentInfo) + continue; + + TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry(talentInfo->TalentTab); + if (!talentTabInfo) + continue; + + // prevent learn talent for different family (cheating) + if (((1 << pet_family->petTalentType) & talentTabInfo->petTalentMask) == 0) + continue; + + // search highest talent rank + uint32 spellid = 0; + + for (int8 rank = MAX_TALENT_RANK-1; rank >= 0; --rank) + { + if (talentInfo->RankID[rank] != 0) + { + spellid = talentInfo->RankID[rank]; + break; + } + } + + if (!spellid) // ??? none spells in talent + continue; + + SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid); + if (!spellInfo || !SpellMgr::IsSpellValid(spellInfo,handler->GetSession()->GetPlayer(),false)) + continue; + + // learn highest rank of talent and learn all non-talent spell ranks (recursive by tree) + pet->learnSpellHighRank(spellid); + } + + pet->SetFreeTalentPoints(0); + + handler->SendSysMessage(LANG_COMMAND_LEARN_PET_TALENTS); + return true; + } + + static bool HandleLearnAllLangCommand(ChatHandler* handler, const char* /*args*/) + { + // skipping UNIVERSAL language (0) + for (uint8 i = 1; i < LANGUAGES_COUNT; ++i) + handler->GetSession()->GetPlayer()->learnSpell(lang_description[i].spell_id, false); + + handler->SendSysMessage(LANG_COMMAND_LEARN_ALL_LANG); + return true; + } + + static bool HandleLearnAllDefaultCommand(ChatHandler* handler, const char* args) + { + Player* target; + if (!handler->extractPlayerTarget((char*)args,&target)) + return false; + + target->learnDefaultSpells(); + target->learnQuestRewardedSpells(); + + handler->PSendSysMessage(LANG_COMMAND_LEARN_ALL_DEFAULT_AND_QUEST,handler->GetNameLink(target).c_str()); + return true; + } + + static bool HandleLearnAllCraftsCommand(ChatHandler* handler, const char* /*args*/) + { + + for (uint32 i = 0; i < sSkillLineStore.GetNumRows(); ++i) + { + SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(i); + if (!skillInfo) + continue; + + if ((skillInfo->categoryId == SKILL_CATEGORY_PROFESSION || skillInfo->categoryId == SKILL_CATEGORY_SECONDARY) && + skillInfo->canLink) // only prof. with recipes have + { + HandleLearnSkillRecipesHelper(handler->GetSession()->GetPlayer(),skillInfo->id); + } + } + + handler->SendSysMessage(LANG_COMMAND_LEARN_ALL_CRAFT); + return true; + } + + static bool HandleLearnAllRecipesCommand(ChatHandler* handler, const char* args) + { + // Learns all recipes of specified profession and sets skill to max + // Example: .learn all_recipes enchanting + + Player* target = handler->getSelectedPlayer(); + if (!target) + { + handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); + return false; + } + + if (!*args) + return false; + + std::wstring wnamepart; + + if (!Utf8toWStr(args,wnamepart)) + return false; + + // converting string that we try to find to lower case + wstrToLower(wnamepart); + + std::string name; + + SkillLineEntry const *targetSkillInfo = NULL; + for (uint32 i = 1; i < sSkillLineStore.GetNumRows(); ++i) + { + SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(i); + if (!skillInfo) + continue; + + if ((skillInfo->categoryId != SKILL_CATEGORY_PROFESSION && + skillInfo->categoryId != SKILL_CATEGORY_SECONDARY) || + !skillInfo->canLink) // only prof with recipes have set + continue; + + int loc = handler->GetSessionDbcLocale(); + name = skillInfo->name[loc]; + if (name.empty()) + continue; + + if (!Utf8FitTo(name, wnamepart)) + { + loc = 0; + for (; loc < TOTAL_LOCALES; ++loc) + { + if (loc == handler->GetSessionDbcLocale()) + continue; + + name = skillInfo->name[loc]; + if (name.empty()) + continue; + + if (Utf8FitTo(name, wnamepart)) + break; + } + } + + if (loc < TOTAL_LOCALES) + { + targetSkillInfo = skillInfo; + break; + } + } + + if (!targetSkillInfo) + return false; + + HandleLearnSkillRecipesHelper(target,targetSkillInfo->id); + + uint16 maxLevel = target->GetPureMaxSkillValue(targetSkillInfo->id); + target->SetSkill(targetSkillInfo->id, target->GetSkillStep(targetSkillInfo->id), maxLevel, maxLevel); + handler->PSendSysMessage(LANG_COMMAND_LEARN_ALL_RECIPES, name.c_str()); + return true; + } + + static void HandleLearnSkillRecipesHelper(Player* player,uint32 skill_id) + { + uint32 classmask = player->getClassMask(); + + for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j) + { + SkillLineAbilityEntry const *skillLine = sSkillLineAbilityStore.LookupEntry(j); + if (!skillLine) + continue; + + // wrong skill + if (skillLine->skillId != skill_id) + continue; + + // not high rank + if (skillLine->forward_spellid) + continue; + + // skip racial skills + if (skillLine->racemask != 0) + continue; + + // skip wrong class skills + if (skillLine->classmask && (skillLine->classmask & classmask) == 0) + continue; + + SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId); + if (!spellInfo || !SpellMgr::IsSpellValid(spellInfo,player,false)) + continue; + + player->learnSpell(skillLine->spellId, false); + } + } +}; + +void AddSC_learn_commandscript() +{ + new learn_commandscript(); +} diff --git a/src/server/scripts/Commands/cs_modify.cpp b/src/server/scripts/Commands/cs_modify.cpp new file mode 100644 index 00000000000..46f5032fd8d --- /dev/null +++ b/src/server/scripts/Commands/cs_modify.cpp @@ -0,0 +1,1418 @@ +/* + * Copyright (C) 2008-2010 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* ScriptData +Name: modify_commandscript +%Complete: 100 +Comment: All modify related commands +Category: commandscripts +EndScriptData */ + +#include "ScriptPCH.h" + +class modify_commandscript : public CommandScript +{ + public: + modify_commandscript() : CommandScript("modify_commandscript") { } + + ChatCommand* GetCommands() const + { + static ChatCommand modifyCommandTable[] = + { + { "hp", SEC_MODERATOR, false, &HandleModifyHPCommand, "", NULL }, + { "mana", SEC_MODERATOR, false, &HandleModifyManaCommand, "", NULL }, + { "rage", SEC_MODERATOR, false, &HandleModifyRageCommand, "", NULL }, + { "runicpower", SEC_MODERATOR, false, &HandleModifyRunicPowerCommand, "", NULL }, + { "energy", SEC_MODERATOR, false, &HandleModifyEnergyCommand, "", NULL }, + { "money", SEC_MODERATOR, false, &HandleModifyMoneyCommand, "", NULL }, + { "speed", SEC_MODERATOR, false, &HandleModifySpeedCommand, "", NULL }, + { "swim", SEC_MODERATOR, false, &HandleModifySwimCommand, "", NULL }, + { "scale", SEC_MODERATOR, false, &HandleModifyScaleCommand, "", NULL }, + { "bit", SEC_MODERATOR, false, &HandleModifyBitCommand, "", NULL }, + { "bwalk", SEC_MODERATOR, false, &HandleModifyBWalkCommand, "", NULL }, + { "fly", SEC_MODERATOR, false, &HandleModifyFlyCommand, "", NULL }, + { "aspeed", SEC_MODERATOR, false, &HandleModifyASpeedCommand, "", NULL }, + { "faction", SEC_MODERATOR, false, &HandleModifyFactionCommand, "", NULL }, + { "spell", SEC_MODERATOR, false, &HandleModifySpellCommand, "", NULL }, + { "tp", SEC_MODERATOR, false, &HandleModifyTalentCommand, "", NULL }, + { "mount", SEC_MODERATOR, false, &HandleModifyMountCommand, "", NULL }, + { "honor", SEC_MODERATOR, false, &HandleModifyHonorCommand, "", NULL }, + { "rep", SEC_GAMEMASTER, false, &HandleModifyRepCommand, "", NULL }, + { "arena", SEC_MODERATOR, false, &HandleModifyArenaCommand, "", NULL }, + { "drunk", SEC_MODERATOR, false, &HandleModifyDrunkCommand, "", NULL }, + { "standstate", SEC_GAMEMASTER, false, &HandleModifyStandStateCommand, "", NULL }, + { "morph", SEC_GAMEMASTER, false, &HandleModifyMorphCommand, "", NULL }, + { "phase", SEC_ADMINISTRATOR, false, &HandleModifyPhaseCommand, "", NULL }, + { "gender", SEC_GAMEMASTER, false, &HandleModifyGenderCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + static ChatCommand commandTable[] = + { + { "modify", SEC_MODERATOR, false, NULL, "", modifyCommandTable }, + { NULL, 0, false, NULL, "", NULL } + }; + return commandTable; + } + + //Edit Player HP + static bool HandleModifyHPCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + int32 hp = atoi((char*)args); + int32 hpm = atoi((char*)args); + + if (hp < 1 || hpm < 1 || hpm < hp) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + + Player* target = handler->getSelectedPlayer(); + if (!target) + { + handler->SendSysMessage(LANG_NO_CHAR_SELECTED); + handler->SetSentErrorMessage(true); + return false; + } + + if (handler->HasLowerSecurity(target, 0)) + return false; + + handler->PSendSysMessage(LANG_YOU_CHANGE_HP, handler->GetNameLink(target).c_str(), hp, hpm); + if (handler->needReportToTarget(target)) + (ChatHandler(target)).PSendSysMessage(LANG_YOURS_HP_CHANGED, handler->GetNameLink().c_str(), hp, hpm); + + target->SetMaxHealth(hpm); + target->SetHealth(hp); + + return true; + } + + //Edit Player Mana + static bool HandleModifyManaCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + int32 mana = atoi((char*)args); + int32 manam = atoi((char*)args); + + if (mana <= 0 || manam <= 0 || manam < mana) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + + Player* target = handler->getSelectedPlayer(); + if (!target) + { + handler->SendSysMessage(LANG_NO_CHAR_SELECTED); + handler->SetSentErrorMessage(true); + return false; + } + + // check online security + if (handler->HasLowerSecurity(target, 0)) + return false; + + handler->PSendSysMessage(LANG_YOU_CHANGE_MANA, handler->GetNameLink(target).c_str(), mana, manam); + if (handler->needReportToTarget(target)) + (ChatHandler(target)).PSendSysMessage(LANG_YOURS_MANA_CHANGED, handler->GetNameLink().c_str(), mana, manam); + + target->SetMaxPower(POWER_MANA,manam); + target->SetPower(POWER_MANA, mana); + + return true; + } + + //Edit Player Energy + static bool HandleModifyEnergyCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + // char* pmana = strtok((char*)args, " "); + // if (!pmana) + // return false; + + // char* pmanaMax = strtok(NULL, " "); + // if (!pmanaMax) + // return false; + + // int32 manam = atoi(pmanaMax); + // int32 mana = atoi(pmana); + + int32 energy = atoi((char*)args)*10; + int32 energym = atoi((char*)args)*10; + + if (energy <= 0 || energym <= 0 || energym < energy) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + + Player* target = handler->getSelectedPlayer(); + if (!target) + { + handler->SendSysMessage(LANG_NO_CHAR_SELECTED); + handler->SetSentErrorMessage(true); + return false; + } + + // check online security + if (handler->HasLowerSecurity(target, 0)) + return false; + + handler->PSendSysMessage(LANG_YOU_CHANGE_ENERGY, handler->GetNameLink(target).c_str(), energy/10, energym/10); + if (handler->needReportToTarget(target)) + (ChatHandler(target)).PSendSysMessage(LANG_YOURS_ENERGY_CHANGED, handler->GetNameLink().c_str(), energy/10, energym/10); + + target->SetMaxPower(POWER_ENERGY,energym); + target->SetPower(POWER_ENERGY, energy); + + sLog.outDetail(handler->GetTrinityString(LANG_CURRENT_ENERGY),target->GetMaxPower(POWER_ENERGY)); + + return true; + } + + //Edit Player Rage + static bool HandleModifyRageCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + // char* pmana = strtok((char*)args, " "); + // if (!pmana) + // return false; + + // char* pmanaMax = strtok(NULL, " "); + // if (!pmanaMax) + // return false; + + // int32 manam = atoi(pmanaMax); + // int32 mana = atoi(pmana); + + int32 rage = atoi((char*)args)*10; + int32 ragem = atoi((char*)args)*10; + + if (rage <= 0 || ragem <= 0 || ragem < rage) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + + Player* target = handler->getSelectedPlayer(); + if (!target) + { + handler->SendSysMessage(LANG_NO_CHAR_SELECTED); + handler->SetSentErrorMessage(true); + return false; + } + + // check online security + if (handler->HasLowerSecurity(target, 0)) + return false; + + handler->PSendSysMessage(LANG_YOU_CHANGE_RAGE, handler->GetNameLink(target).c_str(), rage/10, ragem/10); + if (handler->needReportToTarget(target)) + (ChatHandler(target)).PSendSysMessage(LANG_YOURS_RAGE_CHANGED, handler->GetNameLink().c_str(), rage/10, ragem/10); + + target->SetMaxPower(POWER_RAGE,ragem); + target->SetPower(POWER_RAGE, rage); + + return true; + } + + // Edit Player Runic Power + static bool HandleModifyRunicPowerCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + int32 rune = atoi((char*)args)*10; + int32 runem = atoi((char*)args)*10; + + if (rune <= 0 || runem <= 0 || runem < rune) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + + Player* target = handler->getSelectedPlayer(); + if (!target) + { + handler->SendSysMessage(LANG_NO_CHAR_SELECTED); + handler->SetSentErrorMessage(true); + return false; + } + + handler->PSendSysMessage(LANG_YOU_CHANGE_RUNIC_POWER, handler->GetNameLink(target).c_str(), rune/10, runem/10); + if (handler->needReportToTarget(target)) + (ChatHandler(target)).PSendSysMessage(LANG_YOURS_RUNIC_POWER_CHANGED, handler->GetNameLink().c_str(), rune/10, runem/10); + + target->SetMaxPower(POWER_RUNIC_POWER,runem); + target->SetPower(POWER_RUNIC_POWER, rune); + + return true; + } + + //Edit Player Faction + static bool HandleModifyFactionCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + char* pfactionid = handler->extractKeyFromLink((char*)args,"Hfaction"); + + Creature* target = handler->getSelectedCreature(); + if (!target) + { + handler->SendSysMessage(LANG_SELECT_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + if (!pfactionid) + { + if (target) + { + uint32 factionid = target->getFaction(); + uint32 flag = target->GetUInt32Value(UNIT_FIELD_FLAGS); + uint32 npcflag = target->GetUInt32Value(UNIT_NPC_FLAGS); + uint32 dyflag = target->GetUInt32Value(UNIT_DYNAMIC_FLAGS); + handler->PSendSysMessage(LANG_CURRENT_FACTION,target->GetGUIDLow(),factionid,flag,npcflag,dyflag); + } + return true; + } + + if (!target) + { + handler->SendSysMessage(LANG_NO_CHAR_SELECTED); + handler->SetSentErrorMessage(true); + return false; + } + + uint32 factionid = atoi(pfactionid); + uint32 flag; + + char *pflag = strtok(NULL, " "); + if (!pflag) + flag = target->GetUInt32Value(UNIT_FIELD_FLAGS); + else + flag = atoi(pflag); + + char* pnpcflag = strtok(NULL, " "); + + uint32 npcflag; + if (!pnpcflag) + npcflag = target->GetUInt32Value(UNIT_NPC_FLAGS); + else + npcflag = atoi(pnpcflag); + + char* pdyflag = strtok(NULL, " "); + + uint32 dyflag; + if (!pdyflag) + dyflag = target->GetUInt32Value(UNIT_DYNAMIC_FLAGS); + else + dyflag = atoi(pdyflag); + + if (!sFactionTemplateStore.LookupEntry(factionid)) + { + handler->PSendSysMessage(LANG_WRONG_FACTION, factionid); + handler->SetSentErrorMessage(true); + return false; + } + + handler->PSendSysMessage(LANG_YOU_CHANGE_FACTION, target->GetGUIDLow(),factionid,flag,npcflag,dyflag); + + target->setFaction(factionid); + target->SetUInt32Value(UNIT_FIELD_FLAGS,flag); + target->SetUInt32Value(UNIT_NPC_FLAGS,npcflag); + target->SetUInt32Value(UNIT_DYNAMIC_FLAGS,dyflag); + + return true; + } + + //Edit Player Spell + static bool HandleModifySpellCommand(ChatHandler* handler, const char* args) + { + if (!*args) return false; + char* pspellflatid = strtok((char*)args, " "); + if (!pspellflatid) + return false; + + char* pop = strtok(NULL, " "); + if (!pop) + return false; + + char* pval = strtok(NULL, " "); + if (!pval) + return false; + + uint16 mark; + + char* pmark = strtok(NULL, " "); + + uint8 spellflatid = atoi(pspellflatid); + uint8 op = atoi(pop); + uint16 val = atoi(pval); + if (!pmark) + mark = 65535; + else + mark = atoi(pmark); + + Player* target = handler->getSelectedPlayer(); + if (target == NULL) + { + handler->SendSysMessage(LANG_NO_CHAR_SELECTED); + handler->SetSentErrorMessage(true); + return false; + } + + // check online security + if (handler->HasLowerSecurity(target, 0)) + return false; + + handler->PSendSysMessage(LANG_YOU_CHANGE_SPELLFLATID, spellflatid, val, mark, handler->GetNameLink(target).c_str()); + if (handler->needReportToTarget(target)) + (ChatHandler(target)).PSendSysMessage(LANG_YOURS_SPELLFLATID_CHANGED, handler->GetNameLink().c_str(), spellflatid, val, mark); + + WorldPacket data(SMSG_SET_FLAT_SPELL_MODIFIER, (1+1+2+2)); + data << uint8(spellflatid); + data << uint8(op); + data << uint16(val); + data << uint16(mark); + target->GetSession()->SendPacket(&data); + + return true; + } + + //Edit Player TP + static bool HandleModifyTalentCommand (ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + int tp = atoi((char*)args); + if (tp < 0) + return false; + + Unit* target = handler->getSelectedUnit(); + if (!target) + { + handler->SendSysMessage(LANG_NO_CHAR_SELECTED); + handler->SetSentErrorMessage(true); + return false; + } + + if (target->GetTypeId() == TYPEID_PLAYER) + { + // check online security + if (handler->HasLowerSecurity(target->ToPlayer(), 0)) + return false; + target->ToPlayer()->SetFreeTalentPoints(tp); + target->ToPlayer()->SendTalentsInfoData(false); + return true; + } + else if (target->ToCreature()->isPet()) + { + Unit *owner = target->GetOwner(); + if (owner && owner->GetTypeId() == TYPEID_PLAYER && ((Pet *)target)->IsPermanentPetFor(owner->ToPlayer())) + { + // check online security + if (handler->HasLowerSecurity(owner->ToPlayer(), 0)) + return false; + ((Pet *)target)->SetFreeTalentPoints(tp); + owner->ToPlayer()->SendTalentsInfoData(true); + return true; + } + } + + handler->SendSysMessage(LANG_NO_CHAR_SELECTED); + handler->SetSentErrorMessage(true); + return false; + } + + //Edit Player Aspeed + static bool HandleModifyASpeedCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + float ASpeed = (float)atof((char*)args); + + if (ASpeed > 50.0f || ASpeed < 0.1f) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + + Player* target = handler->getSelectedPlayer(); + if (!target) + { + handler->SendSysMessage(LANG_NO_CHAR_SELECTED); + handler->SetSentErrorMessage(true); + return false; + } + + // check online security + if (handler->HasLowerSecurity(target, 0)) + return false; + + std::string targetNameLink = handler->GetNameLink(target); + + if (target->isInFlight()) + { + handler->PSendSysMessage(LANG_CHAR_IN_FLIGHT,targetNameLink.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + + handler->PSendSysMessage(LANG_YOU_CHANGE_ASPEED, ASpeed, targetNameLink.c_str()); + if (handler->needReportToTarget(target)) + (ChatHandler(target)).PSendSysMessage(LANG_YOURS_ASPEED_CHANGED, handler->GetNameLink().c_str(), ASpeed); + + target->SetSpeed(MOVE_WALK, ASpeed,true); + target->SetSpeed(MOVE_RUN, ASpeed,true); + target->SetSpeed(MOVE_SWIM, ASpeed,true); + //target->SetSpeed(MOVE_TURN, ASpeed,true); + target->SetSpeed(MOVE_FLIGHT, ASpeed,true); + return true; + } + + //Edit Player Speed + static bool HandleModifySpeedCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + float Speed = (float)atof((char*)args); + + if (Speed > 50.0f || Speed < 0.1f) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + + Player* target = handler->getSelectedPlayer(); + if (!target) + { + handler->SendSysMessage(LANG_NO_CHAR_SELECTED); + handler->SetSentErrorMessage(true); + return false; + } + + // check online security + if (handler->HasLowerSecurity(target, 0)) + return false; + + std::string targetNameLink = handler->GetNameLink(target); + + if (target->isInFlight()) + { + handler->PSendSysMessage(LANG_CHAR_IN_FLIGHT,targetNameLink.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + + handler->PSendSysMessage(LANG_YOU_CHANGE_SPEED, Speed, targetNameLink.c_str()); + if (handler->needReportToTarget(target)) + (ChatHandler(target)).PSendSysMessage(LANG_YOURS_SPEED_CHANGED, handler->GetNameLink().c_str(), Speed); + + target->SetSpeed(MOVE_RUN,Speed,true); + + return true; + } + + //Edit Player Swim Speed + static bool HandleModifySwimCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + float Swim = (float)atof((char*)args); + + if (Swim > 50.0f || Swim < 0.1f) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + + Player* target = handler->getSelectedPlayer(); + if (!target) + { + handler->SendSysMessage(LANG_NO_CHAR_SELECTED); + handler->SetSentErrorMessage(true); + return false; + } + + // check online security + if (handler->HasLowerSecurity(target, 0)) + return false; + + std::string targetNameLink = handler->GetNameLink(target); + + if (target->isInFlight()) + { + handler->PSendSysMessage(LANG_CHAR_IN_FLIGHT,targetNameLink.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + + handler->PSendSysMessage(LANG_YOU_CHANGE_SWIM_SPEED, Swim, targetNameLink.c_str()); + if (handler->needReportToTarget(target)) + (ChatHandler(target)).PSendSysMessage(LANG_YOURS_SWIM_SPEED_CHANGED, handler->GetNameLink().c_str(), Swim); + + target->SetSpeed(MOVE_SWIM,Swim,true); + + return true; + } + + //Edit Player Walk Speed + static bool HandleModifyBWalkCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + float BSpeed = (float)atof((char*)args); + + if (BSpeed > 50.0f || BSpeed < 0.1f) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + + Player* target = handler->getSelectedPlayer(); + if (!target) + { + handler->SendSysMessage(LANG_NO_CHAR_SELECTED); + handler->SetSentErrorMessage(true); + return false; + } + + // check online security + if (handler->HasLowerSecurity(target, 0)) + return false; + + std::string targetNameLink = handler->GetNameLink(target); + + if (target->isInFlight()) + { + handler->PSendSysMessage(LANG_CHAR_IN_FLIGHT,targetNameLink.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + + handler->PSendSysMessage(LANG_YOU_CHANGE_BACK_SPEED, BSpeed, targetNameLink.c_str()); + if (handler->needReportToTarget(target)) + (ChatHandler(target)).PSendSysMessage(LANG_YOURS_BACK_SPEED_CHANGED, handler->GetNameLink().c_str(), BSpeed); + + target->SetSpeed(MOVE_RUN_BACK,BSpeed,true); + + return true; + } + + //Edit Player Fly + static bool HandleModifyFlyCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + float FSpeed = (float)atof((char*)args); + + if (FSpeed > 50.0f || FSpeed < 0.1f) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + + Player* target = handler->getSelectedPlayer(); + if (!target) + { + handler->SendSysMessage(LANG_NO_CHAR_SELECTED); + handler->SetSentErrorMessage(true); + return false; + } + + // check online security + if (handler->HasLowerSecurity(target, 0)) + return false; + + handler->PSendSysMessage(LANG_YOU_CHANGE_FLY_SPEED, FSpeed, handler->GetNameLink(target).c_str()); + if (handler->needReportToTarget(target)) + (ChatHandler(target)).PSendSysMessage(LANG_YOURS_FLY_SPEED_CHANGED, handler->GetNameLink().c_str(), FSpeed); + + target->SetSpeed(MOVE_FLIGHT,FSpeed,true); + + return true; + } + + //Edit Player Scale + static bool HandleModifyScaleCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + float Scale = (float)atof((char*)args); + if (Scale > 10.0f || Scale < 0.1f) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + + Player* target = handler->getSelectedPlayer(); + if (!target) + { + handler->SendSysMessage(LANG_NO_CHAR_SELECTED); + handler->SetSentErrorMessage(true); + return false; + } + + // check online security + if (handler->HasLowerSecurity(target, 0)) + return false; + + handler->PSendSysMessage(LANG_YOU_CHANGE_SIZE, Scale, handler->GetNameLink(target).c_str()); + if (handler->needReportToTarget(target)) + (ChatHandler(target)).PSendSysMessage(LANG_YOURS_SIZE_CHANGED, handler->GetNameLink().c_str(), Scale); + + target->SetFloatValue(OBJECT_FIELD_SCALE_X, Scale); + + return true; + } + + //Enable Player mount + static bool HandleModifyMountCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + uint16 mId = 1147; + float speed = (float)15; + uint32 num = 0; + + num = atoi((char*)args); + switch(num) + { + case 1: + mId=14340; + break; + case 2: + mId=4806; + break; + case 3: + mId=6471; + break; + case 4: + mId=12345; + break; + case 5: + mId=6472; + break; + case 6: + mId=6473; + break; + case 7: + mId=10670; + break; + case 8: + mId=10719; + break; + case 9: + mId=10671; + break; + case 10: + mId=10672; + break; + case 11: + mId=10720; + break; + case 12: + mId=14349; + break; + case 13: + mId=11641; + break; + case 14: + mId=12244; + break; + case 15: + mId=12242; + break; + case 16: + mId=14578; + break; + case 17: + mId=14579; + break; + case 18: + mId=14349; + break; + case 19: + mId=12245; + break; + case 20: + mId=14335; + break; + case 21: + mId=207; + break; + case 22: + mId=2328; + break; + case 23: + mId=2327; + break; + case 24: + mId=2326; + break; + case 25: + mId=14573; + break; + case 26: + mId=14574; + break; + case 27: + mId=14575; + break; + case 28: + mId=604; + break; + case 29: + mId=1166; + break; + case 30: + mId=2402; + break; + case 31: + mId=2410; + break; + case 32: + mId=2409; + break; + case 33: + mId=2408; + break; + case 34: + mId=2405; + break; + case 35: + mId=14337; + break; + case 36: + mId=6569; + break; + case 37: + mId=10661; + break; + case 38: + mId=10666; + break; + case 39: + mId=9473; + break; + case 40: + mId=9476; + break; + case 41: + mId=9474; + break; + case 42: + mId=14374; + break; + case 43: + mId=14376; + break; + case 44: + mId=14377; + break; + case 45: + mId=2404; + break; + case 46: + mId=2784; + break; + case 47: + mId=2787; + break; + case 48: + mId=2785; + break; + case 49: + mId=2736; + break; + case 50: + mId=2786; + break; + case 51: + mId=14347; + break; + case 52: + mId=14346; + break; + case 53: + mId=14576; + break; + case 54: + mId=9695; + break; + case 55: + mId=9991; + break; + case 56: + mId=6448; + break; + case 57: + mId=6444; + break; + case 58: + mId=6080; + break; + case 59: + mId=6447; + break; + case 60: + mId=4805; + break; + case 61: + mId=9714; + break; + case 62: + mId=6448; + break; + case 63: + mId=6442; + break; + case 64: + mId=14632; + break; + case 65: + mId=14332; + break; + case 66: + mId=14331; + break; + case 67: + mId=8469; + break; + case 68: + mId=2830; + break; + case 69: + mId=2346; + break; + default: + handler->SendSysMessage(LANG_NO_MOUNT); + handler->SetSentErrorMessage(true); + return false; + } + + Player* target = handler->getSelectedPlayer(); + if (!target) + { + handler->SendSysMessage(LANG_NO_CHAR_SELECTED); + handler->SetSentErrorMessage(true); + return false; + } + + // check online security + if (handler->HasLowerSecurity(target, 0)) + return false; + + handler->PSendSysMessage(LANG_YOU_GIVE_MOUNT, handler->GetNameLink(target).c_str()); + if (handler->needReportToTarget(target)) + (ChatHandler(target)).PSendSysMessage(LANG_MOUNT_GIVED, handler->GetNameLink().c_str()); + + target->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP); + target->Mount(mId); + + WorldPacket data(SMSG_FORCE_RUN_SPEED_CHANGE, (8+4+1+4)); + data.append(target->GetPackGUID()); + data << (uint32)0; + data << (uint8)0; //new 2.1.0 + data << float(speed); + target->SendMessageToSet(&data, true); + + data.Initialize(SMSG_FORCE_SWIM_SPEED_CHANGE, (8+4+4)); + data.append(target->GetPackGUID()); + data << (uint32)0; + data << float(speed); + target->SendMessageToSet(&data, true); + + return true; + } + + //Edit Player money + static bool HandleModifyMoneyCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + Player* target = handler->getSelectedPlayer(); + if (!target) + { + handler->SendSysMessage(LANG_NO_CHAR_SELECTED); + handler->SetSentErrorMessage(true); + return false; + } + + // check online security + if (handler->HasLowerSecurity(target, 0)) + return false; + + int32 addmoney = atoi((char*)args); + + uint32 moneyuser = target->GetMoney(); + + if (addmoney < 0) + { + int32 newmoney = int32(moneyuser) + addmoney; + + sLog.outDetail(handler->GetTrinityString(LANG_CURRENT_MONEY), moneyuser, addmoney, newmoney); + if (newmoney <= 0) + { + handler->PSendSysMessage(LANG_YOU_TAKE_ALL_MONEY, handler->GetNameLink(target).c_str()); + if (handler->needReportToTarget(target)) + (ChatHandler(target)).PSendSysMessage(LANG_YOURS_ALL_MONEY_GONE, handler->GetNameLink().c_str()); + + target->SetMoney(0); + } + else + { + if (newmoney > MAX_MONEY_AMOUNT) + newmoney = MAX_MONEY_AMOUNT; + + handler->PSendSysMessage(LANG_YOU_TAKE_MONEY, abs(addmoney), handler->GetNameLink(target).c_str()); + if (handler->needReportToTarget(target)) + (ChatHandler(target)).PSendSysMessage(LANG_YOURS_MONEY_TAKEN, handler->GetNameLink().c_str(), abs(addmoney)); + target->SetMoney(newmoney); + } + } + else + { + handler->PSendSysMessage(LANG_YOU_GIVE_MONEY, addmoney, handler->GetNameLink(target).c_str()); + if (handler->needReportToTarget(target)) + (ChatHandler(target)).PSendSysMessage(LANG_YOURS_MONEY_GIVEN, handler->GetNameLink().c_str(), addmoney); + + if (addmoney >=MAX_MONEY_AMOUNT) + target->SetMoney(MAX_MONEY_AMOUNT); + else + target->ModifyMoney(addmoney); + } + + sLog.outDetail(handler->GetTrinityString(LANG_NEW_MONEY), moneyuser, addmoney, target->GetMoney()); + + return true; + } + + //Edit Unit field + static bool HandleModifyBitCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + Unit* target = handler->getSelectedUnit(); + if (!target) + { + handler->SendSysMessage(LANG_NO_CHAR_SELECTED); + handler->SetSentErrorMessage(true); + return false; + } + + // check online security + if (target->GetTypeId() == TYPEID_PLAYER && handler->HasLowerSecurity(target->ToPlayer(), 0)) + return false; + + char* pField = strtok((char*)args, " "); + if (!pField) + return false; + + char* pBit = strtok(NULL, " "); + if (!pBit) + return false; + + uint16 field = atoi(pField); + uint32 bit = atoi(pBit); + + if (field < OBJECT_END || field >= target->GetValuesCount()) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + if (bit < 1 || bit > 32) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + + if (target->HasFlag(field, (1<<(bit-1)))) + { + target->RemoveFlag(field, (1<<(bit-1))); + handler->PSendSysMessage(LANG_REMOVE_BIT, bit, field); + } + else + { + target->SetFlag(field, (1<<(bit-1))); + handler->PSendSysMessage(LANG_SET_BIT, bit, field); + } + return true; + } + + static bool HandleModifyHonorCommand (ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + Player* target = handler->getSelectedPlayer(); + if (!target) + { + handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); + handler->SetSentErrorMessage(true); + return false; + } + + // check online security + if (handler->HasLowerSecurity(target, 0)) + return false; + + int32 amount = (uint32)atoi(args); + + target->ModifyHonorPoints(amount); + + handler->PSendSysMessage(LANG_COMMAND_MODIFY_HONOR, handler->GetNameLink(target).c_str(), target->GetHonorPoints()); + + return true; + } + + static bool HandleTeleCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + Player* me = handler->GetSession()->GetPlayer(); + + // id, or string, or [name] Shift-click form |color|Htele:id|h[name]|h|r + GameTele const* tele = handler->extractGameTeleFromLink((char*)args); + + if (!tele) + { + handler->SendSysMessage(LANG_COMMAND_TELE_NOTFOUND); + handler->SetSentErrorMessage(true); + return false; + } + + if (me->isInCombat()) + { + handler->SendSysMessage(LANG_YOU_IN_COMBAT); + handler->SetSentErrorMessage(true); + return false; + } + + MapEntry const * map = sMapStore.LookupEntry(tele->mapId); + if (!map || map->IsBattlegroundOrArena()) + { + handler->SendSysMessage(LANG_CANNOT_TELE_TO_BG); + handler->SetSentErrorMessage(true); + return false; + } + + // stop flight if need + if (me->isInFlight()) + { + me->GetMotionMaster()->MovementExpired(); + me->CleanupAfterTaxiFlight(); + } + // save only in non-flight case + else + me->SaveRecallPosition(); + + me->TeleportTo(tele->mapId, tele->position_x, tele->position_y, tele->position_z, tele->orientation); + return true; + } + + static bool HandleModifyDrunkCommand(ChatHandler* handler, const char* args) + { + if (!*args) return false; + + uint32 drunklevel = (uint32)atoi(args); + if (drunklevel > 100) + drunklevel = 100; + + uint16 drunkMod = drunklevel * 0xFFFF / 100; + + handler->GetSession()->GetPlayer()->SetDrunkValue(drunkMod); + + return true; + } + + static bool HandleModifyRepCommand(ChatHandler* handler, const char* args) + { + if (!*args) return false; + + Player* target = handler->getSelectedPlayer(); + + if (!target) + { + handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); + handler->SetSentErrorMessage(true); + return false; + } + + // check online security + if (handler->HasLowerSecurity(target, 0)) + return false; + + char* factionTxt = handler->extractKeyFromLink((char*)args,"Hfaction"); + if (!factionTxt) + return false; + + uint32 factionId = atoi(factionTxt); + + int32 amount = 0; + char *rankTxt = strtok(NULL, " "); + if (!factionTxt || !rankTxt) + return false; + + amount = atoi(rankTxt); + if ((amount == 0) && (rankTxt[0] != '-') && !isdigit(rankTxt[0])) + { + std::string rankStr = rankTxt; + std::wstring wrankStr; + if (!Utf8toWStr(rankStr,wrankStr)) + return false; + wstrToLower(wrankStr); + + int r = 0; + amount = -42000; + for (; r < MAX_REPUTATION_RANK; ++r) + { + std::string rank = handler->GetTrinityString(ReputationRankStrIndex[r]); + if (rank.empty()) + continue; + + std::wstring wrank; + if (!Utf8toWStr(rank,wrank)) + continue; + + wstrToLower(wrank); + + if (wrank.substr(0,wrankStr.size()) == wrankStr) + { + char *deltaTxt = strtok(NULL, " "); + if (deltaTxt) + { + int32 delta = atoi(deltaTxt); + if ((delta < 0) || (delta > ReputationMgr::PointsInRank[r] -1)) + { + handler->PSendSysMessage(LANG_COMMAND_FACTION_DELTA, (ReputationMgr::PointsInRank[r]-1)); + handler->SetSentErrorMessage(true); + return false; + } + amount += delta; + } + break; + } + amount += ReputationMgr::PointsInRank[r]; + } + if (r >= MAX_REPUTATION_RANK) + { + handler->PSendSysMessage(LANG_COMMAND_FACTION_INVPARAM, rankTxt); + handler->SetSentErrorMessage(true); + return false; + } + } + + FactionEntry const *factionEntry = sFactionStore.LookupEntry(factionId); + + if (!factionEntry) + { + handler->PSendSysMessage(LANG_COMMAND_FACTION_UNKNOWN, factionId); + handler->SetSentErrorMessage(true); + return false; + } + + if (factionEntry->reputationListID < 0) + { + handler->PSendSysMessage(LANG_COMMAND_FACTION_NOREP_ERROR, factionEntry->name[handler->GetSessionDbcLocale()], factionId); + handler->SetSentErrorMessage(true); + return false; + } + + target->GetReputationMgr().SetReputation(factionEntry,amount); + handler->PSendSysMessage(LANG_COMMAND_MODIFY_REP, factionEntry->name[handler->GetSessionDbcLocale()], factionId, + handler->GetNameLink(target).c_str(), target->GetReputationMgr().GetReputation(factionEntry)); + return true; + } + + //morph creature or player + static bool HandleModifyMorphCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + uint16 display_id = (uint16)atoi((char*)args); + + Unit* target = handler->getSelectedUnit(); + if (!target) + target = handler->GetSession()->GetPlayer(); + + // check online security + else if (target->GetTypeId() == TYPEID_PLAYER && handler->HasLowerSecurity(target->ToPlayer(), 0)) + return false; + + target->SetDisplayId(display_id); + + return true; + } + + //set temporary phase mask for player + static bool HandleModifyPhaseCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + uint32 phasemask = (uint32)atoi((char*)args); + + Unit* target = handler->getSelectedUnit(); + if (!target) + target = handler->GetSession()->GetPlayer(); + + // check online security + else if (target->GetTypeId() == TYPEID_PLAYER && handler->HasLowerSecurity(target->ToPlayer(), 0)) + return false; + + target->SetPhaseMask(phasemask,true); + + return true; + } + + //change standstate + static bool HandleModifyStandStateCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + uint32 anim_id = atoi((char*)args); + handler->GetSession()->GetPlayer()->SetUInt32Value(UNIT_NPC_EMOTESTATE , anim_id); + + return true; + } + + static bool HandleModifyArenaCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + Player* target = handler->getSelectedPlayer(); + if (!target) + { + handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); + handler->SetSentErrorMessage(true); + return false; + } + + int32 amount = (uint32)atoi(args); + + target->ModifyArenaPoints(amount); + + handler->PSendSysMessage(LANG_COMMAND_MODIFY_ARENA, handler->GetNameLink(target).c_str(), target->GetArenaPoints()); + + return true; + } + + static bool HandleModifyGenderCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + Player* target = handler->getSelectedPlayer(); + + if (!target) + { + handler->PSendSysMessage(LANG_PLAYER_NOT_FOUND); + handler->SetSentErrorMessage(true); + return false; + } + + PlayerInfo const* info = sObjectMgr.GetPlayerInfo(target->getRace(), target->getClass()); + if (!info) + return false; + + char const* gender_str = (char*)args; + int gender_len = strlen(gender_str); + + Gender gender; + + if (!strncmp(gender_str, "male", gender_len)) // MALE + { + if (target->getGender() == GENDER_MALE) + return true; + + gender = GENDER_MALE; + } + else if (!strncmp(gender_str, "female", gender_len)) // FEMALE + { + if (target->getGender() == GENDER_FEMALE) + return true; + + gender = GENDER_FEMALE; + } + else + { + handler->SendSysMessage(LANG_MUST_MALE_OR_FEMALE); + handler->SetSentErrorMessage(true); + return false; + } + + // Set gender + target->SetByteValue(UNIT_FIELD_BYTES_0, 2, gender); + target->SetByteValue(PLAYER_BYTES_3, 0, gender); + + // Change display ID + target->InitDisplayIds(); + + char const* gender_full = gender ? "female" : "male"; + + handler->PSendSysMessage(LANG_YOU_CHANGE_GENDER, handler->GetNameLink(target).c_str(), gender_full); + + if (handler->needReportToTarget(target)) + (ChatHandler(target)).PSendSysMessage(LANG_YOUR_GENDER_CHANGED, gender_full, handler->GetNameLink().c_str()); + + return true; + } +}; + +void AddSC_modify_commandscript() +{ + new modify_commandscript(); +} diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp new file mode 100644 index 00000000000..a0c81ae608f --- /dev/null +++ b/src/server/scripts/Commands/cs_npc.cpp @@ -0,0 +1,1433 @@ +/* + * Copyright (C) 2008-2010 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* ScriptData +Name: npc_commandscript +%Complete: 100 +Comment: All npc related commands +Category: commandscripts +EndScriptData */ + +#include "ScriptPCH.h" +#include "Transport.h" +#include "CreatureGroups.h" +#include "TargetedMovementGenerator.h" // for HandleNpcUnFollowCommand + +class npc_commandscript : public CommandScript +{ + public: + npc_commandscript() : CommandScript("npc_commandscript") { } + + ChatCommand* GetCommands() const + { + static ChatCommand npcAddCommandTable[] = + { + { "", SEC_GAMEMASTER, false, &HandleNpcAddCommand, "", NULL }, + { "formation", SEC_MODERATOR, false, &HandleNpcAddFormationCommand, "", NULL }, + { "item", SEC_GAMEMASTER, false, &HandleNpcAddVendorItemCommand, "", NULL }, + { "move", SEC_GAMEMASTER, false, &HandleNpcAddMoveCommand, "", NULL }, + { "temp", SEC_GAMEMASTER, false, &HandleNpcAddTempSpawnCommand, "", NULL }, + //{ TODO: fix or remove this commands + { "weapon", SEC_ADMINISTRATOR, false, &HandleNpcAddWeaponCommand, "", NULL }, + //} + { NULL, 0, false, NULL, "", NULL } + }; + static ChatCommand npcDeleteCommandTable[] = + { + { "", SEC_GAMEMASTER, false, &HandleNpcDeleteCommand, "", NULL }, + { "item", SEC_GAMEMASTER, false, &HandleNpcDeleteVendorItemCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + static ChatCommand npcFollowCommandTable[] = + { + { "", SEC_GAMEMASTER, false, &HandleNpcFollowCommand, "", NULL }, + { "stop", SEC_GAMEMASTER, false, &HandleNpcUnFollowCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + static ChatCommand npcSetCommandTable[] = + { + { "allowmove", SEC_ADMINISTRATOR, false, &HandleNpcSetAllowMovementCommand, "", NULL }, + { "deathstate", SEC_GAMEMASTER, false, &HandleNpcSetDeathStateCommand, "", NULL }, + { "entry", SEC_ADMINISTRATOR, false, &HandleNpcSetEntryCommand, "", NULL }, + { "factionid", SEC_GAMEMASTER, false, &HandleNpcSetFactionIdCommand, "", NULL }, + { "flag", SEC_GAMEMASTER, false, &HandleNpcSetFlagCommand, "", NULL }, + { "level", SEC_GAMEMASTER, false, &HandleNpcSetLevelCommand, "", NULL }, + { "link", SEC_GAMEMASTER, false, &HandleNpcSetLinkCommand, "", NULL }, + { "model", SEC_GAMEMASTER, false, &HandleNpcSetModelCommand, "", NULL }, + { "movetype", SEC_GAMEMASTER, false, &HandleNpcSetMoveTypeCommand, "", NULL }, + { "phase", SEC_GAMEMASTER, false, &HandleNpcSetPhaseCommand, "", NULL }, + { "spawndist", SEC_GAMEMASTER, false, &HandleNpcSetSpawnDistCommand, "", NULL }, + { "spawntime", SEC_GAMEMASTER, false, &HandleNpcSetSpawnTimeCommand, "", NULL }, + //{ TODO: fix or remove this commands + { "name", SEC_GAMEMASTER, false, &HandleNpcSetNameCommand, "", NULL }, + { "subname", SEC_GAMEMASTER, false, &HandleNpcSetSubNameCommand, "", NULL }, + //} + { NULL, 0, false, NULL, "", NULL } + }; + static ChatCommand npcCommandTable[] = + { + { "info", SEC_ADMINISTRATOR, false, &HandleNpcInfoCommand, "", NULL }, + { "move", SEC_GAMEMASTER, false, &HandleNpcMoveCommand, "", NULL }, + { "playemote", SEC_ADMINISTRATOR, false, &HandleNpcPlayEmoteCommand, "", NULL }, + { "say", SEC_MODERATOR, false, &HandleNpcSayCommand, "", NULL }, + { "textemote", SEC_MODERATOR, false, &HandleNpcTextEmoteCommand, "", NULL }, + { "whisper", SEC_MODERATOR, false, &HandleNpcWhisperCommand, "", NULL }, + { "yell", SEC_MODERATOR, false, &HandleNpcYellCommand, "", NULL }, + { "tame", SEC_GAMEMASTER, false, &HandleNpcTameCommand, "", NULL }, + { "add", SEC_GAMEMASTER, false, NULL, "", npcAddCommandTable }, + { "delete", SEC_GAMEMASTER, false, NULL, "", npcDeleteCommandTable }, + { "follow", SEC_GAMEMASTER, false, NULL, "", npcFollowCommandTable }, + { "set", SEC_GAMEMASTER, false, NULL, "", npcSetCommandTable }, + { NULL, 0, false, NULL, "", NULL } + }; + static ChatCommand commandTable[] = + { + { "npc", SEC_MODERATOR, false, NULL, "", npcCommandTable }, + { NULL, 0, false, NULL, "", NULL } + }; + return commandTable; + } + + //add spawn of creature + static bool HandleNpcAddCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + char* charID = handler->extractKeyFromLink((char*)args,"Hcreature_entry"); + if (!charID) + return false; + + char* team = strtok(NULL, " "); + int32 teamval = 0; + if (team) { teamval = atoi(team); } + if (teamval < 0) { teamval = 0; } + + uint32 id = atoi(charID); + + Player *chr = handler->GetSession()->GetPlayer(); + float x = chr->GetPositionX(); + float y = chr->GetPositionY(); + float z = chr->GetPositionZ(); + float o = chr->GetOrientation(); + Map *map = chr->GetMap(); + + if (chr->GetTransport()) + { + uint32 tguid = chr->GetTransport()->AddNPCPassenger(0, id, chr->GetTransOffsetX(), chr->GetTransOffsetY(), chr->GetTransOffsetZ(), chr->GetTransOffsetO()); + if (tguid > 0) + WorldDatabase.PQuery("INSERT INTO creature_transport (guid, npc_entry, transport_entry, TransOffsetX, TransOffsetY, TransOffsetZ, TransOffsetO) values (%u, %u, %f, %f, %f, %f, %u)", tguid, id, chr->GetTransport()->GetEntry(), chr->GetTransOffsetX(), chr->GetTransOffsetY(), chr->GetTransOffsetZ(), chr->GetTransOffsetO()); + + return true; + } + + Creature* pCreature = new Creature; + if (!pCreature->Create(sObjectMgr.GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0, (uint32)teamval, x, y, z, o)) + { + delete pCreature; + return false; + } + + pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn()); + + uint32 db_guid = pCreature->GetDBTableGUIDLow(); + + // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells(); + pCreature->LoadFromDB(db_guid, map); + + map->Add(pCreature); + sObjectMgr.AddCreatureToGrid(db_guid, sObjectMgr.GetCreatureData(db_guid)); + return true; + } + + //add item in vendorlist + static bool HandleNpcAddVendorItemCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + char* pitem = handler->extractKeyFromLink((char*)args,"Hitem"); + if (!pitem) + { + handler->SendSysMessage(LANG_COMMAND_NEEDITEMSEND); + handler->SetSentErrorMessage(true); + return false; + } + + uint32 itemId = atol(pitem); + + char* fmaxcount = strtok(NULL, " "); //add maxcount, default: 0 + uint32 maxcount = 0; + if (fmaxcount) + maxcount = atol(fmaxcount); + + char* fincrtime = strtok(NULL, " "); //add incrtime, default: 0 + uint32 incrtime = 0; + if (fincrtime) + incrtime = atol(fincrtime); + + char* fextendedcost = strtok(NULL, " "); //add ExtendedCost, default: 0 + uint32 extendedcost = fextendedcost ? atol(fextendedcost) : 0; + + Creature* vendor = handler->getSelectedCreature(); + + uint32 vendor_entry = vendor ? vendor->GetEntry() : 0; + + if (!sObjectMgr.IsVendorItemValid(vendor_entry,itemId,maxcount,incrtime,extendedcost,handler->GetSession()->GetPlayer())) + { + handler->SetSentErrorMessage(true); + return false; + } + + sObjectMgr.AddVendorItem(vendor_entry,itemId,maxcount,incrtime,extendedcost); + + ItemPrototype const* pProto = sObjectMgr.GetItemPrototype(itemId); + + handler->PSendSysMessage(LANG_ITEM_ADDED_TO_LIST,itemId,pProto->Name1,maxcount,incrtime,extendedcost); + return true; + } + + //add move for creature + static bool HandleNpcAddMoveCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + char* guid_str = strtok((char*)args, " "); + char* wait_str = strtok((char*)NULL, " "); + + uint32 lowguid = atoi((char*)guid_str); + + Creature* pCreature = NULL; + + /* FIXME: impossible without entry + if (lowguid) + pCreature = ObjectAccessor::GetCreature(*handler->GetSession()->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT)); + */ + + // attempt check creature existence by DB data + if (!pCreature) + { + CreatureData const* data = sObjectMgr.GetCreatureData(lowguid); + if (!data) + { + handler->PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid); + handler->SetSentErrorMessage(true); + return false; + } + } + else + { + // obtain real GUID for DB operations + lowguid = pCreature->GetDBTableGUIDLow(); + } + + int wait = wait_str ? atoi(wait_str) : 0; + + if (wait < 0) + wait = 0; + + //Player* player = handler->GetSession()->GetPlayer(); + + //WaypointMgr.AddLastNode(lowguid, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation(), wait, 0); + + // update movement type + WorldDatabase.PExecute("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE,lowguid); + if (pCreature && pCreature->GetWaypointPath()) + { + pCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE); + pCreature->GetMotionMaster()->Initialize(); + if (pCreature->isAlive()) // dead creature will reset movement generator at respawn + { + pCreature->setDeathState(JUST_DIED); + pCreature->Respawn(true); + } + pCreature->SaveToDB(); + } + + handler->SendSysMessage(LANG_WAYPOINT_ADDED); + + return true; + } + + static bool HandleNpcSetAllowMovementCommand(ChatHandler* handler, const char* /*args*/) + { + if (sWorld.getAllowMovement()) + { + sWorld.SetAllowMovement(false); + handler->SendSysMessage(LANG_CREATURE_MOVE_DISABLED); + } + else + { + sWorld.SetAllowMovement(true); + handler->SendSysMessage(LANG_CREATURE_MOVE_ENABLED); + } + return true; + } + + static bool HandleNpcSetEntryCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + uint32 newEntryNum = atoi(args); + if (!newEntryNum) + return false; + + Unit* unit = handler->getSelectedUnit(); + if (!unit || unit->GetTypeId() != TYPEID_UNIT) + { + handler->SendSysMessage(LANG_SELECT_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + Creature* creature = unit->ToCreature(); + if (creature->UpdateEntry(newEntryNum)) + handler->SendSysMessage(LANG_DONE); + else + handler->SendSysMessage(LANG_ERROR); + return true; + } + + //change level of creature or pet + static bool HandleNpcSetLevelCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + uint8 lvl = (uint8) atoi((char*)args); + if (lvl < 1 || lvl > sWorld.getIntConfig(CONFIG_MAX_PLAYER_LEVEL) + 3) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + + Creature* pCreature = handler->getSelectedCreature(); + if (!pCreature) + { + handler->SendSysMessage(LANG_SELECT_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + if (pCreature->isPet()) + { + if (((Pet*)pCreature)->getPetType() == HUNTER_PET) + { + pCreature->SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, sObjectMgr.GetXPForLevel(lvl)/4); + pCreature->SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, 0); + } + ((Pet*)pCreature)->GivePetLevel(lvl); + } + else + { + pCreature->SetMaxHealth(100 + 30*lvl); + pCreature->SetHealth(100 + 30*lvl); + pCreature->SetLevel(lvl); + pCreature->SaveToDB(); + } + + return true; + } + + static bool HandleNpcDeleteCommand(ChatHandler* handler, const char* args) + { + Creature* unit = NULL; + + if (*args) + { + // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r + char* cId = handler->extractKeyFromLink((char*)args,"Hcreature"); + if (!cId) + return false; + + uint32 lowguid = atoi(cId); + if (!lowguid) + return false; + + if (CreatureData const* cr_data = sObjectMgr.GetCreatureData(lowguid)) + unit = handler->GetSession()->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid, cr_data->id, HIGHGUID_UNIT)); + } + else + unit = handler->getSelectedCreature(); + + if (!unit || unit->isPet() || unit->isTotem()) + { + handler->SendSysMessage(LANG_SELECT_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + // Delete the creature + unit->CombatStop(); + unit->DeleteFromDB(); + unit->AddObjectToRemoveList(); + + handler->SendSysMessage(LANG_COMMAND_DELCREATMESSAGE); + + return true; + } + + //del item from vendor list + static bool HandleNpcDeleteVendorItemCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + Creature* vendor = handler->getSelectedCreature(); + if (!vendor || !vendor->isVendor()) + { + handler->SendSysMessage(LANG_COMMAND_VENDORSELECTION); + handler->SetSentErrorMessage(true); + return false; + } + + char* pitem = handler->extractKeyFromLink((char*)args,"Hitem"); + if (!pitem) + { + handler->SendSysMessage(LANG_COMMAND_NEEDITEMSEND); + handler->SetSentErrorMessage(true); + return false; + } + uint32 itemId = atol(pitem); + + if (!sObjectMgr.RemoveVendorItem(vendor->GetEntry(),itemId)) + { + handler->PSendSysMessage(LANG_ITEM_NOT_IN_LIST,itemId); + handler->SetSentErrorMessage(true); + return false; + } + + ItemPrototype const* pProto = sObjectMgr.GetItemPrototype(itemId); + + handler->PSendSysMessage(LANG_ITEM_DELETED_FROM_LIST,itemId,pProto->Name1); + return true; + } + + //set faction of creature + static bool HandleNpcSetFactionIdCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + uint32 factionId = (uint32) atoi((char*)args); + + if (!sFactionTemplateStore.LookupEntry(factionId)) + { + handler->PSendSysMessage(LANG_WRONG_FACTION, factionId); + handler->SetSentErrorMessage(true); + return false; + } + + Creature* pCreature = handler->getSelectedCreature(); + + if (!pCreature) + { + handler->SendSysMessage(LANG_SELECT_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + pCreature->setFaction(factionId); + + // faction is set in creature_template - not inside creature + + // update in memory + if (CreatureInfo const *cinfo = pCreature->GetCreatureInfo()) + { + const_cast<CreatureInfo*>(cinfo)->faction_A = factionId; + const_cast<CreatureInfo*>(cinfo)->faction_H = factionId; + } + + // and DB + WorldDatabase.PExecute("UPDATE creature_template SET faction_A = '%u', faction_H = '%u' WHERE entry = '%u'", factionId, factionId, pCreature->GetEntry()); + + return true; + } + + //set npcflag of creature + static bool HandleNpcSetFlagCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + uint32 npcFlags = (uint32) atoi((char*)args); + + Creature* pCreature = handler->getSelectedCreature(); + + if (!pCreature) + { + handler->SendSysMessage(LANG_SELECT_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + pCreature->SetUInt32Value(UNIT_NPC_FLAGS, npcFlags); + + WorldDatabase.PExecute("UPDATE creature_template SET npcflag = '%u' WHERE entry = '%u'", npcFlags, pCreature->GetEntry()); + + handler->SendSysMessage(LANG_VALUE_SAVED_REJOIN); + + return true; + } + + //npc follow handling + static bool HandleNpcFollowCommand(ChatHandler* handler, const char* /*args*/) + { + Player *player = handler->GetSession()->GetPlayer(); + Creature *creature = handler->getSelectedCreature(); + + if (!creature) + { + handler->PSendSysMessage(LANG_SELECT_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + // Follow player - Using pet's default dist and angle + creature->GetMotionMaster()->MoveFollow(player, PET_FOLLOW_DIST, creature->GetFollowAngle()); + + handler->PSendSysMessage(LANG_CREATURE_FOLLOW_YOU_NOW, creature->GetName()); + return true; + } + + static bool HandleNpcInfoCommand(ChatHandler* handler, const char* /*args*/) + { + Creature* target = handler->getSelectedCreature(); + + if (!target) + { + handler->SendSysMessage(LANG_SELECT_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + uint32 faction = target->getFaction(); + uint32 npcflags = target->GetUInt32Value(UNIT_NPC_FLAGS); + uint32 displayid = target->GetDisplayId(); + uint32 nativeid = target->GetNativeDisplayId(); + uint32 Entry = target->GetEntry(); + CreatureInfo const* cInfo = target->GetCreatureInfo(); + + int64 curRespawnDelay = target->GetRespawnTimeEx()-time(NULL); + if (curRespawnDelay < 0) + curRespawnDelay = 0; + std::string curRespawnDelayStr = secsToTimeString(uint64(curRespawnDelay),true); + std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(),true); + + handler->PSendSysMessage(LANG_NPCINFO_CHAR, target->GetDBTableGUIDLow(), faction, npcflags, Entry, displayid, nativeid); + handler->PSendSysMessage(LANG_NPCINFO_LEVEL, target->getLevel()); + handler->PSendSysMessage(LANG_NPCINFO_HEALTH,target->GetCreateHealth(), target->GetMaxHealth(), target->GetHealth()); + handler->PSendSysMessage(LANG_NPCINFO_FLAGS, target->GetUInt32Value(UNIT_FIELD_FLAGS), target->GetUInt32Value(UNIT_DYNAMIC_FLAGS), target->getFaction()); + handler->PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES, defRespawnDelayStr.c_str(),curRespawnDelayStr.c_str()); + handler->PSendSysMessage(LANG_NPCINFO_LOOT, cInfo->lootid,cInfo->pickpocketLootId,cInfo->SkinLootId); + handler->PSendSysMessage(LANG_NPCINFO_DUNGEON_ID, target->GetInstanceId()); + handler->PSendSysMessage(LANG_NPCINFO_PHASEMASK, target->GetPhaseMask()); + handler->PSendSysMessage(LANG_NPCINFO_ARMOR, target->GetArmor()); + handler->PSendSysMessage(LANG_NPCINFO_POSITION,float(target->GetPositionX()), float(target->GetPositionY()), float(target->GetPositionZ())); + if (const CreatureData* const linked = target->GetLinkedRespawnCreatureData()) + if (CreatureInfo const *master = GetCreatureInfo(linked->id)) + handler->PSendSysMessage(LANG_NPCINFO_LINKGUID, sObjectMgr.GetLinkedRespawnGuid(target->GetDBTableGUIDLow()), linked->id, master->Name); + + if ((npcflags & UNIT_NPC_FLAG_VENDOR)) + { + handler->SendSysMessage(LANG_NPCINFO_VENDOR); + } + if ((npcflags & UNIT_NPC_FLAG_TRAINER)) + { + handler->SendSysMessage(LANG_NPCINFO_TRAINER); + } + + return true; + } + + //move selected creature + static bool HandleNpcMoveCommand(ChatHandler* handler, const char* args) + { + uint32 lowguid = 0; + + Creature* pCreature = handler->getSelectedCreature(); + + if (!pCreature) + { + // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r + char* cId = handler->extractKeyFromLink((char*)args,"Hcreature"); + if (!cId) + return false; + + lowguid = atoi(cId); + + /* FIXME: impossibel without entry + if (lowguid) + pCreature = ObjectAccessor::GetCreature(*handler->GetSession()->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT)); + */ + + // Attempting creature load from DB data + if (!pCreature) + { + CreatureData const* data = sObjectMgr.GetCreatureData(lowguid); + if (!data) + { + handler->PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid); + handler->SetSentErrorMessage(true); + return false; + } + + uint32 map_id = data->mapid; + + if (handler->GetSession()->GetPlayer()->GetMapId() != map_id) + { + handler->PSendSysMessage(LANG_COMMAND_CREATUREATSAMEMAP, lowguid); + handler->SetSentErrorMessage(true); + return false; + } + } + else + { + lowguid = pCreature->GetDBTableGUIDLow(); + } + } + else + { + lowguid = pCreature->GetDBTableGUIDLow(); + } + + float x = handler->GetSession()->GetPlayer()->GetPositionX(); + float y = handler->GetSession()->GetPlayer()->GetPositionY(); + float z = handler->GetSession()->GetPlayer()->GetPositionZ(); + float o = handler->GetSession()->GetPlayer()->GetOrientation(); + + if (pCreature) + { + if (CreatureData const* data = sObjectMgr.GetCreatureData(pCreature->GetDBTableGUIDLow())) + { + const_cast<CreatureData*>(data)->posX = x; + const_cast<CreatureData*>(data)->posY = y; + const_cast<CreatureData*>(data)->posZ = z; + const_cast<CreatureData*>(data)->orientation = o; + } + pCreature->GetMap()->CreatureRelocation(pCreature,x, y, z,o); + pCreature->GetMotionMaster()->Initialize(); + if (pCreature->isAlive()) // dead creature will reset movement generator at respawn + { + pCreature->setDeathState(JUST_DIED); + pCreature->Respawn(); + } + } + + WorldDatabase.PExecute("UPDATE creature SET position_x = '%f', position_y = '%f', position_z = '%f', orientation = '%f' WHERE guid = '%u'", x, y, z, o, lowguid); + handler->PSendSysMessage(LANG_COMMAND_CREATUREMOVED); + return true; + } + + //play npc emote + static bool HandleNpcPlayEmoteCommand(ChatHandler* handler, const char* args) + { + uint32 emote = atoi((char*)args); + + Creature* target = handler->getSelectedCreature(); + if (!target) + { + handler->SendSysMessage(LANG_SELECT_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + if (target->GetTransport()) + if (target->GetGUIDTransport()) + WorldDatabase.PQuery("UPDATE creature_transport SET emote=%u WHERE transport_entry=%u AND guid=%u", emote, target->GetTransport()->GetEntry(), target->GetGUIDTransport()); + + target->SetUInt32Value(UNIT_NPC_EMOTESTATE,emote); + + return true; + } + + //set model of creature + static bool HandleNpcSetModelCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + uint32 displayId = (uint32) atoi((char*)args); + + Creature *pCreature = handler->getSelectedCreature(); + + if (!pCreature || pCreature->isPet()) + { + handler->SendSysMessage(LANG_SELECT_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + pCreature->SetDisplayId(displayId); + pCreature->SetNativeDisplayId(displayId); + + pCreature->SaveToDB(); + + return true; + } + + /**HandleNpcSetMoveTypeCommand + * Set the movement type for an NPC.<br/> + * <br/> + * Valid movement types are: + * <ul> + * <li> stay - NPC wont move </li> + * <li> random - NPC will move randomly according to the spawndist </li> + * <li> way - NPC will move with given waypoints set </li> + * </ul> + * additional parameter: NODEL - so no waypoints are deleted, if you + * change the movement type + */ + static bool HandleNpcSetMoveTypeCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + // 3 arguments: + // GUID (optional - you can also select the creature) + // stay|random|way (determines the kind of movement) + // NODEL (optional - tells the system NOT to delete any waypoints) + // this is very handy if you want to do waypoints, that are + // later switched on/off according to special events (like escort + // quests, etc) + char* guid_str = strtok((char*)args, " "); + char* type_str = strtok((char*)NULL, " "); + char* dontdel_str = strtok((char*)NULL, " "); + + bool doNotDelete = false; + + if (!guid_str) + return false; + + uint32 lowguid = 0; + Creature* pCreature = NULL; + + if (dontdel_str) + { + //sLog.outError("DEBUG: All 3 params are set"); + + // All 3 params are set + // GUID + // type + // doNotDEL + if (stricmp(dontdel_str, "NODEL") == 0) + { + //sLog.outError("DEBUG: doNotDelete = true;"); + doNotDelete = true; + } + } + else + { + // Only 2 params - but maybe NODEL is set + if (type_str) + { + sLog.outError("DEBUG: Only 2 params "); + if (stricmp(type_str, "NODEL") == 0) + { + //sLog.outError("DEBUG: type_str, NODEL "); + doNotDelete = true; + type_str = NULL; + } + } + } + + if (!type_str) // case .setmovetype $move_type (with selected creature) + { + type_str = guid_str; + pCreature = handler->getSelectedCreature(); + if (!pCreature || pCreature->isPet()) + return false; + lowguid = pCreature->GetDBTableGUIDLow(); + } + else // case .setmovetype #creature_guid $move_type (with selected creature) + { + lowguid = atoi((char*)guid_str); + + /* impossible without entry + if (lowguid) + pCreature = ObjectAccessor::GetCreature(*handler->GetSession()->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT)); + */ + + // attempt check creature existence by DB data + if (!pCreature) + { + CreatureData const* data = sObjectMgr.GetCreatureData(lowguid); + if (!data) + { + handler->PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid); + handler->SetSentErrorMessage(true); + return false; + } + } + else + { + lowguid = pCreature->GetDBTableGUIDLow(); + } + } + + // now lowguid is low guid really existed creature + // and pCreature point (maybe) to this creature or NULL + + MovementGeneratorType move_type; + + std::string type = type_str; + + if (type == "stay") + move_type = IDLE_MOTION_TYPE; + else if (type == "random") + move_type = RANDOM_MOTION_TYPE; + else if (type == "way") + move_type = WAYPOINT_MOTION_TYPE; + else + return false; + + // update movement type + //if (doNotDelete == false) + // WaypointMgr.DeletePath(lowguid); + + if (pCreature) + { + // update movement type + if (doNotDelete == false) + pCreature->LoadPath(0); + + pCreature->SetDefaultMovementType(move_type); + pCreature->GetMotionMaster()->Initialize(); + if (pCreature->isAlive()) // dead creature will reset movement generator at respawn + { + pCreature->setDeathState(JUST_DIED); + pCreature->Respawn(); + } + pCreature->SaveToDB(); + } + if (doNotDelete == false) + { + handler->PSendSysMessage(LANG_MOVE_TYPE_SET,type_str); + } + else + { + handler->PSendSysMessage(LANG_MOVE_TYPE_SET_NODEL,type_str); + } + + return true; + } + + //npc phasemask handling + //change phasemask of creature or pet + static bool HandleNpcSetPhaseCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + uint32 phasemask = (uint32) atoi((char*)args); + if (phasemask == 0) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + + Creature* pCreature = handler->getSelectedCreature(); + if (!pCreature) + { + handler->SendSysMessage(LANG_SELECT_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + pCreature->SetPhaseMask(phasemask,true); + + if (!pCreature->isPet()) + pCreature->SaveToDB(); + + return true; + } + + //set spawn dist of creature + static bool HandleNpcSetSpawnDistCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + float option = (float)(atof((char*)args)); + if (option < 0.0f) + { + handler->SendSysMessage(LANG_BAD_VALUE); + return false; + } + + MovementGeneratorType mtype = IDLE_MOTION_TYPE; + if (option >0.0f) + mtype = RANDOM_MOTION_TYPE; + + Creature *pCreature = handler->getSelectedCreature(); + uint32 u_guidlow = 0; + + if (pCreature) + u_guidlow = pCreature->GetDBTableGUIDLow(); + else + return false; + + pCreature->SetRespawnRadius((float)option); + pCreature->SetDefaultMovementType(mtype); + pCreature->GetMotionMaster()->Initialize(); + if (pCreature->isAlive()) // dead creature will reset movement generator at respawn + { + pCreature->setDeathState(JUST_DIED); + pCreature->Respawn(); + } + + WorldDatabase.PExecute("UPDATE creature SET spawndist=%f, MovementType=%i WHERE guid=%u",option,mtype,u_guidlow); + handler->PSendSysMessage(LANG_COMMAND_SPAWNDIST,option); + return true; + } + + //spawn time handling + static bool HandleNpcSetSpawnTimeCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + char* stime = strtok((char*)args, " "); + + if (!stime) + return false; + + int i_stime = atoi((char*)stime); + + if (i_stime < 0) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + + Creature *pCreature = handler->getSelectedCreature(); + uint32 u_guidlow = 0; + + if (pCreature) + u_guidlow = pCreature->GetDBTableGUIDLow(); + else + return false; + + WorldDatabase.PExecute("UPDATE creature SET spawntimesecs=%i WHERE guid=%u",i_stime,u_guidlow); + pCreature->SetRespawnDelay((uint32)i_stime); + handler->PSendSysMessage(LANG_COMMAND_SPAWNTIME,i_stime); + + return true; + } + + static bool HandleNpcSayCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + Creature* pCreature = handler->getSelectedCreature(); + if (!pCreature) + { + handler->SendSysMessage(LANG_SELECT_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + pCreature->MonsterSay(args, LANG_UNIVERSAL, 0); + + // make some emotes + char lastchar = args[strlen(args) - 1]; + switch(lastchar) + { + case '?': pCreature->HandleEmoteCommand(EMOTE_ONESHOT_QUESTION); break; + case '!': pCreature->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION); break; + default: pCreature->HandleEmoteCommand(EMOTE_ONESHOT_TALK); break; + } + + return true; + } + + //show text emote by creature in chat + static bool HandleNpcTextEmoteCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + Creature* pCreature = handler->getSelectedCreature(); + + if (!pCreature) + { + handler->SendSysMessage(LANG_SELECT_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + pCreature->MonsterTextEmote(args, 0); + + return true; + } + + //npc unfollow handling + static bool HandleNpcUnFollowCommand(ChatHandler* handler, const char* /*args*/) + { + Player *player = handler->GetSession()->GetPlayer(); + Creature *creature = handler->getSelectedCreature(); + + if (!creature) + { + handler->PSendSysMessage(LANG_SELECT_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + if (/*creature->GetMotionMaster()->empty() ||*/ + creature->GetMotionMaster()->GetCurrentMovementGeneratorType () != TARGETED_MOTION_TYPE) + { + handler->PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU, creature->GetName()); + handler->SetSentErrorMessage(true); + return false; + } + + TargetedMovementGenerator<Creature> const* mgen + = static_cast<TargetedMovementGenerator<Creature> const*>((creature->GetMotionMaster()->top())); + + if (mgen->GetTarget() != player) + { + handler->PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU, creature->GetName()); + handler->SetSentErrorMessage(true); + return false; + } + + // reset movement + creature->GetMotionMaster()->MovementExpired(true); + + handler->PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU_NOW, creature->GetName()); + return true; + } + + // make npc whisper to player + static bool HandleNpcWhisperCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + char* receiver_str = strtok((char*)args, " "); + char* text = strtok(NULL, ""); + + uint64 guid = handler->GetSession()->GetPlayer()->GetSelection(); + Creature* pCreature = handler->GetSession()->GetPlayer()->GetMap()->GetCreature(guid); + + if (!pCreature || !receiver_str || !text) + { + return false; + } + + uint64 receiver_guid= atol(receiver_str); + + // check online security + if (handler->HasLowerSecurity(sObjectMgr.GetPlayer(receiver_guid), 0)) + return false; + + pCreature->MonsterWhisper(text,receiver_guid); + + return true; + } + + static bool HandleNpcYellCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + Creature* pCreature = handler->getSelectedCreature(); + if (!pCreature) + { + handler->SendSysMessage(LANG_SELECT_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + pCreature->MonsterYell(args, LANG_UNIVERSAL, 0); + + // make an emote + pCreature->HandleEmoteCommand(EMOTE_ONESHOT_SHOUT); + + return true; + } + + // add creature, temp only + static bool HandleNpcAddTempSpawnCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + char* charID = strtok((char*)args, " "); + if (!charID) + return false; + + Player *chr = handler->GetSession()->GetPlayer(); + + uint32 id = atoi(charID); + if (!id) + return false; + + chr->SummonCreature(id, *chr, TEMPSUMMON_CORPSE_DESPAWN, 120); + + return true; + } + + //npc tame handling + static bool HandleNpcTameCommand(ChatHandler* handler, const char* /*args*/) + { + Creature *creatureTarget = handler->getSelectedCreature (); + if (!creatureTarget || creatureTarget->isPet ()) + { + handler->PSendSysMessage (LANG_SELECT_CREATURE); + handler->SetSentErrorMessage (true); + return false; + } + + Player *player = handler->GetSession()->GetPlayer (); + + if (player->GetPetGUID ()) + { + handler->SendSysMessage (LANG_YOU_ALREADY_HAVE_PET); + handler->SetSentErrorMessage (true); + return false; + } + + CreatureInfo const* cInfo = creatureTarget->GetCreatureInfo(); + + if (!cInfo->isTameable (player->CanTameExoticPets())) + { + handler->PSendSysMessage (LANG_CREATURE_NON_TAMEABLE,cInfo->Entry); + handler->SetSentErrorMessage (true); + return false; + } + + // Everything looks OK, create new pet + Pet* pet = player->CreateTamedPetFrom (creatureTarget); + if (!pet) + { + handler->PSendSysMessage (LANG_CREATURE_NON_TAMEABLE,cInfo->Entry); + handler->SetSentErrorMessage (true); + return false; + } + + // place pet before player + float x,y,z; + player->GetClosePoint (x,y,z,creatureTarget->GetObjectSize (),CONTACT_DISTANCE); + pet->Relocate (x,y,z,M_PI-player->GetOrientation ()); + + // set pet to defensive mode by default (some classes can't control controlled pets in fact). + pet->SetReactState(REACT_DEFENSIVE); + + // calculate proper level + uint8 level = (creatureTarget->getLevel() < (player->getLevel() - 5)) ? (player->getLevel() - 5) : creatureTarget->getLevel(); + + // prepare visual effect for levelup + pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1); + + // add to world + pet->GetMap()->Add(pet->ToCreature()); + + // visual effect for levelup + pet->SetUInt32Value(UNIT_FIELD_LEVEL, level); + + // caster have pet now + player->SetMinion(pet, true); + + pet->SavePetToDB(PET_SAVE_AS_CURRENT); + player->PetSpellInitialize(); + + return true; + } + + //npc deathstate handling + static bool HandleNpcSetDeathStateCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + Creature* pCreature = handler->getSelectedCreature(); + if (!pCreature || pCreature->isPet()) + { + handler->SendSysMessage(LANG_SELECT_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + if (strncmp(args, "on", 3) == 0) + pCreature->SetDeadByDefault(true); + else if (strncmp(args, "off", 4) == 0) + pCreature->SetDeadByDefault(false); + else + { + handler->SendSysMessage(LANG_USE_BOL); + handler->SetSentErrorMessage(true); + return false; + } + + pCreature->SaveToDB(); + pCreature->Respawn(); + + return true; + } + + static bool HandleNpcAddFormationCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + uint32 leaderGUID = (uint32) atoi((char*)args); + Creature *pCreature = handler->getSelectedCreature(); + + if (!pCreature || !pCreature->GetDBTableGUIDLow()) + { + handler->SendSysMessage(LANG_SELECT_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + uint32 lowguid = pCreature->GetDBTableGUIDLow(); + if (pCreature->GetFormation()) + { + handler->PSendSysMessage("Selected creature is already member of group %u", pCreature->GetFormation()->GetId()); + return false; + } + + if (!lowguid) + return false; + + Player *chr = handler->GetSession()->GetPlayer(); + FormationInfo *group_member; + + group_member = new FormationInfo; + group_member->follow_angle = (pCreature->GetAngle(chr) - chr->GetOrientation()) * 180 / M_PI; + group_member->follow_dist = sqrtf(pow(chr->GetPositionX() - pCreature->GetPositionX(),int(2))+pow(chr->GetPositionY()-pCreature->GetPositionY(),int(2))); + group_member->leaderGUID = leaderGUID; + group_member->groupAI = 0; + + CreatureGroupMap[lowguid] = group_member; + pCreature->SearchFormation(); + + WorldDatabase.PExecute("INSERT INTO creature_formations (leaderGUID, memberGUID, dist, angle, groupAI) VALUES ('%u','%u','%f', '%f', '%u')", + leaderGUID, lowguid, group_member->follow_dist, group_member->follow_angle, group_member->groupAI); + + handler->PSendSysMessage("Creature %u added to formation with leader %u", lowguid, leaderGUID); + + return true; + } + + static bool HandleNpcSetLinkCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + uint32 linkguid = (uint32) atoi((char*)args); + + Creature* pCreature = handler->getSelectedCreature(); + + if (!pCreature) + { + handler->SendSysMessage(LANG_SELECT_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + if (!pCreature->GetDBTableGUIDLow()) + { + handler->PSendSysMessage("Selected creature %u isn't in creature table", pCreature->GetGUIDLow()); + handler->SetSentErrorMessage(true); + return false; + } + + if (!sObjectMgr.SetCreatureLinkedRespawn(pCreature->GetDBTableGUIDLow(), linkguid)) + { + handler->PSendSysMessage("Selected creature can't link with guid '%u'", linkguid); + handler->SetSentErrorMessage(true); + return false; + } + + handler->PSendSysMessage("LinkGUID '%u' added to creature with DBTableGUID: '%u'", linkguid, pCreature->GetDBTableGUIDLow()); + return true; + } + + //TODO: NpcCommands that needs to be fixed : + static bool HandleNpcAddWeaponCommand(ChatHandler* handler, const char* /*args*/) + { + /*if (!*args) + return false; + + uint64 guid = handler->GetSession()->GetPlayer()->GetSelection(); + if (guid == 0) + { + handler->SendSysMessage(LANG_NO_SELECTION); + return true; + } + + Creature *pCreature = ObjectAccessor::GetCreature(*handler->GetSession()->GetPlayer(), guid); + + if (!pCreature) + { + handler->SendSysMessage(LANG_SELECT_CREATURE); + return true; + } + + char* pSlotID = strtok((char*)args, " "); + if (!pSlotID) + return false; + + char* pItemID = strtok(NULL, " "); + if (!pItemID) + return false; + + uint32 ItemID = atoi(pItemID); + uint32 SlotID = atoi(pSlotID); + + ItemPrototype* tmpItem = sObjectMgr.GetItemPrototype(ItemID); + + bool added = false; + if (tmpItem) + { + switch(SlotID) + { + case 1: + pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, ItemID); + added = true; + break; + case 2: + pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_01, ItemID); + added = true; + break; + case 3: + pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_02, ItemID); + added = true; + break; + default: + handler->PSendSysMessage(LANG_ITEM_SLOT_NOT_EXIST,SlotID); + added = false; + break; + } + + if (added) + handler->PSendSysMessage(LANG_ITEM_ADDED_TO_SLOT,ItemID,tmpItem->Name1,SlotID); + } + else + { + handler->PSendSysMessage(LANG_ITEM_NOT_FOUND,ItemID); + return true; + } + */ + return true; + } + + static bool HandleNpcSetNameCommand(ChatHandler* handler, const char* /*args*/) + { + /* Temp. disabled + if (!*args) + return false; + + if (strlen((char*)args)>75) + { + handler->PSendSysMessage(LANG_TOO_LONG_NAME, strlen((char*)args)-75); + return true; + } + + for (uint8 i = 0; i < strlen(args); ++i) + { + if (!isalpha(args[i]) && args[i] != ' ') + { + handler->SendSysMessage(LANG_CHARS_ONLY); + return false; + } + } + + uint64 guid; + guid = handler->GetSession()->GetPlayer()->GetSelection(); + if (guid == 0) + { + handler->SendSysMessage(LANG_NO_SELECTION); + return true; + } + + Creature* pCreature = ObjectAccessor::GetCreature(*handler->GetSession()->GetPlayer(), guid); + + if (!pCreature) + { + handler->SendSysMessage(LANG_SELECT_CREATURE); + return true; + } + + pCreature->SetName(args); + uint32 idname = sObjectMgr.AddCreatureTemplate(pCreature->GetName()); + pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname); + + pCreature->SaveToDB(); + */ + + return true; + } + + static bool HandleNpcSetSubNameCommand(ChatHandler* handler, const char* /*args*/) + { + /* Temp. disabled + + if (!*args) + args = ""; + + if (strlen((char*)args)>75) + { + + handler->PSendSysMessage(LANG_TOO_LONG_SUBNAME, strlen((char*)args)-75); + return true; + } + + for (uint8 i = 0; i < strlen(args); i++) + { + if (!isalpha(args[i]) && args[i] != ' ') + { + handler->SendSysMessage(LANG_CHARS_ONLY); + return false; + } + } + uint64 guid; + guid = handler->GetSession()->GetPlayer()->GetSelection(); + if (guid == 0) + { + handler->SendSysMessage(LANG_NO_SELECTION); + return true; + } + + Creature* pCreature = ObjectAccessor::GetCreature(*handler->GetSession()->GetPlayer(), guid); + + if (!pCreature) + { + handler->SendSysMessage(LANG_SELECT_CREATURE); + return true; + } + + uint32 idname = sObjectMgr.AddCreatureSubName(pCreature->GetName(),args,pCreature->GetUInt32Value(UNIT_FIELD_DISPLAYID)); + pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname); + + pCreature->SaveToDB(); + */ + return true; + } + //---------------------------------------------------------- +}; + +void AddSC_npc_commandscript() +{ + new npc_commandscript(); +} |
