/** * MaNGOS is a full featured server for World of Warcraft, supporting * the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8 * * Copyright (C) 2005-2018 MaNGOS project * * 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, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * World of Warcraft, and all World of Warcraft or Warcraft art, images, * and lore are copyrighted by Blizzard Entertainment, Inc. */ #include "Common.h" #include "Database/DatabaseEnv.h" #include "WorldPacket.h" #include "WorldSession.h" #include "World.h" #include "ObjectMgr.h" #include "AccountMgr.h" #include "PlayerDump.h" #include "SpellMgr.h" #include "Player.h" #include "Opcodes.h" #include "GameObject.h" #include "Chat.h" #include "Log.h" #include "Guild.h" #include "GuildMgr.h" #include "ObjectAccessor.h" #include "MapManager.h" #include "MassMailMgr.h" #include "ScriptMgr.h" #include "Language.h" #include "GridNotifiersImpl.h" #include "CellImpl.h" #include "Weather.h" #include "PointMovementGenerator.h" #include "PathFinder.h" #include "TargetedMovementGenerator.h" #include "SkillDiscovery.h" #include "SkillExtraItems.h" #include "SystemConfig.h" #include "Config/Config.h" #include "Mail.h" #include "Util.h" #include "ItemEnchantmentMgr.h" #include "BattleGround/BattleGroundMgr.h" #include "MapPersistentStateMgr.h" #include "InstanceData.h" #include "CreatureEventAIMgr.h" #include "DBCEnums.h" #include "AuctionHouseBot/AuctionHouseBot.h" #include "SQLStorages.h" static uint32 ahbotQualityIds[MAX_AUCTION_QUALITY] = { LANG_AHBOT_QUALITY_GREY, LANG_AHBOT_QUALITY_WHITE, LANG_AHBOT_QUALITY_GREEN, LANG_AHBOT_QUALITY_BLUE, LANG_AHBOT_QUALITY_PURPLE, LANG_AHBOT_QUALITY_ORANGE, LANG_AHBOT_QUALITY_YELLOW }; bool ChatHandler::HandleAHBotItemsAmountCommand(char* args) { uint32 qVals[MAX_AUCTION_QUALITY]; for (int i = 0; i < MAX_AUCTION_QUALITY; ++i) if (!ExtractUInt32(&args, qVals[i])) { return false; } sAuctionBot.SetItemsAmount(qVals); for (int i = 0; i < MAX_AUCTION_QUALITY; ++i) { PSendSysMessage(LANG_AHBOT_ITEMS_AMOUNT, GetMangosString(ahbotQualityIds[i]), sAuctionBotConfig.getConfigItemQualityAmount(AuctionQuality(i))); } return true; } template bool ChatHandler::HandleAHBotItemsAmountQualityCommand(char* args) { uint32 qVal; if (!ExtractUInt32(&args, qVal)) { return false; } sAuctionBot.SetItemsAmountForQuality(AuctionQuality(Q), qVal); PSendSysMessage(LANG_AHBOT_ITEMS_AMOUNT, GetMangosString(ahbotQualityIds[Q]), sAuctionBotConfig.getConfigItemQualityAmount(AuctionQuality(Q))); return true; } template bool ChatHandler::HandleAHBotItemsAmountQualityCommand(char*); template bool ChatHandler::HandleAHBotItemsAmountQualityCommand(char*); template bool ChatHandler::HandleAHBotItemsAmountQualityCommand(char*); template bool ChatHandler::HandleAHBotItemsAmountQualityCommand(char*); template bool ChatHandler::HandleAHBotItemsAmountQualityCommand(char*); template bool ChatHandler::HandleAHBotItemsAmountQualityCommand(char*); template bool ChatHandler::HandleAHBotItemsAmountQualityCommand(char*); bool ChatHandler::HandleAHBotItemsRatioCommand(char* args) { uint32 rVal[MAX_AUCTION_HOUSE_TYPE]; for (int i = 0; i < MAX_AUCTION_HOUSE_TYPE; ++i) if (!ExtractUInt32(&args, rVal[i])) { return false; } sAuctionBot.SetItemsRatio(rVal[0], rVal[1], rVal[2]); for (int i = 0; i < MAX_AUCTION_HOUSE_TYPE; ++i) { PSendSysMessage(LANG_AHBOT_ITEMS_RATIO, AuctionBotConfig::GetHouseTypeName(AuctionHouseType(i)), sAuctionBotConfig.getConfigItemAmountRatio(AuctionHouseType(i))); } return true; } template bool ChatHandler::HandleAHBotItemsRatioHouseCommand(char* args) { uint32 rVal; if (!ExtractUInt32(&args, rVal)) { return false; } sAuctionBot.SetItemsRatioForHouse(AuctionHouseType(H), rVal); PSendSysMessage(LANG_AHBOT_ITEMS_RATIO, AuctionBotConfig::GetHouseTypeName(AuctionHouseType(H)), sAuctionBotConfig.getConfigItemAmountRatio(AuctionHouseType(H))); return true; } template bool ChatHandler::HandleAHBotItemsRatioHouseCommand(char*); template bool ChatHandler::HandleAHBotItemsRatioHouseCommand(char*); template bool ChatHandler::HandleAHBotItemsRatioHouseCommand(char*); bool ChatHandler::HandleAHBotRebuildCommand(char* args) { bool all = false; if (*args) { if (!ExtractLiteralArg(&args, "all")) { return false; } all = true; } sAuctionBot.Rebuild(all); return true; } bool ChatHandler::HandleAHBotReloadCommand(char* /*args*/) { if (sAuctionBot.ReloadAllConfig()) { SendSysMessage(LANG_AHBOT_RELOAD_OK); return true; } else { SendSysMessage(LANG_AHBOT_RELOAD_FAIL); SetSentErrorMessage(true); return false; } } bool ChatHandler::HandleAHBotStatusCommand(char* args) { bool all = false; if (*args) { if (!ExtractLiteralArg(&args, "all")) { return false; } all = true; } AuctionHouseBotStatusInfo statusInfo; sAuctionBot.PrepareStatusInfos(statusInfo); if (!m_session) { SendSysMessage(LANG_AHBOT_STATUS_BAR_CONSOLE); SendSysMessage(LANG_AHBOT_STATUS_TITLE1_CONSOLE); SendSysMessage(LANG_AHBOT_STATUS_MIDBAR_CONSOLE); } else { SendSysMessage(LANG_AHBOT_STATUS_TITLE1_CHAT); } uint32 fmtId = m_session ? LANG_AHBOT_STATUS_FORMAT_CHAT : LANG_AHBOT_STATUS_FORMAT_CONSOLE; PSendSysMessage(fmtId, GetMangosString(LANG_AHBOT_STATUS_ITEM_COUNT), statusInfo[AUCTION_HOUSE_ALLIANCE].ItemsCount, statusInfo[AUCTION_HOUSE_HORDE].ItemsCount, statusInfo[AUCTION_HOUSE_NEUTRAL].ItemsCount, statusInfo[AUCTION_HOUSE_ALLIANCE].ItemsCount + statusInfo[AUCTION_HOUSE_HORDE].ItemsCount + statusInfo[AUCTION_HOUSE_NEUTRAL].ItemsCount); if (all) { PSendSysMessage(fmtId, GetMangosString(LANG_AHBOT_STATUS_ITEM_RATIO), sAuctionBotConfig.getConfig(CONFIG_UINT32_AHBOT_ALLIANCE_ITEM_AMOUNT_RATIO), sAuctionBotConfig.getConfig(CONFIG_UINT32_AHBOT_HORDE_ITEM_AMOUNT_RATIO), sAuctionBotConfig.getConfig(CONFIG_UINT32_AHBOT_NEUTRAL_ITEM_AMOUNT_RATIO), sAuctionBotConfig.getConfig(CONFIG_UINT32_AHBOT_ALLIANCE_ITEM_AMOUNT_RATIO) + sAuctionBotConfig.getConfig(CONFIG_UINT32_AHBOT_HORDE_ITEM_AMOUNT_RATIO) + sAuctionBotConfig.getConfig(CONFIG_UINT32_AHBOT_NEUTRAL_ITEM_AMOUNT_RATIO)); if (!m_session) { SendSysMessage(LANG_AHBOT_STATUS_BAR_CONSOLE); SendSysMessage(LANG_AHBOT_STATUS_TITLE2_CONSOLE); SendSysMessage(LANG_AHBOT_STATUS_MIDBAR_CONSOLE); } else { SendSysMessage(LANG_AHBOT_STATUS_TITLE2_CHAT); } for (int i = 0; i < MAX_AUCTION_QUALITY; ++i) PSendSysMessage(fmtId, GetMangosString(ahbotQualityIds[i]), statusInfo[AUCTION_HOUSE_ALLIANCE].QualityInfo[i], statusInfo[AUCTION_HOUSE_HORDE].QualityInfo[i], statusInfo[AUCTION_HOUSE_NEUTRAL].QualityInfo[i], sAuctionBotConfig.getConfigItemQualityAmount(AuctionQuality(i))); } if (!m_session) { SendSysMessage(LANG_AHBOT_STATUS_BAR_CONSOLE); } return true; } // reload commands bool ChatHandler::HandleReloadAllCommand(char* /*args*/) { HandleReloadSkillFishingBaseLevelCommand((char*)""); HandleReloadAllAchievementCommand((char*)""); HandleReloadAllAreaCommand((char*)""); HandleReloadAutoBroadcastCommand((char*)""); HandleReloadAllEventAICommand((char*)""); HandleReloadAllLootCommand((char*)""); HandleReloadAllNpcCommand((char*)""); HandleReloadAllQuestCommand((char*)""); HandleReloadAllSpellCommand((char*)""); HandleReloadAllItemCommand((char*)""); HandleReloadAllGossipsCommand((char*)""); HandleReloadAllLocalesCommand((char*)""); HandleReloadMailLevelRewardCommand((char*)""); HandleReloadCommandCommand((char*)""); HandleReloadReservedNameCommand((char*)""); HandleReloadMangosStringCommand((char*)""); HandleReloadGameTeleCommand((char*)""); return true; } bool ChatHandler::HandleReloadAllAchievementCommand(char* /*args*/) { HandleReloadAchievementCriteriaRequirementCommand((char*)""); HandleReloadAchievementRewardCommand((char*)""); return true; } bool ChatHandler::HandleReloadAllAreaCommand(char* /*args*/) { // HandleReloadQuestAreaTriggersCommand((char*)""); -- reloaded in HandleReloadAllQuestCommand HandleReloadAreaTriggerTeleportCommand((char*)""); HandleReloadAreaTriggerTavernCommand((char*)""); HandleReloadGameGraveyardZoneCommand((char*)""); return true; } bool ChatHandler::HandleReloadAllLootCommand(char* /*args*/) { sLog.outString("Re-Loading Loot Tables..."); LoadLootTables(); SendGlobalSysMessage("DB tables `*_loot_template` reloaded."); return true; } bool ChatHandler::HandleReloadAllNpcCommand(char* args) { HandleReloadNpcTrainerCommand((char*)"a"); HandleReloadNpcVendorCommand((char*)"a"); HandleReloadPointsOfInterestCommand((char*)"a"); HandleReloadSpellClickSpellsCommand((char*)"a"); return true; } bool ChatHandler::HandleReloadAllQuestCommand(char* /*args*/) { HandleReloadQuestAreaTriggersCommand((char*)"a"); HandleReloadQuestPOICommand((char*)"a"); HandleReloadQuestTemplateCommand((char*)"a"); sLog.outString("Re-Loading Quests Relations..."); sObjectMgr.LoadQuestRelations(); SendGlobalSysMessage("DB tables `*_questrelation` and `*_involvedrelation` reloaded."); return true; } bool ChatHandler::HandleReloadAllScriptsCommand(char* /*args*/) { if (sScriptMgr.IsScriptScheduled()) { PSendSysMessage("DB scripts used currently, please attempt reload later."); SetSentErrorMessage(true); return false; } sLog.outString("Re-Loading Scripts..."); HandleReloadDBScriptsOnCreatureDeathCommand((char*)"a"); HandleReloadDBScriptsOnGoUseCommand((char*)"a"); HandleReloadDBScriptsOnGossipCommand((char*)"a"); HandleReloadDBScriptsOnEventCommand((char*)"a"); HandleReloadDBScriptsOnQuestEndCommand((char*)"a"); HandleReloadDBScriptsOnQuestStartCommand((char*)"a"); HandleReloadDBScriptsOnSpellCommand((char*)"a"); SendGlobalSysMessage("DB tables `*_scripts` reloaded."); HandleReloadDbScriptStringCommand((char*)"a"); return true; } bool ChatHandler::HandleReloadAllEventAICommand(char* /*args*/) { HandleReloadEventAITextsCommand((char*)"a"); HandleReloadEventAISummonsCommand((char*)"a"); HandleReloadEventAIScriptsCommand((char*)"a"); return true; } bool ChatHandler::HandleReloadAllSpellCommand(char* /*args*/) { HandleReloadSkillDiscoveryTemplateCommand((char*)"a"); HandleReloadSkillExtraItemTemplateCommand((char*)"a"); HandleReloadSpellAreaCommand((char*)"a"); HandleReloadSpellChainCommand((char*)"a"); HandleReloadSpellElixirCommand((char*)"a"); HandleReloadSpellLearnSpellCommand((char*)"a"); HandleReloadSpellProcEventCommand((char*)"a"); HandleReloadSpellBonusesCommand((char*)"a"); HandleReloadSpellProcItemEnchantCommand((char*)"a"); HandleReloadSpellScriptTargetCommand((char*)"a"); HandleReloadSpellTargetPositionCommand((char*)"a"); HandleReloadSpellThreatsCommand((char*)"a"); HandleReloadSpellPetAurasCommand((char*)"a"); return true; } bool ChatHandler::HandleReloadAllGossipsCommand(char* args) { if (*args != 'a') // already reload from all_scripts { HandleReloadDBScriptsOnGossipCommand((char*)"a"); } HandleReloadGossipMenuCommand((char*)"a"); HandleReloadPointsOfInterestCommand((char*)"a"); return true; } bool ChatHandler::HandleReloadAllItemCommand(char* /*args*/) { HandleReloadPageTextsCommand((char*)"a"); HandleReloadItemConvertCommand((char*)"a"); HandleReloadItemEnchantementsCommand((char*)"a"); HandleReloadItemRequiredTragetCommand((char*)"a"); return true; } bool ChatHandler::HandleReloadAllLocalesCommand(char* /*args*/) { HandleReloadLocalesAchievementRewardCommand((char*)"a"); HandleReloadLocalesCreatureCommand((char*)"a"); HandleReloadLocalesGameobjectCommand((char*)"a"); HandleReloadLocalesGossipMenuOptionCommand((char*)"a"); HandleReloadLocalesItemCommand((char*)"a"); HandleReloadLocalesNpcTextCommand((char*)"a"); HandleReloadLocalesPageTextCommand((char*)"a"); HandleReloadLocalesPointsOfInterestCommand((char*)"a"); HandleReloadLocalesQuestCommand((char*)"a"); return true; } bool ChatHandler::HandleReloadConfigCommand(char* /*args*/) { sLog.outString("Re-Loading config settings..."); sWorld.LoadConfigSettings(true); sMapMgr.InitializeVisibilityDistanceInfo(); SendGlobalSysMessage("World config settings reloaded."); return true; } bool ChatHandler::HandleReloadAchievementCriteriaRequirementCommand(char* /*args*/) { sLog.outString("Re-Loading Additional Achievement Criteria Requirements Data..."); sAchievementMgr.LoadAchievementCriteriaRequirements(); SendGlobalSysMessage("DB table `achievement_criteria_requirement` reloaded."); return true; } bool ChatHandler::HandleReloadAchievementRewardCommand(char* /*args*/) { sLog.outString("Re-Loading Achievement Reward Data..."); sAchievementMgr.LoadRewards(); SendGlobalSysMessage("DB table `achievement_reward` reloaded."); return true; } bool ChatHandler::HandleReloadAreaTriggerTavernCommand(char* /*args*/) { sLog.outString("Re-Loading Tavern Area Triggers..."); sObjectMgr.LoadTavernAreaTriggers(); SendGlobalSysMessage("DB table `areatrigger_tavern` reloaded."); return true; } bool ChatHandler::HandleReloadAreaTriggerTeleportCommand(char* /*args*/) { sLog.outString("Re-Loading AreaTrigger teleport definitions..."); sObjectMgr.LoadAreaTriggerTeleports(); SendGlobalSysMessage("DB table `areatrigger_teleport` reloaded."); return true; } bool ChatHandler::HandleReloadAutoBroadcastCommand(char* /*args*/) { sLog.outString("Re-Loading broadcast strings..."); sWorld.LoadBroadcastStrings(); SendGlobalSysMessage("Broadcast strings reloaded."); return true; } bool ChatHandler::HandleReloadCommandCommand(char* /*args*/) { load_command_table = true; SendGlobalSysMessage("DB table `command` will be reloaded at next chat command use."); return true; } bool ChatHandler::HandleReloadCreatureQuestRelationsCommand(char* /*args*/) { sLog.outString("Loading Quests Relations... (`creature_questrelation`)"); sObjectMgr.LoadCreatureQuestRelations(); SendGlobalSysMessage("DB table `creature_questrelation` (creature quest givers) reloaded."); return true; } bool ChatHandler::HandleReloadCreatureQuestInvRelationsCommand(char* /*args*/) { sLog.outString("Loading Quests Relations... (`creature_involvedrelation`)"); sObjectMgr.LoadCreatureInvolvedRelations(); SendGlobalSysMessage("DB table `creature_involvedrelation` (creature quest takers) reloaded."); return true; } bool ChatHandler::HandleReloadConditionsCommand(char* /*args*/) { sLog.outString("Re-Loading `conditions`... "); sObjectMgr.LoadConditions(); SendGlobalSysMessage("DB table `conditions` reloaded."); return true; } bool ChatHandler::HandleReloadHotfixDataCommand(char* /*args*/) { sLog.outString("Re-Loading hotfix data..."); sObjectMgr.LoadHotfixData(); SendGlobalSysMessage("DB table `hotfix_data` reloaded."); return true; } bool ChatHandler::HandleReloadGossipMenuCommand(char* /*args*/) { sObjectMgr.LoadGossipMenus(); SendGlobalSysMessage("DB tables `gossip_menu` and `gossip_menu_option` reloaded."); return true; } bool ChatHandler::HandleReloadGOQuestRelationsCommand(char* /*args*/) { sLog.outString("Loading Quests Relations... (`gameobject_questrelation`)"); sObjectMgr.LoadGameobjectQuestRelations(); SendGlobalSysMessage("DB table `gameobject_questrelation` (gameobject quest givers) reloaded."); return true; } bool ChatHandler::HandleReloadGOQuestInvRelationsCommand(char* /*args*/) { sLog.outString("Loading Quests Relations... (`gameobject_involvedrelation`)"); sObjectMgr.LoadGameobjectInvolvedRelations(); SendGlobalSysMessage("DB table `gameobject_involvedrelation` (gameobject quest takers) reloaded."); return true; } bool ChatHandler::HandleReloadQuestAreaTriggersCommand(char* /*args*/) { sLog.outString("Re-Loading Quest Area Triggers..."); sObjectMgr.LoadQuestAreaTriggers(); SendGlobalSysMessage("DB table `areatrigger_involvedrelation` (quest area triggers) reloaded."); return true; } bool ChatHandler::HandleReloadQuestTemplateCommand(char* /*args*/) { sLog.outString("Re-Loading Quest Templates..."); sObjectMgr.LoadQuests(); SendGlobalSysMessage("DB table `quest_template` (quest definitions) reloaded."); /// dependent also from `gameobject` but this table not reloaded anyway sLog.outString("Re-Loading GameObjects for quests..."); sObjectMgr.LoadGameObjectForQuests(); SendGlobalSysMessage("Data GameObjects for quests reloaded."); return true; } bool ChatHandler::HandleReloadLootTemplatesCreatureCommand(char* /*args*/) { sLog.outString("Re-Loading Loot Tables... (`creature_loot_template`)"); LoadLootTemplates_Creature(); LootTemplates_Creature.CheckLootRefs(); SendGlobalSysMessage("DB table `creature_loot_template` reloaded."); return true; } bool ChatHandler::HandleReloadLootTemplatesDisenchantCommand(char* /*args*/) { sLog.outString("Re-Loading Loot Tables... (`disenchant_loot_template`)"); LoadLootTemplates_Disenchant(); LootTemplates_Disenchant.CheckLootRefs(); SendGlobalSysMessage("DB table `disenchant_loot_template` reloaded."); return true; } bool ChatHandler::HandleReloadLootTemplatesFishingCommand(char* /*args*/) { sLog.outString("Re-Loading Loot Tables... (`fishing_loot_template`)"); LoadLootTemplates_Fishing(); LootTemplates_Fishing.CheckLootRefs(); SendGlobalSysMessage("DB table `fishing_loot_template` reloaded."); return true; } bool ChatHandler::HandleReloadLootTemplatesGameobjectCommand(char* /*args*/) { sLog.outString("Re-Loading Loot Tables... (`gameobject_loot_template`)"); LoadLootTemplates_Gameobject(); LootTemplates_Gameobject.CheckLootRefs(); SendGlobalSysMessage("DB table `gameobject_loot_template` reloaded."); return true; } bool ChatHandler::HandleReloadLootTemplatesItemCommand(char* /*args*/) { sLog.outString("Re-Loading Loot Tables... (`item_loot_template`)"); LoadLootTemplates_Item(); LootTemplates_Item.CheckLootRefs(); SendGlobalSysMessage("DB table `item_loot_template` reloaded."); return true; } bool ChatHandler::HandleReloadLootTemplatesMillingCommand(char* /*args*/) { sLog.outString("Re-Loading Loot Tables... (`milling_loot_template`)"); LoadLootTemplates_Milling(); LootTemplates_Milling.CheckLootRefs(); SendGlobalSysMessage("DB table `milling_loot_template` reloaded."); return true; } bool ChatHandler::HandleReloadLootTemplatesPickpocketingCommand(char* /*args*/) { sLog.outString("Re-Loading Loot Tables... (`pickpocketing_loot_template`)"); LoadLootTemplates_Pickpocketing(); LootTemplates_Pickpocketing.CheckLootRefs(); SendGlobalSysMessage("DB table `pickpocketing_loot_template` reloaded."); return true; } bool ChatHandler::HandleReloadLootTemplatesProspectingCommand(char* /*args*/) { sLog.outString("Re-Loading Loot Tables... (`prospecting_loot_template`)"); LoadLootTemplates_Prospecting(); LootTemplates_Prospecting.CheckLootRefs(); SendGlobalSysMessage("DB table `prospecting_loot_template` reloaded."); return true; } bool ChatHandler::HandleReloadLootTemplatesMailCommand(char* /*args*/) { sLog.outString("Re-Loading Loot Tables... (`mail_loot_template`)"); LoadLootTemplates_Mail(); LootTemplates_Mail.CheckLootRefs(); SendGlobalSysMessage("DB table `mail_loot_template` reloaded."); return true; } bool ChatHandler::HandleReloadLootTemplatesReferenceCommand(char* /*args*/) { sLog.outString("Re-Loading Loot Tables... (`reference_loot_template`)"); LoadLootTemplates_Reference(); SendGlobalSysMessage("DB table `reference_loot_template` reloaded."); return true; } bool ChatHandler::HandleReloadLootTemplatesSkinningCommand(char* /*args*/) { sLog.outString("Re-Loading Loot Tables... (`skinning_loot_template`)"); LoadLootTemplates_Skinning(); LootTemplates_Skinning.CheckLootRefs(); SendGlobalSysMessage("DB table `skinning_loot_template` reloaded."); return true; } bool ChatHandler::HandleReloadLootTemplatesSpellCommand(char* /*args*/) { sLog.outString("Re-Loading Loot Tables... (`spell_loot_template`)"); LoadLootTemplates_Spell(); LootTemplates_Spell.CheckLootRefs(); SendGlobalSysMessage("DB table `spell_loot_template` reloaded."); return true; } bool ChatHandler::HandleReloadMangosStringCommand(char* /*args*/) { sLog.outString("Re-Loading mangos_string Table!"); sObjectMgr.LoadMangosStrings(); SendGlobalSysMessage("DB table `mangos_string` reloaded."); return true; } bool ChatHandler::HandleReloadNpcTextCommand(char* /*args*/) { sLog.outString("Re-Loading `npc_text` Table!"); sObjectMgr.LoadGossipText(); SendGlobalSysMessage("DB table `npc_text` reloaded."); return true; } bool ChatHandler::HandleReloadNpcTrainerCommand(char* /*args*/) { sLog.outString("Re-Loading `npc_trainer_template` Table!"); sObjectMgr.LoadTrainerTemplates(); SendGlobalSysMessage("DB table `npc_trainer_template` reloaded."); sLog.outString("Re-Loading `npc_trainer` Table!"); sObjectMgr.LoadTrainers(); SendGlobalSysMessage("DB table `npc_trainer` reloaded."); return true; } bool ChatHandler::HandleReloadNpcVendorCommand(char* /*args*/) { // not safe reload vendor template tables independent... sLog.outString("Re-Loading `npc_vendor_template` Table!"); sObjectMgr.LoadVendorTemplates(); SendGlobalSysMessage("DB table `npc_vendor_template` reloaded."); sLog.outString("Re-Loading `npc_vendor` Table!"); sObjectMgr.LoadVendors(); SendGlobalSysMessage("DB table `npc_vendor` reloaded."); return true; } bool ChatHandler::HandleReloadPointsOfInterestCommand(char* /*args*/) { sLog.outString("Re-Loading `points_of_interest` Table!"); sObjectMgr.LoadPointsOfInterest(); SendGlobalSysMessage("DB table `points_of_interest` reloaded."); return true; } bool ChatHandler::HandleReloadQuestPOICommand(char* /*args*/) { sLog.outString("Re-Loading `quest_poi` and `quest_poi_points` Tables!"); sObjectMgr.LoadQuestPOI(); SendGlobalSysMessage("DB Table `quest_poi` and `quest_poi_points` reloaded."); return true; } bool ChatHandler::HandleReloadSpellClickSpellsCommand(char* /*args*/) { sLog.outString("Re-Loading `npc_spellclick_spells` Table!"); sObjectMgr.LoadNPCSpellClickSpells(); SendGlobalSysMessage("DB table `npc_spellclick_spells` reloaded."); return true; } bool ChatHandler::HandleReloadReservedNameCommand(char* /*args*/) { sLog.outString("Loading ReservedNames... (`reserved_name`)"); sObjectMgr.LoadReservedPlayersNames(); SendGlobalSysMessage("DB table `reserved_name` (player reserved names) reloaded."); return true; } bool ChatHandler::HandleReloadReputationRewardRateCommand(char* /*args*/) { sLog.outString("Re-Loading `reputation_reward_rate` Table!"); sObjectMgr.LoadReputationRewardRate(); SendGlobalSysMessage("DB table `reputation_reward_rate` reloaded."); return true; } bool ChatHandler::HandleReloadReputationSpilloverTemplateCommand(char* /*args*/) { sLog.outString("Re-Loading `reputation_spillover_template` Table!"); sObjectMgr.LoadReputationSpilloverTemplate(); SendGlobalSysMessage("DB table `reputation_spillover_template` reloaded."); return true; } bool ChatHandler::HandleReloadSkillDiscoveryTemplateCommand(char* /*args*/) { sLog.outString("Re-Loading Skill Discovery Table..."); LoadSkillDiscoveryTable(); SendGlobalSysMessage("DB table `skill_discovery_template` (recipes discovered at crafting) reloaded."); return true; } bool ChatHandler::HandleReloadSkillExtraItemTemplateCommand(char* /*args*/) { sLog.outString("Re-Loading Skill Extra Item Table..."); LoadSkillExtraItemTable(); SendGlobalSysMessage("DB table `skill_extra_item_template` (extra item creation when crafting) reloaded."); return true; } bool ChatHandler::HandleReloadSkillFishingBaseLevelCommand(char* /*args*/) { sLog.outString("Re-Loading Skill Fishing base level requirements..."); sObjectMgr.LoadFishingBaseSkillLevel(); SendGlobalSysMessage("DB table `skill_fishing_base_level` (fishing base level for zone/subzone) reloaded."); return true; } bool ChatHandler::HandleReloadSpellAreaCommand(char* /*args*/) { sLog.outString("Re-Loading SpellArea Data..."); sSpellMgr.LoadSpellAreas(); SendGlobalSysMessage("DB table `spell_area` (spell dependences from area/quest/auras state) reloaded."); return true; } bool ChatHandler::HandleReloadSpellBonusesCommand(char* /*args*/) { sLog.outString("Re-Loading Spell Bonus Data..."); sSpellMgr.LoadSpellBonuses(); SendGlobalSysMessage("DB table `spell_bonus_data` (spell damage/healing coefficients) reloaded."); return true; } bool ChatHandler::HandleReloadSpellChainCommand(char* /*args*/) { sLog.outString("Re-Loading Spell Chain Data... "); sSpellMgr.LoadSpellChains(); SendGlobalSysMessage("DB table `spell_chain` (spell ranks) reloaded."); return true; } bool ChatHandler::HandleReloadSpellElixirCommand(char* /*args*/) { sLog.outString("Re-Loading Spell Elixir types..."); sSpellMgr.LoadSpellElixirs(); SendGlobalSysMessage("DB table `spell_elixir` (spell elixir types) reloaded."); return true; } bool ChatHandler::HandleReloadSpellLearnSpellCommand(char* /*args*/) { sLog.outString("Re-Loading Spell Learn Spells..."); sSpellMgr.LoadSpellLearnSpells(); SendGlobalSysMessage("DB table `spell_learn_spell` reloaded."); return true; } bool ChatHandler::HandleReloadSpellProcEventCommand(char* /*args*/) { sLog.outString("Re-Loading Spell Proc Event conditions..."); sSpellMgr.LoadSpellProcEvents(); SendGlobalSysMessage("DB table `spell_proc_event` (spell proc trigger requirements) reloaded."); return true; } bool ChatHandler::HandleReloadSpellProcItemEnchantCommand(char* /*args*/) { sLog.outString("Re-Loading Spell Proc Item Enchant..."); sSpellMgr.LoadSpellProcItemEnchant(); SendGlobalSysMessage("DB table `spell_proc_item_enchant` (item enchantment ppm) reloaded."); return true; } bool ChatHandler::HandleReloadSpellScriptTargetCommand(char* /*args*/) { sLog.outString("Re-Loading SpellsScriptTarget..."); sSpellMgr.LoadSpellScriptTarget(); SendGlobalSysMessage("DB table `spell_script_target` (spell targets selection in case specific creature/GO requirements) reloaded."); return true; } bool ChatHandler::HandleReloadSpellTargetPositionCommand(char* /*args*/) { sLog.outString("Re-Loading spell target destination coordinates..."); sSpellMgr.LoadSpellTargetPositions(); SendGlobalSysMessage("DB table `spell_target_position` (destination coordinates for spell targets) reloaded."); return true; } bool ChatHandler::HandleReloadSpellThreatsCommand(char* /*args*/) { sLog.outString("Re-Loading Aggro Spells Definitions..."); sSpellMgr.LoadSpellThreats(); SendGlobalSysMessage("DB table `spell_threat` (spell aggro definitions) reloaded."); return true; } bool ChatHandler::HandleReloadSpellPetAurasCommand(char* /*args*/) { sLog.outString("Re-Loading Spell pet auras..."); sSpellMgr.LoadSpellPetAuras(); SendGlobalSysMessage("DB table `spell_pet_auras` reloaded."); return true; } bool ChatHandler::HandleReloadPageTextsCommand(char* /*args*/) { sLog.outString("Re-Loading Page Texts..."); sObjectMgr.LoadPageTexts(); SendGlobalSysMessage("DB table `page_texts` reloaded."); return true; } bool ChatHandler::HandleReloadItemEnchantementsCommand(char* /*args*/) { sLog.outString("Re-Loading Item Random Enchantments Table..."); LoadRandomEnchantmentsTable(); SendGlobalSysMessage("DB table `item_enchantment_template` reloaded."); return true; } bool ChatHandler::HandleReloadItemConvertCommand(char* /*args*/) { sLog.outString("Re-Loading Item Converts Table..."); sObjectMgr.LoadItemConverts(); SendGlobalSysMessage("DB table `item_convert` reloaded."); return true; } bool ChatHandler::HandleReloadItemRequiredTragetCommand(char* /*args*/) { sLog.outString("Re-Loading Item Required Targets Table..."); sObjectMgr.LoadItemRequiredTarget(); SendGlobalSysMessage("DB table `item_required_target` reloaded."); return true; } bool ChatHandler::HandleReloadBattleEventCommand(char* /*args*/) { sLog.outString("Re-Loading BattleGround Eventindexes..."); sBattleGroundMgr.LoadBattleEventIndexes(); SendGlobalSysMessage("DB table `gameobject_battleground` and `creature_battleground` reloaded."); return true; } bool ChatHandler::HandleReloadEventAITextsCommand(char* /*args*/) { sLog.outString("Re-Loading Texts from `creature_ai_texts`..."); sEventAIMgr.LoadCreatureEventAI_Texts(true); SendGlobalSysMessage("DB table `creature_ai_texts` reloaded."); return true; } bool ChatHandler::HandleReloadEventAISummonsCommand(char* /*args*/) { sLog.outString("Re-Loading Summons from `creature_ai_summons`..."); sEventAIMgr.LoadCreatureEventAI_Summons(true); SendGlobalSysMessage("DB table `creature_ai_summons` reloaded."); return true; } bool ChatHandler::HandleReloadEventAIScriptsCommand(char* /*args*/) { sLog.outString("Re-Loading Scripts from `creature_ai_scripts`..."); sEventAIMgr.LoadCreatureEventAI_Scripts(); SendGlobalSysMessage("DB table `creature_ai_scripts` reloaded."); return true; } bool ChatHandler::HandleReloadDbScriptStringCommand(char* /*args*/) { sLog.outString("Re-Loading Script strings from `db_script_string`..."); sScriptMgr.LoadDbScriptStrings(); SendGlobalSysMessage("DB table `db_script_string` reloaded."); return true; } bool ChatHandler::HandleReloadDBScriptsOnGossipCommand(char* args) { if (sScriptMgr.IsScriptScheduled()) { SendSysMessage("DB scripts used currently, please attempt reload later."); SetSentErrorMessage(true); return false; } if (*args != 'a') { sLog.outString("Re-Loading Scripts from `db_scripts [type = DBS_ON_GOSSIP]`..."); } sScriptMgr.LoadDbScripts(DBS_ON_GOSSIP); if (*args != 'a') SendGlobalSysMessage("DB table `db_scripts [type = DBS_ON_GOSSIP]` reloaded."); return true; } bool ChatHandler::HandleReloadDBScriptsOnSpellCommand(char* args) { if (sScriptMgr.IsScriptScheduled()) { SendSysMessage("DB scripts used currently, please attempt reload later."); SetSentErrorMessage(true); return false; } if (*args != 'a') { sLog.outString("Re-Loading Scripts from `db_scripts [type = DBS_ON_SPELL]`..."); } sScriptMgr.LoadDbScripts(DBS_ON_SPELL); if (*args != 'a') SendGlobalSysMessage("DB table `db_scripts [type = DBS_ON_SPELL]` reloaded."); return true; } bool ChatHandler::HandleReloadDBScriptsOnQuestStartCommand(char* args) { if (sScriptMgr.IsScriptScheduled()) { SendSysMessage("DB scripts used currently, please attempt reload later."); SetSentErrorMessage(true); return false; } if (*args != 'a') { sLog.outString("Re-Loading Scripts from `db_scripts [type = DBS_ON_QUEST_START]`..."); } sScriptMgr.LoadDbScripts(DBS_ON_QUEST_START); if (*args != 'a') SendGlobalSysMessage("DB table `db_scripts [type = DBS_ON_QUEST_START]` reloaded."); return true; } bool ChatHandler::HandleReloadDBScriptsOnQuestEndCommand(char* args) { if (sScriptMgr.IsScriptScheduled()) { SendSysMessage("DB scripts used currently, please attempt reload later."); SetSentErrorMessage(true); return false; } if (*args != 'a') { sLog.outString("Re-Loading Scripts from `db_scripts [type = DBS_ON_QUEST_END]`..."); } sScriptMgr.LoadDbScripts(DBS_ON_QUEST_END); if (*args != 'a') SendGlobalSysMessage("DB table `db_scripts [type = DBS_ON_QUEST_END]` reloaded."); return true; } bool ChatHandler::HandleReloadDBScriptsOnEventCommand(char* args) { if (sScriptMgr.IsScriptScheduled()) { SendSysMessage("DB scripts used currently, please attempt reload later."); SetSentErrorMessage(true); return false; } if (*args != 'a') { sLog.outString("Re-Loading Scripts from `db_scripts [type = DBS_ON_EVENT]`..."); } sScriptMgr.LoadDbScripts(DBS_ON_EVENT); if (*args != 'a') SendGlobalSysMessage("DB table `db_scripts [type = DBS_ON_EVENT]` reloaded."); return true; } bool ChatHandler::HandleReloadDBScriptsOnGoUseCommand(char* args) { if (sScriptMgr.IsScriptScheduled()) { SendSysMessage("DB scripts used currently, please attempt reload later."); SetSentErrorMessage(true); return false; } if (*args != 'a') { sLog.outString("Re-Loading Scripts from `db_scripts [type = DBS_ON_GO[_TEMPLATE]_USE]`..."); } sScriptMgr.LoadDbScripts(DBS_ON_GO_USE); sScriptMgr.LoadDbScripts(DBS_ON_GOT_USE); if (*args != 'a') SendGlobalSysMessage("DB table `db_scripts [type = DBS_ON_GO[_TEMPLATE]_USE]` reloaded."); return true; } bool ChatHandler::HandleReloadDBScriptsOnCreatureDeathCommand(char* args) { if (sScriptMgr.IsScriptScheduled()) { SendSysMessage("DB scripts used currently, please attempt reload later."); SetSentErrorMessage(true); return false; } if (*args != 'a') { sLog.outString("Re-Loading Scripts from `db_scripts [type = DBS_ON_CREATURE_DEATH]`..."); } sScriptMgr.LoadDbScripts(DBS_ON_CREATURE_DEATH); if (*args != 'a') SendGlobalSysMessage("DB table `db_scripts [type = DBS_ON_CREATURE_DEATH]` reloaded."); return true; } bool ChatHandler::HandleReloadGameGraveyardZoneCommand(char* /*args*/) { sLog.outString("Re-Loading Graveyard-zone links..."); sObjectMgr.LoadGraveyardZones(); SendGlobalSysMessage("DB table `game_graveyard_zone` reloaded."); return true; } bool ChatHandler::HandleReloadGameTeleCommand(char* /*args*/) { sLog.outString("Re-Loading Game Tele coordinates..."); sObjectMgr.LoadGameTele(); SendGlobalSysMessage("DB table `game_tele` reloaded."); return true; } bool ChatHandler::HandleReloadLocalesAchievementRewardCommand(char* /*args*/) { sLog.outString("Re-Loading Locales Achievement Reward Data..."); sAchievementMgr.LoadRewardLocales(); SendGlobalSysMessage("DB table `locales_achievement_reward` reloaded."); return true; } bool ChatHandler::HandleReloadLocalesCreatureCommand(char* /*args*/) { sLog.outString("Re-Loading Locales Creature ..."); sObjectMgr.LoadCreatureLocales(); SendGlobalSysMessage("DB table `locales_creature` reloaded."); return true; } bool ChatHandler::HandleReloadLocalesGameobjectCommand(char* /*args*/) { sLog.outString("Re-Loading Locales Gameobject ... "); sObjectMgr.LoadGameObjectLocales(); SendGlobalSysMessage("DB table `locales_gameobject` reloaded."); return true; } bool ChatHandler::HandleReloadLocalesGossipMenuOptionCommand(char* /*args*/) { sLog.outString("Re-Loading Locales Gossip Menu Option ... "); sObjectMgr.LoadGossipMenuItemsLocales(); SendGlobalSysMessage("DB table `locales_gossip_menu_option` reloaded."); return true; } bool ChatHandler::HandleReloadLocalesItemCommand(char* /*args*/) { sLog.outString("Re-Loading Locales Item ... "); sObjectMgr.LoadItemLocales(); SendGlobalSysMessage("DB table `locales_item` reloaded."); return true; } bool ChatHandler::HandleReloadLocalesNpcTextCommand(char* /*args*/) { sLog.outString("Re-Loading Locales NPC Text ... "); sObjectMgr.LoadGossipTextLocales(); SendGlobalSysMessage("DB table `locales_npc_text` reloaded."); return true; } bool ChatHandler::HandleReloadLocalesPageTextCommand(char* /*args*/) { sLog.outString("Re-Loading Locales Page Text ... "); sObjectMgr.LoadPageTextLocales(); SendGlobalSysMessage("DB table `locales_page_text` reloaded."); return true; } bool ChatHandler::HandleReloadLocalesPointsOfInterestCommand(char* /*args*/) { sLog.outString("Re-Loading Locales Points Of Interest ... "); sObjectMgr.LoadPointOfInterestLocales(); SendGlobalSysMessage("DB table `locales_points_of_interest` reloaded."); return true; } bool ChatHandler::HandleReloadLocalesQuestCommand(char* /*args*/) { sLog.outString("Re-Loading Locales Quest ... "); sObjectMgr.LoadQuestLocales(); SendGlobalSysMessage("DB table `locales_quest` reloaded."); return true; } bool ChatHandler::HandleReloadMailLevelRewardCommand(char* /*args*/) { sLog.outString("Re-Loading Player level dependent mail rewards..."); sObjectMgr.LoadMailLevelRewards(); SendGlobalSysMessage("DB table `mail_level_reward` reloaded."); return true; } bool ChatHandler::HandleReloadCreaturesStatsCommand(char* /*args*/) { sLog.outString("Re-Loading stats data..."); sObjectMgr.LoadCreatureClassLvlStats(); SendGlobalSysMessage("DB table `creature_template_classlevelstats` reloaded."); return true; } bool ChatHandler::HandleLoadScriptsCommand(char* args) { if (!*args) { return false; } switch (sScriptMgr.LoadScriptLibrary(args)) { case SCRIPT_LOAD_OK: sWorld.SendWorldText(LANG_SCRIPTS_RELOADED_ANNOUNCE); SendSysMessage(LANG_SCRIPTS_RELOADED_OK); break; case SCRIPT_LOAD_ERR_NOT_FOUND: SendSysMessage(LANG_SCRIPTS_NOT_FOUND); break; case SCRIPT_LOAD_ERR_WRONG_API: SendSysMessage(LANG_SCRIPTS_WRONG_API); break; case SCRIPT_LOAD_ERR_OUTDATED: SendSysMessage(LANG_SCRIPTS_OUTDATED); break; } return true; } bool ChatHandler::HandleAccountSetGmLevelCommand(char* args) { char* accountStr = ExtractOptNotLastArg(&args); std::string targetAccountName; Player* targetPlayer = NULL; uint32 targetAccountId = ExtractAccountId(&accountStr, &targetAccountName, &targetPlayer); if (!targetAccountId) { return false; } /// only target player different from self allowed if (GetAccountId() == targetAccountId) { return false; } int32 gm; if (!ExtractInt32(&args, gm)) { return false; } if (gm < SEC_PLAYER || gm > SEC_ADMINISTRATOR) { SendSysMessage(LANG_BAD_VALUE); SetSentErrorMessage(true); return false; } /// can set security level only for target with less security and to less security that we have /// This will reject self apply by specify account name if (HasLowerSecurityAccount(NULL, targetAccountId, true)) { return false; } /// account can't set security to same or grater level, need more power GM or console AccountTypes plSecurity = GetAccessLevel(); if (AccountTypes(gm) >= plSecurity) { SendSysMessage(LANG_YOURS_SECURITY_IS_LOW); SetSentErrorMessage(true); return false; } if (targetPlayer) { ChatHandler(targetPlayer).PSendSysMessage(LANG_YOURS_SECURITY_CHANGED, GetNameLink().c_str(), gm); targetPlayer->GetSession()->SetSecurity(AccountTypes(gm)); } PSendSysMessage(LANG_YOU_CHANGE_SECURITY, targetAccountName.c_str(), gm); LoginDatabase.PExecute("UPDATE account SET gmlevel = '%i' WHERE id = '%u'", gm, targetAccountId); return true; } /// Set password for account bool ChatHandler::HandleAccountSetPasswordCommand(char* args) { ///- Get the command line arguments std::string account_name; uint32 targetAccountId = ExtractAccountId(&args, &account_name); if (!targetAccountId) { return false; } // allow or quoted string with possible spaces or literal without spaces char* szPassword1 = ExtractQuotedOrLiteralArg(&args); char* szPassword2 = ExtractQuotedOrLiteralArg(&args); if (!szPassword1 || !szPassword2) { return false; } /// can set password only for target with less security /// This is also reject self apply in fact if (HasLowerSecurityAccount(NULL, targetAccountId, true)) { return false; } if (strcmp(szPassword1, szPassword2)) { SendSysMessage(LANG_NEW_PASSWORDS_NOT_MATCH); SetSentErrorMessage(true); return false; } AccountOpResult result = sAccountMgr.ChangePassword(targetAccountId, szPassword1); switch (result) { case AOR_OK: SendSysMessage(LANG_COMMAND_PASSWORD); break; case AOR_NAME_NOT_EXIST: PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, account_name.c_str()); SetSentErrorMessage(true); return false; case AOR_PASS_TOO_LONG: SendSysMessage(LANG_PASSWORD_TOO_LONG); SetSentErrorMessage(true); return false; default: SendSysMessage(LANG_COMMAND_NOTCHANGEPASSWORD); SetSentErrorMessage(true); return false; } // OK, but avoid normal report for hide passwords, but log use command for anyone char msg[100]; snprintf(msg, 100, ".account set password %s *** ***", account_name.c_str()); LogCommand(msg); SetSentErrorMessage(true); return false; } void ChatHandler::ShowAchievementCriteriaListHelper(AchievementCriteriaEntry const* criEntry, AchievementEntry const* achEntry, LocaleConstant loc, Player* target /*= NULL*/) { std::ostringstream ss; if (m_session) { ss << criEntry->ID << " - |cffffffff|Hachievement_criteria:" << criEntry->ID << "|h[" << criEntry->name[loc] << " " << localeNames[loc] << "]|h|r"; } else ss << criEntry->ID << " - " << criEntry->name[loc] << " " << localeNames[loc]; if (target) ss << " = " << target->GetAchievementMgr().GetCriteriaProgressCounter(criEntry); if (achEntry->flags & ACHIEVEMENT_FLAG_COUNTER) ss << GetMangosString(LANG_COUNTER); else { ss << " [" << AchievementMgr::GetCriteriaProgressMaxCounter(criEntry, achEntry) << "]"; if (target && target->GetAchievementMgr().IsCompletedCriteria(criEntry, achEntry)) ss << GetMangosString(LANG_COMPLETE); } SendSysMessage(ss.str().c_str()); } bool ChatHandler::HandleAchievementCommand(char* args) { char* nameStr = ExtractOptNotLastArg(&args); Player* target = NULL; if (nameStr) { if (!ExtractPlayerTarget(&nameStr, &target)) return false; } else target = getSelectedPlayer(); uint32 achId; if (!ExtractUint32KeyFromLink(&args, "Hachievement", achId)) return false; AchievementEntry const* achEntry = sAchievementStore.LookupEntry(achId); if (!achEntry) { PSendSysMessage(LANG_ACHIEVEMENT_NOT_EXIST, achId); SetSentErrorMessage(true); return false; } LocaleConstant loc = GetSessionDbcLocale(); CompletedAchievementData const* completed = target ? target->GetAchievementMgr().GetCompleteData(achId) : NULL; ShowAchievementListHelper(achEntry, loc, completed ? &completed->date : NULL, target); if (AchievementCriteriaEntryList const* criteriaList = sAchievementMgr.GetAchievementCriteriaByAchievement(achEntry->ID)) { SendSysMessage(LANG_COMMAND_ACHIEVEMENT_CRITERIA); for (AchievementCriteriaEntryList::const_iterator itr = criteriaList->begin(); itr != criteriaList->end(); ++itr) ShowAchievementCriteriaListHelper(*itr, achEntry, loc, target); } return true; } bool ChatHandler::HandleAchievementAddCommand(char* args) { char* nameStr = ExtractOptNotLastArg(&args); Player* target; if (!ExtractPlayerTarget(&nameStr, &target)) return false; uint32 achId; if (!ExtractUint32KeyFromLink(&args, "Hachievement", achId)) return false; AchievementEntry const* achEntry = sAchievementStore.LookupEntry(achId); if (!achEntry || achEntry->flags & ACHIEVEMENT_FLAG_COUNTER) { PSendSysMessage(LANG_ACHIEVEMENT_NOT_EXIST, achId); SetSentErrorMessage(true); return false; } AchievementMgr& mgr = target->GetAchievementMgr(); if (AchievementCriteriaEntryList const* criteriaList = sAchievementMgr.GetAchievementCriteriaByAchievement(achEntry->ID)) { for (AchievementCriteriaEntryList::const_iterator itr = criteriaList->begin(); itr != criteriaList->end(); ++itr) { if (mgr.IsCompletedCriteria(*itr, achEntry)) continue; uint32 maxValue = AchievementMgr::GetCriteriaProgressMaxCounter(*itr, achEntry); if (maxValue == std::numeric_limits::max()) maxValue = 1; // Exception for counter like achievements, set them only to 1 mgr.SetCriteriaProgress(*itr, achEntry, maxValue, AchievementMgr::PROGRESS_SET); } } LocaleConstant loc = GetSessionDbcLocale(); CompletedAchievementData const* completed = target ? target->GetAchievementMgr().GetCompleteData(achId) : NULL; ShowAchievementListHelper(achEntry, loc, completed ? &completed->date : NULL, target); return true; } bool ChatHandler::HandleAchievementRemoveCommand(char* args) { char* nameStr = ExtractOptNotLastArg(&args); Player* target; if (!ExtractPlayerTarget(&nameStr, &target)) return false; uint32 achId; if (!ExtractUint32KeyFromLink(&args, "Hachievement", achId)) return false; AchievementEntry const* achEntry = sAchievementStore.LookupEntry(achId); if (!achEntry) { PSendSysMessage(LANG_ACHIEVEMENT_NOT_EXIST, achId); SetSentErrorMessage(true); return false; } AchievementMgr& mgr = target->GetAchievementMgr(); if (AchievementCriteriaEntryList const* criteriaList = sAchievementMgr.GetAchievementCriteriaByAchievement(achEntry->ID)) for (AchievementCriteriaEntryList::const_iterator itr = criteriaList->begin(); itr != criteriaList->end(); ++itr) mgr.SetCriteriaProgress(*itr, achEntry, 0, AchievementMgr::PROGRESS_SET); LocaleConstant loc = GetSessionDbcLocale(); CompletedAchievementData const* completed = target ? target->GetAchievementMgr().GetCompleteData(achId) : NULL; ShowAchievementListHelper(achEntry, loc, completed ? &completed->date : NULL, target); return true; } bool ChatHandler::HandleAchievementCriteriaAddCommand(char* args) { Player* target; uint32 criId; if (!ExtractUint32KeyFromLink(&args, "Hachievement_criteria", criId)) { // maybe player first char* nameStr = ExtractArg(&args); if (!ExtractPlayerTarget(&nameStr, &target)) return false; if (!ExtractUint32KeyFromLink(&args, "Hachievement_criteria", criId)) return false; } else target = getSelectedPlayer(); AchievementCriteriaEntry const* criEntry = sAchievementCriteriaStore.LookupEntry(criId); if (!criEntry) { PSendSysMessage(LANG_ACHIEVEMENT_CRITERIA_NOT_EXIST, criId); SetSentErrorMessage(true); return false; } AchievementEntry const* achEntry = sAchievementStore.LookupEntry(criEntry->referredAchievement); if (!achEntry) return false; LocaleConstant loc = GetSessionDbcLocale(); uint32 maxValue = AchievementMgr::GetCriteriaProgressMaxCounter(criEntry, achEntry); if (maxValue == std::numeric_limits::max()) maxValue = 1; // Exception for counter like achievements, set them only to 1 AchievementMgr& mgr = target->GetAchievementMgr(); // nothing do if completed if (mgr.IsCompletedCriteria(criEntry, achEntry)) { ShowAchievementCriteriaListHelper(criEntry, achEntry, loc, target); return true; } uint32 progress = mgr.GetCriteriaProgressCounter(criEntry); uint32 val; if (!ExtractOptUInt32(&args, val, maxValue ? maxValue : 1)) return false; uint32 new_val; if (maxValue) new_val = progress < maxValue && maxValue - progress > val ? progress + val : maxValue; else { uint32 max_int = std::numeric_limits::max(); new_val = progress < max_int && max_int - progress > val ? progress + val : max_int; } mgr.SetCriteriaProgress(criEntry, achEntry, new_val, AchievementMgr::PROGRESS_SET); ShowAchievementCriteriaListHelper(criEntry, achEntry, loc, target); return true; } bool ChatHandler::HandleAchievementCriteriaRemoveCommand(char* args) { Player* target; uint32 criId; if (!ExtractUint32KeyFromLink(&args, "Hachievement_criteria", criId)) { // maybe player first char* nameStr = ExtractArg(&args); if (!ExtractPlayerTarget(&nameStr, &target)) return false; if (!ExtractUint32KeyFromLink(&args, "Hachievement_criteria", criId)) return false; } else target = getSelectedPlayer(); AchievementCriteriaEntry const* criEntry = sAchievementCriteriaStore.LookupEntry(criId); if (!criEntry) { PSendSysMessage(LANG_ACHIEVEMENT_CRITERIA_NOT_EXIST, criId); SetSentErrorMessage(true); return false; } AchievementEntry const* achEntry = sAchievementStore.LookupEntry(criEntry->referredAchievement); if (!achEntry) return false; LocaleConstant loc = GetSessionDbcLocale(); uint32 maxValue = AchievementMgr::GetCriteriaProgressMaxCounter(criEntry, achEntry); if (maxValue == std::numeric_limits::max()) maxValue = 1; // Exception for counter like achievements, set them only to 1 AchievementMgr& mgr = target->GetAchievementMgr(); uint32 progress = mgr.GetCriteriaProgressCounter(criEntry); // nothing do if not started if (progress == 0) { ShowAchievementCriteriaListHelper(criEntry, achEntry, loc, target); return true; } uint32 change; if (!ExtractOptUInt32(&args, change, maxValue ? maxValue : 1)) return false; uint32 newval = change < progress ? progress - change : 0; mgr.SetCriteriaProgress(criEntry, achEntry, newval, AchievementMgr::PROGRESS_SET); ShowAchievementCriteriaListHelper(criEntry, achEntry, loc, target); return true; } bool ChatHandler::HandleMaxSkillCommand(char* /*args*/) { Player* SelectedPlayer = getSelectedPlayer(); if (!SelectedPlayer) { SendSysMessage(LANG_NO_CHAR_SELECTED); SetSentErrorMessage(true); return false; } // each skills that have max skill value dependent from level seted to current level max skill value SelectedPlayer->UpdateSkillsToMaxSkillsForLevel(); return true; } bool ChatHandler::HandleSetSkillCommand(char* args) { Player* target = getSelectedPlayer(); if (!target) { SendSysMessage(LANG_NO_CHAR_SELECTED); SetSentErrorMessage(true); return false; } // number or [name] Shift-click form |color|Hskill:skill_id|h[name]|h|r char* skill_p = ExtractKeyFromLink(&args, "Hskill"); if (!skill_p) { return false; } int32 skill; if (!ExtractInt32(&skill_p, skill)) { return false; } int32 level; if (!ExtractInt32(&args, level)) { return false; } int32 maxskill; if (!ExtractOptInt32(&args, maxskill, target->GetPureMaxSkillValue(skill))) { return false; } if (skill <= 0) { PSendSysMessage(LANG_INVALID_SKILL_ID, skill); SetSentErrorMessage(true); return false; } SkillLineEntry const* sl = sSkillLineStore.LookupEntry(skill); if (!sl) { PSendSysMessage(LANG_INVALID_SKILL_ID, skill); SetSentErrorMessage(true); return false; } std::string tNameLink = GetNameLink(target); if (!target->GetSkillValue(skill)) { PSendSysMessage(LANG_SET_SKILL_ERROR, tNameLink.c_str(), skill, sl->name[GetSessionDbcLocale()]); SetSentErrorMessage(true); return false; } if (level <= 0 || level > maxskill || maxskill <= 0) { return false; } target->SetSkill(skill, level, maxskill, target->GetSkillStep(skill)); PSendSysMessage(LANG_SET_SKILL, skill, sl->name[GetSessionDbcLocale()], tNameLink.c_str(), level, maxskill); return true; } bool ChatHandler::HandleUnLearnCommand(char* args) { if (!*args) { return false; } // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r uint32 spell_id = ExtractSpellIdFromLink(&args); if (!spell_id) { return false; } bool allRanks = ExtractLiteralArg(&args, "all") != NULL; if (!allRanks && *args) // can be fail also at syntax error { return false; } Player* target = getSelectedPlayer(); if (!target) { SendSysMessage(LANG_NO_CHAR_SELECTED); SetSentErrorMessage(true); return false; } if (allRanks) { spell_id = sSpellMgr.GetFirstSpellInChain(spell_id); } if (target->HasSpell(spell_id)) { target->removeSpell(spell_id, false, !allRanks); } else { SendSysMessage(LANG_FORGET_SPELL); } if (GetTalentSpellCost(spell_id)) target->SendTalentsInfoData(false); return true; } bool ChatHandler::HandleCooldownCommand(char* args) { Player* target = getSelectedPlayer(); if (!target) { SendSysMessage(LANG_PLAYER_NOT_FOUND); SetSentErrorMessage(true); return false; } std::string tNameLink = GetNameLink(target); if (!*args) { target->RemoveAllSpellCooldown(); PSendSysMessage(LANG_REMOVEALL_COOLDOWN, tNameLink.c_str()); } else { // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form uint32 spell_id = ExtractSpellIdFromLink(&args); if (!spell_id) { return false; } if (!sSpellStore.LookupEntry(spell_id)) { PSendSysMessage(LANG_UNKNOWN_SPELL, target == m_session->GetPlayer() ? GetMangosString(LANG_YOU) : tNameLink.c_str()); SetSentErrorMessage(true); return false; } target->RemoveSpellCooldown(spell_id, true); PSendSysMessage(LANG_REMOVE_COOLDOWN, spell_id, target == m_session->GetPlayer() ? GetMangosString(LANG_YOU) : tNameLink.c_str()); } return true; } bool ChatHandler::HandleLearnAllCommand(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", "12842", "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", "15053", "12580", "12475", "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 = std::stoul((char*)allSpellList[loop++]); if (m_session->GetPlayer()->HasSpell(spell)) { continue; } SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell); if (!spellInfo || !SpellMgr::IsSpellValid(spellInfo, m_session->GetPlayer())) { PSendSysMessage(LANG_COMMAND_SPELL_BROKEN, spell); continue; } m_session->GetPlayer()->learnSpell(spell, false); } SendSysMessage(LANG_COMMAND_LEARN_MANY_SPELLS); return true; } bool ChatHandler::HandleLearnAllGMCommand(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 = std::stoul((char*)gmSpellList[gmSpellIter++]); SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell); if (!spellInfo || !SpellMgr::IsSpellValid(spellInfo, m_session->GetPlayer())) { PSendSysMessage(LANG_COMMAND_SPELL_BROKEN, spell); continue; } m_session->GetPlayer()->learnSpell(spell, false); } SendSysMessage(LANG_LEARNING_GM_SKILLS); return true; } bool ChatHandler::HandleLearnAllMyClassCommand(char* /*args*/) { HandleLearnAllMySpellsCommand((char*)""); HandleLearnAllMyTalentsCommand((char*)""); return true; } bool ChatHandler::HandleLearnAllMySpellsCommand(char* /*args*/) { Player* player = m_session->GetPlayer(); ChrClassesEntry const* clsEntry = sChrClassesStore.LookupEntry(player->getClass()); if (!clsEntry) { return true; } uint32 family = clsEntry->spellfamily; for (uint32 i = 0; i < sSkillLineAbilityStore.GetNumRows(); ++i) { SkillLineAbilityEntry const* entry = sSkillLineAbilityStore.LookupEntry(i); if (!entry) { continue; } SpellEntry const* spellInfo = sSpellStore.LookupEntry(entry->spellId); if (!spellInfo) { continue; } // skip server-side/triggered spells if(spellInfo->GetSpellLevel()==0) { continue; } // skip wrong class/race skills if (!player->IsSpellFitByClassAndRace(spellInfo->Id)) { continue; } // skip other spell families if( spellInfo->GetSpellFamilyName() != 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, player, false)) { continue; } player->learnSpell(spellInfo->Id, false); } SendSysMessage(LANG_COMMAND_LEARN_CLASS_SPELLS); return true; } bool ChatHandler::HandleLearnAllMyTalentsCommand(char* /*args*/) { Player* player = m_session->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 (int 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, player, false)) { continue; } // learn highest rank of talent and learn all non-talent spell ranks (recursive by tree) player->learnSpellHighRank(spellid); } player->SendTalentsInfoData(false); SendSysMessage(LANG_COMMAND_LEARN_CLASS_TALENTS); return true; } bool ChatHandler::HandleLearnAllMyPetTalentsCommand(char* /*args*/) { Player* player = m_session->GetPlayer(); Pet* pet = player->GetPet(); if (!pet) { SendSysMessage(LANG_NO_PET_FOUND); SetSentErrorMessage(true); return false; } CreatureInfo const* ci = pet->GetCreatureInfo(); if (!ci) { SendSysMessage(LANG_WRONG_PET_TYPE); SetSentErrorMessage(true); return false; } CreatureFamilyEntry const* pet_family = sCreatureFamilyStore.LookupEntry(ci->Family); if (!pet_family) { SendSysMessage(LANG_WRONG_PET_TYPE); SetSentErrorMessage(true); return false; } if (pet_family->petTalentType < 0) // not hunter pet { SendSysMessage(LANG_WRONG_PET_TYPE); 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 (int 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, m_session->GetPlayer(), false)) continue; // learn highest rank of talent and learn all non-talent spell ranks (recursive by tree) pet->learnSpellHighRank(spellid); } player->SendTalentsInfoData(true); SendSysMessage(LANG_COMMAND_LEARN_PET_TALENTS); return true; } bool ChatHandler::HandleLearnAllLangCommand(char* /*args*/) { Player* player = m_session->GetPlayer(); // skipping UNIVERSAL language (0) for (int i = 1; i < LANGUAGES_COUNT; ++i) { player->learnSpell(lang_description[i].spell_id, false); } SendSysMessage(LANG_COMMAND_LEARN_ALL_LANG); return true; } bool ChatHandler::HandleLearnAllDefaultCommand(char* args) { Player* target; if (!ExtractPlayerTarget(&args, &target)) { return false; } target->learnDefaultSpells(); target->learnQuestRewardedSpells(); PSendSysMessage(LANG_COMMAND_LEARN_ALL_DEFAULT_AND_QUEST, GetNameLink(target).c_str()); return true; } bool ChatHandler::HandleLearnCommand(char* args) { Player* player = m_session->GetPlayer(); Player* targetPlayer = getSelectedPlayer(); if (!targetPlayer) { SendSysMessage(LANG_PLAYER_NOT_FOUND); SetSentErrorMessage(true); return false; } // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form uint32 spell = ExtractSpellIdFromLink(&args); if (!spell || !sSpellStore.LookupEntry(spell)) { return false; } bool allRanks = ExtractLiteralArg(&args, "all") != NULL; if (!allRanks && *args) // can be fail also at syntax error { return false; } SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell); if (!spellInfo || !SpellMgr::IsSpellValid(spellInfo, player)) { PSendSysMessage(LANG_COMMAND_SPELL_BROKEN, spell); SetSentErrorMessage(true); return false; } if (!allRanks && targetPlayer->HasSpell(spell)) { if (targetPlayer == player) { SendSysMessage(LANG_YOU_KNOWN_SPELL); } else PSendSysMessage(LANG_TARGET_KNOWN_SPELL, GetNameLink(targetPlayer).c_str()); 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; } bool ChatHandler::HandleAddItemCommand(char* args) { char* cId = ExtractKeyFromLink(&args, "Hitem"); if (!cId) { return false; } uint32 itemId = 0; if (!ExtractUInt32(&cId, itemId)) // [name] manual form { std::string itemName = cId; WorldDatabase.escape_string(itemName); QueryResult* result = WorldDatabase.PQuery("SELECT entry FROM item_template WHERE name = '%s'", itemName.c_str()); if (!result) { PSendSysMessage(LANG_COMMAND_COULDNOTFIND, cId); SetSentErrorMessage(true); return false; } itemId = result->Fetch()->GetUInt16(); delete result; } int32 count; if (!ExtractOptInt32(&args, count, 1)) { return false; } Player* pl = m_session->GetPlayer(); Player* plTarget = getSelectedPlayer(); if (!plTarget) { plTarget = pl; } DETAIL_LOG(GetMangosString(LANG_ADDITEM), itemId, count); ItemPrototype const* pProto = ObjectMgr::GetItemPrototype(itemId); if (!pProto) { PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId); SetSentErrorMessage(true); return false; } // Subtract if (count < 0) { plTarget->DestroyItemCount(itemId, -count, true, false); PSendSysMessage(LANG_REMOVEITEM, itemId, -count, GetNameLink(plTarget).c_str()); return true; } // Adding items uint32 noSpaceForCount = 0; // check space and find places ItemPosCountVec dest; uint8 msg = plTarget->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemId, count, &noSpaceForCount); if (msg != EQUIP_ERR_OK) // convert to possible store amount { count -= noSpaceForCount; } if (count == 0 || dest.empty()) // can't add any { PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount); SetSentErrorMessage(true); return false; } Item* item = plTarget->StoreNewItem(dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId)); // remove binding (let GM give it to another player later) if (pl == plTarget) for (ItemPosCountVec::const_iterator itr = dest.begin(); itr != dest.end(); ++itr) if (Item* item1 = pl->GetItemByPos(itr->pos)) { item1->SetBinding(false); } if (count > 0 && item) { pl->SendNewItem(item, count, false, true); if (pl != plTarget) { plTarget->SendNewItem(item, count, true, false); } } if (noSpaceForCount > 0) { PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount); } return true; } bool ChatHandler::HandleAddItemSetCommand(char* args) { uint32 itemsetId; if (!ExtractUint32KeyFromLink(&args, "Hitemset", itemsetId)) { return false; } // prevent generation all items with itemset field value '0' if (itemsetId == 0) { PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND, itemsetId); SetSentErrorMessage(true); return false; } Player* pl = m_session->GetPlayer(); Player* plTarget = getSelectedPlayer(); if (!plTarget) { plTarget = pl; } DETAIL_LOG(GetMangosString(LANG_ADDITEMSET), itemsetId); bool found = false; for (uint32 id = 0; id < sItemStorage.GetMaxEntry(); ++id) { ItemPrototype const* pProto = sItemStorage.LookupEntry(id); if (!pProto) { continue; } if (pProto->ItemSet == itemsetId) { found = true; ItemPosCountVec dest; InventoryResult msg = plTarget->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, pProto->ItemId, 1); if (msg == EQUIP_ERR_OK) { Item* item = plTarget->StoreNewItem(dest, pProto->ItemId, true); // remove binding (let GM give it to another player later) if (pl == plTarget) { item->SetBinding(false); } pl->SendNewItem(item, 1, false, true); if (pl != plTarget) { plTarget->SendNewItem(item, 1, true, false); } } else { pl->SendEquipError(msg, NULL, NULL, pProto->ItemId); PSendSysMessage(LANG_ITEM_CANNOT_CREATE, pProto->ItemId, 1); } } } if (!found) { PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND, itemsetId); SetSentErrorMessage(true); return false; } return true; } bool ChatHandler::HandleListItemCommand(char* args) { uint32 item_id; if (!ExtractUint32KeyFromLink(&args, "Hitem", item_id)) { return false; } if (!item_id) { PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id); SetSentErrorMessage(true); return false; } ItemPrototype const* itemProto = ObjectMgr::GetItemPrototype(item_id); if (!itemProto) { PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id); SetSentErrorMessage(true); return false; } uint32 count; if (!ExtractOptUInt32(&args, count, 10)) { return false; } QueryResult* result; // inventory case uint32 inv_count = 0; result = CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM character_inventory WHERE item_template='%u'", item_id); if (result) { inv_count = (*result)[0].GetUInt32(); delete result; } result = CharacterDatabase.PQuery( // 0 1 2 3 4 5 "SELECT ci.item, cibag.slot AS bag, ci.slot, ci.guid, characters.account,characters.name " "FROM character_inventory AS ci LEFT JOIN character_inventory AS cibag ON (cibag.item=ci.bag),characters " "WHERE ci.item_template='%u' AND ci.guid = characters.guid LIMIT %u ", item_id, uint32(count)); if (result) { do { Field* fields = result->Fetch(); uint32 item_guid = fields[0].GetUInt32(); uint32 item_bag = fields[1].GetUInt32(); uint32 item_slot = fields[2].GetUInt32(); uint32 owner_guid = fields[3].GetUInt32(); uint32 owner_acc = fields[4].GetUInt32(); std::string owner_name = fields[5].GetCppString(); char const* item_pos = 0; if (Player::IsEquipmentPos(item_bag, item_slot)) { item_pos = "[equipped]"; } else if (Player::IsInventoryPos(item_bag, item_slot)) { item_pos = "[in inventory]"; } else if (Player::IsBankPos(item_bag, item_slot)) { item_pos = "[in bank]"; } else { item_pos = ""; } PSendSysMessage(LANG_ITEMLIST_SLOT, item_guid, owner_name.c_str(), owner_guid, owner_acc, item_pos); } while (result->NextRow()); uint32 res_count = uint32(result->GetRowCount()); delete result; if (count > res_count) { count -= res_count; } else if (count) { count = 0; } } // mail case uint32 mail_count = 0; result = CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM mail_items WHERE item_template='%u'", item_id); if (result) { mail_count = (*result)[0].GetUInt32(); delete result; } if (count > 0) { result = CharacterDatabase.PQuery( // 0 1 2 3 4 5 6 "SELECT mail_items.item_guid, mail.sender, mail.receiver, char_s.account, char_s.name, char_r.account, char_r.name " "FROM mail,mail_items,characters as char_s,characters as char_r " "WHERE mail_items.item_template='%u' AND char_s.guid = mail.sender AND char_r.guid = mail.receiver AND mail.id=mail_items.mail_id LIMIT %u", item_id, uint32(count)); } else { result = NULL; } if (result) { do { Field* fields = result->Fetch(); uint32 item_guid = fields[0].GetUInt32(); uint32 item_s = fields[1].GetUInt32(); uint32 item_r = fields[2].GetUInt32(); uint32 item_s_acc = fields[3].GetUInt32(); std::string item_s_name = fields[4].GetCppString(); uint32 item_r_acc = fields[5].GetUInt32(); std::string item_r_name = fields[6].GetCppString(); char const* item_pos = "[in mail]"; PSendSysMessage(LANG_ITEMLIST_MAIL, item_guid, item_s_name.c_str(), item_s, item_s_acc, item_r_name.c_str(), item_r, item_r_acc, item_pos); } while (result->NextRow()); uint32 res_count = uint32(result->GetRowCount()); delete result; if (count > res_count) { count -= res_count; } else if (count) { count = 0; } } // auction case uint32 auc_count = 0; result = CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM auction WHERE item_template='%u'", item_id); if (result) { auc_count = (*result)[0].GetUInt32(); delete result; } if (count > 0) { result = CharacterDatabase.PQuery( // 0 1 2 3 "SELECT auction.itemguid, auction.itemowner, characters.account, characters.name " "FROM auction,characters WHERE auction.item_template='%u' AND characters.guid = auction.itemowner LIMIT %u", item_id, uint32(count)); } else { result = NULL; } if (result) { do { Field* fields = result->Fetch(); uint32 item_guid = fields[0].GetUInt32(); uint32 owner = fields[1].GetUInt32(); uint32 owner_acc = fields[2].GetUInt32(); std::string owner_name = fields[3].GetCppString(); char const* item_pos = "[in auction]"; PSendSysMessage(LANG_ITEMLIST_AUCTION, item_guid, owner_name.c_str(), owner, owner_acc, item_pos); } while (result->NextRow()); delete result; } // guild bank case uint32 guild_count = 0; result = CharacterDatabase.PQuery("SELECT COUNT(item_entry) FROM guild_bank_item WHERE item_entry='%u'", item_id); if (result) { guild_count = (*result)[0].GetUInt32(); delete result; } result = CharacterDatabase.PQuery( // 0 1 2 "SELECT gi.item_guid, gi.guildid, guild.name " "FROM guild_bank_item AS gi, guild WHERE gi.item_entry='%u' AND gi.guildid = guild.guildid LIMIT %u ", item_id, uint32(count)); if (result) { do { Field* fields = result->Fetch(); uint32 item_guid = fields[0].GetUInt32(); uint32 guild_guid = fields[1].GetUInt32(); std::string guild_name = fields[2].GetCppString(); char const* item_pos = "[in guild bank]"; PSendSysMessage(LANG_ITEMLIST_GUILD, item_guid, guild_name.c_str(), guild_guid, item_pos); } while (result->NextRow()); uint32 res_count = uint32(result->GetRowCount()); delete result; if (count > res_count) count -= res_count; else if (count) count = 0; } if (inv_count + mail_count + auc_count + guild_count == 0) { SendSysMessage(LANG_COMMAND_NOITEMFOUND); SetSentErrorMessage(true); return false; } PSendSysMessage(LANG_COMMAND_LISTITEMMESSAGE, item_id, inv_count + mail_count + auc_count + guild_count, inv_count, mail_count, auc_count, guild_count); return true; } bool ChatHandler::HandleListObjectCommand(char* args) { // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r uint32 go_id; if (!ExtractUint32KeyFromLink(&args, "Hgameobject_entry", go_id)) { return false; } if (!go_id) { PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id); SetSentErrorMessage(true); return false; } GameObjectInfo const* gInfo = ObjectMgr::GetGameObjectInfo(go_id); if (!gInfo) { PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id); SetSentErrorMessage(true); return false; } uint32 count; if (!ExtractOptUInt32(&args, count, 10)) { return false; } QueryResult* result; uint32 obj_count = 0; result = WorldDatabase.PQuery("SELECT COUNT(guid) FROM gameobject WHERE id='%u'", go_id); if (result) { obj_count = (*result)[0].GetUInt32(); delete result; } if (m_session) { Player* pl = m_session->GetPlayer(); result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map, (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ FROM gameobject WHERE id = '%u' ORDER BY order_ ASC LIMIT %u", pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), go_id, uint32(count)); } else result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map FROM gameobject WHERE id = '%u' LIMIT %u", go_id, uint32(count)); if (result) { do { Field* fields = result->Fetch(); uint32 guid = fields[0].GetUInt32(); float x = fields[1].GetFloat(); float y = fields[2].GetFloat(); float z = fields[3].GetFloat(); int mapid = fields[4].GetUInt16(); if (m_session) { PSendSysMessage(LANG_GO_LIST_CHAT, guid, PrepareStringNpcOrGoSpawnInformation(guid).c_str(), guid, gInfo->name, x, y, z, mapid); } else { PSendSysMessage(LANG_GO_LIST_CONSOLE, guid, PrepareStringNpcOrGoSpawnInformation(guid).c_str(), gInfo->name, x, y, z, mapid); } } while (result->NextRow()); delete result; } PSendSysMessage(LANG_COMMAND_LISTOBJMESSAGE, go_id, obj_count); return true; } bool ChatHandler::HandleListCreatureCommand(char* args) { // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r uint32 cr_id; if (!ExtractUint32KeyFromLink(&args, "Hcreature_entry", cr_id)) { return false; } if (!cr_id) { PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id); SetSentErrorMessage(true); return false; } CreatureInfo const* cInfo = ObjectMgr::GetCreatureTemplate(cr_id); if (!cInfo) { PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id); SetSentErrorMessage(true); return false; } uint32 count; if (!ExtractOptUInt32(&args, count, 10)) { return false; } QueryResult* result; uint32 cr_count = 0; result = WorldDatabase.PQuery("SELECT COUNT(guid) FROM creature WHERE id='%u'", cr_id); if (result) { cr_count = (*result)[0].GetUInt32(); delete result; } if (m_session) { Player* pl = m_session->GetPlayer(); result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map, (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ FROM creature WHERE id = '%u' ORDER BY order_ ASC LIMIT %u", pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), cr_id, uint32(count)); } else result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map FROM creature WHERE id = '%u' LIMIT %u", cr_id, uint32(count)); if (result) { do { Field* fields = result->Fetch(); uint32 guid = fields[0].GetUInt32(); float x = fields[1].GetFloat(); float y = fields[2].GetFloat(); float z = fields[3].GetFloat(); int mapid = fields[4].GetUInt16(); if (m_session) { PSendSysMessage(LANG_CREATURE_LIST_CHAT, guid, PrepareStringNpcOrGoSpawnInformation(guid).c_str(), guid, cInfo->Name, x, y, z, mapid); } else { PSendSysMessage(LANG_CREATURE_LIST_CONSOLE, guid, PrepareStringNpcOrGoSpawnInformation(guid).c_str(), cInfo->Name, x, y, z, mapid); } } while (result->NextRow()); delete result; } PSendSysMessage(LANG_COMMAND_LISTCREATUREMESSAGE, cr_id, cr_count); return true; } void ChatHandler::ShowItemListHelper(uint32 itemId, int loc_idx, Player* target /*=NULL*/) { ItemPrototype const* itemProto = sItemStorage.LookupEntry(itemId); if (!itemProto) { return; } std::string name = itemProto->Name1; sObjectMgr.GetItemLocaleStrings(itemProto->ItemId, loc_idx, &name); char const* usableStr = ""; if (target) { if (target->CanUseItem(itemProto)) { usableStr = GetMangosString(LANG_COMMAND_ITEM_USABLE); } } if (m_session) { PSendSysMessage(LANG_ITEM_LIST_CHAT, itemId, itemId, name.c_str(), usableStr); } else { PSendSysMessage(LANG_ITEM_LIST_CONSOLE, itemId, name.c_str(), usableStr); } } bool ChatHandler::HandleLookupItemCommand(char* args) { if (!*args) { return false; } std::string namepart = args; std::wstring wnamepart; // converting string that we try to find to lower case if (!Utf8toWStr(namepart, wnamepart)) { return false; } wstrToLower(wnamepart); Player* pl = m_session ? m_session->GetPlayer() : NULL; uint32 counter = 0; // Search in `item_template` for (uint32 id = 0; id < sItemStorage.GetMaxEntry(); ++id) { ItemPrototype const* pProto = sItemStorage.LookupEntry(id); if (!pProto) { continue; } int loc_idx = GetSessionDbLocaleIndex(); std::string name; // "" for let later only single time check default locale name directly sObjectMgr.GetItemLocaleStrings(id, loc_idx, &name); if ((name.empty() || !Utf8FitTo(name, wnamepart)) && !Utf8FitTo(pProto->Name1, wnamepart)) { continue; } ShowItemListHelper(id, loc_idx, pl); ++counter; } if (counter == 0) { SendSysMessage(LANG_COMMAND_NOITEMFOUND); } return true; } bool ChatHandler::HandleLookupItemSetCommand(char* args) { if (!*args) { return false; } std::string namepart = args; std::wstring wnamepart; if (!Utf8toWStr(namepart, wnamepart)) { return false; } // converting string that we try to find to lower case wstrToLower(wnamepart); uint32 counter = 0; // Counter for figure out that we found smth. // Search in ItemSet.dbc for (uint32 id = 0; id < sItemSetStore.GetNumRows(); ++id) { ItemSetEntry const* set = sItemSetStore.LookupEntry(id); if (set) { int loc = GetSessionDbcLocale(); std::string name = set->name[loc]; if (name.empty()) { continue; } if (!Utf8FitTo(name, wnamepart)) { loc = 0; for (; loc < MAX_LOCALE; ++loc) { if (loc == GetSessionDbcLocale()) { continue; } name = set->name[loc]; if (name.empty()) { continue; } if (Utf8FitTo(name, wnamepart)) { break; } } } if (loc < MAX_LOCALE) { // send item set in "id - [namedlink locale]" format if (m_session) { PSendSysMessage(LANG_ITEMSET_LIST_CHAT, id, id, name.c_str(), localeNames[loc]); } else { PSendSysMessage(LANG_ITEMSET_LIST_CONSOLE, id, name.c_str(), localeNames[loc]); } ++counter; } } } if (counter == 0) // if counter == 0 then we found nth { SendSysMessage(LANG_COMMAND_NOITEMSETFOUND); } return true; } bool ChatHandler::HandleLookupSkillCommand(char* args) { if (!*args) { return false; } // can be NULL in console call Player* target = getSelectedPlayer(); std::string namepart = args; std::wstring wnamepart; if (!Utf8toWStr(namepart, wnamepart)) { return false; } // converting string that we try to find to lower case wstrToLower(wnamepart); uint32 counter = 0; // Counter for figure out that we found smth. // Search in SkillLine.dbc for (uint32 id = 0; id < sSkillLineStore.GetNumRows(); ++id) { SkillLineEntry const* skillInfo = sSkillLineStore.LookupEntry(id); if (skillInfo) { int loc = GetSessionDbcLocale(); std::string name = skillInfo->name[loc]; if (name.empty()) { continue; } if (!Utf8FitTo(name, wnamepart)) { loc = 0; for (; loc < MAX_LOCALE; ++loc) { if (loc == GetSessionDbcLocale()) { continue; } name = skillInfo->name[loc]; if (name.empty()) { continue; } if (Utf8FitTo(name, wnamepart)) { break; } } } if (loc < MAX_LOCALE) { char valStr[50] = ""; char const* knownStr = ""; if (target && target->HasSkill(id)) { knownStr = GetMangosString(LANG_KNOWN); uint32 curValue = target->GetPureSkillValue(id); uint32 maxValue = target->GetPureMaxSkillValue(id); uint32 permValue = target->GetSkillPermBonusValue(id); uint32 tempValue = target->GetSkillTempBonusValue(id); char const* valFormat = GetMangosString(LANG_SKILL_VALUES); snprintf(valStr, 50, valFormat, curValue, maxValue, permValue, tempValue); } // send skill in "id - [namedlink locale]" format if (m_session) { PSendSysMessage(LANG_SKILL_LIST_CHAT, id, id, name.c_str(), localeNames[loc], knownStr, valStr); } else { PSendSysMessage(LANG_SKILL_LIST_CONSOLE, id, name.c_str(), localeNames[loc], knownStr, valStr); } ++counter; } } } if (counter == 0) // if counter == 0 then we found nth { SendSysMessage(LANG_COMMAND_NOSKILLFOUND); } return true; } void ChatHandler::ShowCurrencyListHelper(Player* target, CurrencyTypesEntry const* currency, LocaleConstant loc) { uint32 id = currency->ID; uint32 count = target ? target->GetCurrencyCount(id) : 0; uint32 talentCost = GetTalentSpellCost(id); // send spell in "id - [name] (Amount: x)" format std::ostringstream ss; if (m_session) ss << id << " - |cff00aa00|Hcurrency:" << id << "|h[" << currency->name[loc]; else ss << id << " - " << currency->name[loc]; if (m_session) ss << " " << localeNames[loc] << "]|h|r"; else ss << " " << localeNames[loc]; if (target) ss << " (" << GetMangosString(LANG_CURRENCY_AMOUNT) << ": " << count << ")"; SendSysMessage(ss.str().c_str()); } void ChatHandler::ShowSpellListHelper(Player* target, SpellEntry const* spellInfo, LocaleConstant loc) { uint32 id = spellInfo->Id; bool known = target && target->HasSpell(id); SpellEffectEntry const* spellEffect = spellInfo->GetSpellEffect(EFFECT_INDEX_0); bool learn = (spellEffect && spellEffect->Effect == SPELL_EFFECT_LEARN_SPELL); uint32 talentCost = GetTalentSpellCost(id); bool talent = (talentCost > 0); bool passive = IsPassiveSpell(spellInfo); bool active = target && target->HasAura(id); // unit32 used to prevent interpreting uint8 as char at output // find rank of learned spell for learning spell, or talent rank uint32 rank = talentCost ? talentCost : sSpellMgr.GetSpellRank(learn ? (spellEffect ? spellEffect->EffectTriggerSpell : 0) : id); // send spell in "id - [name, rank N] [talent] [passive] [learn] [known]" format std::ostringstream ss; if (m_session) { ss << id << " - |cffffffff|Hspell:" << id << "|h[" << spellInfo->SpellName[loc]; } else { ss << id << " - " << spellInfo->SpellName[loc]; } // include rank in link name if (rank) { ss << GetMangosString(LANG_SPELL_RANK) << rank; } if (m_session) { ss << " " << localeNames[loc] << "]|h|r"; } else { ss << " " << localeNames[loc]; } if (talent) { ss << GetMangosString(LANG_TALENT); } if (passive) { ss << GetMangosString(LANG_PASSIVE); } if (learn) { ss << GetMangosString(LANG_LEARN); } if (known) { ss << GetMangosString(LANG_KNOWN); } if (active) { ss << GetMangosString(LANG_ACTIVE); } SendSysMessage(ss.str().c_str()); } bool ChatHandler::HandleLookupCurrencyCommand(char* args) { if (!*args) return false; // can be NULL at console call Player* target = getSelectedPlayer(); std::string namepart = args; std::wstring wnamepart; if (!Utf8toWStr(namepart, wnamepart)) return false; // converting string that we try to find to lower case wstrToLower(wnamepart); uint32 counter = 0; // Counter for figure out that we found smth. // Search in CurrencyTypes.dbc for (uint32 id = 0; id < sCurrencyTypesStore.GetNumRows(); ++id) { CurrencyTypesEntry const* currency = sCurrencyTypesStore.LookupEntry(id); if (currency) { int loc = GetSessionDbcLocale(); std::string name = currency->name[loc]; if (name.empty()) continue; if (!Utf8FitTo(name, wnamepart)) { loc = 0; for (; loc < MAX_LOCALE; ++loc) { if (loc == GetSessionDbcLocale()) continue; name = currency->name[loc]; if (name.empty()) continue; if (Utf8FitTo(name, wnamepart)) break; } } if (loc < MAX_LOCALE) { ShowCurrencyListHelper(target, currency, LocaleConstant(loc)); ++counter; } } } if (counter == 0) // if counter == 0 then we found nth SendSysMessage(LANG_COMMAND_NOCURRENCYFOUND); return true; } bool ChatHandler::HandleLookupSpellCommand(char* args) { if (!*args) { return false; } // can be NULL at console call Player* target = getSelectedPlayer(); std::string namepart = args; std::wstring wnamepart; if (!Utf8toWStr(namepart, wnamepart)) { return false; } // converting string that we try to find to lower case wstrToLower(wnamepart); uint32 counter = 0; // Counter for figure out that we found smth. // Search in Spell.dbc for (uint32 id = 0; id < sSpellStore.GetNumRows(); id++) { SpellEntry const* spellInfo = sSpellStore.LookupEntry(id); if (spellInfo) { int loc = GetSessionDbcLocale(); DEBUG_LOG("Spellid %u locale %u", id, loc); std::string name = spellInfo->SpellName[loc]; if (name.empty()) { continue; } if (!Utf8FitTo(name, wnamepart)) { loc = 0; for (; loc < MAX_LOCALE; ++loc) { if (loc == GetSessionDbcLocale()) { continue; } name = spellInfo->SpellName[loc]; if (name.empty()) { continue; } if (Utf8FitTo(name, wnamepart)) { break; } } } if (loc < MAX_LOCALE) { if (target) ShowSpellListHelper(target, spellInfo, LocaleConstant(loc)); ++counter; } } } if (counter == 0) // if counter == 0 then we found nth { SendSysMessage(LANG_COMMAND_NOSPELLFOUND); } return true; } void ChatHandler::ShowQuestListHelper(uint32 questId, int32 loc_idx, Player* target /*= NULL*/) { Quest const* qinfo = sObjectMgr.GetQuestTemplate(questId); if (!qinfo) { return; } std::string title = qinfo->GetTitle(); sObjectMgr.GetQuestLocaleStrings(questId, loc_idx, &title); char const* statusStr = ""; if (target) { QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId()); if (status == QUEST_STATUS_COMPLETE) { if (target->GetQuestRewardStatus(qinfo->GetQuestId())) { statusStr = GetMangosString(LANG_COMMAND_QUEST_REWARDED); } else { statusStr = GetMangosString(LANG_COMMAND_QUEST_COMPLETE); } } else if (status == QUEST_STATUS_INCOMPLETE) { statusStr = GetMangosString(LANG_COMMAND_QUEST_ACTIVE); } } if (m_session) { PSendSysMessage(LANG_QUEST_LIST_CHAT, qinfo->GetQuestId(), qinfo->GetQuestId(), qinfo->GetQuestLevel(), title.c_str(), statusStr); } else { PSendSysMessage(LANG_QUEST_LIST_CONSOLE, qinfo->GetQuestId(), title.c_str(), statusStr); } } bool ChatHandler::HandleLookupQuestCommand(char* args) { if (!*args) { return false; } // can be NULL at console call Player* target = getSelectedPlayer(); std::string namepart = args; std::wstring wnamepart; // converting string that we try to find to lower case if (!Utf8toWStr(namepart, wnamepart)) { return false; } wstrToLower(wnamepart); uint32 counter = 0 ; int loc_idx = GetSessionDbLocaleIndex(); ObjectMgr::QuestMap const& qTemplates = sObjectMgr.GetQuestTemplates(); for (ObjectMgr::QuestMap::const_iterator iter = qTemplates.begin(); iter != qTemplates.end(); ++iter) { Quest* qinfo = iter->second; std::string title; // "" for avoid repeating check default locale sObjectMgr.GetQuestLocaleStrings(qinfo->GetQuestId(), loc_idx, &title); if ((title.empty() || !Utf8FitTo(title, wnamepart)) && !Utf8FitTo(qinfo->GetTitle(), wnamepart)) { continue; } ShowQuestListHelper(qinfo->GetQuestId(), loc_idx, target); ++counter; } if (counter == 0) { SendSysMessage(LANG_COMMAND_NOQUESTFOUND); } return true; } bool ChatHandler::HandleLookupCreatureCommand(char* args) { if (!*args) { return false; } std::string namepart = args; std::wstring wnamepart; // converting string that we try to find to lower case if (!Utf8toWStr(namepart, wnamepart)) { return false; } wstrToLower(wnamepart); uint32 counter = 0; for (uint32 id = 0; id < sCreatureStorage.GetMaxEntry(); ++id) { CreatureInfo const* cInfo = sCreatureStorage.LookupEntry (id); if (!cInfo) { continue; } int loc_idx = GetSessionDbLocaleIndex(); char const* name = ""; // "" for avoid repeating check for default locale sObjectMgr.GetCreatureLocaleStrings(id, loc_idx, &name); if (!*name || !Utf8FitTo(name, wnamepart)) { name = cInfo->Name; if (!Utf8FitTo(name, wnamepart)) { continue; } } if (m_session) { PSendSysMessage(LANG_CREATURE_ENTRY_LIST_CHAT, id, id, name); } else { PSendSysMessage(LANG_CREATURE_ENTRY_LIST_CONSOLE, id, name); } ++counter; } if (counter == 0) { SendSysMessage(LANG_COMMAND_NOCREATUREFOUND); } return true; } bool ChatHandler::HandleLookupObjectCommand(char* args) { if (!*args) { return false; } std::string namepart = args; std::wstring wnamepart; // converting string that we try to find to lower case if (!Utf8toWStr(namepart, wnamepart)) { return false; } wstrToLower(wnamepart); uint32 counter = 0; for (SQLStorageBase::SQLSIterator itr = sGOStorage.getDataBegin(); itr < sGOStorage.getDataEnd(); ++itr) { int loc_idx = GetSessionDbLocaleIndex(); if (loc_idx >= 0) { GameObjectLocale const* gl = sObjectMgr.GetGameObjectLocale(itr->id); if (gl) { if ((int32)gl->Name.size() > loc_idx && !gl->Name[loc_idx].empty()) { std::string name = gl->Name[loc_idx]; if (Utf8FitTo(name, wnamepart)) { if (m_session) { PSendSysMessage(LANG_GO_ENTRY_LIST_CHAT, itr->id, itr->id, name.c_str()); } else { PSendSysMessage(LANG_GO_ENTRY_LIST_CONSOLE, itr->id, name.c_str()); } ++counter; continue; } } } } std::string name = itr->name; if (name.empty()) { continue; } if (Utf8FitTo(name, wnamepart)) { if (m_session) { PSendSysMessage(LANG_GO_ENTRY_LIST_CHAT, itr->id, itr->id, name.c_str()); } else { PSendSysMessage(LANG_GO_ENTRY_LIST_CONSOLE, itr->id, name.c_str()); } ++counter; } } if (counter == 0) { SendSysMessage(LANG_COMMAND_NOGAMEOBJECTFOUND); } return true; } bool ChatHandler::HandleLookupTaxiNodeCommand(char* args) { if (!*args) { return false; } std::string namepart = args; std::wstring wnamepart; if (!Utf8toWStr(namepart, wnamepart)) { return false; } // converting string that we try to find to lower case wstrToLower(wnamepart); uint32 counter = 0; // Counter for figure out that we found smth. // Search in TaxiNodes.dbc for (uint32 id = 0; id < sTaxiNodesStore.GetNumRows(); ++id) { TaxiNodesEntry const* nodeEntry = sTaxiNodesStore.LookupEntry(id); if (nodeEntry) { int loc = GetSessionDbcLocale(); std::string name = nodeEntry->name[loc]; if (name.empty()) { continue; } if (!Utf8FitTo(name, wnamepart)) { loc = 0; for (; loc < MAX_LOCALE; ++loc) { if (loc == GetSessionDbcLocale()) { continue; } name = nodeEntry->name[loc]; if (name.empty()) { continue; } if (Utf8FitTo(name, wnamepart)) { break; } } } if (loc < MAX_LOCALE) { // send taxinode in "id - [name] (Map:m X:x Y:y Z:z)" format if (m_session) PSendSysMessage(LANG_TAXINODE_ENTRY_LIST_CHAT, id, id, name.c_str(), localeNames[loc], nodeEntry->map_id, nodeEntry->x, nodeEntry->y, nodeEntry->z); else PSendSysMessage(LANG_TAXINODE_ENTRY_LIST_CONSOLE, id, name.c_str(), localeNames[loc], nodeEntry->map_id, nodeEntry->x, nodeEntry->y, nodeEntry->z); ++counter; } } } if (counter == 0) // if counter == 0 then we found nth { SendSysMessage(LANG_COMMAND_NOTAXINODEFOUND); } return true; } /** \brief GM command level 3 - Create a guild. * * This command allows a GM (level 3) to create a guild. * * The "args" parameter contains the name of the guild leader * and then the name of the guild. * */ bool ChatHandler::HandleGuildCreateCommand(char* args) { // guildmaster name optional char* guildMasterStr = ExtractOptNotLastArg(&args); Player* target; if (!ExtractPlayerTarget(&guildMasterStr, &target)) { return false; } char* guildStr = ExtractQuotedArg(&args); if (!guildStr) { return false; } std::string guildname = guildStr; if (target->GetGuildId()) { SendSysMessage(LANG_PLAYER_IN_GUILD); return true; } Guild* guild = new Guild; if (!guild->Create(target, guildname)) { delete guild; SendSysMessage(LANG_GUILD_NOT_CREATED); SetSentErrorMessage(true); return false; } sGuildMgr.AddGuild(guild); return true; } bool ChatHandler::HandleGuildInviteCommand(char* args) { // player name optional char* nameStr = ExtractOptNotLastArg(&args); // if not guild name only (in "") then player name ObjectGuid target_guid; if (!ExtractPlayerTarget(&nameStr, NULL, &target_guid)) { return false; } char* guildStr = ExtractQuotedArg(&args); if (!guildStr) { return false; } std::string glName = guildStr; Guild* targetGuild = sGuildMgr.GetGuildByName(glName); if (!targetGuild) { return false; } // player's guild membership checked in AddMember before add if (!targetGuild->AddMember(target_guid, targetGuild->GetLowestRank())) { return false; } return true; } bool ChatHandler::HandleGuildUninviteCommand(char* args) { Player* target; ObjectGuid target_guid; if (!ExtractPlayerTarget(&args, &target, &target_guid)) { return false; } uint32 glId = target ? target->GetGuildId() : Player::GetGuildIdFromDB(target_guid); if (!glId) { return false; } Guild* targetGuild = sGuildMgr.GetGuildById(glId); if (!targetGuild) { return false; } if (targetGuild->DelMember(target_guid)) { targetGuild->Disband(); delete targetGuild; } return true; } bool ChatHandler::HandleGuildRankCommand(char* args) { char* nameStr = ExtractOptNotLastArg(&args); Player* target; ObjectGuid target_guid; std::string target_name; if (!ExtractPlayerTarget(&nameStr, &target, &target_guid, &target_name)) { return false; } uint32 glId = target ? target->GetGuildId() : Player::GetGuildIdFromDB(target_guid); if (!glId) { return false; } Guild* targetGuild = sGuildMgr.GetGuildById(glId); if (!targetGuild) { return false; } uint32 newrank; if (!ExtractUInt32(&args, newrank)) { return false; } if (newrank > targetGuild->GetLowestRank()) { return false; } MemberSlot* slot = targetGuild->GetMemberSlot(target_guid); if (!slot) { return false; } slot->ChangeRank(newrank); return true; } bool ChatHandler::HandleGuildDeleteCommand(char* args) { if (!*args) { return false; } char* guildStr = ExtractQuotedArg(&args); if (!guildStr) { return false; } std::string gld = guildStr; Guild* targetGuild = sGuildMgr.GetGuildByName(gld); if (!targetGuild) { return false; } targetGuild->Disband(); delete targetGuild; return true; } bool ChatHandler::HandleGetDistanceCommand(char* args) { WorldObject* obj = NULL; if (*args) { if (ObjectGuid guid = ExtractGuidFromLink(&args)) { obj = (WorldObject*)m_session->GetPlayer()->GetObjectByTypeMask(guid, TYPEMASK_CREATURE_OR_GAMEOBJECT); } if (!obj) { SendSysMessage(LANG_PLAYER_NOT_FOUND); SetSentErrorMessage(true); return false; } } else { obj = getSelectedUnit(); if (!obj) { SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); SetSentErrorMessage(true); return false; } } Player* player = m_session->GetPlayer(); // Calculate point-to-point distance float dx, dy, dz; dx = player->GetPositionX() - obj->GetPositionX(); dy = player->GetPositionY() - obj->GetPositionY(); dz = player->GetPositionZ() - obj->GetPositionZ(); PSendSysMessage(LANG_DISTANCE, player->GetDistance(obj), player->GetDistance2d(obj), sqrt(dx * dx + dy * dy + dz * dz)); return true; } bool ChatHandler::HandleDieCommand(char* /*args*/) { Player* player = m_session->GetPlayer(); Unit* target = getSelectedUnit(); if (!target || !player->GetSelectionGuid()) { SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); SetSentErrorMessage(true); return false; } if (target->GetTypeId() == TYPEID_PLAYER) { if (HasLowerSecurity((Player*)target, ObjectGuid(), false)) { return false; } } if (target->IsAlive()) { player->DealDamage(target, target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); } return true; } bool ChatHandler::HandleDamageCommand(char* args) { if (!*args) { return false; } Unit* target = getSelectedUnit(); Player* player = m_session->GetPlayer(); if (!target || !player->GetSelectionGuid()) { SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); SetSentErrorMessage(true); return false; } if (!target->IsAlive()) { return true; } int32 damage_int; if (!ExtractInt32(&args, damage_int)) { return false; } if (damage_int <= 0) { return true; } uint32 damage = damage_int; // flat melee damage without resistance/etc reduction if (!*args) { player->DealDamage(target, damage, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); if (target != player) { player->SendAttackStateUpdate(HITINFO_NORMALSWING2, target, SPELL_SCHOOL_MASK_NORMAL, damage, 0, 0, VICTIMSTATE_NORMAL, 0); } return true; } uint32 school; if (!ExtractUInt32(&args, school)) { return false; } if (school >= MAX_SPELL_SCHOOL) { return false; } SpellSchoolMask schoolmask = SpellSchoolMask(1 << school); if (schoolmask & SPELL_SCHOOL_MASK_NORMAL) { damage = player->CalcArmorReducedDamage(target, damage); } // melee damage by specific school if (!*args) { uint32 absorb = 0; uint32 resist = 0; target->CalculateDamageAbsorbAndResist(player, schoolmask, SPELL_DIRECT_DAMAGE, damage, &absorb, &resist); if (damage <= absorb + resist) { return true; } damage -= absorb + resist; player->DealDamageMods(target, damage, &absorb); player->DealDamage(target, damage, NULL, DIRECT_DAMAGE, schoolmask, NULL, false); player->SendAttackStateUpdate(HITINFO_NORMALSWING2, target, schoolmask, damage, absorb, resist, VICTIMSTATE_NORMAL, 0); return true; } // non-melee damage // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form uint32 spellid = ExtractSpellIdFromLink(&args); if (!spellid || !sSpellStore.LookupEntry(spellid)) { return false; } player->SpellNonMeleeDamageLog(target, spellid, damage); return true; } bool ChatHandler::HandleModifyCurrencyCommand(char* args) { if (!*args) return false; uint32 currencyId; if (!ExtractUint32KeyFromLink(&args, "Hcurrency", currencyId)) return false; CurrencyTypesEntry const * entry = sCurrencyTypesStore.LookupEntry(currencyId); if (!entry) return false; int32 amount; if (!ExtractInt32(&args, amount)) return false; Player* target = getSelectedPlayer(); if (!target) { SendSysMessage(LANG_PLAYER_NOT_FOUND); SetSentErrorMessage(true); return false; } target->ModifyCurrencyCount(currencyId, amount, false, false); PSendSysMessage(LANG_COMMAND_MODIFY_CURRENCY, currencyId, GetNameLink(target).c_str(), target->GetCurrencyCount(currencyId)); return true; } bool ChatHandler::HandleReviveCommand(char* args) { Player* target; ObjectGuid target_guid; if (!ExtractPlayerTarget(&args, &target, &target_guid)) { return false; } if (target) { target->ResurrectPlayer(0.5f); target->SpawnCorpseBones(); } else // will resurrected at login without corpse { sObjectAccessor.ConvertCorpseForPlayer(target_guid); } return true; } bool ChatHandler::HandleAuraCommand(char* args) { Unit* target = getSelectedUnit(); if (!target) { SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); SetSentErrorMessage(true); return false; } // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form uint32 spellID = ExtractSpellIdFromLink(&args); SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellID); if (!spellInfo) { return false; } if (!IsSpellAppliesAura(spellInfo) && !IsSpellHaveEffect(spellInfo, SPELL_EFFECT_PERSISTENT_AREA_AURA)) { PSendSysMessage(LANG_SPELL_NO_HAVE_AURAS, spellID); SetSentErrorMessage(true); return false; } SpellAuraHolder* holder = CreateSpellAuraHolder(spellInfo, target, m_session->GetPlayer()); for (uint32 i = 0; i < MAX_EFFECT_INDEX; ++i) { SpellEffectEntry const* spellEffect = spellInfo->GetSpellEffect(SpellEffectIndex(i)); if(!spellEffect) continue; uint8 eff = spellEffect->Effect; if (eff >= TOTAL_SPELL_EFFECTS) { continue; } if (IsAreaAuraEffect(eff) || eff == SPELL_EFFECT_APPLY_AURA || eff == SPELL_EFFECT_PERSISTENT_AREA_AURA) { Aura* aur = CreateAura(spellInfo, SpellEffectIndex(i), NULL, holder, target); holder->AddAura(aur, SpellEffectIndex(i)); } } target->AddSpellAuraHolder(holder); return true; } bool ChatHandler::HandleUnAuraCommand(char* args) { Unit* target = getSelectedUnit(); if (!target) { SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); SetSentErrorMessage(true); return false; } std::string argstr = args; if (argstr == "all") { target->RemoveAllAuras(); return true; } // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form uint32 spellID = ExtractSpellIdFromLink(&args); if (!spellID) { return false; } target->RemoveAurasDueToSpell(spellID); return true; } bool ChatHandler::HandleLinkGraveCommand(char* args) { uint32 g_id; if (!ExtractUInt32(&args, g_id)) { return false; } char* teamStr = ExtractLiteralArg(&args); Team g_team; if (!teamStr) { g_team = TEAM_BOTH_ALLOWED; } else if (strncmp(teamStr, "horde", strlen(teamStr)) == 0) { g_team = HORDE; } else if (strncmp(teamStr, "alliance", strlen(teamStr)) == 0) { g_team = ALLIANCE; } else { return false; } WorldSafeLocsEntry const* graveyard = sWorldSafeLocsStore.LookupEntry(g_id); if (!graveyard) { PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST, g_id); SetSentErrorMessage(true); return false; } Player* player = m_session->GetPlayer(); uint32 zoneId = player->GetZoneId(); AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(zoneId); if (!areaEntry || areaEntry->zone != 0) { PSendSysMessage(LANG_COMMAND_GRAVEYARDWRONGZONE, g_id, zoneId); SetSentErrorMessage(true); return false; } if (sObjectMgr.AddGraveYardLink(g_id, zoneId, g_team)) { PSendSysMessage(LANG_COMMAND_GRAVEYARDLINKED, g_id, zoneId); } else { PSendSysMessage(LANG_COMMAND_GRAVEYARDALRLINKED, g_id, zoneId); } return true; } bool ChatHandler::HandleNearGraveCommand(char* args) { Team g_team; size_t argslen = strlen(args); if (!*args) { g_team = TEAM_BOTH_ALLOWED; } else if (strncmp(args, "horde", argslen) == 0) { g_team = HORDE; } else if (strncmp(args, "alliance", argslen) == 0) { g_team = ALLIANCE; } else { return false; } Player* player = m_session->GetPlayer(); uint32 zone_id = player->GetZoneId(); WorldSafeLocsEntry const* graveyard = sObjectMgr.GetClosestGraveYard(player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetMapId(), g_team); if (graveyard) { uint32 g_id = graveyard->ID; GraveYardData const* data = sObjectMgr.FindGraveYardData(g_id, zone_id); if (!data) { PSendSysMessage(LANG_COMMAND_GRAVEYARDERROR, g_id); SetSentErrorMessage(true); return false; } std::string team_name; if (data->team == TEAM_BOTH_ALLOWED) { team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ANY); } else if (data->team == HORDE) { team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_HORDE); } else if (data->team == ALLIANCE) { team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ALLIANCE); } else // Actually, this case can not happen { team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_NOTEAM); } PSendSysMessage(LANG_COMMAND_GRAVEYARDNEAREST, g_id, team_name.c_str(), zone_id); } else { std::string team_name; if (g_team == TEAM_BOTH_ALLOWED) { team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ANY); } else if (g_team == HORDE) { team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_HORDE); } else if (g_team == ALLIANCE) { team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ALLIANCE); } if (g_team == TEAM_BOTH_ALLOWED) { PSendSysMessage(LANG_COMMAND_ZONENOGRAVEYARDS, zone_id); } else { PSendSysMessage(LANG_COMMAND_ZONENOGRAFACTION, zone_id, team_name.c_str()); } } return true; } //-----------------------Npc Commands----------------------- bool ChatHandler::HandleNpcAllowMovementCommand(char* /*args*/) { if (sWorld.getAllowMovement()) { sWorld.SetAllowMovement(false); SendSysMessage(LANG_CREATURE_MOVE_DISABLED); } else { sWorld.SetAllowMovement(true); SendSysMessage(LANG_CREATURE_MOVE_ENABLED); } return true; } bool ChatHandler::HandleNpcChangeEntryCommand(char* args) { if (!*args) { return false; } uint32 newEntryNum = atoi(args); if (!newEntryNum) { return false; } Unit* unit = getSelectedUnit(); if (!unit || unit->GetTypeId() != TYPEID_UNIT) { SendSysMessage(LANG_SELECT_CREATURE); SetSentErrorMessage(true); return false; } Creature* creature = (Creature*)unit; if (creature->UpdateEntry(newEntryNum)) { SendSysMessage(LANG_DONE); } else { SendSysMessage(LANG_ERROR); } return true; } bool ChatHandler::HandleNpcInfoCommand(char* /*args*/) { Creature* target = getSelectedCreature(); if (!target) { SendSysMessage(LANG_SELECT_CREATURE); SetSentErrorMessage(true); return false; } uint32 faction = target->getFaction(); uint32 NpcFlagss = target->GetUInt32Value(UNIT_NPC_FLAGS); uint32 displayid = target->GetDisplayId(); uint32 nativeid = target->GetNativeDisplayId(); uint32 Entry = target->GetEntry(); CreatureInfo const* cInfo = target->GetCreatureInfo(); time_t curRespawnDelay = target->GetRespawnTimeEx() - time(NULL); if (curRespawnDelay < 0) { curRespawnDelay = 0; } std::string curRespawnDelayStr = secsToTimeString(curRespawnDelay, true); std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(), true); // Send information dependend on difficulty mode CreatureInfo const* baseInfo = ObjectMgr::GetCreatureTemplate(Entry); uint32 diff = 1; for (; diff < MAX_DIFFICULTY; ++diff) if (baseInfo->DifficultyEntry[diff - 1] == target->GetCreatureInfo()->Entry) break; if (diff < MAX_DIFFICULTY) PSendSysMessage(LANG_NPCINFO_CHAR_DIFFICULTY, target->GetGuidStr().c_str(), faction, NpcFlagss, Entry, target->GetCreatureInfo()->Entry, diff, displayid, nativeid); else PSendSysMessage(LANG_NPCINFO_CHAR, target->GetGuidStr().c_str(), faction, NpcFlagss, Entry, displayid, nativeid); PSendSysMessage(LANG_NPCINFO_LEVEL, target->getLevel()); PSendSysMessage(LANG_NPCINFO_HEALTH, target->GetCreateHealth(), target->GetMaxHealth(), target->GetHealth()); PSendSysMessage(LANG_NPCINFO_FLAGS, target->GetUInt32Value(UNIT_FIELD_FLAGS), target->GetUInt32Value(UNIT_DYNAMIC_FLAGS), target->getFaction()); PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES, defRespawnDelayStr.c_str(), curRespawnDelayStr.c_str()); PSendSysMessage(LANG_NPCINFO_LOOT, cInfo->LootId, cInfo->PickpocketLootId, cInfo->SkinningLootId); PSendSysMessage(LANG_NPCINFO_DUNGEON_ID, target->GetInstanceId()); PSendSysMessage(LANG_NPCINFO_POSITION, float(target->GetPositionX()), float(target->GetPositionY()), float(target->GetPositionZ())); if ((NpcFlagss & UNIT_NPC_FLAG_VENDOR)) { SendSysMessage(LANG_NPCINFO_VENDOR); } if ((NpcFlagss & UNIT_NPC_FLAG_TRAINER)) { SendSysMessage(LANG_NPCINFO_TRAINER); } ShowNpcOrGoSpawnInformation(target->GetGUIDLow()); return true; } // play npc emote bool ChatHandler::HandleNpcPlayEmoteCommand(char* args) { uint32 emote = atoi(args); Creature* target = getSelectedCreature(); if (!target) { SendSysMessage(LANG_SELECT_CREATURE); SetSentErrorMessage(true); return false; } target->HandleEmote(emote); return true; } // TODO: NpcCommands that needs to be fixed : bool ChatHandler::HandleNpcAddWeaponCommand(char* /*args*/) { /*if (!*args) return false; ObjectGuid guid = m_session->GetPlayer()->GetSelectionGuid(); if (guid.IsEmpty()) { SendSysMessage(LANG_NO_SELECTION); return true; } Creature *pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid); if(!pCreature) { 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 = ObjectMgr::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: PSendSysMessage(LANG_ITEM_SLOT_NOT_EXIST,SlotID); added = false; break; } if(added) PSendSysMessage(LANG_ITEM_ADDED_TO_SLOT,ItemID,tmpItem->Name1,SlotID); } else { PSendSysMessage(LANG_ITEM_NOT_FOUND,ItemID); return true; } */ return true; } //---------------------------------------------------------- bool ChatHandler::HandleExploreCheatCommand(char* args) { if (!*args) { return false; } int flag = atoi(args); Player* chr = getSelectedPlayer(); if (chr == NULL) { SendSysMessage(LANG_NO_CHAR_SELECTED); SetSentErrorMessage(true); return false; } if (flag != 0) { PSendSysMessage(LANG_YOU_SET_EXPLORE_ALL, GetNameLink(chr).c_str()); if (needReportToTarget(chr)) { ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_ALL, GetNameLink().c_str()); } } else { PSendSysMessage(LANG_YOU_SET_EXPLORE_NOTHING, GetNameLink(chr).c_str()); if (needReportToTarget(chr)) { ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_NOTHING, GetNameLink().c_str()); } } for (uint8 i = 0; i < PLAYER_EXPLORED_ZONES_SIZE; ++i) { if (flag != 0) { m_session->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1 + i, 0xFFFFFFFF); } else { m_session->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1 + i, 0); } } return true; } void ChatHandler::HandleCharacterLevel(Player* player, ObjectGuid player_guid, uint32 oldlevel, uint32 newlevel) { if (player) { player->GiveLevel(newlevel); player->InitTalentForLevel(); player->SetUInt32Value(PLAYER_XP, 0); if (needReportToTarget(player)) { if (oldlevel == newlevel) { ChatHandler(player).PSendSysMessage(LANG_YOURS_LEVEL_PROGRESS_RESET, GetNameLink().c_str()); } else if (oldlevel < newlevel) { ChatHandler(player).PSendSysMessage(LANG_YOURS_LEVEL_UP, GetNameLink().c_str(), newlevel); } else // if(oldlevel > newlevel) { ChatHandler(player).PSendSysMessage(LANG_YOURS_LEVEL_DOWN, GetNameLink().c_str(), newlevel); } } } else { // update level and XP at level, all other will be updated at loading CharacterDatabase.PExecute("UPDATE characters SET level = '%u', xp = 0 WHERE guid = '%u'", newlevel, player_guid.GetCounter()); } } bool ChatHandler::HandleCharacterLevelCommand(char* args) { char* nameStr = ExtractOptNotLastArg(&args); int32 newlevel; bool nolevel = false; // exception opt second arg: .character level $name if (!ExtractInt32(&args, newlevel)) { if (!nameStr) { nameStr = ExtractArg(&args); if (!nameStr) { return false; } nolevel = true; } else { return false; } } Player* target; ObjectGuid target_guid; std::string target_name; if (!ExtractPlayerTarget(&nameStr, &target, &target_guid, &target_name)) { return false; } int32 oldlevel = target ? target->getLevel() : Player::GetLevelFromDB(target_guid); if (nolevel) { newlevel = oldlevel; } if (newlevel < 1) { return false; } // invalid level if (newlevel > STRONG_MAX_LEVEL) // hardcoded maximum level { newlevel = STRONG_MAX_LEVEL; } HandleCharacterLevel(target, target_guid, oldlevel, newlevel); if (!m_session || m_session->GetPlayer() != target) // including player==NULL { std::string nameLink = playerLink(target_name); PSendSysMessage(LANG_YOU_CHANGE_LVL, nameLink.c_str(), newlevel); } return true; } bool ChatHandler::HandleLevelUpCommand(char* args) { int32 addlevel = 1; char* nameStr = NULL; if (*args) { nameStr = ExtractOptNotLastArg(&args); // exception opt second arg: .levelup $name if (!ExtractInt32(&args, addlevel)) { if (!nameStr) { nameStr = ExtractArg(&args); } else { return false; } } } //add pet to levelup command if (m_session) { Creature* creatureTarget = getSelectedCreature(); Player* player = m_session->GetPlayer(); if (creatureTarget && creatureTarget->IsPet() && creatureTarget->GetOwner() && creatureTarget->GetOwner()->GetTypeId() == TYPEID_PLAYER) { Pet* petTarget = (Pet*)creatureTarget; if (petTarget->getPetType() == HUNTER_PET) { uint32 newPetLevel = petTarget->getLevel() + addlevel; if (newPetLevel <= player->getLevel()) { petTarget->GivePetLevel(newPetLevel); std::string nameLink = petLink(petTarget->GetName()); PSendSysMessage(LANG_YOU_CHANGE_LVL, nameLink.c_str(), newPetLevel); return true; } } return false; } } Player* target; ObjectGuid target_guid; std::string target_name; if (!ExtractPlayerTarget(&nameStr, &target, &target_guid, &target_name)) { return false; } int32 oldlevel = target ? target->getLevel() : Player::GetLevelFromDB(target_guid); int32 newlevel = oldlevel + addlevel; if (newlevel < 1) { newlevel = 1; } if (newlevel > STRONG_MAX_LEVEL) // hardcoded maximum level { newlevel = STRONG_MAX_LEVEL; } HandleCharacterLevel(target, target_guid, oldlevel, newlevel); if (!m_session || m_session->GetPlayer() != target) // including chr==NULL { std::string nameLink = playerLink(target_name); PSendSysMessage(LANG_YOU_CHANGE_LVL, nameLink.c_str(), newlevel); } return true; } bool ChatHandler::HandleShowAreaCommand(char* args) { if (!*args) { return false; } Player* chr = getSelectedPlayer(); if (chr == NULL) { SendSysMessage(LANG_NO_CHAR_SELECTED); SetSentErrorMessage(true); return false; } int area = GetAreaFlagByAreaID(atoi(args)); int offset = area / 32; uint32 val = (uint32)(1 << (area % 32)); if (area < 0 || offset >= PLAYER_EXPLORED_ZONES_SIZE) { SendSysMessage(LANG_BAD_VALUE); SetSentErrorMessage(true); return false; } uint32 currFields = chr->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset); chr->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields | val)); SendSysMessage(LANG_EXPLORE_AREA); return true; } bool ChatHandler::HandleHideAreaCommand(char* args) { if (!*args) { return false; } Player* chr = getSelectedPlayer(); if (chr == NULL) { SendSysMessage(LANG_NO_CHAR_SELECTED); SetSentErrorMessage(true); return false; } int area = GetAreaFlagByAreaID(atoi(args)); int offset = area / 32; uint32 val = (uint32)(1 << (area % 32)); if (area < 0 || offset >= PLAYER_EXPLORED_ZONES_SIZE) { SendSysMessage(LANG_BAD_VALUE); SetSentErrorMessage(true); return false; } uint32 currFields = chr->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset); chr->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields ^ val)); SendSysMessage(LANG_UNEXPLORE_AREA); return true; } bool ChatHandler::HandleAuctionAllianceCommand(char* /*args*/) { m_session->GetPlayer()->SetAuctionAccessMode(m_session->GetPlayer()->GetTeam() != ALLIANCE ? -1 : 0); m_session->SendAuctionHello(m_session->GetPlayer()); return true; } bool ChatHandler::HandleAuctionHordeCommand(char* /*args*/) { m_session->GetPlayer()->SetAuctionAccessMode(m_session->GetPlayer()->GetTeam() != HORDE ? -1 : 0); m_session->SendAuctionHello(m_session->GetPlayer()); return true; } bool ChatHandler::HandleAuctionGoblinCommand(char* /*args*/) { m_session->GetPlayer()->SetAuctionAccessMode(1); m_session->SendAuctionHello(m_session->GetPlayer()); return true; } bool ChatHandler::HandleAuctionCommand(char* /*args*/) { m_session->GetPlayer()->SetAuctionAccessMode(0); m_session->SendAuctionHello(m_session->GetPlayer()); return true; } bool ChatHandler::HandleAuctionItemCommand(char* args) { // format: (alliance|horde|goblin) item[:count] price [buyout] [short|long|verylong] char* typeStr = ExtractLiteralArg(&args); if (!typeStr) { return false; } uint32 houseid; if (strncmp(typeStr, "alliance", strlen(typeStr)) == 0) { houseid = 1; } else if (strncmp(typeStr, "horde", strlen(typeStr)) == 0) { houseid = 6; } else if (strncmp(typeStr, "goblin", strlen(typeStr)) == 0) { houseid = 7; } else { return false; } // parse item str char* itemStr = ExtractArg(&args); if (!itemStr) { return false; } uint32 item_id = 0; uint32 item_count = 1; if (sscanf(itemStr, "%u:%u", &item_id, &item_count) != 2) if (sscanf(itemStr, "%u", &item_id) != 1) { return false; } uint32 price; if (!ExtractUInt32(&args, price)) { return false; } uint32 buyout; if (!ExtractOptUInt32(&args, buyout, 0)) { return false; } uint32 etime = 4 * MIN_AUCTION_TIME; if (char* timeStr = ExtractLiteralArg(&args)) { if (strncmp(timeStr, "short", strlen(timeStr)) == 0) { etime = 1 * MIN_AUCTION_TIME; } else if (strncmp(timeStr, "long", strlen(timeStr)) == 0) { etime = 2 * MIN_AUCTION_TIME; } else if (strncmp(timeStr, "verylong", strlen(timeStr)) == 0) { etime = 4 * MIN_AUCTION_TIME; } else { return false; } } AuctionHouseEntry const* auctionHouseEntry = sAuctionHouseStore.LookupEntry(houseid); AuctionHouseObject* auctionHouse = sAuctionMgr.GetAuctionsMap(auctionHouseEntry); if (!item_id) { PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id); SetSentErrorMessage(true); return false; } ItemPrototype const* item_proto = ObjectMgr::GetItemPrototype(item_id); if (!item_proto) { PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id); SetSentErrorMessage(true); return false; } if (item_count < 1 || (item_proto->MaxCount > 0 && item_count > uint32(item_proto->MaxCount))) { PSendSysMessage(LANG_COMMAND_INVALID_ITEM_COUNT, item_count, item_id); SetSentErrorMessage(true); return false; } do { uint32 item_stack = item_count > item_proto->GetMaxStackSize() ? item_proto->GetMaxStackSize() : item_count; item_count -= item_stack; Item* newItem = Item::CreateItem(item_id, item_stack); MANGOS_ASSERT(newItem); auctionHouse->AddAuction(auctionHouseEntry, newItem, etime, price, buyout); } while (item_count); return true; } bool ChatHandler::HandleBankCommand(char* /*args*/) { m_session->SendShowBank(m_session->GetPlayer()->GetObjectGuid()); return true; } bool ChatHandler::HandleMailBoxCommand(char* /*args*/) { m_session->SendShowMailBox(m_session->GetPlayer()->GetObjectGuid()); return true; } bool ChatHandler::HandleStableCommand(char* /*args*/) { m_session->SendStablePet(m_session->GetPlayer()->GetObjectGuid()); return true; } bool ChatHandler::HandleChangeWeatherCommand(char* args) { // Weather is OFF if (!sWorld.getConfig(CONFIG_BOOL_WEATHER)) { SendSysMessage(LANG_WEATHER_DISABLED); SetSentErrorMessage(true); return false; } uint32 type; if (!ExtractUInt32(&args, type)) { return false; } // see enum WeatherType if (!Weather::IsValidWeatherType(type)) { return false; } float grade; if (!ExtractFloat(&args, grade)) { return false; } // clamp grade from 0 to 1 if (grade < 0.0f) grade = 0.0f; else if (grade > 1.0f) grade = 1.0f; Player* player = m_session->GetPlayer(); uint32 zoneId = player->GetZoneId(); if (!sWeatherMgr.GetWeatherChances(zoneId)) { SendSysMessage(LANG_NO_WEATHER); SetSentErrorMessage(true); } player->GetMap()->SetWeather(zoneId, (WeatherType)type, grade, false); return true; } bool ChatHandler::HandleTeleAddCommand(char* args) { if (!*args) { return false; } Player* player = m_session->GetPlayer(); if (!player) { return false; } std::string name = args; if (sObjectMgr.GetGameTele(name)) { SendSysMessage(LANG_COMMAND_TP_ALREADYEXIST); SetSentErrorMessage(true); return false; } GameTele tele; tele.position_x = player->GetPositionX(); tele.position_y = player->GetPositionY(); tele.position_z = player->GetPositionZ(); tele.orientation = player->GetOrientation(); tele.mapId = player->GetMapId(); tele.name = name; if (sObjectMgr.AddGameTele(tele)) { SendSysMessage(LANG_COMMAND_TP_ADDED); } else { SendSysMessage(LANG_COMMAND_TP_ADDEDERR); SetSentErrorMessage(true); return false; } return true; } bool ChatHandler::HandleTeleDelCommand(char* args) { if (!*args) { return false; } std::string name = args; if (!sObjectMgr.DeleteGameTele(name)) { SendSysMessage(LANG_COMMAND_TELE_NOTFOUND); SetSentErrorMessage(true); return false; } SendSysMessage(LANG_COMMAND_TP_DELETED); return true; } bool ChatHandler::HandleListAurasCommand(char* /*args*/) { Unit* unit = getSelectedUnit(); if (!unit) { SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); SetSentErrorMessage(true); return false; } char const* talentStr = GetMangosString(LANG_TALENT); char const* passiveStr = GetMangosString(LANG_PASSIVE); Unit::SpellAuraHolderMap const& uAuras = unit->GetSpellAuraHolderMap(); PSendSysMessage(LANG_COMMAND_TARGET_LISTAURAS, uAuras.size()); for (Unit::SpellAuraHolderMap::const_iterator itr = uAuras.begin(); itr != uAuras.end(); ++itr) { bool talent = GetTalentSpellCost(itr->second->GetId()) > 0; SpellAuraHolder* holder = itr->second; char const* name = holder->GetSpellProto()->SpellName[GetSessionDbcLocale()]; for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) { Aura* aur = holder->GetAuraByEffectIndex(SpellEffectIndex(i)); if (!aur) { continue; } if (m_session) { std::ostringstream ss_name; ss_name << "|cffffffff|Hspell:" << itr->second->GetId() << "|h[" << name << "]|h|r"; PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, holder->GetId(), aur->GetEffIndex(), aur->GetModifier()->m_auraname, aur->GetAuraDuration(), aur->GetAuraMaxDuration(), ss_name.str().c_str(), (holder->IsPassive() ? passiveStr : ""), (talent ? talentStr : ""), holder->GetCasterGuid().GetString().c_str()); } else { PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, holder->GetId(), aur->GetEffIndex(), aur->GetModifier()->m_auraname, aur->GetAuraDuration(), aur->GetAuraMaxDuration(), name, (holder->IsPassive() ? passiveStr : ""), (talent ? talentStr : ""), holder->GetCasterGuid().GetString().c_str()); } } } for (int i = 0; i < TOTAL_AURAS; ++i) { Unit::AuraList const& uAuraList = unit->GetAurasByType(AuraType(i)); if (uAuraList.empty()) { continue; } PSendSysMessage(LANG_COMMAND_TARGET_LISTAURATYPE, uAuraList.size(), i); for (Unit::AuraList::const_iterator itr = uAuraList.begin(); itr != uAuraList.end(); ++itr) { bool talent = GetTalentSpellCost((*itr)->GetId()) > 0; char const* name = (*itr)->GetSpellProto()->SpellName[GetSessionDbcLocale()]; if (m_session) { std::ostringstream ss_name; ss_name << "|cffffffff|Hspell:" << (*itr)->GetId() << "|h[" << name << "]|h|r"; PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(), ss_name.str().c_str(), ((*itr)->GetHolder()->IsPassive() ? passiveStr : ""), (talent ? talentStr : ""), (*itr)->GetCasterGuid().GetString().c_str()); } else { PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(), name, ((*itr)->GetHolder()->IsPassive() ? passiveStr : ""), (talent ? talentStr : ""), (*itr)->GetCasterGuid().GetString().c_str()); } } } return true; } bool ChatHandler::HandleListTalentsCommand(char* /*args*/) { Player* player = getSelectedPlayer(); if (!player) { SendSysMessage(LANG_NO_CHAR_SELECTED); SetSentErrorMessage(true); return false; } SendSysMessage(LANG_LIST_TALENTS_TITLE); uint32 count = 0; uint32 cost = 0; PlayerSpellMap const& uSpells = player->GetSpellMap(); for (PlayerSpellMap::const_iterator itr = uSpells.begin(); itr != uSpells.end(); ++itr) { if (itr->second.state == PLAYERSPELL_REMOVED || itr->second.disabled) { continue; } uint32 cost_itr = GetTalentSpellCost(itr->first); if (cost_itr == 0) { continue; } SpellEntry const* spellEntry = sSpellStore.LookupEntry(itr->first); if (!spellEntry) { continue; } ShowSpellListHelper(player, spellEntry, GetSessionDbcLocale()); ++count; cost += cost_itr; } PSendSysMessage(LANG_LIST_TALENTS_COUNT, count, cost); return true; } bool ChatHandler::HandleResetAchievementsCommand(char* args) { Player* target; ObjectGuid target_guid; if (!ExtractPlayerTarget(&args, &target, &target_guid)) return false; if (target) target->GetAchievementMgr().Reset(); else AchievementMgr::DeleteFromDB(target_guid); return true; } bool ChatHandler::HandleResetHonorCommand(char* args) { Player* target; if (!ExtractPlayerTarget(&args, &target)) { return false; } target->SetCurrencyCount(CURRENCY_HONOR_POINTS, 0); target->SetUInt32Value(PLAYER_FIELD_KILLS, 0); target->SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORBALE_KILLS, 0); target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL); return true; } static bool HandleResetStatsOrLevelHelper(Player* player) { ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(player->getClass()); if (!cEntry) { sLog.outError("Class %u not found in DBC (Wrong DBC files?)", player->getClass()); return false; } uint8 powertype = cEntry->powerType; // reset m_form if no aura if (!player->HasAuraType(SPELL_AURA_MOD_SHAPESHIFT)) { player->SetShapeshiftForm(FORM_NONE); } player->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE); player->SetFloatValue(UNIT_FIELD_COMBATREACH, 1.5f); player->setFactionForRace(player->getRace()); player->SetByteValue(UNIT_FIELD_BYTES_0, 3, powertype); // reset only if player not in some form; if (player->GetShapeshiftForm() == FORM_NONE) { player->InitDisplayIds(); } player->SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP); player->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); //-1 is default value player->SetInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, -1); // player->SetUInt32Value(PLAYER_FIELD_BYTES, 0xEEE00000 ); return true; } bool ChatHandler::HandleResetLevelCommand(char* args) { Player* target; if (!ExtractPlayerTarget(&args, &target)) { return false; } if (!HandleResetStatsOrLevelHelper(target)) { return false; } // set starting level uint32 start_level = target->getClass() != CLASS_DEATH_KNIGHT ? sWorld.getConfig(CONFIG_UINT32_START_PLAYER_LEVEL) : sWorld.getConfig(CONFIG_UINT32_START_HEROIC_PLAYER_LEVEL); target->_ApplyAllLevelScaleItemMods(false); target->SetLevel(start_level); target->InitRunes(); target->InitStatsForLevel(true); target->InitTaxiNodesForLevel(); target->InitGlyphsForLevel(); target->InitTalentForLevel(); target->SetUInt32Value(PLAYER_XP, 0); target->_ApplyAllLevelScaleItemMods(true); // reset level for pet if (Pet* pet = target->GetPet()) { pet->SynchronizeLevelWithOwner(); } return true; } bool ChatHandler::HandleResetStatsCommand(char* args) { Player* target; if (!ExtractPlayerTarget(&args, &target)) { return false; } if (!HandleResetStatsOrLevelHelper(target)) { return false; } target->InitRunes(); target->InitStatsForLevel(true); target->InitTaxiNodesForLevel(); target->InitGlyphsForLevel(); target->InitTalentForLevel(); return true; } bool ChatHandler::HandleResetSpellsCommand(char* args) { Player* target; ObjectGuid target_guid; std::string target_name; if (!ExtractPlayerTarget(&args, &target, &target_guid, &target_name)) { return false; } if (target) { target->resetSpells(); ChatHandler(target).SendSysMessage(LANG_RESET_SPELLS); if (!m_session || m_session->GetPlayer() != target) { PSendSysMessage(LANG_RESET_SPELLS_ONLINE, GetNameLink(target).c_str()); } } else { CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'", uint32(AT_LOGIN_RESET_SPELLS), target_guid.GetCounter()); PSendSysMessage(LANG_RESET_SPELLS_OFFLINE, target_name.c_str()); } return true; } bool ChatHandler::HandleResetSpecsCommand(char* args) { Player* target; ObjectGuid target_guid; std::string target_name; if (!ExtractPlayerTarget(&args, &target, &target_guid, &target_name)) { return false; } if (target) { target->resetTalents(true, true); target->SendTalentsInfoData(false); ChatHandler(target).SendSysMessage(LANG_RESET_TALENTS); if (!m_session || m_session->GetPlayer() != target) { PSendSysMessage(LANG_RESET_TALENTS_ONLINE, GetNameLink(target).c_str()); } Pet* pet = target->GetPet(); Pet::resetTalentsForAllPetsOf(target, pet); if (pet) target->SendTalentsInfoData(true); return true; } else if (target_guid) { uint32 at_flags = AT_LOGIN_RESET_TALENTS | AT_LOGIN_RESET_PET_TALENTS; CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'", at_flags, target_guid.GetCounter()); std::string nameLink = playerLink(target_name); PSendSysMessage(LANG_RESET_TALENTS_OFFLINE, nameLink.c_str()); return true; } SendSysMessage(LANG_NO_CHAR_SELECTED); SetSentErrorMessage(true); return false; } bool ChatHandler::HandleResetTalentsCommand(char* args) { Player* target; std::string target_name; if (!ExtractPlayerTarget(&args, &target, NULL, &target_name)) { // Try reset talents as Hunter Pet Creature* creature = getSelectedCreature(); if (!*args && creature && creature->IsPet()) { Unit* owner = creature->GetOwner(); if (owner && owner->GetTypeId() == TYPEID_PLAYER && ((Pet*)creature)->isControlled()) { ((Pet*)creature)->resetTalents(true); ((Player*)owner)->SendTalentsInfoData(true); ChatHandler((Player*)owner).SendSysMessage(LANG_RESET_PET_TALENTS); if (!m_session || m_session->GetPlayer() != ((Player*)owner)) PSendSysMessage(LANG_RESET_PET_TALENTS_ONLINE, GetNameLink((Player*)owner).c_str()); } return true; } SendSysMessage(LANG_NO_CHAR_SELECTED); SetSentErrorMessage(true); return false; } if (target) { target->resetTalents(true); target->SendTalentsInfoData(false); ChatHandler(target).SendSysMessage(LANG_RESET_TALENTS); if (!m_session || m_session->GetPlayer() != target) PSendSysMessage(LANG_RESET_TALENTS_ONLINE, GetNameLink(target).c_str()); Pet* pet = target->GetPet(); Pet::resetTalentsForAllPetsOf(target, pet); if (pet) target->SendTalentsInfoData(true); return true; } SendSysMessage(LANG_NO_CHAR_SELECTED); SetSentErrorMessage(true); return false; } bool ChatHandler::HandleResetAllCommand(char* args) { if (!*args) { return false; } std::string casename = args; AtLoginFlags atLogin; // Command specially created as single command to prevent using short case names if (casename == "spells") { atLogin = AT_LOGIN_RESET_SPELLS; sWorld.SendWorldText(LANG_RESETALL_SPELLS); if (!m_session) { SendSysMessage(LANG_RESETALL_SPELLS); } } else if (casename == "talents") { atLogin = AtLoginFlags(AT_LOGIN_RESET_TALENTS | AT_LOGIN_RESET_PET_TALENTS); sWorld.SendWorldText(LANG_RESETALL_TALENTS); if (!m_session) { SendSysMessage(LANG_RESETALL_TALENTS); } } else { PSendSysMessage(LANG_RESETALL_UNKNOWN_CASE, args); SetSentErrorMessage(true); return false; } CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE (at_login & '%u') = '0'", atLogin, atLogin); HashMapHolder::MapType const& plist = sObjectAccessor.GetPlayers(); for (HashMapHolder::MapType::const_iterator itr = plist.begin(); itr != plist.end(); ++itr) { itr->second->SetAtLoginFlag(atLogin); } return true; } bool ChatHandler::HandleServerShutDownCancelCommand(char* /*args*/) { sWorld.ShutdownCancel(); return true; } bool ChatHandler::HandleServerShutDownCommand(char* args) { uint32 delay; if (!ExtractUInt32(&args, delay)) return false; uint32 exitcode; if (!ExtractOptUInt32(&args, exitcode, SHUTDOWN_EXIT_CODE)) return false; // Exit code should be in range of 0-125, 126-255 is used // in many shells for their own return codes and code > 255 // is not supported in many others if (exitcode > 125) return false; sWorld.ShutdownServ(delay, 0, exitcode); return true; } bool ChatHandler::HandleServerRestartCommand(char* args) { uint32 delay; if (!ExtractUInt32(&args, delay)) return false; uint32 exitcode; if (!ExtractOptUInt32(&args, exitcode, RESTART_EXIT_CODE)) return false; // Exit code should be in range of 0-125, 126-255 is used // in many shells for their own return codes and code > 255 // is not supported in many others if (exitcode > 125) return false; sWorld.ShutdownServ(delay, SHUTDOWN_MASK_RESTART, exitcode); return true; } bool ChatHandler::HandleServerIdleRestartCommand(char* args) { uint32 delay; if (!ExtractUInt32(&args, delay)) return false; uint32 exitcode; if (!ExtractOptUInt32(&args, exitcode, RESTART_EXIT_CODE)) return false; // Exit code should be in range of 0-125, 126-255 is used // in many shells for their own return codes and code > 255 // is not supported in many others if (exitcode > 125) return false; sWorld.ShutdownServ(delay, SHUTDOWN_MASK_RESTART | SHUTDOWN_MASK_IDLE, exitcode); return true; } bool ChatHandler::HandleServerIdleShutDownCommand(char* args) { uint32 delay; if (!ExtractUInt32(&args, delay)) return false; uint32 exitcode; if (!ExtractOptUInt32(&args, exitcode, SHUTDOWN_EXIT_CODE)) return false; // Exit code should be in range of 0-125, 126-255 is used // in many shells for their own return codes and code > 255 // is not supported in many others if (exitcode > 125) return false; sWorld.ShutdownServ(delay, SHUTDOWN_MASK_IDLE, exitcode); return true; } bool ChatHandler::HandleQuestAddCommand(char* args) { Player* player = getSelectedPlayer(); if (!player) { SendSysMessage(LANG_NO_CHAR_SELECTED); SetSentErrorMessage(true); return false; } // .addquest #entry' // number or [name] Shift-click form |color|Hquest:quest_id:quest_level|h[name]|h|r uint32 entry; if (!ExtractUint32KeyFromLink(&args, "Hquest", entry)) { return false; } Quest const* pQuest = sObjectMgr.GetQuestTemplate(entry); if (!pQuest) { PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry); SetSentErrorMessage(true); return false; } // check item starting quest (it can work incorrectly if added without item in inventory) for (uint32 id = 0; id < sItemStorage.GetMaxEntry(); ++id) { ItemPrototype const* pProto = sItemStorage.LookupEntry(id); if (!pProto) { continue; } if (pProto->StartQuest == entry) { PSendSysMessage(LANG_COMMAND_QUEST_STARTFROMITEM, entry, pProto->ItemId); SetSentErrorMessage(true); return false; } } // ok, normal (creature/GO starting) quest if (player->CanAddQuest(pQuest, true)) { player->AddQuest(pQuest, NULL); if (player->CanCompleteQuest(entry)) { player->CompleteQuest(entry); } } return true; } bool ChatHandler::HandleQuestRemoveCommand(char* args) { Player* player = getSelectedPlayer(); if (!player) { SendSysMessage(LANG_NO_CHAR_SELECTED); SetSentErrorMessage(true); return false; } // .removequest #entry' // number or [name] Shift-click form |color|Hquest:quest_id:quest_level|h[name]|h|r uint32 entry; if (!ExtractUint32KeyFromLink(&args, "Hquest", entry)) { return false; } Quest const* pQuest = sObjectMgr.GetQuestTemplate(entry); if (!pQuest) { PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry); SetSentErrorMessage(true); return false; } // remove all quest entries for 'entry' from quest log for (uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot) { uint32 quest = player->GetQuestSlotQuestId(slot); if (quest == entry) { player->SetQuestSlot(slot, 0); // we ignore unequippable quest items in this case, its' still be equipped player->TakeQuestSourceItem(quest, false); } } // set quest status to not started (will updated in DB at next save) player->SetQuestStatus(entry, QUEST_STATUS_NONE); // reset rewarded for restart repeatable quest player->getQuestStatusMap()[entry].m_rewarded = false; SendSysMessage(LANG_COMMAND_QUEST_REMOVED); return true; } bool ChatHandler::HandleQuestCompleteCommand(char* args) { Player* player = getSelectedPlayer(); if (!player) { SendSysMessage(LANG_NO_CHAR_SELECTED); SetSentErrorMessage(true); return false; } // .quest complete #entry // number or [name] Shift-click form |color|Hquest:quest_id:quest_level|h[name]|h|r uint32 entry; if (!ExtractUint32KeyFromLink(&args, "Hquest", entry)) { return false; } Quest const* pQuest = sObjectMgr.GetQuestTemplate(entry); // If player doesn't have the quest if (!pQuest || player->GetQuestStatus(entry) == QUEST_STATUS_NONE) { PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry); SetSentErrorMessage(true); return false; } // Add quest items for quests that require items for (uint8 x = 0; x < QUEST_ITEM_OBJECTIVES_COUNT; ++x) { uint32 id = pQuest->ReqItemId[x]; uint32 count = pQuest->ReqItemCount[x]; if (!id || !count) { continue; } uint32 curItemCount = player->GetItemCount(id, true); ItemPosCountVec dest; uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, id, count - curItemCount); if (msg == EQUIP_ERR_OK) { Item* item = player->StoreNewItem(dest, id, true); player->SendNewItem(item, count - curItemCount, true, false); } } // All creature/GO slain/casted (not required, but otherwise it will display "Creature slain 0/10") for (uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i) { int32 creature = pQuest->ReqCreatureOrGOId[i]; uint32 creaturecount = pQuest->ReqCreatureOrGOCount[i]; if (uint32 spell_id = pQuest->ReqSpell[i]) { for (uint16 z = 0; z < creaturecount; ++z) { player->CastedCreatureOrGO(creature, ObjectGuid(), spell_id); } } else if (creature > 0) { if (CreatureInfo const* cInfo = ObjectMgr::GetCreatureTemplate(creature)) for (uint16 z = 0; z < creaturecount; ++z) { player->KilledMonster(cInfo, ObjectGuid()); } } else if (creature < 0) { for (uint16 z = 0; z < creaturecount; ++z) { player->CastedCreatureOrGO(-creature, ObjectGuid(), 0); } } } // If the quest requires reputation to complete if (uint32 repFaction = pQuest->GetRepObjectiveFaction()) { uint32 repValue = pQuest->GetRepObjectiveValue(); uint32 curRep = player->GetReputationMgr().GetReputation(repFaction); if (curRep < repValue) if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(repFaction)) { player->GetReputationMgr().SetReputation(factionEntry, repValue); } } // If the quest requires money int32 ReqOrRewMoney = pQuest->GetRewOrReqMoney(); if (ReqOrRewMoney < 0) { player->ModifyMoney(-ReqOrRewMoney); } for (int i = 0; i < QUEST_REQUIRED_CURRENCY_COUNT; ++i) { if (pQuest->ReqCurrencyId[i]) player->ModifyCurrencyCount(pQuest->ReqCurrencyId[i], int32(pQuest->ReqCurrencyCount[i] * GetCurrencyPrecision(pQuest->ReqCurrencyId[i]))); } if (uint32 spell = pQuest->GetReqSpellLearned()) player->learnSpell(spell, false); player->CompleteQuest(entry, QUEST_STATUS_FORCE_COMPLETE); return true; } bool ChatHandler::HandleBanAccountCommand(char* args) { return HandleBanHelper(BAN_ACCOUNT, args); } bool ChatHandler::HandleBanCharacterCommand(char* args) { return HandleBanHelper(BAN_CHARACTER, args); } bool ChatHandler::HandleBanIPCommand(char* args) { return HandleBanHelper(BAN_IP, args); } bool ChatHandler::HandleBanHelper(BanMode mode, char* args) { if (!*args) { return false; } char* cnameOrIP = ExtractArg(&args); if (!cnameOrIP) { return false; } std::string nameOrIP = cnameOrIP; char* duration = ExtractArg(&args); // time string if (!duration) { return false; } uint32 duration_secs = TimeStringToSecs(duration); char* reason = ExtractArg(&args); if (!reason) { return false; } switch (mode) { case BAN_ACCOUNT: if (!AccountMgr::normalizeString(nameOrIP)) { PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, nameOrIP.c_str()); SetSentErrorMessage(true); return false; } break; case BAN_CHARACTER: if (!normalizePlayerName(nameOrIP)) { SendSysMessage(LANG_PLAYER_NOT_FOUND); SetSentErrorMessage(true); return false; } break; case BAN_IP: if (!IsIPAddress(nameOrIP.c_str())) { return false; } break; } switch (sWorld.BanAccount(mode, nameOrIP, duration_secs, reason, m_session ? m_session->GetPlayerName() : "")) { case BAN_SUCCESS: if (duration_secs > 0) { PSendSysMessage(LANG_BAN_YOUBANNED, nameOrIP.c_str(), secsToTimeString(duration_secs, true).c_str(), reason); } else { PSendSysMessage(LANG_BAN_YOUPERMBANNED, nameOrIP.c_str(), reason); } break; case BAN_SYNTAX_ERROR: return false; case BAN_NOTFOUND: switch (mode) { default: PSendSysMessage(LANG_BAN_NOTFOUND, "account", nameOrIP.c_str()); break; case BAN_CHARACTER: PSendSysMessage(LANG_BAN_NOTFOUND, "character", nameOrIP.c_str()); break; case BAN_IP: PSendSysMessage(LANG_BAN_NOTFOUND, "ip", nameOrIP.c_str()); break; } SetSentErrorMessage(true); return false; } return true; } bool ChatHandler::HandleUnBanAccountCommand(char* args) { return HandleUnBanHelper(BAN_ACCOUNT, args); } bool ChatHandler::HandleUnBanCharacterCommand(char* args) { return HandleUnBanHelper(BAN_CHARACTER, args); } bool ChatHandler::HandleUnBanIPCommand(char* args) { return HandleUnBanHelper(BAN_IP, args); } bool ChatHandler::HandleUnBanHelper(BanMode mode, char* args) { if (!*args) { return false; } char* cnameOrIP = ExtractArg(&args); if (!cnameOrIP) { return false; } std::string nameOrIP = cnameOrIP; switch (mode) { case BAN_ACCOUNT: if (!AccountMgr::normalizeString(nameOrIP)) { PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, nameOrIP.c_str()); SetSentErrorMessage(true); return false; } break; case BAN_CHARACTER: if (!normalizePlayerName(nameOrIP)) { SendSysMessage(LANG_PLAYER_NOT_FOUND); SetSentErrorMessage(true); return false; } break; case BAN_IP: if (!IsIPAddress(nameOrIP.c_str())) { return false; } break; } if (sWorld.RemoveBanAccount(mode, nameOrIP)) { PSendSysMessage(LANG_UNBAN_UNBANNED, nameOrIP.c_str()); } else { PSendSysMessage(LANG_UNBAN_ERROR, nameOrIP.c_str()); } return true; } bool ChatHandler::HandleBanInfoAccountCommand(char* args) { if (!*args) { return false; } std::string account_name; uint32 accountid = ExtractAccountId(&args, &account_name); if (!accountid) { return false; } return HandleBanInfoHelper(accountid, account_name.c_str()); } bool ChatHandler::HandleBanInfoCharacterCommand(char* args) { Player* target; ObjectGuid target_guid; if (!ExtractPlayerTarget(&args, &target, &target_guid)) { return false; } uint32 accountid = target ? target->GetSession()->GetAccountId() : sObjectMgr.GetPlayerAccountIdByGUID(target_guid); std::string accountname; if (!sAccountMgr.GetName(accountid, accountname)) { PSendSysMessage(LANG_BANINFO_NOCHARACTER); return true; } return HandleBanInfoHelper(accountid, accountname.c_str()); } bool ChatHandler::HandleBanInfoHelper(uint32 accountid, char const* accountname) { QueryResult* result = LoginDatabase.PQuery("SELECT FROM_UNIXTIME(bandate), unbandate-bandate, active, unbandate,banreason,bannedby FROM account_banned WHERE id = '%u' ORDER BY bandate ASC", accountid); if (!result) { PSendSysMessage(LANG_BANINFO_NOACCOUNTBAN, accountname); return true; } PSendSysMessage(LANG_BANINFO_BANHISTORY, accountname); do { Field* fields = result->Fetch(); time_t unbandate = time_t(fields[3].GetUInt64()); bool active = false; if (fields[2].GetBool() && (fields[1].GetUInt64() == (uint64)0 || unbandate >= time(NULL))) { active = true; } bool permanent = (fields[1].GetUInt64() == (uint64)0); std::string bantime = permanent ? GetMangosString(LANG_BANINFO_INFINITE) : secsToTimeString(fields[1].GetUInt64(), true); PSendSysMessage(LANG_BANINFO_HISTORYENTRY, fields[0].GetString(), bantime.c_str(), active ? GetMangosString(LANG_BANINFO_YES) : GetMangosString(LANG_BANINFO_NO), fields[4].GetString(), fields[5].GetString()); } while (result->NextRow()); delete result; return true; } bool ChatHandler::HandleBanInfoIPCommand(char* args) { if (!*args) { return false; } char* cIP = ExtractQuotedOrLiteralArg(&args); if (!cIP) { return false; } if (!IsIPAddress(cIP)) { return false; } std::string IP = cIP; LoginDatabase.escape_string(IP); QueryResult* result = LoginDatabase.PQuery("SELECT ip, FROM_UNIXTIME(bandate), FROM_UNIXTIME(unbandate), unbandate-UNIX_TIMESTAMP(), banreason,bannedby,unbandate-bandate FROM ip_banned WHERE ip = '%s'", IP.c_str()); if (!result) { PSendSysMessage(LANG_BANINFO_NOIP); return true; } Field* fields = result->Fetch(); bool permanent = !fields[6].GetUInt64(); PSendSysMessage(LANG_BANINFO_IPENTRY, fields[0].GetString(), fields[1].GetString(), permanent ? GetMangosString(LANG_BANINFO_NEVER) : fields[2].GetString(), permanent ? GetMangosString(LANG_BANINFO_INFINITE) : secsToTimeString(fields[3].GetUInt64(), true).c_str(), fields[4].GetString(), fields[5].GetString()); delete result; return true; } bool ChatHandler::HandleBanListCharacterCommand(char* args) { LoginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); char* cFilter = ExtractLiteralArg(&args); if (!cFilter) { return false; } std::string filter = cFilter; LoginDatabase.escape_string(filter); QueryResult* result = CharacterDatabase.PQuery("SELECT account FROM characters WHERE name " _LIKE_ " " _CONCAT3_("'%%'", "'%s'", "'%%'"), filter.c_str()); if (!result) { PSendSysMessage(LANG_BANLIST_NOCHARACTER); return true; } return HandleBanListHelper(result); } bool ChatHandler::HandleBanListAccountCommand(char* args) { LoginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); char* cFilter = ExtractLiteralArg(&args); std::string filter = cFilter ? cFilter : ""; LoginDatabase.escape_string(filter); QueryResult* result; if (filter.empty()) { result = LoginDatabase.Query("SELECT account.id, username FROM account, account_banned" " WHERE account.id = account_banned.id AND active = 1 GROUP BY account.id"); } else { result = LoginDatabase.PQuery("SELECT account.id, username FROM account, account_banned" " WHERE account.id = account_banned.id AND active = 1 AND username " _LIKE_ " " _CONCAT3_("'%%'", "'%s'", "'%%'")" GROUP BY account.id", filter.c_str()); } if (!result) { PSendSysMessage(LANG_BANLIST_NOACCOUNT); return true; } return HandleBanListHelper(result); } bool ChatHandler::HandleBanListHelper(QueryResult* result) { PSendSysMessage(LANG_BANLIST_MATCHINGACCOUNT); // Chat short output if (m_session) { do { Field* fields = result->Fetch(); uint32 accountid = fields[0].GetUInt32(); QueryResult* banresult = LoginDatabase.PQuery("SELECT account.username FROM account,account_banned WHERE account_banned.id='%u' AND account_banned.id=account.id", accountid); if (banresult) { Field* fields2 = banresult->Fetch(); PSendSysMessage("%s", fields2[0].GetString()); delete banresult; } } while (result->NextRow()); } // Console wide output else { SendSysMessage(LANG_BANLIST_ACCOUNTS); SendSysMessage("==============================================================================="); SendSysMessage(LANG_BANLIST_ACCOUNTS_HEADER); do { SendSysMessage("-------------------------------------------------------------------------------"); Field* fields = result->Fetch(); uint32 account_id = fields[0].GetUInt32(); std::string account_name; // "account" case, name can be get in same query if (result->GetFieldCount() > 1) { account_name = fields[1].GetCppString(); } // "character" case, name need extract from another DB else { sAccountMgr.GetName(account_id, account_name); } // No SQL injection. id is uint32. QueryResult* banInfo = LoginDatabase.PQuery("SELECT bandate,unbandate,bannedby,banreason FROM account_banned WHERE id = %u ORDER BY unbandate", account_id); if (banInfo) { Field* fields2 = banInfo->Fetch(); do { time_t t_ban = fields2[0].GetUInt64(); tm* aTm_ban = localtime(&t_ban); if (fields2[0].GetUInt64() == fields2[1].GetUInt64()) { PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|", account_name.c_str(), aTm_ban->tm_year % 100, aTm_ban->tm_mon + 1, aTm_ban->tm_mday, aTm_ban->tm_hour, aTm_ban->tm_min, fields2[2].GetString(), fields2[3].GetString()); } else { time_t t_unban = fields2[1].GetUInt64(); tm* aTm_unban = localtime(&t_unban); PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|", account_name.c_str(), aTm_ban->tm_year % 100, aTm_ban->tm_mon + 1, aTm_ban->tm_mday, aTm_ban->tm_hour, aTm_ban->tm_min, aTm_unban->tm_year % 100, aTm_unban->tm_mon + 1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min, fields2[2].GetString(), fields2[3].GetString()); } } while (banInfo->NextRow()); delete banInfo; } } while (result->NextRow()); SendSysMessage("==============================================================================="); } delete result; return true; } bool ChatHandler::HandleBanListIPCommand(char* args) { LoginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); char* cFilter = ExtractLiteralArg(&args); std::string filter = cFilter ? cFilter : ""; LoginDatabase.escape_string(filter); QueryResult* result; if (filter.empty()) { result = LoginDatabase.Query("SELECT ip,bandate,unbandate,bannedby,banreason FROM ip_banned" " WHERE (bandate=unbandate OR unbandate>UNIX_TIMESTAMP())" " ORDER BY unbandate"); } else { result = LoginDatabase.PQuery("SELECT ip,bandate,unbandate,bannedby,banreason FROM ip_banned" " WHERE (bandate=unbandate OR unbandate>UNIX_TIMESTAMP()) AND ip " _LIKE_ " " _CONCAT3_("'%%'", "'%s'", "'%%'") " ORDER BY unbandate", filter.c_str()); } if (!result) { PSendSysMessage(LANG_BANLIST_NOIP); return true; } PSendSysMessage(LANG_BANLIST_MATCHINGIP); // Chat short output if (m_session) { do { Field* fields = result->Fetch(); PSendSysMessage("%s", fields[0].GetString()); } while (result->NextRow()); } // Console wide output else { SendSysMessage(LANG_BANLIST_IPS); SendSysMessage("==============================================================================="); SendSysMessage(LANG_BANLIST_IPS_HEADER); do { SendSysMessage("-------------------------------------------------------------------------------"); Field* fields = result->Fetch(); time_t t_ban = fields[1].GetUInt64(); tm* aTm_ban = localtime(&t_ban); if (fields[1].GetUInt64() == fields[2].GetUInt64()) { PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|", fields[0].GetString(), aTm_ban->tm_year % 100, aTm_ban->tm_mon + 1, aTm_ban->tm_mday, aTm_ban->tm_hour, aTm_ban->tm_min, fields[3].GetString(), fields[4].GetString()); } else { time_t t_unban = fields[2].GetUInt64(); tm* aTm_unban = localtime(&t_unban); PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|", fields[0].GetString(), aTm_ban->tm_year % 100, aTm_ban->tm_mon + 1, aTm_ban->tm_mday, aTm_ban->tm_hour, aTm_ban->tm_min, aTm_unban->tm_year % 100, aTm_unban->tm_mon + 1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min, fields[3].GetString(), fields[4].GetString()); } } while (result->NextRow()); SendSysMessage("==============================================================================="); } delete result; return true; } bool ChatHandler::HandleRespawnCommand(char* /*args*/) { Player* pl = m_session->GetPlayer(); // accept only explicitly selected target (not implicitly self targeting case) Unit* target = getSelectedUnit(); if (pl->GetSelectionGuid() && target) { if (target->GetTypeId() != TYPEID_UNIT) { SendSysMessage(LANG_SELECT_CREATURE); SetSentErrorMessage(true); return false; } if (target->IsDead()) { ((Creature*)target)->Respawn(); } return true; } MaNGOS::RespawnDo u_do; MaNGOS::WorldObjectWorker worker(pl, u_do); Cell::VisitGridObjects(pl, worker, pl->GetMap()->GetVisibilityDistance()); return true; } bool ChatHandler::HandleGMFlyCommand(char* args) { bool value; if (!ExtractOnOff(&args, value)) { SendSysMessage(LANG_USE_BOL); SetSentErrorMessage(true); return false; } Player* target = getSelectedPlayer(); if (!target) { target = m_session->GetPlayer(); } target->SetCanFly(value); PSendSysMessage(LANG_COMMAND_FLYMODE_STATUS, GetNameLink(target).c_str(), args); return true; } bool ChatHandler::HandlePDumpLoadCommand(char* args) { char* file = ExtractQuotedOrLiteralArg(&args); if (!file) { return false; } std::string account_name; uint32 account_id = ExtractAccountId(&args, &account_name); if (!account_id) { return false; } char* name_str = ExtractLiteralArg(&args); uint32 lowguid = 0; std::string name; if (name_str) { name = name_str; // normalize the name if specified and check if it exists if (!normalizePlayerName(name)) { PSendSysMessage(LANG_INVALID_CHARACTER_NAME); SetSentErrorMessage(true); return false; } if (ObjectMgr::CheckPlayerName(name, true) != CHAR_NAME_SUCCESS) { PSendSysMessage(LANG_INVALID_CHARACTER_NAME); SetSentErrorMessage(true); return false; } if (*args) { if (!ExtractUInt32(&args, lowguid)) { return false; } if (!lowguid) { PSendSysMessage(LANG_INVALID_CHARACTER_GUID); SetSentErrorMessage(true); return false; } ObjectGuid guid = ObjectGuid(HIGHGUID_PLAYER, lowguid); if (sObjectMgr.GetPlayerAccountIdByGUID(guid)) { PSendSysMessage(LANG_CHARACTER_GUID_IN_USE, lowguid); SetSentErrorMessage(true); return false; } } } switch (PlayerDumpReader().LoadDump(file, account_id, name, lowguid)) { case DUMP_SUCCESS: PSendSysMessage(LANG_COMMAND_IMPORT_SUCCESS); break; case DUMP_FILE_OPEN_ERROR: PSendSysMessage(LANG_FILE_OPEN_FAIL, file); SetSentErrorMessage(true); return false; case DUMP_FILE_BROKEN: PSendSysMessage(LANG_DUMP_BROKEN, file); SetSentErrorMessage(true); return false; case DUMP_TOO_MANY_CHARS: PSendSysMessage(LANG_ACCOUNT_CHARACTER_LIST_FULL, account_name.c_str(), account_id); SetSentErrorMessage(true); return false; default: PSendSysMessage(LANG_COMMAND_IMPORT_FAILED); SetSentErrorMessage(true); return false; } return true; } bool ChatHandler::HandlePDumpWriteCommand(char* args) { if (!*args) { return false; } char* file = ExtractQuotedOrLiteralArg(&args); if (!file) { return false; } char* p2 = ExtractLiteralArg(&args); uint32 lowguid; ObjectGuid guid; // character name can't start from number if (!ExtractUInt32(&p2, lowguid)) { std::string name = ExtractPlayerNameFromLink(&p2); if (name.empty()) { SendSysMessage(LANG_PLAYER_NOT_FOUND); SetSentErrorMessage(true); return false; } guid = sObjectMgr.GetPlayerGuidByName(name); if (!guid) { PSendSysMessage(LANG_PLAYER_NOT_FOUND); SetSentErrorMessage(true); return false; } lowguid = guid.GetCounter(); } else { guid = ObjectGuid(HIGHGUID_PLAYER, lowguid); } if (!sObjectMgr.GetPlayerAccountIdByGUID(guid)) { PSendSysMessage(LANG_PLAYER_NOT_FOUND); SetSentErrorMessage(true); return false; } switch (PlayerDumpWriter().WriteDump(file, lowguid)) { case DUMP_SUCCESS: PSendSysMessage(LANG_COMMAND_EXPORT_SUCCESS); break; case DUMP_FILE_OPEN_ERROR: PSendSysMessage(LANG_FILE_OPEN_FAIL, file); SetSentErrorMessage(true); return false; default: PSendSysMessage(LANG_COMMAND_EXPORT_FAILED); SetSentErrorMessage(true); return false; } return true; } bool ChatHandler::HandleMovegensCommand(char* /*args*/) { Unit* unit = getSelectedUnit(); if (!unit) { SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); SetSentErrorMessage(true); return false; } PSendSysMessage(LANG_MOVEGENS_LIST, (unit->GetTypeId() == TYPEID_PLAYER ? "Player" : "Creature"), unit->GetGUIDLow()); MotionMaster* mm = unit->GetMotionMaster(); float x, y, z; mm->GetDestination(x, y, z); for (MotionMaster::const_iterator itr = mm->begin(); itr != mm->end(); ++itr) { switch ((*itr)->GetMovementGeneratorType()) { case IDLE_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_IDLE); break; case RANDOM_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_RANDOM); break; case WAYPOINT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_WAYPOINT); break; case CONFUSED_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_CONFUSED); break; case CHASE_MOTION_TYPE: { Unit* target = NULL; if (unit->GetTypeId() == TYPEID_PLAYER) { target = static_cast const*>(*itr)->GetTarget(); } else { target = static_cast const*>(*itr)->GetTarget(); } if (!target) { SendSysMessage(LANG_MOVEGENS_CHASE_NULL); } else if (target->GetTypeId() == TYPEID_PLAYER) { PSendSysMessage(LANG_MOVEGENS_CHASE_PLAYER, target->GetName(), target->GetGUIDLow()); } else { PSendSysMessage(LANG_MOVEGENS_CHASE_CREATURE, target->GetName(), target->GetGUIDLow()); } break; } case FOLLOW_MOTION_TYPE: { Unit* target = NULL; if (unit->GetTypeId() == TYPEID_PLAYER) { target = static_cast const*>(*itr)->GetTarget(); } else { target = static_cast const*>(*itr)->GetTarget(); } if (!target) { SendSysMessage(LANG_MOVEGENS_FOLLOW_NULL); } else if (target->GetTypeId() == TYPEID_PLAYER) { PSendSysMessage(LANG_MOVEGENS_FOLLOW_PLAYER, target->GetName(), target->GetGUIDLow()); } else { PSendSysMessage(LANG_MOVEGENS_FOLLOW_CREATURE, target->GetName(), target->GetGUIDLow()); } break; } case HOME_MOTION_TYPE: if (unit->GetTypeId() == TYPEID_UNIT) { PSendSysMessage(LANG_MOVEGENS_HOME_CREATURE, x, y, z); } else { SendSysMessage(LANG_MOVEGENS_HOME_PLAYER); } break; case FLIGHT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_FLIGHT); break; case POINT_MOTION_TYPE: { PSendSysMessage(LANG_MOVEGENS_POINT, x, y, z); break; } case FLEEING_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_FEAR); break; case DISTRACT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_DISTRACT); break; case EFFECT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_EFFECT); break; default: PSendSysMessage(LANG_MOVEGENS_UNKNOWN, (*itr)->GetMovementGeneratorType()); break; } } return true; } bool ChatHandler::HandleServerPLimitCommand(char* args) { if (*args) { char* param = ExtractLiteralArg(&args); if (!param) { return false; } int l = strlen(param); int val; if (strncmp(param, "player", l) == 0) { sWorld.SetPlayerLimit(-SEC_PLAYER); } else if (strncmp(param, "moderator", l) == 0) { sWorld.SetPlayerLimit(-SEC_MODERATOR); } else if (strncmp(param, "gamemaster", l) == 0) { sWorld.SetPlayerLimit(-SEC_GAMEMASTER); } else if (strncmp(param, "administrator", l) == 0) { sWorld.SetPlayerLimit(-SEC_ADMINISTRATOR); } else if (strncmp(param, "reset", l) == 0) { sWorld.SetPlayerLimit(sConfig.GetIntDefault("PlayerLimit", DEFAULT_PLAYER_LIMIT)); } else if (ExtractInt32(¶m, val)) { if (val < -SEC_ADMINISTRATOR) { val = -SEC_ADMINISTRATOR; } sWorld.SetPlayerLimit(val); } else { return false; } // kick all low security level players if (sWorld.GetPlayerAmountLimit() > SEC_PLAYER) { sWorld.KickAllLess(sWorld.GetPlayerSecurityLimit()); } } uint32 pLimit = sWorld.GetPlayerAmountLimit(); AccountTypes allowedAccountType = sWorld.GetPlayerSecurityLimit(); char const* secName = ""; switch (allowedAccountType) { case SEC_PLAYER: secName = "Player"; break; case SEC_MODERATOR: secName = "Moderator"; break; case SEC_GAMEMASTER: secName = "Gamemaster"; break; case SEC_ADMINISTRATOR: secName = "Administrator"; break; default: secName = ""; break; } PSendSysMessage("Player limits: amount %u, min. security level %s.", pLimit, secName); return true; } bool ChatHandler::HandleCastCommand(char* args) { if (!*args) { return false; } Unit* target = getSelectedUnit(); if (!target) { SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); SetSentErrorMessage(true); return false; } // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form uint32 spell = ExtractSpellIdFromLink(&args); if (!spell) { return false; } SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell); if (!spellInfo) { return false; } if (!SpellMgr::IsSpellValid(spellInfo, m_session->GetPlayer())) { PSendSysMessage(LANG_COMMAND_SPELL_BROKEN, spell); SetSentErrorMessage(true); return false; } bool triggered = ExtractLiteralArg(&args, "triggered") != NULL; if (!triggered && *args) // can be fail also at syntax error { return false; } m_session->GetPlayer()->CastSpell(target, spell, triggered); return true; } bool ChatHandler::HandleCastBackCommand(char* args) { Creature* caster = getSelectedCreature(); if (!caster) { SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); SetSentErrorMessage(true); return false; } // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form uint32 spell = ExtractSpellIdFromLink(&args); if (!spell || !sSpellStore.LookupEntry(spell)) { return false; } bool triggered = ExtractLiteralArg(&args, "triggered") != NULL; if (!triggered && *args) // can be fail also at syntax error { return false; } caster->SetFacingToObject(m_session->GetPlayer()); caster->CastSpell(m_session->GetPlayer(), spell, triggered); return true; } bool ChatHandler::HandleCastDistCommand(char* args) { if (!*args) { return false; } // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form uint32 spell = ExtractSpellIdFromLink(&args); if (!spell) { return false; } SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell); if (!spellInfo) { return false; } if (!SpellMgr::IsSpellValid(spellInfo, m_session->GetPlayer())) { PSendSysMessage(LANG_COMMAND_SPELL_BROKEN, spell); SetSentErrorMessage(true); return false; } float dist; if (!ExtractFloat(&args, dist)) { return false; } bool triggered = ExtractLiteralArg(&args, "triggered") != NULL; if (!triggered && *args) // can be fail also at syntax error { return false; } float x, y, z; m_session->GetPlayer()->GetClosePoint(x, y, z, dist); m_session->GetPlayer()->CastSpell(x, y, z, spell, triggered); return true; } bool ChatHandler::HandleCastTargetCommand(char* args) { Creature* caster = getSelectedCreature(); if (!caster) { SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); SetSentErrorMessage(true); return false; } if (!caster->getVictim()) { SendSysMessage(LANG_SELECTED_TARGET_NOT_HAVE_VICTIM); SetSentErrorMessage(true); return false; } // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form uint32 spell = ExtractSpellIdFromLink(&args); if (!spell || !sSpellStore.LookupEntry(spell)) { return false; } bool triggered = ExtractLiteralArg(&args, "triggered") != NULL; if (!triggered && *args) // can be fail also at syntax error { return false; } caster->SetFacingToObject(m_session->GetPlayer()); caster->CastSpell(caster->getVictim(), spell, triggered); return true; } /* ComeToMe command REQUIRED for 3rd party scripting library to have access to PointMovementGenerator Without this function 3rd party scripting library will get linking errors (unresolved external) when attempting to use the PointMovementGenerator */ bool ChatHandler::HandleComeToMeCommand(char* /*args*/) { Creature* caster = getSelectedCreature(); if (!caster) { SendSysMessage(LANG_SELECT_CREATURE); SetSentErrorMessage(true); return false; } Player* pl = m_session->GetPlayer(); caster->GetMotionMaster()->MovePoint(0, pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ()); return true; } bool ChatHandler::HandleCastSelfCommand(char* args) { if (!*args) { return false; } Unit* target = getSelectedUnit(); if (!target) { SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); SetSentErrorMessage(true); return false; } // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form uint32 spell = ExtractSpellIdFromLink(&args); if (!spell) { return false; } SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell); if (!spellInfo) { return false; } if (!SpellMgr::IsSpellValid(spellInfo, m_session->GetPlayer())) { PSendSysMessage(LANG_COMMAND_SPELL_BROKEN, spell); SetSentErrorMessage(true); return false; } bool triggered = ExtractLiteralArg(&args, "triggered") != NULL; if (!triggered && *args) // can be fail also at syntax error { return false; } target->CastSpell(target, spell, triggered); return true; } bool ChatHandler::HandleInstanceListBindsCommand(char* /*args*/) { Player* player = getSelectedPlayer(); if (!player) { player = m_session->GetPlayer(); } uint32 counter = 0; for (uint8 i = 0; i < MAX_DIFFICULTY; ++i) { Player::BoundInstancesMap& binds = player->GetBoundInstances(Difficulty(i)); for (Player::BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end(); ++itr) { DungeonPersistentState* state = itr->second.state; std::string timeleft = secsToTimeString(state->GetResetTime() - time(NULL), true); if (const MapEntry* entry = sMapStore.LookupEntry(itr->first)) { PSendSysMessage("map: %d (%s) inst: %d perm: %s diff: %d canReset: %s TTR: %s", itr->first, entry->name[GetSessionDbcLocale()], state->GetInstanceId(), itr->second.perm ? "yes" : "no", state->GetDifficulty(), state->CanReset() ? "yes" : "no", timeleft.c_str()); } else PSendSysMessage("bound for a nonexistent map %u", itr->first); ++counter; } } PSendSysMessage("player binds: %d", counter); counter = 0; if (Group* group = player->GetGroup()) { for (uint8 i = 0; i < MAX_DIFFICULTY; ++i) { Group::BoundInstancesMap& binds = group->GetBoundInstances(Difficulty(i)); for (Group::BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end(); ++itr) { DungeonPersistentState* state = itr->second.state; std::string timeleft = secsToTimeString(state->GetResetTime() - time(NULL), true); if (const MapEntry* entry = sMapStore.LookupEntry(itr->first)) { PSendSysMessage("map: %d (%s) inst: %d perm: %s diff: %d canReset: %s TTR: %s", itr->first, entry->name[GetSessionDbcLocale()], state->GetInstanceId(), itr->second.perm ? "yes" : "no", state->GetDifficulty(), state->CanReset() ? "yes" : "no", timeleft.c_str()); } else PSendSysMessage("bound for a nonexistent map %u", itr->first); ++counter; } } } PSendSysMessage("group binds: %d", counter); return true; } bool ChatHandler::HandleInstanceUnbindCommand(char* args) { if (!*args) { return false; } Player* player = getSelectedPlayer(); if (!player) { player = m_session->GetPlayer(); } uint32 counter = 0; uint32 mapid = 0; bool got_map = false; if (strncmp(args, "all", strlen(args)) != 0) { if (!isNumeric(args[0])) { return false; } got_map = true; mapid = atoi(args); } for (uint8 i = 0; i < MAX_DIFFICULTY; ++i) { Player::BoundInstancesMap& binds = player->GetBoundInstances(Difficulty(i)); for (Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end();) { if (got_map && mapid != itr->first) { ++itr; continue; } if (itr->first != player->GetMapId()) { DungeonPersistentState* save = itr->second.state; std::string timeleft = secsToTimeString(save->GetResetTime() - time(NULL), true); if (const MapEntry* entry = sMapStore.LookupEntry(itr->first)) { PSendSysMessage("unbinding map: %d (%s) inst: %d perm: %s diff: %d canReset: %s TTR: %s", itr->first, entry->name[GetSessionDbcLocale()], save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str()); } else PSendSysMessage("bound for a nonexistent map %u", itr->first); player->UnbindInstance(itr, Difficulty(i)); ++counter; } else ++itr; } } PSendSysMessage("instances unbound: %d", counter); return true; } bool ChatHandler::HandleInstanceStatsCommand(char* /*args*/) { PSendSysMessage("instances loaded: %d", sMapMgr.GetNumInstances()); PSendSysMessage("players in instances: %d", sMapMgr.GetNumPlayersInInstances()); uint32 numSaves, numBoundPlayers, numBoundGroups; sMapPersistentStateMgr.GetStatistics(numSaves, numBoundPlayers, numBoundGroups); PSendSysMessage("instance saves: %d", numSaves); PSendSysMessage("players bound: %d", numBoundPlayers); PSendSysMessage("groups bound: %d", numBoundGroups); return true; } bool ChatHandler::HandleInstanceSaveDataCommand(char* /*args*/) { Player* pl = m_session->GetPlayer(); Map* map = pl->GetMap(); InstanceData* iData = map->GetInstanceData(); if (!iData) { PSendSysMessage("Map has no instance data."); SetSentErrorMessage(true); return false; } iData->SaveToDB(); return true; } /// Display the list of GMs bool ChatHandler::HandleGMListFullCommand(char* /*args*/) { ///- Get the accounts with GM Level >0 QueryResult* result = LoginDatabase.Query("SELECT username,gmlevel FROM account WHERE gmlevel > 0"); if (result) { SendSysMessage(LANG_GMLIST); SendSysMessage("========================"); SendSysMessage(LANG_GMLIST_HEADER); SendSysMessage("========================"); ///- Circle through them. Display username and GM level do { Field* fields = result->Fetch(); PSendSysMessage("|%15s|%6s|", fields[0].GetString(), fields[1].GetString()); } while (result->NextRow()); PSendSysMessage("========================"); delete result; } else { PSendSysMessage(LANG_GMLIST_EMPTY); } return true; } /// Define the 'Message of the day' for the realm bool ChatHandler::HandleServerSetMotdCommand(char* args) { sWorld.SetMotd(args); PSendSysMessage(LANG_MOTD_NEW, args); return true; } bool ChatHandler::ShowPlayerListHelper(QueryResult* result, uint32* limit, bool title, bool error) { if (!result) { if (error) { PSendSysMessage(LANG_NO_PLAYERS_FOUND); SetSentErrorMessage(true); } return false; } if (!m_session && title) { SendSysMessage(LANG_CHARACTERS_LIST_BAR); SendSysMessage(LANG_CHARACTERS_LIST_HEADER); SendSysMessage(LANG_CHARACTERS_LIST_BAR); } if (result) { ///- Circle through them. Display username and GM level do { // check limit if (limit) { if (*limit == 0) { break; } --*limit; } Field* fields = result->Fetch(); uint32 guid = fields[0].GetUInt32(); std::string name = fields[1].GetCppString(); uint8 race = fields[2].GetUInt8(); uint8 class_ = fields[3].GetUInt8(); uint32 level = fields[4].GetUInt32(); ChrRacesEntry const* raceEntry = sChrRacesStore.LookupEntry(race); ChrClassesEntry const* classEntry = sChrClassesStore.LookupEntry(class_); char const* race_name = raceEntry ? raceEntry->name[GetSessionDbcLocale()] : ""; char const* class_name = classEntry ? classEntry->name[GetSessionDbcLocale()] : ""; if (!m_session) { PSendSysMessage(LANG_CHARACTERS_LIST_LINE_CONSOLE, guid, name.c_str(), race_name, class_name, level); } else { PSendSysMessage(LANG_CHARACTERS_LIST_LINE_CHAT, guid, name.c_str(), name.c_str(), race_name, class_name, level); } } while (result->NextRow()); delete result; } if (!m_session) { SendSysMessage(LANG_CHARACTERS_LIST_BAR); } return true; } /// Output list of character for account bool ChatHandler::HandleAccountCharactersCommand(char* args) { ///- Get the command line arguments std::string account_name; Player* target = NULL; // only for triggering use targeted player account uint32 account_id = ExtractAccountId(&args, &account_name, &target); if (!account_id) { return false; } ///- Get the characters for account id QueryResult* result = CharacterDatabase.PQuery("SELECT guid, name, race, class, level FROM characters WHERE account = %u", account_id); return ShowPlayerListHelper(result); } /// Set/Unset the expansion level for an account bool ChatHandler::HandleAccountSetAddonCommand(char* args) { ///- Get the command line arguments char* accountStr = ExtractOptNotLastArg(&args); std::string account_name; uint32 account_id = ExtractAccountId(&accountStr, &account_name); if (!account_id) { return false; } // Let set addon state only for lesser (strong) security level // or to self account if (GetAccountId() && GetAccountId() != account_id && HasLowerSecurityAccount(NULL, account_id, true)) { return false; } uint32 lev; if (!ExtractUInt32(&args, lev)) { return false; } // No SQL injection LoginDatabase.PExecute("UPDATE account SET expansion = '%u' WHERE id = '%u'", lev, account_id); PSendSysMessage(LANG_ACCOUNT_SETADDON, account_name.c_str(), account_id, lev); return true; } bool ChatHandler::HandleSendMailHelper(MailDraft& draft, char* args) { // format: "subject text" "mail text" std::string msgSubject = ExtractQuotedArg(&args); if (msgSubject.empty()) { return false; } std::string msgText = ExtractQuotedArg(&args); if (msgText.empty()) { return false; } // msgSubject, msgText isn't NUL after prev. check draft.SetSubjectAndBody(msgSubject, msgText); return true; } bool ChatHandler::HandleSendMassMailCommand(char* args) { // format: raceMask "subject text" "mail text" uint32 raceMask = 0; char const* name = NULL; if (!ExtractRaceMask(&args, raceMask, &name)) { return false; } // need dynamic object because it trasfered to mass mailer MailDraft* draft = new MailDraft; // fill mail if (!HandleSendMailHelper(*draft, args)) { delete draft; return false; } // from console show nonexistent sender MailSender sender(MAIL_NORMAL, m_session ? m_session->GetPlayer()->GetObjectGuid().GetCounter() : 0, MAIL_STATIONERY_GM); sMassMailMgr.AddMassMailTask(draft, sender, raceMask); PSendSysMessage(LANG_MAIL_SENT, name); return true; } bool ChatHandler::HandleSendItemsHelper(MailDraft& draft, char* args) { // format: "subject text" "mail text" item1[:count1] item2[:count2] ... item12[:count12] std::string msgSubject = ExtractQuotedArg(&args); if (msgSubject.empty()) { return false; } std::string msgText = ExtractQuotedArg(&args); if (msgText.empty()) { return false; } // extract items typedef std::pair ItemPair; typedef std::list< ItemPair > ItemPairs; ItemPairs items; // get from tail next item str while (char* itemStr = ExtractArg(&args)) { // parse item str uint32 item_id = 0; uint32 item_count = 1; if (sscanf(itemStr, "%u:%u", &item_id, &item_count) != 2) if (sscanf(itemStr, "%u", &item_id) != 1) { return false; } if (!item_id) { PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id); SetSentErrorMessage(true); return false; } ItemPrototype const* item_proto = ObjectMgr::GetItemPrototype(item_id); if (!item_proto) { PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id); SetSentErrorMessage(true); return false; } if (item_count < 1 || (item_proto->MaxCount > 0 && item_count > uint32(item_proto->MaxCount))) { PSendSysMessage(LANG_COMMAND_INVALID_ITEM_COUNT, item_count, item_id); SetSentErrorMessage(true); return false; } while (item_count > item_proto->GetMaxStackSize()) { items.push_back(ItemPair(item_id, item_proto->GetMaxStackSize())); item_count -= item_proto->GetMaxStackSize(); } items.push_back(ItemPair(item_id, item_count)); if (items.size() > MAX_MAIL_ITEMS) { PSendSysMessage(LANG_COMMAND_MAIL_ITEMS_LIMIT, MAX_MAIL_ITEMS); SetSentErrorMessage(true); return false; } } // fill mail draft.SetSubjectAndBody(msgSubject, msgText); for (ItemPairs::const_iterator itr = items.begin(); itr != items.end(); ++itr) { if (Item* item = Item::CreateItem(itr->first, itr->second, m_session ? m_session->GetPlayer() : 0)) { item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted draft.AddItem(item); } } return true; } bool ChatHandler::HandleSendItemsCommand(char* args) { // format: name "subject text" "mail text" item1[:count1] item2[:count2] ... item12[:count12] Player* receiver; ObjectGuid receiver_guid; std::string receiver_name; if (!ExtractPlayerTarget(&args, &receiver, &receiver_guid, &receiver_name)) { return false; } MailDraft draft; // fill mail if (!HandleSendItemsHelper(draft, args)) { return false; } // from console show nonexistent sender MailSender sender(MAIL_NORMAL, m_session ? m_session->GetPlayer()->GetObjectGuid().GetCounter() : 0, MAIL_STATIONERY_GM); draft.SendMailTo(MailReceiver(receiver, receiver_guid), sender); std::string nameLink = playerLink(receiver_name); PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str()); return true; } bool ChatHandler::HandleSendMassItemsCommand(char* args) { // format: racemask "subject text" "mail text" item1[:count1] item2[:count2] ... item12[:count12] uint32 raceMask = 0; char const* name = NULL; if (!ExtractRaceMask(&args, raceMask, &name)) { return false; } // need dynamic object because it trasfered to mass mailer MailDraft* draft = new MailDraft; // fill mail if (!HandleSendItemsHelper(*draft, args)) { delete draft; return false; } // from console show nonexistent sender MailSender sender(MAIL_NORMAL, m_session ? m_session->GetPlayer()->GetObjectGuid().GetCounter() : 0, MAIL_STATIONERY_GM); sMassMailMgr.AddMassMailTask(draft, sender, raceMask); PSendSysMessage(LANG_MAIL_SENT, name); return true; } bool ChatHandler::HandleSendMoneyHelper(MailDraft& draft, char* args) { /// format: "subject text" "mail text" money std::string msgSubject = ExtractQuotedArg(&args); if (msgSubject.empty()) { return false; } char* msgText = ExtractQuotedArg(&args); if (!msgText) { return false; } uint32 money; if (!ExtractUInt32(&args, money)) { return false; } if (money <= 0) { return false; } // msgSubject, msgText isn't NUL after prev. check draft.SetSubjectAndBody(msgSubject, msgText).SetMoney(money); return true; } bool ChatHandler::HandleSendMoneyCommand(char* args) { /// format: name "subject text" "mail text" money Player* receiver; ObjectGuid receiver_guid; std::string receiver_name; if (!ExtractPlayerTarget(&args, &receiver, &receiver_guid, &receiver_name)) { return false; } MailDraft draft; // fill mail if (!HandleSendMoneyHelper(draft, args)) { return false; } // from console show nonexistent sender MailSender sender(MAIL_NORMAL, m_session ? m_session->GetPlayer()->GetObjectGuid().GetCounter() : 0, MAIL_STATIONERY_GM); draft.SendMailTo(MailReceiver(receiver, receiver_guid), sender); std::string nameLink = playerLink(receiver_name); PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str()); return true; } bool ChatHandler::HandleSendMassMoneyCommand(char* args) { /// format: raceMask "subject text" "mail text" money uint32 raceMask = 0; char const* name = NULL; if (!ExtractRaceMask(&args, raceMask, &name)) { return false; } // need dynamic object because it trasfered to mass mailer MailDraft* draft = new MailDraft; // fill mail if (!HandleSendMoneyHelper(*draft, args)) { delete draft; return false; } // from console show nonexistent sender MailSender sender(MAIL_NORMAL, m_session ? m_session->GetPlayer()->GetObjectGuid().GetCounter() : 0, MAIL_STATIONERY_GM); sMassMailMgr.AddMassMailTask(draft, sender, raceMask); PSendSysMessage(LANG_MAIL_SENT, name); return true; } /// Send a message to a player in game bool ChatHandler::HandleSendMessageCommand(char* args) { ///- Find the player Player* rPlayer; if (!ExtractPlayerTarget(&args, &rPlayer)) { return false; } ///- message if (!*args) { return false; } WorldSession* rPlayerSession = rPlayer->GetSession(); ///- Check that he is not logging out. if (rPlayerSession->isLogingOut()) { SendSysMessage(LANG_PLAYER_NOT_FOUND); SetSentErrorMessage(true); return false; } ///- Send the message // Use SendAreaTriggerMessage for fastest delivery. rPlayerSession->SendAreaTriggerMessage("%s", args); rPlayerSession->SendAreaTriggerMessage("|cffff0000[Message from administrator]:|r"); // Confirmation message std::string nameLink = GetNameLink(rPlayer); PSendSysMessage(LANG_SENDMESSAGE, nameLink.c_str(), args); return true; } bool ChatHandler::HandleModifyGenderCommand(char* args) { if (!*args) { return false; } Player* player = getSelectedPlayer(); if (!player) { PSendSysMessage(LANG_PLAYER_NOT_FOUND); SetSentErrorMessage(true); return false; } PlayerInfo const* info = sObjectMgr.GetPlayerInfo(player->getRace(), player->getClass()); if (!info) { return false; } char* gender_str = args; int gender_len = strlen(gender_str); Gender gender; if (!strncmp(gender_str, "male", gender_len)) // MALE { if (player->getGender() == GENDER_MALE) { return true; } gender = GENDER_MALE; } else if (!strncmp(gender_str, "female", gender_len)) // FEMALE { if (player->getGender() == GENDER_FEMALE) { return true; } gender = GENDER_FEMALE; } else { SendSysMessage(LANG_MUST_MALE_OR_FEMALE); SetSentErrorMessage(true); return false; } // Set gender player->SetByteValue(UNIT_FIELD_BYTES_0, 2, gender); player->SetUInt16Value(PLAYER_BYTES_3, 0, uint16(gender) | (player->GetDrunkValue() & 0xFFFE)); // Change display ID player->InitDisplayIds(); char const* gender_full = gender ? "female" : "male"; PSendSysMessage(LANG_YOU_CHANGE_GENDER, GetNameLink(player).c_str(), gender_full); if (needReportToTarget(player)) { ChatHandler(player).PSendSysMessage(LANG_YOUR_GENDER_CHANGED, gender_full, GetNameLink().c_str()); } return true; } bool ChatHandler::HandleShowGearScoreCommand(char* args) { Player* player = getSelectedPlayer(); if (!player) { PSendSysMessage(LANG_PLAYER_NOT_FOUND); SetSentErrorMessage(true); return false; } uint32 withBags, withBank; if (!ExtractOptUInt32(&args, withBags, 1)) return false; if (!ExtractOptUInt32(&args, withBank, 0)) return false; // always recalculate gear score for display player->ResetCachedGearScore(); uint32 gearScore = player->GetEquipGearScore(withBags != 0, withBank != 0); PSendSysMessage(LANG_GEARSCORE, GetNameLink(player).c_str(), gearScore); return true; } bool ChatHandler::HandleMmap(char* args) { bool on; if (ExtractOnOff(&args, on)) { if (on) { sWorld.setConfig(CONFIG_BOOL_MMAP_ENABLED, true); SendSysMessage("WORLD: mmaps are now ENABLED (individual map settings still in effect)"); } else { sWorld.setConfig(CONFIG_BOOL_MMAP_ENABLED, false); SendSysMessage("WORLD: mmaps are now DISABLED"); } return true; } on = sWorld.getConfig(CONFIG_BOOL_MMAP_ENABLED); PSendSysMessage("mmaps are %sabled", on ? "en" : "dis"); return true; } bool ChatHandler::HandleMmapTestArea(char* args) { float radius = 40.0f; ExtractFloat(&args, radius); std::list creatureList; MaNGOS::AnyUnitInObjectRangeCheck go_check(m_session->GetPlayer(), radius); MaNGOS::CreatureListSearcher go_search(creatureList, go_check); // Get Creatures Cell::VisitGridObjects(m_session->GetPlayer(), go_search, radius); if (!creatureList.empty()) { PSendSysMessage("Found " SIZEFMTD " Creatures.", creatureList.size()); uint32 paths = 0; uint32 uStartTime = WorldTimer::getMSTime(); float gx, gy, gz; m_session->GetPlayer()->GetPosition(gx, gy, gz); for (std::list::iterator itr = creatureList.begin(); itr != creatureList.end(); ++itr) { PathFinder path(*itr); path.calculate(gx, gy, gz); ++paths; } uint32 uPathLoadTime = WorldTimer::getMSTimeDiff(uStartTime, WorldTimer::getMSTime()); PSendSysMessage("Generated %i paths in %i ms", paths, uPathLoadTime); } else { PSendSysMessage("No creatures in %f yard range.", radius); } return true; } // use ".mmap testheight 10" selecting any creature/player bool ChatHandler::HandleMmapTestHeight(char* args) { float radius = 0.0f; ExtractFloat(&args, radius); if (radius > 40.0f) radius = 40.0f; Unit* unit = getSelectedUnit(); Player* player = m_session->GetPlayer(); if (!unit) unit = player; if (unit->GetTypeId() == TYPEID_UNIT) { if (radius < 0.1f) radius = static_cast(unit)->GetRespawnRadius(); } else { if (unit->GetTypeId() != TYPEID_PLAYER) { PSendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); return false; } } if (radius < 0.1f) { PSendSysMessage("Provided spawn radius for %s is too small. Using 5.0f instead.", unit->GetGuidStr().c_str()); radius = 5.0f; } float gx, gy, gz; unit->GetPosition(gx, gy, gz); Creature* summoned = unit->SummonCreature(VISUAL_WAYPOINT, gx, gy, gz + 0.5f, 0, TEMPSUMMON_TIMED_DESPAWN, 20000); summoned->CastSpell(summoned, 8599, false); uint32 tries = 1; uint32 successes = 0; uint32 startTime = WorldTimer::getMSTime(); for (; tries < 500; ++tries) { unit->GetPosition(gx, gy, gz); if (unit->GetMap()->GetReachableRandomPosition(unit, gx, gy, gz, radius)) { unit->SummonCreature(VISUAL_WAYPOINT, gx, gy, gz, 0, TEMPSUMMON_TIMED_DESPAWN, 15000); ++successes; if (successes >= 100) break; } } uint32 genTime = WorldTimer::getMSTimeDiff(startTime, WorldTimer::getMSTime()); PSendSysMessage("Generated %u valid points for %u try in %ums.", successes, tries, genTime); return true; } bool ChatHandler::HandleServerResetAllRaidCommand(char* args) { PSendSysMessage("Global raid instances reset, all players in raid instances will be teleported to homebind!"); sMapPersistentStateMgr.GetScheduler().ResetAllRaid(); return true; }