[7918] Improve portability in work with uint64 string format specifiers and in code...
[getmangos.git] / src / game / Level3.cpp
blobaa1a392a3d7752d96ecf54071075ec8b06a314c5
1 /*
2 * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include "Common.h"
20 #include "Database/DatabaseEnv.h"
21 #include "WorldPacket.h"
22 #include "WorldSession.h"
23 #include "World.h"
24 #include "ObjectMgr.h"
25 #include "AccountMgr.h"
26 #include "PlayerDump.h"
27 #include "SpellMgr.h"
28 #include "Player.h"
29 #include "Opcodes.h"
30 #include "GameObject.h"
31 #include "Chat.h"
32 #include "Log.h"
33 #include "Guild.h"
34 #include "ObjectAccessor.h"
35 #include "MapManager.h"
36 #include "ScriptCalls.h"
37 #include "Language.h"
38 #include "GridNotifiersImpl.h"
39 #include "CellImpl.h"
40 #include "Weather.h"
41 #include "PointMovementGenerator.h"
42 #include "TargetedMovementGenerator.h"
43 #include "SkillDiscovery.h"
44 #include "SkillExtraItems.h"
45 #include "SystemConfig.h"
46 #include "Config/ConfigEnv.h"
47 #include "Util.h"
48 #include "ItemEnchantmentMgr.h"
49 #include "BattleGroundMgr.h"
50 #include "InstanceSaveMgr.h"
51 #include "InstanceData.h"
52 #include "CreatureEventAIMgr.h"
54 //reload commands
55 bool ChatHandler::HandleReloadAllCommand(const char*)
57 HandleReloadSkillFishingBaseLevelCommand("");
59 HandleReloadAllAchievementCommand("");
60 HandleReloadAllAreaCommand("");
61 HandleReloadAllEventAICommand("");
62 HandleReloadAllLootCommand("");
63 HandleReloadAllNpcCommand("");
64 HandleReloadAllQuestCommand("");
65 HandleReloadAllSpellCommand("");
66 HandleReloadAllItemCommand("");
67 HandleReloadAllLocalesCommand("");
69 HandleReloadCommandCommand("");
70 HandleReloadReservedNameCommand("");
71 HandleReloadMangosStringCommand("");
72 HandleReloadGameTeleCommand("");
73 return true;
76 bool ChatHandler::HandleReloadAllAchievementCommand(const char*)
78 HandleReloadAchievementCriteriaDataCommand("");
79 HandleReloadAchievementRewardCommand("");
80 return true;
83 bool ChatHandler::HandleReloadAllAreaCommand(const char*)
85 //HandleReloadQuestAreaTriggersCommand(""); -- reloaded in HandleReloadAllQuestCommand
86 HandleReloadAreaTriggerTeleportCommand("");
87 HandleReloadAreaTriggerTavernCommand("");
88 HandleReloadGameGraveyardZoneCommand("");
89 return true;
92 bool ChatHandler::HandleReloadAllLootCommand(const char*)
94 sLog.outString( "Re-Loading Loot Tables..." );
95 LoadLootTables();
96 SendGlobalSysMessage("DB tables `*_loot_template` reloaded.");
97 return true;
100 bool ChatHandler::HandleReloadAllNpcCommand(const char* /*args*/)
102 HandleReloadNpcGossipCommand("a");
103 HandleReloadNpcOptionCommand("a");
104 HandleReloadNpcTrainerCommand("a");
105 HandleReloadNpcVendorCommand("a");
106 HandleReloadPointsOfInterestCommand("a");
107 HandleReloadSpellClickSpellsCommand("a");
108 return true;
111 bool ChatHandler::HandleReloadAllQuestCommand(const char* /*args*/)
113 HandleReloadQuestAreaTriggersCommand("a");
114 HandleReloadQuestTemplateCommand("a");
116 sLog.outString( "Re-Loading Quests Relations..." );
117 objmgr.LoadQuestRelations();
118 SendGlobalSysMessage("DB tables `*_questrelation` and `*_involvedrelation` reloaded.");
119 return true;
122 bool ChatHandler::HandleReloadAllScriptsCommand(const char*)
124 if(sWorld.IsScriptScheduled())
126 PSendSysMessage("DB scripts used currently, please attempt reload later.");
127 SetSentErrorMessage(true);
128 return false;
131 sLog.outString( "Re-Loading Scripts..." );
132 HandleReloadGameObjectScriptsCommand("a");
133 HandleReloadEventScriptsCommand("a");
134 HandleReloadQuestEndScriptsCommand("a");
135 HandleReloadQuestStartScriptsCommand("a");
136 HandleReloadSpellScriptsCommand("a");
137 SendGlobalSysMessage("DB tables `*_scripts` reloaded.");
138 HandleReloadDbScriptStringCommand("a");
139 return true;
142 bool ChatHandler::HandleReloadAllEventAICommand(const char*)
144 HandleReloadEventAITextsCommand("a");
145 HandleReloadEventAISummonsCommand("a");
146 HandleReloadEventAIScriptsCommand("a");
147 return true;
150 bool ChatHandler::HandleReloadAllSpellCommand(const char*)
152 HandleReloadSkillDiscoveryTemplateCommand("a");
153 HandleReloadSkillExtraItemTemplateCommand("a");
154 HandleReloadSpellAffectCommand("a");
155 HandleReloadSpellAreaCommand("a");
156 HandleReloadSpellChainCommand("a");
157 HandleReloadSpellElixirCommand("a");
158 HandleReloadSpellLearnSpellCommand("a");
159 HandleReloadSpellProcEventCommand("a");
160 HandleReloadSpellBonusesCommand("a");
161 HandleReloadSpellScriptTargetCommand("a");
162 HandleReloadSpellTargetPositionCommand("a");
163 HandleReloadSpellThreatsCommand("a");
164 HandleReloadSpellPetAurasCommand("a");
165 return true;
168 bool ChatHandler::HandleReloadAllItemCommand(const char*)
170 HandleReloadPageTextsCommand("a");
171 HandleReloadItemEnchantementsCommand("a");
172 return true;
175 bool ChatHandler::HandleReloadAllLocalesCommand(const char* /*args*/)
177 HandleReloadLocalesAchievementRewardCommand("a");
178 HandleReloadLocalesCreatureCommand("a");
179 HandleReloadLocalesGameobjectCommand("a");
180 HandleReloadLocalesItemCommand("a");
181 HandleReloadLocalesNpcTextCommand("a");
182 HandleReloadLocalesPageTextCommand("a");
183 HandleReloadLocalesPointsOfInterestCommand("a");
184 HandleReloadLocalesQuestCommand("a");
185 return true;
188 bool ChatHandler::HandleReloadConfigCommand(const char* /*args*/)
190 sLog.outString( "Re-Loading config settings..." );
191 sWorld.LoadConfigSettings(true);
192 SendGlobalSysMessage("World config settings reloaded.");
193 return true;
196 bool ChatHandler::HandleReloadAchievementCriteriaDataCommand(const char*)
198 sLog.outString( "Re-Loading Additional Achievement Criteria Data..." );
199 achievementmgr.LoadAchievementCriteriaData();
200 SendGlobalSysMessage("DB table `achievement_criteria_data` reloaded.");
201 return true;
204 bool ChatHandler::HandleReloadAchievementRewardCommand(const char*)
206 sLog.outString( "Re-Loading Achievement Reward Data..." );
207 achievementmgr.LoadRewards();
208 SendGlobalSysMessage("DB table `achievement_reward` reloaded.");
209 return true;
212 bool ChatHandler::HandleReloadAreaTriggerTavernCommand(const char*)
214 sLog.outString( "Re-Loading Tavern Area Triggers..." );
215 objmgr.LoadTavernAreaTriggers();
216 SendGlobalSysMessage("DB table `areatrigger_tavern` reloaded.");
217 return true;
220 bool ChatHandler::HandleReloadAreaTriggerTeleportCommand(const char*)
222 sLog.outString( "Re-Loading AreaTrigger teleport definitions..." );
223 objmgr.LoadAreaTriggerTeleports();
224 SendGlobalSysMessage("DB table `areatrigger_teleport` reloaded.");
225 return true;
228 bool ChatHandler::HandleReloadCommandCommand(const char*)
230 load_command_table = true;
231 SendGlobalSysMessage("DB table `command` will be reloaded at next chat command use.");
232 return true;
235 bool ChatHandler::HandleReloadCreatureQuestRelationsCommand(const char*)
237 sLog.outString( "Loading Quests Relations... (`creature_questrelation`)" );
238 objmgr.LoadCreatureQuestRelations();
239 SendGlobalSysMessage("DB table `creature_questrelation` (creature quest givers) reloaded.");
240 return true;
243 bool ChatHandler::HandleReloadCreatureQuestInvRelationsCommand(const char*)
245 sLog.outString( "Loading Quests Relations... (`creature_involvedrelation`)" );
246 objmgr.LoadCreatureInvolvedRelations();
247 SendGlobalSysMessage("DB table `creature_involvedrelation` (creature quest takers) reloaded.");
248 return true;
251 bool ChatHandler::HandleReloadGOQuestRelationsCommand(const char*)
253 sLog.outString( "Loading Quests Relations... (`gameobject_questrelation`)" );
254 objmgr.LoadGameobjectQuestRelations();
255 SendGlobalSysMessage("DB table `gameobject_questrelation` (gameobject quest givers) reloaded.");
256 return true;
259 bool ChatHandler::HandleReloadGOQuestInvRelationsCommand(const char*)
261 sLog.outString( "Loading Quests Relations... (`gameobject_involvedrelation`)" );
262 objmgr.LoadGameobjectInvolvedRelations();
263 SendGlobalSysMessage("DB table `gameobject_involvedrelation` (gameobject quest takers) reloaded.");
264 return true;
267 bool ChatHandler::HandleReloadQuestAreaTriggersCommand(const char*)
269 sLog.outString( "Re-Loading Quest Area Triggers..." );
270 objmgr.LoadQuestAreaTriggers();
271 SendGlobalSysMessage("DB table `areatrigger_involvedrelation` (quest area triggers) reloaded.");
272 return true;
275 bool ChatHandler::HandleReloadQuestTemplateCommand(const char*)
277 sLog.outString( "Re-Loading Quest Templates..." );
278 objmgr.LoadQuests();
279 SendGlobalSysMessage("DB table `quest_template` (quest definitions) reloaded.");
281 /// dependent also from `gameobject` but this table not reloaded anyway
282 sLog.outString( "Re-Loading GameObjects for quests..." );
283 objmgr.LoadGameObjectForQuests();
284 SendGlobalSysMessage("Data GameObjects for quests reloaded.");
285 return true;
288 bool ChatHandler::HandleReloadLootTemplatesCreatureCommand(const char*)
290 sLog.outString( "Re-Loading Loot Tables... (`creature_loot_template`)" );
291 LoadLootTemplates_Creature();
292 LootTemplates_Creature.CheckLootRefs();
293 SendGlobalSysMessage("DB table `creature_loot_template` reloaded.");
294 return true;
297 bool ChatHandler::HandleReloadLootTemplatesDisenchantCommand(const char*)
299 sLog.outString( "Re-Loading Loot Tables... (`disenchant_loot_template`)" );
300 LoadLootTemplates_Disenchant();
301 LootTemplates_Disenchant.CheckLootRefs();
302 SendGlobalSysMessage("DB table `disenchant_loot_template` reloaded.");
303 return true;
306 bool ChatHandler::HandleReloadLootTemplatesFishingCommand(const char*)
308 sLog.outString( "Re-Loading Loot Tables... (`fishing_loot_template`)" );
309 LoadLootTemplates_Fishing();
310 LootTemplates_Fishing.CheckLootRefs();
311 SendGlobalSysMessage("DB table `fishing_loot_template` reloaded.");
312 return true;
315 bool ChatHandler::HandleReloadLootTemplatesGameobjectCommand(const char*)
317 sLog.outString( "Re-Loading Loot Tables... (`gameobject_loot_template`)" );
318 LoadLootTemplates_Gameobject();
319 LootTemplates_Gameobject.CheckLootRefs();
320 SendGlobalSysMessage("DB table `gameobject_loot_template` reloaded.");
321 return true;
324 bool ChatHandler::HandleReloadLootTemplatesItemCommand(const char*)
326 sLog.outString( "Re-Loading Loot Tables... (`item_loot_template`)" );
327 LoadLootTemplates_Item();
328 LootTemplates_Item.CheckLootRefs();
329 SendGlobalSysMessage("DB table `item_loot_template` reloaded.");
330 return true;
333 bool ChatHandler::HandleReloadLootTemplatesMillingCommand(const char*)
335 sLog.outString( "Re-Loading Loot Tables... (`milling_loot_template`)" );
336 LoadLootTemplates_Milling();
337 LootTemplates_Milling.CheckLootRefs();
338 SendGlobalSysMessage("DB table `milling_loot_template` reloaded.");
339 return true;
342 bool ChatHandler::HandleReloadLootTemplatesPickpocketingCommand(const char*)
344 sLog.outString( "Re-Loading Loot Tables... (`pickpocketing_loot_template`)" );
345 LoadLootTemplates_Pickpocketing();
346 LootTemplates_Pickpocketing.CheckLootRefs();
347 SendGlobalSysMessage("DB table `pickpocketing_loot_template` reloaded.");
348 return true;
351 bool ChatHandler::HandleReloadLootTemplatesProspectingCommand(const char*)
353 sLog.outString( "Re-Loading Loot Tables... (`prospecting_loot_template`)" );
354 LoadLootTemplates_Prospecting();
355 LootTemplates_Prospecting.CheckLootRefs();
356 SendGlobalSysMessage("DB table `prospecting_loot_template` reloaded.");
357 return true;
360 bool ChatHandler::HandleReloadLootTemplatesQuestMailCommand(const char*)
362 sLog.outString( "Re-Loading Loot Tables... (`quest_mail_loot_template`)" );
363 LoadLootTemplates_QuestMail();
364 LootTemplates_QuestMail.CheckLootRefs();
365 SendGlobalSysMessage("DB table `quest_mail_loot_template` reloaded.");
366 return true;
369 bool ChatHandler::HandleReloadLootTemplatesReferenceCommand(const char*)
371 sLog.outString( "Re-Loading Loot Tables... (`reference_loot_template`)" );
372 LoadLootTemplates_Reference();
373 SendGlobalSysMessage("DB table `reference_loot_template` reloaded.");
374 return true;
377 bool ChatHandler::HandleReloadLootTemplatesSkinningCommand(const char*)
379 sLog.outString( "Re-Loading Loot Tables... (`skinning_loot_template`)" );
380 LoadLootTemplates_Skinning();
381 LootTemplates_Skinning.CheckLootRefs();
382 SendGlobalSysMessage("DB table `skinning_loot_template` reloaded.");
383 return true;
386 bool ChatHandler::HandleReloadLootTemplatesSpellCommand(const char*)
388 sLog.outString( "Re-Loading Loot Tables... (`spell_loot_template`)" );
389 LoadLootTemplates_Spell();
390 LootTemplates_Spell.CheckLootRefs();
391 SendGlobalSysMessage("DB table `spell_loot_template` reloaded.");
392 return true;
395 bool ChatHandler::HandleReloadMangosStringCommand(const char*)
397 sLog.outString( "Re-Loading mangos_string Table!" );
398 objmgr.LoadMangosStrings();
399 SendGlobalSysMessage("DB table `mangos_string` reloaded.");
400 return true;
403 bool ChatHandler::HandleReloadNpcOptionCommand(const char*)
405 sLog.outString( "Re-Loading `npc_option` Table!" );
406 objmgr.LoadNpcOptions();
407 SendGlobalSysMessage("DB table `npc_option` reloaded.");
408 return true;
411 bool ChatHandler::HandleReloadNpcGossipCommand(const char*)
413 sLog.outString( "Re-Loading `npc_gossip` Table!" );
414 objmgr.LoadNpcTextId();
415 SendGlobalSysMessage("DB table `npc_gossip` reloaded.");
416 return true;
419 bool ChatHandler::HandleReloadNpcTrainerCommand(const char*)
421 sLog.outString( "Re-Loading `npc_trainer` Table!" );
422 objmgr.LoadTrainerSpell();
423 SendGlobalSysMessage("DB table `npc_trainer` reloaded.");
424 return true;
427 bool ChatHandler::HandleReloadNpcVendorCommand(const char*)
429 sLog.outString( "Re-Loading `npc_vendor` Table!" );
430 objmgr.LoadVendors();
431 SendGlobalSysMessage("DB table `npc_vendor` reloaded.");
432 return true;
435 bool ChatHandler::HandleReloadPointsOfInterestCommand(const char*)
437 sLog.outString( "Re-Loading `points_of_interest` Table!" );
438 objmgr.LoadPointsOfInterest();
439 SendGlobalSysMessage("DB table `points_of_interest` reloaded.");
440 return true;
443 bool ChatHandler::HandleReloadSpellClickSpellsCommand(const char*)
445 sLog.outString( "Re-Loading `npc_spellclick_spells` Table!" );
446 objmgr.LoadNPCSpellClickSpells();
447 SendGlobalSysMessage("DB table `npc_spellclick_spells` reloaded.");
448 return true;
451 bool ChatHandler::HandleReloadReservedNameCommand(const char*)
453 sLog.outString( "Loading ReservedNames... (`reserved_name`)" );
454 objmgr.LoadReservedPlayersNames();
455 SendGlobalSysMessage("DB table `reserved_name` (player reserved names) reloaded.");
456 return true;
459 bool ChatHandler::HandleReloadSkillDiscoveryTemplateCommand(const char* /*args*/)
461 sLog.outString( "Re-Loading Skill Discovery Table..." );
462 LoadSkillDiscoveryTable();
463 SendGlobalSysMessage("DB table `skill_discovery_template` (recipes discovered at crafting) reloaded.");
464 return true;
467 bool ChatHandler::HandleReloadSkillExtraItemTemplateCommand(const char* /*args*/)
469 sLog.outString( "Re-Loading Skill Extra Item Table..." );
470 LoadSkillExtraItemTable();
471 SendGlobalSysMessage("DB table `skill_extra_item_template` (extra item creation when crafting) reloaded.");
472 return true;
475 bool ChatHandler::HandleReloadSkillFishingBaseLevelCommand(const char* /*args*/)
477 sLog.outString( "Re-Loading Skill Fishing base level requirements..." );
478 objmgr.LoadFishingBaseSkillLevel();
479 SendGlobalSysMessage("DB table `skill_fishing_base_level` (fishing base level for zone/subzone) reloaded.");
480 return true;
483 bool ChatHandler::HandleReloadSpellAffectCommand(const char*)
485 sLog.outString( "Re-Loading SpellAffect definitions..." );
486 spellmgr.LoadSpellAffects();
487 SendGlobalSysMessage("DB table `spell_affect` (spell mods apply requirements) reloaded.");
488 return true;
491 bool ChatHandler::HandleReloadSpellAreaCommand(const char*)
493 sLog.outString( "Re-Loading SpellArea Data..." );
494 spellmgr.LoadSpellAreas();
495 SendGlobalSysMessage("DB table `spell_area` (spell dependences from area/quest/auras state) reloaded.");
496 return true;
499 bool ChatHandler::HandleReloadSpellChainCommand(const char*)
501 sLog.outString( "Re-Loading Spell Chain Data... " );
502 spellmgr.LoadSpellChains();
503 SendGlobalSysMessage("DB table `spell_chain` (spell ranks) reloaded.");
504 return true;
507 bool ChatHandler::HandleReloadSpellElixirCommand(const char*)
509 sLog.outString( "Re-Loading Spell Elixir types..." );
510 spellmgr.LoadSpellElixirs();
511 SendGlobalSysMessage("DB table `spell_elixir` (spell elixir types) reloaded.");
512 return true;
515 bool ChatHandler::HandleReloadSpellLearnSpellCommand(const char*)
517 sLog.outString( "Re-Loading Spell Learn Spells..." );
518 spellmgr.LoadSpellLearnSpells();
519 SendGlobalSysMessage("DB table `spell_learn_spell` reloaded.");
520 return true;
523 bool ChatHandler::HandleReloadSpellProcEventCommand(const char*)
525 sLog.outString( "Re-Loading Spell Proc Event conditions..." );
526 spellmgr.LoadSpellProcEvents();
527 SendGlobalSysMessage("DB table `spell_proc_event` (spell proc trigger requirements) reloaded.");
528 return true;
531 bool ChatHandler::HandleReloadSpellBonusesCommand(const char*)
533 sLog.outString( "Re-Loading Spell Bonus Data..." );
534 spellmgr.LoadSpellBonusess();
535 SendGlobalSysMessage("DB table `spell_bonus_data` (spell damage/healing coefficients) reloaded.");
536 return true;
539 bool ChatHandler::HandleReloadSpellScriptTargetCommand(const char*)
541 sLog.outString( "Re-Loading SpellsScriptTarget..." );
542 spellmgr.LoadSpellScriptTarget();
543 SendGlobalSysMessage("DB table `spell_script_target` (spell targets selection in case specific creature/GO requirements) reloaded.");
544 return true;
547 bool ChatHandler::HandleReloadSpellTargetPositionCommand(const char*)
549 sLog.outString( "Re-Loading Spell target coordinates..." );
550 spellmgr.LoadSpellTargetPositions();
551 SendGlobalSysMessage("DB table `spell_target_position` (destination coordinates for spell targets) reloaded.");
552 return true;
555 bool ChatHandler::HandleReloadSpellThreatsCommand(const char*)
557 sLog.outString( "Re-Loading Aggro Spells Definitions...");
558 spellmgr.LoadSpellThreats();
559 SendGlobalSysMessage("DB table `spell_threat` (spell aggro definitions) reloaded.");
560 return true;
563 bool ChatHandler::HandleReloadSpellPetAurasCommand(const char*)
565 sLog.outString( "Re-Loading Spell pet auras...");
566 spellmgr.LoadSpellPetAuras();
567 SendGlobalSysMessage("DB table `spell_pet_auras` reloaded.");
568 return true;
571 bool ChatHandler::HandleReloadPageTextsCommand(const char*)
573 sLog.outString( "Re-Loading Page Texts..." );
574 objmgr.LoadPageTexts();
575 SendGlobalSysMessage("DB table `page_texts` reloaded.");
576 return true;
579 bool ChatHandler::HandleReloadItemEnchantementsCommand(const char*)
581 sLog.outString( "Re-Loading Item Random Enchantments Table..." );
582 LoadRandomEnchantmentsTable();
583 SendGlobalSysMessage("DB table `item_enchantment_template` reloaded.");
584 return true;
587 bool ChatHandler::HandleReloadGameObjectScriptsCommand(const char* arg)
589 if(sWorld.IsScriptScheduled())
591 SendSysMessage("DB scripts used currently, please attempt reload later.");
592 SetSentErrorMessage(true);
593 return false;
596 if(*arg!='a')
597 sLog.outString( "Re-Loading Scripts from `gameobject_scripts`...");
599 objmgr.LoadGameObjectScripts();
601 if(*arg!='a')
602 SendGlobalSysMessage("DB table `gameobject_scripts` reloaded.");
604 return true;
607 bool ChatHandler::HandleReloadEventScriptsCommand(const char* arg)
609 if(sWorld.IsScriptScheduled())
611 SendSysMessage("DB scripts used currently, please attempt reload later.");
612 SetSentErrorMessage(true);
613 return false;
616 if(*arg!='a')
617 sLog.outString( "Re-Loading Scripts from `event_scripts`...");
619 objmgr.LoadEventScripts();
621 if(*arg!='a')
622 SendGlobalSysMessage("DB table `event_scripts` reloaded.");
624 return true;
627 bool ChatHandler::HandleReloadEventAITextsCommand(const char* arg)
630 sLog.outString( "Re-Loading Texts from `creature_ai_texts`...");
631 CreatureEAI_Mgr.LoadCreatureEventAI_Texts();
632 SendGlobalSysMessage("DB table `creature_ai_texts` reloaded.");
633 return true;
636 bool ChatHandler::HandleReloadEventAISummonsCommand(const char* arg)
638 sLog.outString( "Re-Loading Summons from `creature_ai_summons`...");
639 CreatureEAI_Mgr.LoadCreatureEventAI_Summons();
640 SendGlobalSysMessage("DB table `creature_ai_summons` reloaded.");
641 return true;
644 bool ChatHandler::HandleReloadEventAIScriptsCommand(const char* arg)
646 sLog.outString( "Re-Loading Scripts from `creature_ai_scripts`...");
647 CreatureEAI_Mgr.LoadCreatureEventAI_Scripts();
648 SendGlobalSysMessage("DB table `creature_ai_scripts` reloaded.");
649 return true;
652 bool ChatHandler::HandleReloadQuestEndScriptsCommand(const char* arg)
654 if(sWorld.IsScriptScheduled())
656 SendSysMessage("DB scripts used currently, please attempt reload later.");
657 SetSentErrorMessage(true);
658 return false;
661 if(*arg!='a')
662 sLog.outString( "Re-Loading Scripts from `quest_end_scripts`...");
664 objmgr.LoadQuestEndScripts();
666 if(*arg!='a')
667 SendGlobalSysMessage("DB table `quest_end_scripts` reloaded.");
669 return true;
672 bool ChatHandler::HandleReloadQuestStartScriptsCommand(const char* arg)
674 if(sWorld.IsScriptScheduled())
676 SendSysMessage("DB scripts used currently, please attempt reload later.");
677 SetSentErrorMessage(true);
678 return false;
681 if(*arg!='a')
682 sLog.outString( "Re-Loading Scripts from `quest_start_scripts`...");
684 objmgr.LoadQuestStartScripts();
686 if(*arg!='a')
687 SendGlobalSysMessage("DB table `quest_start_scripts` reloaded.");
689 return true;
692 bool ChatHandler::HandleReloadSpellScriptsCommand(const char* arg)
694 if(sWorld.IsScriptScheduled())
696 SendSysMessage("DB scripts used currently, please attempt reload later.");
697 SetSentErrorMessage(true);
698 return false;
701 if(*arg!='a')
702 sLog.outString( "Re-Loading Scripts from `spell_scripts`...");
704 objmgr.LoadSpellScripts();
706 if(*arg!='a')
707 SendGlobalSysMessage("DB table `spell_scripts` reloaded.");
709 return true;
712 bool ChatHandler::HandleReloadDbScriptStringCommand(const char* /*arg*/)
714 sLog.outString( "Re-Loading Script strings from `db_script_string`...");
715 objmgr.LoadDbScriptStrings();
716 SendGlobalSysMessage("DB table `db_script_string` reloaded.");
717 return true;
720 bool ChatHandler::HandleReloadGameGraveyardZoneCommand(const char* /*arg*/)
722 sLog.outString( "Re-Loading Graveyard-zone links...");
724 objmgr.LoadGraveyardZones();
726 SendGlobalSysMessage("DB table `game_graveyard_zone` reloaded.");
728 return true;
731 bool ChatHandler::HandleReloadGameTeleCommand(const char* /*arg*/)
733 sLog.outString( "Re-Loading Game Tele coordinates...");
735 objmgr.LoadGameTele();
737 SendGlobalSysMessage("DB table `game_tele` reloaded.");
739 return true;
742 bool ChatHandler::HandleReloadLocalesAchievementRewardCommand(const char*)
744 sLog.outString( "Re-Loading Locales Achievement Reward Data..." );
745 achievementmgr.LoadRewardLocales();
746 SendGlobalSysMessage("DB table `locales_achievement_reward` reloaded.");
747 return true;
750 bool ChatHandler::HandleReloadLocalesCreatureCommand(const char* /*arg*/)
752 sLog.outString( "Re-Loading Locales Creature ...");
753 objmgr.LoadCreatureLocales();
754 SendGlobalSysMessage("DB table `locales_creature` reloaded.");
755 return true;
758 bool ChatHandler::HandleReloadLocalesGameobjectCommand(const char* /*arg*/)
760 sLog.outString( "Re-Loading Locales Gameobject ... ");
761 objmgr.LoadGameObjectLocales();
762 SendGlobalSysMessage("DB table `locales_gameobject` reloaded.");
763 return true;
766 bool ChatHandler::HandleReloadLocalesItemCommand(const char* /*arg*/)
768 sLog.outString( "Re-Loading Locales Item ... ");
769 objmgr.LoadItemLocales();
770 SendGlobalSysMessage("DB table `locales_item` reloaded.");
771 return true;
774 bool ChatHandler::HandleReloadLocalesNpcTextCommand(const char* /*arg*/)
776 sLog.outString( "Re-Loading Locales NPC Text ... ");
777 objmgr.LoadNpcTextLocales();
778 SendGlobalSysMessage("DB table `locales_npc_text` reloaded.");
779 return true;
782 bool ChatHandler::HandleReloadLocalesPageTextCommand(const char* /*arg*/)
784 sLog.outString( "Re-Loading Locales Page Text ... ");
785 objmgr.LoadPageTextLocales();
786 SendGlobalSysMessage("DB table `locales_page_text` reloaded.");
787 return true;
790 bool ChatHandler::HandleReloadLocalesPointsOfInterestCommand(const char* /*arg*/)
792 sLog.outString( "Re-Loading Locales Points Of Interest ... ");
793 objmgr.LoadPointOfInterestLocales();
794 SendGlobalSysMessage("DB table `locales_points_of_interest` reloaded.");
795 return true;
798 bool ChatHandler::HandleReloadLocalesQuestCommand(const char* /*arg*/)
800 sLog.outString( "Re-Loading Locales Quest ... ");
801 objmgr.LoadQuestLocales();
802 SendGlobalSysMessage("DB table `locales_quest` reloaded.");
803 return true;
806 bool ChatHandler::HandleLoadScriptsCommand(const char* args)
808 if(!LoadScriptingModule(args)) return true;
810 sWorld.SendWorldText(LANG_SCRIPTS_RELOADED);
811 return true;
814 bool ChatHandler::HandleAccountSetGmLevelCommand(const char* args)
816 char* arg1 = strtok((char*)args, " ");
817 if( !arg1 )
818 return false;
820 /// must be NULL if targeted syntax and must be not nULL if not targeted
821 char* arg2 = strtok(NULL, " ");
823 std::string targetAccountName;
824 uint32 targetAccountId = 0;
826 /// only target player different from self allowed (if targetPlayer!=NULL then not console)
827 Player* targetPlayer = getSelectedPlayer();
828 if(targetPlayer && m_session->GetPlayer()!=targetPlayer)
830 /// wrong command syntax or unexpected targeting
831 if(arg2)
832 return false;
834 /// security level expected in arg2 after this if.
835 arg2 = arg1;
837 targetAccountId = targetPlayer->GetSession()->GetAccountId();
838 accmgr.GetName(targetAccountId, targetAccountName);
840 else
842 /// wrong command syntax (second arg expected)
843 if(!arg2)
844 return false;
846 targetAccountName = arg1;
847 if(!AccountMgr::normilizeString(targetAccountName))
849 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,targetAccountName.c_str());
850 SetSentErrorMessage(true);
851 return false;
854 targetAccountId = accmgr.GetId(targetAccountName);
855 if(!targetAccountId)
857 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,targetAccountName.c_str());
858 SetSentErrorMessage(true);
859 return false;
863 int32 gm = (int32)atoi(arg2);
864 if ( gm < SEC_PLAYER || gm > SEC_ADMINISTRATOR )
866 SendSysMessage(LANG_BAD_VALUE);
867 SetSentErrorMessage(true);
868 return false;
871 /// can set security level only for target with less security and to less security that we have
872 /// This will reject self apply by specify account name
873 if(HasLowerSecurityAccount(NULL,targetAccountId,true))
874 return false;
876 /// account can't set security to same or grater level, need more power GM or console
877 AccountTypes plSecurity = m_session ? m_session->GetSecurity() : SEC_CONSOLE;
878 if (AccountTypes(gm) >= plSecurity )
880 SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
881 SetSentErrorMessage(true);
882 return false;
885 // This will prevent self apply by self target or no target
886 if(targetPlayer && m_session->GetPlayer()!=targetPlayer)
888 ChatHandler(targetPlayer).PSendSysMessage(LANG_YOURS_SECURITY_CHANGED,GetNameLink().c_str(), gm);
889 targetPlayer->GetSession()->SetSecurity(AccountTypes(gm));
892 PSendSysMessage(LANG_YOU_CHANGE_SECURITY, targetAccountName.c_str(), gm);
893 loginDatabase.PExecute("UPDATE account SET gmlevel = '%i' WHERE id = '%u'", gm, targetAccountId);
895 return true;
898 /// Set password for account
899 bool ChatHandler::HandleAccountSetPasswordCommand(const char* args)
901 if(!*args)
902 return false;
904 ///- Get the command line arguments
905 char *szAccount = strtok ((char*)args," ");
906 char *szPassword1 = strtok (NULL," ");
907 char *szPassword2 = strtok (NULL," ");
909 if (!szAccount||!szPassword1 || !szPassword2)
910 return false;
912 std::string account_name = szAccount;
913 if(!AccountMgr::normilizeString(account_name))
915 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
916 SetSentErrorMessage(true);
917 return false;
920 uint32 targetAccountId = accmgr.GetId(account_name);
921 if (!targetAccountId)
923 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
924 SetSentErrorMessage(true);
925 return false;
928 /// can set password only for target with less security
929 /// This is also reject self apply in fact
930 if(HasLowerSecurityAccount (NULL,targetAccountId,true))
931 return false;
933 if (strcmp(szPassword1,szPassword2))
935 SendSysMessage (LANG_NEW_PASSWORDS_NOT_MATCH);
936 SetSentErrorMessage (true);
937 return false;
940 AccountOpResult result = accmgr.ChangePassword(targetAccountId, szPassword1);
942 switch(result)
944 case AOR_OK:
945 SendSysMessage(LANG_COMMAND_PASSWORD);
946 break;
947 case AOR_NAME_NOT_EXIST:
948 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
949 SetSentErrorMessage(true);
950 return false;
951 case AOR_PASS_TOO_LONG:
952 SendSysMessage(LANG_PASSWORD_TOO_LONG);
953 SetSentErrorMessage(true);
954 return false;
955 default:
956 SendSysMessage(LANG_COMMAND_NOTCHANGEPASSWORD);
957 SetSentErrorMessage(true);
958 return false;
961 return true;
964 bool ChatHandler::HandleMaxSkillCommand(const char* /*args*/)
966 Player* SelectedPlayer = getSelectedPlayer();
967 if(!SelectedPlayer)
969 SendSysMessage(LANG_NO_CHAR_SELECTED);
970 SetSentErrorMessage(true);
971 return false;
974 // each skills that have max skill value dependent from level seted to current level max skill value
975 SelectedPlayer->UpdateSkillsToMaxSkillsForLevel();
976 return true;
979 bool ChatHandler::HandleSetSkillCommand(const char* args)
981 // number or [name] Shift-click form |color|Hskill:skill_id|h[name]|h|r
982 char* skill_p = extractKeyFromLink((char*)args,"Hskill");
983 if(!skill_p)
984 return false;
986 char *level_p = strtok (NULL, " ");
988 if( !level_p)
989 return false;
991 char *max_p = strtok (NULL, " ");
993 int32 skill = atoi(skill_p);
994 if (skill <= 0)
996 PSendSysMessage(LANG_INVALID_SKILL_ID, skill);
997 SetSentErrorMessage(true);
998 return false;
1001 int32 level = atol (level_p);
1003 Player * target = getSelectedPlayer();
1004 if(!target)
1006 SendSysMessage(LANG_NO_CHAR_SELECTED);
1007 SetSentErrorMessage(true);
1008 return false;
1011 SkillLineEntry const* sl = sSkillLineStore.LookupEntry(skill);
1012 if(!sl)
1014 PSendSysMessage(LANG_INVALID_SKILL_ID, skill);
1015 SetSentErrorMessage(true);
1016 return false;
1019 std::string tNameLink = GetNameLink(target);
1021 if(!target->GetSkillValue(skill))
1023 PSendSysMessage(LANG_SET_SKILL_ERROR, tNameLink.c_str(), skill, sl->name[0]);
1024 SetSentErrorMessage(true);
1025 return false;
1028 int32 max = max_p ? atol (max_p) : target->GetPureMaxSkillValue(skill);
1030 if( level <= 0 || level > max || max <= 0 )
1031 return false;
1033 target->SetSkill(skill, level, max);
1034 PSendSysMessage(LANG_SET_SKILL, skill, sl->name[0], tNameLink.c_str(), level, max);
1036 return true;
1039 bool ChatHandler::HandleUnLearnCommand(const char* args)
1041 if (!*args)
1042 return false;
1044 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
1045 uint32 spell_id = extractSpellIdFromLink((char*)args);
1046 if(!spell_id)
1047 return false;
1049 char const* allStr = strtok(NULL," ");
1050 bool allRanks = allStr ? (strncmp(allStr, "all", strlen(allStr)) == 0) : false;
1052 Player* target = getSelectedPlayer();
1053 if(!target)
1055 SendSysMessage(LANG_NO_CHAR_SELECTED);
1056 SetSentErrorMessage(true);
1057 return false;
1060 if(allRanks)
1061 spell_id = spellmgr.GetFirstSpellInChain (spell_id);
1063 if (target->HasSpell(spell_id))
1064 target->removeSpell(spell_id,false,!allRanks);
1065 else
1066 SendSysMessage(LANG_FORGET_SPELL);
1068 return true;
1071 bool ChatHandler::HandleCooldownCommand(const char* args)
1073 Player* target = getSelectedPlayer();
1074 if(!target)
1076 SendSysMessage(LANG_PLAYER_NOT_FOUND);
1077 SetSentErrorMessage(true);
1078 return false;
1081 std::string tNameLink = GetNameLink(target);
1083 if (!*args)
1085 target->RemoveAllSpellCooldown();
1086 PSendSysMessage(LANG_REMOVEALL_COOLDOWN, tNameLink.c_str());
1088 else
1090 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
1091 uint32 spell_id = extractSpellIdFromLink((char*)args);
1092 if(!spell_id)
1093 return false;
1095 if(!sSpellStore.LookupEntry(spell_id))
1097 PSendSysMessage(LANG_UNKNOWN_SPELL, target==m_session->GetPlayer() ? GetMangosString(LANG_YOU) : tNameLink.c_str());
1098 SetSentErrorMessage(true);
1099 return false;
1102 target->RemoveSpellCooldown(spell_id,true);
1103 PSendSysMessage(LANG_REMOVE_COOLDOWN, spell_id, target==m_session->GetPlayer() ? GetMangosString(LANG_YOU) : tNameLink.c_str());
1105 return true;
1108 bool ChatHandler::HandleLearnAllCommand(const char* /*args*/)
1110 static const char *allSpellList[] =
1112 "3365",
1113 "6233",
1114 "6247",
1115 "6246",
1116 "6477",
1117 "6478",
1118 "22810",
1119 "8386",
1120 "21651",
1121 "21652",
1122 "522",
1123 "7266",
1124 "8597",
1125 "2479",
1126 "22027",
1127 "6603",
1128 "5019",
1129 "133",
1130 "168",
1131 "227",
1132 "5009",
1133 "9078",
1134 "668",
1135 "203",
1136 "20599",
1137 "20600",
1138 "81",
1139 "20597",
1140 "20598",
1141 "20864",
1142 "1459",
1143 "5504",
1144 "587",
1145 "5143",
1146 "118",
1147 "5505",
1148 "597",
1149 "604",
1150 "1449",
1151 "1460",
1152 "2855",
1153 "1008",
1154 "475",
1155 "5506",
1156 "1463",
1157 "12824",
1158 "8437",
1159 "990",
1160 "5145",
1161 "8450",
1162 "1461",
1163 "759",
1164 "8494",
1165 "8455",
1166 "8438",
1167 "6127",
1168 "8416",
1169 "6129",
1170 "8451",
1171 "8495",
1172 "8439",
1173 "3552",
1174 "8417",
1175 "10138",
1176 "12825",
1177 "10169",
1178 "10156",
1179 "10144",
1180 "10191",
1181 "10201",
1182 "10211",
1183 "10053",
1184 "10173",
1185 "10139",
1186 "10145",
1187 "10192",
1188 "10170",
1189 "10202",
1190 "10054",
1191 "10174",
1192 "10193",
1193 "12826",
1194 "2136",
1195 "143",
1196 "145",
1197 "2137",
1198 "2120",
1199 "3140",
1200 "543",
1201 "2138",
1202 "2948",
1203 "8400",
1204 "2121",
1205 "8444",
1206 "8412",
1207 "8457",
1208 "8401",
1209 "8422",
1210 "8445",
1211 "8402",
1212 "8413",
1213 "8458",
1214 "8423",
1215 "8446",
1216 "10148",
1217 "10197",
1218 "10205",
1219 "10149",
1220 "10215",
1221 "10223",
1222 "10206",
1223 "10199",
1224 "10150",
1225 "10216",
1226 "10207",
1227 "10225",
1228 "10151",
1229 "116",
1230 "205",
1231 "7300",
1232 "122",
1233 "837",
1234 "10",
1235 "7301",
1236 "7322",
1237 "6143",
1238 "120",
1239 "865",
1240 "8406",
1241 "6141",
1242 "7302",
1243 "8461",
1244 "8407",
1245 "8492",
1246 "8427",
1247 "8408",
1248 "6131",
1249 "7320",
1250 "10159",
1251 "8462",
1252 "10185",
1253 "10179",
1254 "10160",
1255 "10180",
1256 "10219",
1257 "10186",
1258 "10177",
1259 "10230",
1260 "10181",
1261 "10161",
1262 "10187",
1263 "10220",
1264 "2018",
1265 "2663",
1266 "12260",
1267 "2660",
1268 "3115",
1269 "3326",
1270 "2665",
1271 "3116",
1272 "2738",
1273 "3293",
1274 "2661",
1275 "3319",
1276 "2662",
1277 "9983",
1278 "8880",
1279 "2737",
1280 "2739",
1281 "7408",
1282 "3320",
1283 "2666",
1284 "3323",
1285 "3324",
1286 "3294",
1287 "22723",
1288 "23219",
1289 "23220",
1290 "23221",
1291 "23228",
1292 "23338",
1293 "10788",
1294 "10790",
1295 "5611",
1296 "5016",
1297 "5609",
1298 "2060",
1299 "10963",
1300 "10964",
1301 "10965",
1302 "22593",
1303 "22594",
1304 "596",
1305 "996",
1306 "499",
1307 "768",
1308 "17002",
1309 "1448",
1310 "1082",
1311 "16979",
1312 "1079",
1313 "5215",
1314 "20484",
1315 "5221",
1316 "15590",
1317 "17007",
1318 "6795",
1319 "6807",
1320 "5487",
1321 "1446",
1322 "1066",
1323 "5421",
1324 "3139",
1325 "779",
1326 "6811",
1327 "6808",
1328 "1445",
1329 "5216",
1330 "1737",
1331 "5222",
1332 "5217",
1333 "1432",
1334 "6812",
1335 "9492",
1336 "5210",
1337 "3030",
1338 "1441",
1339 "783",
1340 "6801",
1341 "20739",
1342 "8944",
1343 "9491",
1344 "22569",
1345 "5226",
1346 "6786",
1347 "1433",
1348 "8973",
1349 "1828",
1350 "9495",
1351 "9006",
1352 "6794",
1353 "8993",
1354 "5203",
1355 "16914",
1356 "6784",
1357 "9635",
1358 "22830",
1359 "20722",
1360 "9748",
1361 "6790",
1362 "9753",
1363 "9493",
1364 "9752",
1365 "9831",
1366 "9825",
1367 "9822",
1368 "5204",
1369 "5401",
1370 "22831",
1371 "6793",
1372 "9845",
1373 "17401",
1374 "9882",
1375 "9868",
1376 "20749",
1377 "9893",
1378 "9899",
1379 "9895",
1380 "9832",
1381 "9902",
1382 "9909",
1383 "22832",
1384 "9828",
1385 "9851",
1386 "9883",
1387 "9869",
1388 "17406",
1389 "17402",
1390 "9914",
1391 "20750",
1392 "9897",
1393 "9848",
1394 "3127",
1395 "107",
1396 "204",
1397 "9116",
1398 "2457",
1399 "78",
1400 "18848",
1401 "331",
1402 "403",
1403 "2098",
1404 "1752",
1405 "11278",
1406 "11288",
1407 "11284",
1408 "6461",
1409 "2344",
1410 "2345",
1411 "6463",
1412 "2346",
1413 "2352",
1414 "775",
1415 "1434",
1416 "1612",
1417 "71",
1418 "2468",
1419 "2458",
1420 "2467",
1421 "7164",
1422 "7178",
1423 "7367",
1424 "7376",
1425 "7381",
1426 "21156",
1427 "5209",
1428 "3029",
1429 "5201",
1430 "9849",
1431 "9850",
1432 "20719",
1433 "22568",
1434 "22827",
1435 "22828",
1436 "22829",
1437 "6809",
1438 "8972",
1439 "9005",
1440 "9823",
1441 "9827",
1442 "6783",
1443 "9913",
1444 "6785",
1445 "6787",
1446 "9866",
1447 "9867",
1448 "9894",
1449 "9896",
1450 "6800",
1451 "8992",
1452 "9829",
1453 "9830",
1454 "780",
1455 "769",
1456 "6749",
1457 "6750",
1458 "9755",
1459 "9754",
1460 "9908",
1461 "20745",
1462 "20742",
1463 "20747",
1464 "20748",
1465 "9746",
1466 "9745",
1467 "9880",
1468 "9881",
1469 "5391",
1470 "842",
1471 "3025",
1472 "3031",
1473 "3287",
1474 "3329",
1475 "1945",
1476 "3559",
1477 "4933",
1478 "4934",
1479 "4935",
1480 "4936",
1481 "5142",
1482 "5390",
1483 "5392",
1484 "5404",
1485 "5420",
1486 "6405",
1487 "7293",
1488 "7965",
1489 "8041",
1490 "8153",
1491 "9033",
1492 "9034",
1493 //"9036", problems with ghost state
1494 "16421",
1495 "21653",
1496 "22660",
1497 "5225",
1498 "9846",
1499 "2426",
1500 "5916",
1501 "6634",
1502 //"6718", phasing stealth, annoying for learn all case.
1503 "6719",
1504 "8822",
1505 "9591",
1506 "9590",
1507 "10032",
1508 "17746",
1509 "17747",
1510 "8203",
1511 "11392",
1512 "12495",
1513 "16380",
1514 "23452",
1515 "4079",
1516 "4996",
1517 "4997",
1518 "4998",
1519 "4999",
1520 "5000",
1521 "6348",
1522 "6349",
1523 "6481",
1524 "6482",
1525 "6483",
1526 "6484",
1527 "11362",
1528 "11410",
1529 "11409",
1530 "12510",
1531 "12509",
1532 "12885",
1533 "13142",
1534 "21463",
1535 "23460",
1536 "11421",
1537 "11416",
1538 "11418",
1539 "1851",
1540 "10059",
1541 "11423",
1542 "11417",
1543 "11422",
1544 "11419",
1545 "11424",
1546 "11420",
1547 "27",
1548 "31",
1549 "33",
1550 "34",
1551 "35",
1552 "15125",
1553 "21127",
1554 "22950",
1555 "1180",
1556 "201",
1557 "12593",
1558 "12842",
1559 "16770",
1560 "6057",
1561 "12051",
1562 "18468",
1563 "12606",
1564 "12605",
1565 "18466",
1566 "12502",
1567 "12043",
1568 "15060",
1569 "12042",
1570 "12341",
1571 "12848",
1572 "12344",
1573 "12353",
1574 "18460",
1575 "11366",
1576 "12350",
1577 "12352",
1578 "13043",
1579 "11368",
1580 "11113",
1581 "12400",
1582 "11129",
1583 "16766",
1584 "12573",
1585 "15053",
1586 "12580",
1587 "12475",
1588 "12472",
1589 "12953",
1590 "12488",
1591 "11189",
1592 "12985",
1593 "12519",
1594 "16758",
1595 "11958",
1596 "12490",
1597 "11426",
1598 "3565",
1599 "3562",
1600 "18960",
1601 "3567",
1602 "3561",
1603 "3566",
1604 "3563",
1605 "1953",
1606 "2139",
1607 "12505",
1608 "13018",
1609 "12522",
1610 "12523",
1611 "5146",
1612 "5144",
1613 "5148",
1614 "8419",
1615 "8418",
1616 "10213",
1617 "10212",
1618 "10157",
1619 "12524",
1620 "13019",
1621 "12525",
1622 "13020",
1623 "12526",
1624 "13021",
1625 "18809",
1626 "13031",
1627 "13032",
1628 "13033",
1629 "4036",
1630 "3920",
1631 "3919",
1632 "3918",
1633 "7430",
1634 "3922",
1635 "3923",
1636 "7411",
1637 "7418",
1638 "7421",
1639 "13262",
1640 "7412",
1641 "7415",
1642 "7413",
1643 "7416",
1644 "13920",
1645 "13921",
1646 "7745",
1647 "7779",
1648 "7428",
1649 "7457",
1650 "7857",
1651 "7748",
1652 "7426",
1653 "13421",
1654 "7454",
1655 "13378",
1656 "7788",
1657 "14807",
1658 "14293",
1659 "7795",
1660 "6296",
1661 "20608",
1662 "755",
1663 "444",
1664 "427",
1665 "428",
1666 "442",
1667 "447",
1668 "3578",
1669 "3581",
1670 "19027",
1671 "3580",
1672 "665",
1673 "3579",
1674 "3577",
1675 "6755",
1676 "3576",
1677 "2575",
1678 "2577",
1679 "2578",
1680 "2579",
1681 "2580",
1682 "2656",
1683 "2657",
1684 "2576",
1685 "3564",
1686 "10248",
1687 "8388",
1688 "2659",
1689 "14891",
1690 "3308",
1691 "3307",
1692 "10097",
1693 "2658",
1694 "3569",
1695 "16153",
1696 "3304",
1697 "10098",
1698 "4037",
1699 "3929",
1700 "3931",
1701 "3926",
1702 "3924",
1703 "3930",
1704 "3977",
1705 "3925",
1706 "136",
1707 "228",
1708 "5487",
1709 "43",
1710 "202",
1714 int loop = 0;
1715 while(strcmp(allSpellList[loop], "0"))
1717 uint32 spell = atol((char*)allSpellList[loop++]);
1719 if (m_session->GetPlayer()->HasSpell(spell))
1720 continue;
1722 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
1723 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
1725 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
1726 continue;
1729 m_session->GetPlayer()->learnSpell(spell,false);
1732 SendSysMessage(LANG_COMMAND_LEARN_MANY_SPELLS);
1734 return true;
1737 bool ChatHandler::HandleLearnAllGMCommand(const char* /*args*/)
1739 static const char *gmSpellList[] =
1741 "24347", // Become A Fish, No Breath Bar
1742 "35132", // Visual Boom
1743 "38488", // Attack 4000-8000 AOE
1744 "38795", // Attack 2000 AOE + Slow Down 90%
1745 "15712", // Attack 200
1746 "1852", // GM Spell Silence
1747 "31899", // Kill
1748 "31924", // Kill
1749 "29878", // Kill My Self
1750 "26644", // More Kill
1752 "28550", //Invisible 24
1753 "23452", //Invisible + Target
1757 uint16 gmSpellIter = 0;
1758 while( strcmp(gmSpellList[gmSpellIter], "0") )
1760 uint32 spell = atol((char*)gmSpellList[gmSpellIter++]);
1762 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
1763 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
1765 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
1766 continue;
1769 m_session->GetPlayer()->learnSpell(spell,false);
1772 SendSysMessage(LANG_LEARNING_GM_SKILLS);
1773 return true;
1776 bool ChatHandler::HandleLearnAllMyClassCommand(const char* /*args*/)
1778 HandleLearnAllMySpellsCommand("");
1779 HandleLearnAllMyTalentsCommand("");
1780 return true;
1783 bool ChatHandler::HandleLearnAllMySpellsCommand(const char* /*args*/)
1785 ChrClassesEntry const* clsEntry = sChrClassesStore.LookupEntry(m_session->GetPlayer()->getClass());
1786 if(!clsEntry)
1787 return true;
1788 uint32 family = clsEntry->spellfamily;
1790 for (uint32 i = 0; i < sSpellStore.GetNumRows(); ++i)
1792 SpellEntry const *spellInfo = sSpellStore.LookupEntry(i);
1793 if(!spellInfo)
1794 continue;
1796 // skip server-side/triggered spells
1797 if(spellInfo->spellLevel==0)
1798 continue;
1800 // skip wrong class/race skills
1801 if(!m_session->GetPlayer()->IsSpellFitByClassAndRace(spellInfo->Id))
1802 continue;
1804 // skip other spell families
1805 if( spellInfo->SpellFamilyName != family)
1806 continue;
1808 // skip spells with first rank learned as talent (and all talents then also)
1809 uint32 first_rank = spellmgr.GetFirstSpellInChain(spellInfo->Id);
1810 if(GetTalentSpellCost(first_rank) > 0 )
1811 continue;
1813 // skip broken spells
1814 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
1815 continue;
1817 m_session->GetPlayer()->learnSpell(i,false);
1820 SendSysMessage(LANG_COMMAND_LEARN_CLASS_SPELLS);
1821 return true;
1824 bool ChatHandler::HandleLearnAllMyTalentsCommand(const char* /*args*/)
1826 Player* player = m_session->GetPlayer();
1827 uint32 classMask = player->getClassMask();
1829 for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
1831 TalentEntry const *talentInfo = sTalentStore.LookupEntry(i);
1832 if(!talentInfo)
1833 continue;
1835 TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab );
1836 if(!talentTabInfo)
1837 continue;
1839 if( (classMask & talentTabInfo->ClassMask) == 0 )
1840 continue;
1842 // search highest talent rank
1843 uint32 spellid = 0;
1845 for(int rank = MAX_TALENT_RANK-1; rank >= 0; --rank)
1847 if(talentInfo->RankID[rank]!=0)
1849 spellid = talentInfo->RankID[rank];
1850 break;
1854 if(!spellid) // ??? none spells in talent
1855 continue;
1857 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid);
1858 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
1859 continue;
1861 // learn highest rank of talent and learn all non-talent spell ranks (recursive by tree)
1862 player->learnSpellHighRank(spellid);
1865 SendSysMessage(LANG_COMMAND_LEARN_CLASS_TALENTS);
1866 return true;
1869 bool ChatHandler::HandleLearnAllMyPetTalentsCommand(const char* /*args*/)
1871 Player* player = m_session->GetPlayer();
1873 Pet* pet = player->GetPet();
1874 if(!pet)
1876 SendSysMessage(LANG_NO_PET_FOUND);
1877 SetSentErrorMessage(true);
1878 return false;
1881 CreatureInfo const *ci = pet->GetCreatureInfo();
1882 if(!ci)
1884 SendSysMessage(LANG_WRONG_PET_TYPE);
1885 SetSentErrorMessage(true);
1886 return false;
1889 CreatureFamilyEntry const *pet_family = sCreatureFamilyStore.LookupEntry(ci->family);
1890 if(!pet_family)
1892 SendSysMessage(LANG_WRONG_PET_TYPE);
1893 SetSentErrorMessage(true);
1894 return false;
1897 if(pet_family->petTalentType < 0) // not hunter pet
1899 SendSysMessage(LANG_WRONG_PET_TYPE);
1900 SetSentErrorMessage(true);
1901 return false;
1904 for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
1906 TalentEntry const *talentInfo = sTalentStore.LookupEntry(i);
1907 if(!talentInfo)
1908 continue;
1910 TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab );
1911 if(!talentTabInfo)
1912 continue;
1914 // prevent learn talent for different family (cheating)
1915 if(((1 << pet_family->petTalentType) & talentTabInfo->petTalentMask)==0)
1916 continue;
1918 // search highest talent rank
1919 uint32 spellid = 0;
1921 for(int rank = MAX_TALENT_RANK-1; rank >= 0; --rank)
1923 if(talentInfo->RankID[rank]!=0)
1925 spellid = talentInfo->RankID[rank];
1926 break;
1930 if(!spellid) // ??? none spells in talent
1931 continue;
1933 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid);
1934 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
1935 continue;
1937 // learn highest rank of talent and learn all non-talent spell ranks (recursive by tree)
1938 pet->learnSpellHighRank(spellid);
1941 SendSysMessage(LANG_COMMAND_LEARN_PET_TALENTS);
1942 return true;
1945 bool ChatHandler::HandleLearnAllLangCommand(const char* /*args*/)
1947 // skipping UNIVERSAL language (0)
1948 for(int i = 1; i < LANGUAGES_COUNT; ++i)
1949 m_session->GetPlayer()->learnSpell(lang_description[i].spell_id,false);
1951 SendSysMessage(LANG_COMMAND_LEARN_ALL_LANG);
1952 return true;
1955 bool ChatHandler::HandleLearnAllDefaultCommand(const char* args)
1957 Player* target;
1958 if(!extractPlayerTarget((char*)args,&target))
1959 return false;
1961 target->learnDefaultSpells();
1962 target->learnQuestRewardedSpells();
1964 PSendSysMessage(LANG_COMMAND_LEARN_ALL_DEFAULT_AND_QUEST,GetNameLink(target).c_str());
1965 return true;
1968 bool ChatHandler::HandleLearnCommand(const char* args)
1970 Player* targetPlayer = getSelectedPlayer();
1972 if(!targetPlayer)
1974 SendSysMessage(LANG_PLAYER_NOT_FOUND);
1975 SetSentErrorMessage(true);
1976 return false;
1979 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
1980 uint32 spell = extractSpellIdFromLink((char*)args);
1981 if(!spell || !sSpellStore.LookupEntry(spell))
1982 return false;
1984 char const* allStr = strtok(NULL," ");
1985 bool allRanks = allStr ? (strncmp(allStr, "all", strlen(allStr)) == 0) : false;
1987 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
1988 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
1990 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
1991 SetSentErrorMessage(true);
1992 return false;
1995 if (!allRanks && targetPlayer->HasSpell(spell))
1997 if(targetPlayer == m_session->GetPlayer())
1998 SendSysMessage(LANG_YOU_KNOWN_SPELL);
1999 else
2000 PSendSysMessage(LANG_TARGET_KNOWN_SPELL,GetNameLink(targetPlayer).c_str());
2001 SetSentErrorMessage(true);
2002 return false;
2005 if(allRanks)
2006 targetPlayer->learnSpellHighRank(spell);
2007 else
2008 targetPlayer->learnSpell(spell,false);
2010 return true;
2013 bool ChatHandler::HandleAddItemCommand(const char* args)
2015 if (!*args)
2016 return false;
2018 uint32 itemId = 0;
2020 if(args[0]=='[') // [name] manual form
2022 char* citemName = strtok((char*)args, "]");
2024 if(citemName && citemName[0])
2026 std::string itemName = citemName+1;
2027 WorldDatabase.escape_string(itemName);
2028 QueryResult *result = WorldDatabase.PQuery("SELECT entry FROM item_template WHERE name = '%s'", itemName.c_str());
2029 if (!result)
2031 PSendSysMessage(LANG_COMMAND_COULDNOTFIND, citemName+1);
2032 SetSentErrorMessage(true);
2033 return false;
2035 itemId = result->Fetch()->GetUInt16();
2036 delete result;
2038 else
2039 return false;
2041 else // item_id or [name] Shift-click form |color|Hitem:item_id:0:0:0|h[name]|h|r
2043 char* cId = extractKeyFromLink((char*)args,"Hitem");
2044 if(!cId)
2045 return false;
2046 itemId = atol(cId);
2049 char* ccount = strtok(NULL, " ");
2051 int32 count = 1;
2053 if (ccount)
2054 count = strtol(ccount, NULL, 10);
2056 if (count == 0)
2057 count = 1;
2059 Player* pl = m_session->GetPlayer();
2060 Player* plTarget = getSelectedPlayer();
2061 if(!plTarget)
2062 plTarget = pl;
2064 sLog.outDetail(GetMangosString(LANG_ADDITEM), itemId, count);
2066 ItemPrototype const *pProto = objmgr.GetItemPrototype(itemId);
2067 if(!pProto)
2069 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId);
2070 SetSentErrorMessage(true);
2071 return false;
2074 //Subtract
2075 if (count < 0)
2077 plTarget->DestroyItemCount(itemId, -count, true, false);
2078 PSendSysMessage(LANG_REMOVEITEM, itemId, -count, GetNameLink(plTarget).c_str());
2079 return true;
2082 //Adding items
2083 uint32 noSpaceForCount = 0;
2085 // check space and find places
2086 ItemPosCountVec dest;
2087 uint8 msg = plTarget->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, itemId, count, &noSpaceForCount );
2088 if( msg != EQUIP_ERR_OK ) // convert to possible store amount
2089 count -= noSpaceForCount;
2091 if( count == 0 || dest.empty()) // can't add any
2093 PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount );
2094 SetSentErrorMessage(true);
2095 return false;
2098 Item* item = plTarget->StoreNewItem( dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId));
2100 // remove binding (let GM give it to another player later)
2101 if(pl==plTarget)
2102 for(ItemPosCountVec::const_iterator itr = dest.begin(); itr != dest.end(); ++itr)
2103 if(Item* item1 = pl->GetItemByPos(itr->pos))
2104 item1->SetBinding( false );
2106 if(count > 0 && item)
2108 pl->SendNewItem(item,count,false,true);
2109 if(pl!=plTarget)
2110 plTarget->SendNewItem(item,count,true,false);
2113 if(noSpaceForCount > 0)
2114 PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount);
2116 return true;
2119 bool ChatHandler::HandleAddItemSetCommand(const char* args)
2121 if (!*args)
2122 return false;
2124 char* cId = extractKeyFromLink((char*)args,"Hitemset"); // number or [name] Shift-click form |color|Hitemset:itemset_id|h[name]|h|r
2125 if (!cId)
2126 return false;
2128 uint32 itemsetId = atol(cId);
2130 // prevent generation all items with itemset field value '0'
2131 if (itemsetId == 0)
2133 PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND,itemsetId);
2134 SetSentErrorMessage(true);
2135 return false;
2138 Player* pl = m_session->GetPlayer();
2139 Player* plTarget = getSelectedPlayer();
2140 if(!plTarget)
2141 plTarget = pl;
2143 sLog.outDetail(GetMangosString(LANG_ADDITEMSET), itemsetId);
2145 bool found = false;
2146 for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
2148 ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype>(id);
2149 if (!pProto)
2150 continue;
2152 if (pProto->ItemSet == itemsetId)
2154 found = true;
2155 ItemPosCountVec dest;
2156 uint8 msg = plTarget->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, pProto->ItemId, 1 );
2157 if (msg == EQUIP_ERR_OK)
2159 Item* item = plTarget->StoreNewItem( dest, pProto->ItemId, true);
2161 // remove binding (let GM give it to another player later)
2162 if (pl==plTarget)
2163 item->SetBinding( false );
2165 pl->SendNewItem(item,1,false,true);
2166 if (pl!=plTarget)
2167 plTarget->SendNewItem(item,1,true,false);
2169 else
2171 pl->SendEquipError( msg, NULL, NULL );
2172 PSendSysMessage(LANG_ITEM_CANNOT_CREATE, pProto->ItemId, 1);
2177 if (!found)
2179 PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND,itemsetId);
2181 SetSentErrorMessage(true);
2182 return false;
2185 return true;
2188 bool ChatHandler::HandleListItemCommand(const char* args)
2190 if(!*args)
2191 return false;
2193 char* cId = extractKeyFromLink((char*)args,"Hitem");
2194 if(!cId)
2195 return false;
2197 uint32 item_id = atol(cId);
2198 if(!item_id)
2200 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
2201 SetSentErrorMessage(true);
2202 return false;
2205 ItemPrototype const* itemProto = objmgr.GetItemPrototype(item_id);
2206 if(!itemProto)
2208 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
2209 SetSentErrorMessage(true);
2210 return false;
2213 char* c_count = strtok(NULL, " ");
2214 int count = c_count ? atol(c_count) : 10;
2216 if(count < 0)
2217 return false;
2219 QueryResult *result;
2221 // inventory case
2222 uint32 inv_count = 0;
2223 result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM character_inventory WHERE item_template='%u'",item_id);
2224 if(result)
2226 inv_count = (*result)[0].GetUInt32();
2227 delete result;
2230 result=CharacterDatabase.PQuery(
2231 // 0 1 2 3 4 5
2232 "SELECT ci.item, cibag.slot AS bag, ci.slot, ci.guid, characters.account,characters.name "
2233 "FROM character_inventory AS ci LEFT JOIN character_inventory AS cibag ON (cibag.item=ci.bag),characters "
2234 "WHERE ci.item_template='%u' AND ci.guid = characters.guid LIMIT %u ",
2235 item_id,uint32(count));
2237 if(result)
2241 Field *fields = result->Fetch();
2242 uint32 item_guid = fields[0].GetUInt32();
2243 uint32 item_bag = fields[1].GetUInt32();
2244 uint32 item_slot = fields[2].GetUInt32();
2245 uint32 owner_guid = fields[3].GetUInt32();
2246 uint32 owner_acc = fields[4].GetUInt32();
2247 std::string owner_name = fields[5].GetCppString();
2249 char const* item_pos = 0;
2250 if(Player::IsEquipmentPos(item_bag,item_slot))
2251 item_pos = "[equipped]";
2252 else if(Player::IsInventoryPos(item_bag,item_slot))
2253 item_pos = "[in inventory]";
2254 else if(Player::IsBankPos(item_bag,item_slot))
2255 item_pos = "[in bank]";
2256 else
2257 item_pos = "";
2259 PSendSysMessage(LANG_ITEMLIST_SLOT,
2260 item_guid,owner_name.c_str(),owner_guid,owner_acc,item_pos);
2261 } while (result->NextRow());
2263 int64 res_count = result->GetRowCount();
2265 delete result;
2267 if(count > res_count)
2268 count-=res_count;
2269 else if(count)
2270 count = 0;
2273 // mail case
2274 uint32 mail_count = 0;
2275 result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM mail_items WHERE item_template='%u'", item_id);
2276 if(result)
2278 mail_count = (*result)[0].GetUInt32();
2279 delete result;
2282 if(count > 0)
2284 result=CharacterDatabase.PQuery(
2285 // 0 1 2 3 4 5 6
2286 "SELECT mail_items.item_guid, mail.sender, mail.receiver, char_s.account, char_s.name, char_r.account, char_r.name "
2287 "FROM mail,mail_items,characters as char_s,characters as char_r "
2288 "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",
2289 item_id,uint32(count));
2291 else
2292 result = NULL;
2294 if(result)
2298 Field *fields = result->Fetch();
2299 uint32 item_guid = fields[0].GetUInt32();
2300 uint32 item_s = fields[1].GetUInt32();
2301 uint32 item_r = fields[2].GetUInt32();
2302 uint32 item_s_acc = fields[3].GetUInt32();
2303 std::string item_s_name = fields[4].GetCppString();
2304 uint32 item_r_acc = fields[5].GetUInt32();
2305 std::string item_r_name = fields[6].GetCppString();
2307 char const* item_pos = "[in mail]";
2309 PSendSysMessage(LANG_ITEMLIST_MAIL,
2310 item_guid,item_s_name.c_str(),item_s,item_s_acc,item_r_name.c_str(),item_r,item_r_acc,item_pos);
2311 } while (result->NextRow());
2313 int64 res_count = result->GetRowCount();
2315 delete result;
2317 if(count > res_count)
2318 count-=res_count;
2319 else if(count)
2320 count = 0;
2323 // auction case
2324 uint32 auc_count = 0;
2325 result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM auctionhouse WHERE item_template='%u'",item_id);
2326 if(result)
2328 auc_count = (*result)[0].GetUInt32();
2329 delete result;
2332 if(count > 0)
2334 result=CharacterDatabase.PQuery(
2335 // 0 1 2 3
2336 "SELECT auctionhouse.itemguid, auctionhouse.itemowner, characters.account, characters.name "
2337 "FROM auctionhouse,characters WHERE auctionhouse.item_template='%u' AND characters.guid = auctionhouse.itemowner LIMIT %u",
2338 item_id,uint32(count));
2340 else
2341 result = NULL;
2343 if(result)
2347 Field *fields = result->Fetch();
2348 uint32 item_guid = fields[0].GetUInt32();
2349 uint32 owner = fields[1].GetUInt32();
2350 uint32 owner_acc = fields[2].GetUInt32();
2351 std::string owner_name = fields[3].GetCppString();
2353 char const* item_pos = "[in auction]";
2355 PSendSysMessage(LANG_ITEMLIST_AUCTION, item_guid, owner_name.c_str(), owner, owner_acc,item_pos);
2356 } while (result->NextRow());
2358 delete result;
2361 // guild bank case
2362 uint32 guild_count = 0;
2363 result=CharacterDatabase.PQuery("SELECT COUNT(item_entry) FROM guild_bank_item WHERE item_entry='%u'",item_id);
2364 if(result)
2366 guild_count = (*result)[0].GetUInt32();
2367 delete result;
2370 result=CharacterDatabase.PQuery(
2371 // 0 1 2
2372 "SELECT gi.item_guid, gi.guildid, guild.name "
2373 "FROM guild_bank_item AS gi, guild WHERE gi.item_entry='%u' AND gi.guildid = guild.guildid LIMIT %u ",
2374 item_id,uint32(count));
2376 if(result)
2380 Field *fields = result->Fetch();
2381 uint32 item_guid = fields[0].GetUInt32();
2382 uint32 guild_guid = fields[1].GetUInt32();
2383 std::string guild_name = fields[2].GetCppString();
2385 char const* item_pos = "[in guild bank]";
2387 PSendSysMessage(LANG_ITEMLIST_GUILD,item_guid,guild_name.c_str(),guild_guid,item_pos);
2388 } while (result->NextRow());
2390 int64 res_count = result->GetRowCount();
2392 delete result;
2394 if(count > res_count)
2395 count-=res_count;
2396 else if(count)
2397 count = 0;
2400 if(inv_count+mail_count+auc_count+guild_count == 0)
2402 SendSysMessage(LANG_COMMAND_NOITEMFOUND);
2403 SetSentErrorMessage(true);
2404 return false;
2407 PSendSysMessage(LANG_COMMAND_LISTITEMMESSAGE,item_id,inv_count+mail_count+auc_count+guild_count,inv_count,mail_count,auc_count,guild_count);
2409 return true;
2412 bool ChatHandler::HandleListObjectCommand(const char* args)
2414 if(!*args)
2415 return false;
2417 // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r
2418 char* cId = extractKeyFromLink((char*)args,"Hgameobject_entry");
2419 if(!cId)
2420 return false;
2422 uint32 go_id = atol(cId);
2423 if(!go_id)
2425 PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id);
2426 SetSentErrorMessage(true);
2427 return false;
2430 GameObjectInfo const * gInfo = objmgr.GetGameObjectInfo(go_id);
2431 if(!gInfo)
2433 PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id);
2434 SetSentErrorMessage(true);
2435 return false;
2438 char* c_count = strtok(NULL, " ");
2439 int count = c_count ? atol(c_count) : 10;
2441 if(count < 0)
2442 return false;
2444 QueryResult *result;
2446 uint32 obj_count = 0;
2447 result=WorldDatabase.PQuery("SELECT COUNT(guid) FROM gameobject WHERE id='%u'",go_id);
2448 if(result)
2450 obj_count = (*result)[0].GetUInt32();
2451 delete result;
2454 if(m_session)
2456 Player* pl = m_session->GetPlayer();
2457 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",
2458 pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),go_id,uint32(count));
2460 else
2461 result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map FROM gameobject WHERE id = '%u' LIMIT %u",
2462 go_id,uint32(count));
2464 if (result)
2468 Field *fields = result->Fetch();
2469 uint32 guid = fields[0].GetUInt32();
2470 float x = fields[1].GetFloat();
2471 float y = fields[2].GetFloat();
2472 float z = fields[3].GetFloat();
2473 int mapid = fields[4].GetUInt16();
2475 if (m_session)
2476 PSendSysMessage(LANG_GO_LIST_CHAT, guid, guid, gInfo->name, x, y, z, mapid);
2477 else
2478 PSendSysMessage(LANG_GO_LIST_CONSOLE, guid, gInfo->name, x, y, z, mapid);
2479 } while (result->NextRow());
2481 delete result;
2484 PSendSysMessage(LANG_COMMAND_LISTOBJMESSAGE,go_id,obj_count);
2485 return true;
2488 bool ChatHandler::HandleListCreatureCommand(const char* args)
2490 if(!*args)
2491 return false;
2493 // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
2494 char* cId = extractKeyFromLink((char*)args,"Hcreature_entry");
2495 if(!cId)
2496 return false;
2498 uint32 cr_id = atol(cId);
2499 if(!cr_id)
2501 PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id);
2502 SetSentErrorMessage(true);
2503 return false;
2506 CreatureInfo const* cInfo = objmgr.GetCreatureTemplate(cr_id);
2507 if(!cInfo)
2509 PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id);
2510 SetSentErrorMessage(true);
2511 return false;
2514 char* c_count = strtok(NULL, " ");
2515 int count = c_count ? atol(c_count) : 10;
2517 if(count < 0)
2518 return false;
2520 QueryResult *result;
2522 uint32 cr_count = 0;
2523 result=WorldDatabase.PQuery("SELECT COUNT(guid) FROM creature WHERE id='%u'",cr_id);
2524 if(result)
2526 cr_count = (*result)[0].GetUInt32();
2527 delete result;
2530 if(m_session)
2532 Player* pl = m_session->GetPlayer();
2533 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",
2534 pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), cr_id,uint32(count));
2536 else
2537 result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map FROM creature WHERE id = '%u' LIMIT %u",
2538 cr_id,uint32(count));
2540 if (result)
2544 Field *fields = result->Fetch();
2545 uint32 guid = fields[0].GetUInt32();
2546 float x = fields[1].GetFloat();
2547 float y = fields[2].GetFloat();
2548 float z = fields[3].GetFloat();
2549 int mapid = fields[4].GetUInt16();
2551 if (m_session)
2552 PSendSysMessage(LANG_CREATURE_LIST_CHAT, guid, guid, cInfo->Name, x, y, z, mapid);
2553 else
2554 PSendSysMessage(LANG_CREATURE_LIST_CONSOLE, guid, cInfo->Name, x, y, z, mapid);
2555 } while (result->NextRow());
2557 delete result;
2560 PSendSysMessage(LANG_COMMAND_LISTCREATUREMESSAGE,cr_id,cr_count);
2561 return true;
2564 bool ChatHandler::HandleLookupItemCommand(const char* args)
2566 if(!*args)
2567 return false;
2569 std::string namepart = args;
2570 std::wstring wnamepart;
2572 // converting string that we try to find to lower case
2573 if(!Utf8toWStr(namepart,wnamepart))
2574 return false;
2576 wstrToLower(wnamepart);
2578 uint32 counter = 0;
2580 // Search in `item_template`
2581 for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
2583 ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype >(id);
2584 if(!pProto)
2585 continue;
2587 int loc_idx = GetSessionDbLocaleIndex();
2588 if ( loc_idx >= 0 )
2590 ItemLocale const *il = objmgr.GetItemLocale(pProto->ItemId);
2591 if (il)
2593 if (il->Name.size() > loc_idx && !il->Name[loc_idx].empty())
2595 std::string name = il->Name[loc_idx];
2597 if (Utf8FitTo(name, wnamepart))
2599 if (m_session)
2600 PSendSysMessage(LANG_ITEM_LIST_CHAT, id, id, name.c_str());
2601 else
2602 PSendSysMessage(LANG_ITEM_LIST_CONSOLE, id, name.c_str());
2603 ++counter;
2604 continue;
2610 std::string name = pProto->Name1;
2611 if(name.empty())
2612 continue;
2614 if (Utf8FitTo(name, wnamepart))
2616 if (m_session)
2617 PSendSysMessage(LANG_ITEM_LIST_CHAT, id, id, name.c_str());
2618 else
2619 PSendSysMessage(LANG_ITEM_LIST_CONSOLE, id, name.c_str());
2620 ++counter;
2624 if (counter==0)
2625 SendSysMessage(LANG_COMMAND_NOITEMFOUND);
2627 return true;
2630 bool ChatHandler::HandleLookupItemSetCommand(const char* args)
2632 if(!*args)
2633 return false;
2635 std::string namepart = args;
2636 std::wstring wnamepart;
2638 if(!Utf8toWStr(namepart,wnamepart))
2639 return false;
2641 // converting string that we try to find to lower case
2642 wstrToLower( wnamepart );
2644 uint32 counter = 0; // Counter for figure out that we found smth.
2646 // Search in ItemSet.dbc
2647 for (uint32 id = 0; id < sItemSetStore.GetNumRows(); id++)
2649 ItemSetEntry const *set = sItemSetStore.LookupEntry(id);
2650 if(set)
2652 int loc = GetSessionDbcLocale();
2653 std::string name = set->name[loc];
2654 if(name.empty())
2655 continue;
2657 if (!Utf8FitTo(name, wnamepart))
2659 loc = 0;
2660 for(; loc < MAX_LOCALE; ++loc)
2662 if(loc==GetSessionDbcLocale())
2663 continue;
2665 name = set->name[loc];
2666 if(name.empty())
2667 continue;
2669 if (Utf8FitTo(name, wnamepart))
2670 break;
2674 if(loc < MAX_LOCALE)
2676 // send item set in "id - [namedlink locale]" format
2677 if (m_session)
2678 PSendSysMessage(LANG_ITEMSET_LIST_CHAT,id,id,name.c_str(),localeNames[loc]);
2679 else
2680 PSendSysMessage(LANG_ITEMSET_LIST_CONSOLE,id,name.c_str(),localeNames[loc]);
2681 ++counter;
2685 if (counter == 0) // if counter == 0 then we found nth
2686 SendSysMessage(LANG_COMMAND_NOITEMSETFOUND);
2687 return true;
2690 bool ChatHandler::HandleLookupSkillCommand(const char* args)
2692 if(!*args)
2693 return false;
2695 // can be NULL in console call
2696 Player* target = getSelectedPlayer();
2698 std::string namepart = args;
2699 std::wstring wnamepart;
2701 if(!Utf8toWStr(namepart,wnamepart))
2702 return false;
2704 // converting string that we try to find to lower case
2705 wstrToLower( wnamepart );
2707 uint32 counter = 0; // Counter for figure out that we found smth.
2709 // Search in SkillLine.dbc
2710 for (uint32 id = 0; id < sSkillLineStore.GetNumRows(); id++)
2712 SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(id);
2713 if(skillInfo)
2715 int loc = GetSessionDbcLocale();
2716 std::string name = skillInfo->name[loc];
2717 if(name.empty())
2718 continue;
2720 if (!Utf8FitTo(name, wnamepart))
2722 loc = 0;
2723 for(; loc < MAX_LOCALE; ++loc)
2725 if(loc==GetSessionDbcLocale())
2726 continue;
2728 name = skillInfo->name[loc];
2729 if(name.empty())
2730 continue;
2732 if (Utf8FitTo(name, wnamepart))
2733 break;
2737 if(loc < MAX_LOCALE)
2739 char valStr[50] = "";
2740 char const* knownStr = "";
2741 if(target && target->HasSkill(id))
2743 knownStr = GetMangosString(LANG_KNOWN);
2744 uint32 curValue = target->GetPureSkillValue(id);
2745 uint32 maxValue = target->GetPureMaxSkillValue(id);
2746 uint32 permValue = target->GetSkillPermBonusValue(id);
2747 uint32 tempValue = target->GetSkillTempBonusValue(id);
2749 char const* valFormat = GetMangosString(LANG_SKILL_VALUES);
2750 snprintf(valStr,50,valFormat,curValue,maxValue,permValue,tempValue);
2753 // send skill in "id - [namedlink locale]" format
2754 if (m_session)
2755 PSendSysMessage(LANG_SKILL_LIST_CHAT,id,id,name.c_str(),localeNames[loc],knownStr,valStr);
2756 else
2757 PSendSysMessage(LANG_SKILL_LIST_CONSOLE,id,name.c_str(),localeNames[loc],knownStr,valStr);
2759 ++counter;
2763 if (counter == 0) // if counter == 0 then we found nth
2764 SendSysMessage(LANG_COMMAND_NOSKILLFOUND);
2765 return true;
2768 bool ChatHandler::HandleLookupSpellCommand(const char* args)
2770 if(!*args)
2771 return false;
2773 // can be NULL at console call
2774 Player* target = getSelectedPlayer();
2776 std::string namepart = args;
2777 std::wstring wnamepart;
2779 if(!Utf8toWStr(namepart,wnamepart))
2780 return false;
2782 // converting string that we try to find to lower case
2783 wstrToLower( wnamepart );
2785 uint32 counter = 0; // Counter for figure out that we found smth.
2787 // Search in Spell.dbc
2788 for (uint32 id = 0; id < sSpellStore.GetNumRows(); id++)
2790 SpellEntry const *spellInfo = sSpellStore.LookupEntry(id);
2791 if(spellInfo)
2793 int loc = GetSessionDbcLocale();
2794 std::string name = spellInfo->SpellName[loc];
2795 if(name.empty())
2796 continue;
2798 if (!Utf8FitTo(name, wnamepart))
2800 loc = 0;
2801 for(; loc < MAX_LOCALE; ++loc)
2803 if(loc==GetSessionDbcLocale())
2804 continue;
2806 name = spellInfo->SpellName[loc];
2807 if(name.empty())
2808 continue;
2810 if (Utf8FitTo(name, wnamepart))
2811 break;
2815 if(loc < MAX_LOCALE)
2817 bool known = target && target->HasSpell(id);
2818 bool learn = (spellInfo->Effect[0] == SPELL_EFFECT_LEARN_SPELL);
2820 uint32 talentCost = GetTalentSpellCost(id);
2822 bool talent = (talentCost > 0);
2823 bool passive = IsPassiveSpell(id);
2824 bool active = target && target->HasAura(id);
2826 // unit32 used to prevent interpreting uint8 as char at output
2827 // find rank of learned spell for learning spell, or talent rank
2828 uint32 rank = talentCost ? talentCost : spellmgr.GetSpellRank(learn ? spellInfo->EffectTriggerSpell[0] : id);
2830 // send spell in "id - [name, rank N] [talent] [passive] [learn] [known]" format
2831 std::ostringstream ss;
2832 if (m_session)
2833 ss << id << " - |cffffffff|Hspell:" << id << "|h[" << name;
2834 else
2835 ss << id << " - " << name;
2837 // include rank in link name
2838 if(rank)
2839 ss << GetMangosString(LANG_SPELL_RANK) << rank;
2841 if (m_session)
2842 ss << " " << localeNames[loc] << "]|h|r";
2843 else
2844 ss << " " << localeNames[loc];
2846 if(talent)
2847 ss << GetMangosString(LANG_TALENT);
2848 if(passive)
2849 ss << GetMangosString(LANG_PASSIVE);
2850 if(learn)
2851 ss << GetMangosString(LANG_LEARN);
2852 if(known)
2853 ss << GetMangosString(LANG_KNOWN);
2854 if(active)
2855 ss << GetMangosString(LANG_ACTIVE);
2857 SendSysMessage(ss.str().c_str());
2859 ++counter;
2863 if (counter == 0) // if counter == 0 then we found nth
2864 SendSysMessage(LANG_COMMAND_NOSPELLFOUND);
2865 return true;
2868 bool ChatHandler::HandleLookupQuestCommand(const char* args)
2870 if(!*args)
2871 return false;
2873 // can be NULL at console call
2874 Player* target = getSelectedPlayer();
2876 std::string namepart = args;
2877 std::wstring wnamepart;
2879 // converting string that we try to find to lower case
2880 if(!Utf8toWStr(namepart,wnamepart))
2881 return false;
2883 wstrToLower(wnamepart);
2885 uint32 counter = 0 ;
2887 ObjectMgr::QuestMap const& qTemplates = objmgr.GetQuestTemplates();
2888 for (ObjectMgr::QuestMap::const_iterator iter = qTemplates.begin(); iter != qTemplates.end(); ++iter)
2890 Quest * qinfo = iter->second;
2892 int loc_idx = GetSessionDbLocaleIndex();
2893 if ( loc_idx >= 0 )
2895 QuestLocale const *il = objmgr.GetQuestLocale(qinfo->GetQuestId());
2896 if (il)
2898 if (il->Title.size() > loc_idx && !il->Title[loc_idx].empty())
2900 std::string title = il->Title[loc_idx];
2902 if (Utf8FitTo(title, wnamepart))
2904 char const* statusStr = "";
2906 if(target)
2908 QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId());
2910 if(status == QUEST_STATUS_COMPLETE)
2912 if(target->GetQuestRewardStatus(qinfo->GetQuestId()))
2913 statusStr = GetMangosString(LANG_COMMAND_QUEST_REWARDED);
2914 else
2915 statusStr = GetMangosString(LANG_COMMAND_QUEST_COMPLETE);
2917 else if(status == QUEST_STATUS_INCOMPLETE)
2918 statusStr = GetMangosString(LANG_COMMAND_QUEST_ACTIVE);
2921 if (m_session)
2922 PSendSysMessage(LANG_QUEST_LIST_CHAT,qinfo->GetQuestId(),qinfo->GetQuestId(),title.c_str(),statusStr);
2923 else
2924 PSendSysMessage(LANG_QUEST_LIST_CONSOLE,qinfo->GetQuestId(),title.c_str(),statusStr);
2925 ++counter;
2926 continue;
2932 std::string title = qinfo->GetTitle();
2933 if(title.empty())
2934 continue;
2936 if (Utf8FitTo(title, wnamepart))
2938 char const* statusStr = "";
2940 if(target)
2942 QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId());
2944 if(status == QUEST_STATUS_COMPLETE)
2946 if(target->GetQuestRewardStatus(qinfo->GetQuestId()))
2947 statusStr = GetMangosString(LANG_COMMAND_QUEST_REWARDED);
2948 else
2949 statusStr = GetMangosString(LANG_COMMAND_QUEST_COMPLETE);
2951 else if(status == QUEST_STATUS_INCOMPLETE)
2952 statusStr = GetMangosString(LANG_COMMAND_QUEST_ACTIVE);
2955 if (m_session)
2956 PSendSysMessage(LANG_QUEST_LIST_CHAT,qinfo->GetQuestId(),qinfo->GetQuestId(),title.c_str(),statusStr);
2957 else
2958 PSendSysMessage(LANG_QUEST_LIST_CONSOLE,qinfo->GetQuestId(),title.c_str(),statusStr);
2960 ++counter;
2964 if (counter==0)
2965 SendSysMessage(LANG_COMMAND_NOQUESTFOUND);
2967 return true;
2970 bool ChatHandler::HandleLookupCreatureCommand(const char* args)
2972 if (!*args)
2973 return false;
2975 std::string namepart = args;
2976 std::wstring wnamepart;
2978 // converting string that we try to find to lower case
2979 if (!Utf8toWStr (namepart,wnamepart))
2980 return false;
2982 wstrToLower (wnamepart);
2984 uint32 counter = 0;
2986 for (uint32 id = 0; id< sCreatureStorage.MaxEntry; ++id)
2988 CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo> (id);
2989 if(!cInfo)
2990 continue;
2992 int loc_idx = GetSessionDbLocaleIndex();
2993 if (loc_idx >= 0)
2995 CreatureLocale const *cl = objmgr.GetCreatureLocale (id);
2996 if (cl)
2998 if (cl->Name.size() > loc_idx && !cl->Name[loc_idx].empty ())
3000 std::string name = cl->Name[loc_idx];
3002 if (Utf8FitTo (name, wnamepart))
3004 if (m_session)
3005 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CHAT, id, id, name.c_str ());
3006 else
3007 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CONSOLE, id, name.c_str ());
3008 ++counter;
3009 continue;
3015 std::string name = cInfo->Name;
3016 if (name.empty ())
3017 continue;
3019 if (Utf8FitTo(name, wnamepart))
3021 if (m_session)
3022 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CHAT, id, id, name.c_str ());
3023 else
3024 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CONSOLE, id, name.c_str ());
3025 ++counter;
3029 if (counter==0)
3030 SendSysMessage (LANG_COMMAND_NOCREATUREFOUND);
3032 return true;
3035 bool ChatHandler::HandleLookupObjectCommand(const char* args)
3037 if(!*args)
3038 return false;
3040 std::string namepart = args;
3041 std::wstring wnamepart;
3043 // converting string that we try to find to lower case
3044 if(!Utf8toWStr(namepart,wnamepart))
3045 return false;
3047 wstrToLower(wnamepart);
3049 uint32 counter = 0;
3051 for (uint32 id = 0; id< sGOStorage.MaxEntry; id++ )
3053 GameObjectInfo const* gInfo = sGOStorage.LookupEntry<GameObjectInfo>(id);
3054 if(!gInfo)
3055 continue;
3057 int loc_idx = GetSessionDbLocaleIndex();
3058 if ( loc_idx >= 0 )
3060 GameObjectLocale const *gl = objmgr.GetGameObjectLocale(id);
3061 if (gl)
3063 if (gl->Name.size() > loc_idx && !gl->Name[loc_idx].empty())
3065 std::string name = gl->Name[loc_idx];
3067 if (Utf8FitTo(name, wnamepart))
3069 if (m_session)
3070 PSendSysMessage(LANG_GO_ENTRY_LIST_CHAT, id, id, name.c_str());
3071 else
3072 PSendSysMessage(LANG_GO_ENTRY_LIST_CONSOLE, id, name.c_str());
3073 ++counter;
3074 continue;
3080 std::string name = gInfo->name;
3081 if(name.empty())
3082 continue;
3084 if(Utf8FitTo(name, wnamepart))
3086 if (m_session)
3087 PSendSysMessage(LANG_GO_ENTRY_LIST_CHAT, id, id, name.c_str());
3088 else
3089 PSendSysMessage(LANG_GO_ENTRY_LIST_CONSOLE, id, name.c_str());
3090 ++counter;
3094 if(counter==0)
3095 SendSysMessage(LANG_COMMAND_NOGAMEOBJECTFOUND);
3097 return true;
3100 bool ChatHandler::HandleLookupTaxiNodeCommand(const char * args)
3102 if(!*args)
3103 return false;
3105 std::string namepart = args;
3106 std::wstring wnamepart;
3108 if(!Utf8toWStr(namepart,wnamepart))
3109 return false;
3111 // converting string that we try to find to lower case
3112 wstrToLower( wnamepart );
3114 uint32 counter = 0; // Counter for figure out that we found smth.
3116 // Search in TaxiNodes.dbc
3117 for (uint32 id = 0; id < sTaxiNodesStore.GetNumRows(); id++)
3119 TaxiNodesEntry const *nodeEntry = sTaxiNodesStore.LookupEntry(id);
3120 if(nodeEntry)
3122 int loc = GetSessionDbcLocale();
3123 std::string name = nodeEntry->name[loc];
3124 if(name.empty())
3125 continue;
3127 if (!Utf8FitTo(name, wnamepart))
3129 loc = 0;
3130 for(; loc < MAX_LOCALE; ++loc)
3132 if(loc==GetSessionDbcLocale())
3133 continue;
3135 name = nodeEntry->name[loc];
3136 if(name.empty())
3137 continue;
3139 if (Utf8FitTo(name, wnamepart))
3140 break;
3144 if(loc < MAX_LOCALE)
3146 // send taxinode in "id - [name] (Map:m X:x Y:y Z:z)" format
3147 if (m_session)
3148 PSendSysMessage (LANG_TAXINODE_ENTRY_LIST_CHAT, id, id, name.c_str(),localeNames[loc],
3149 nodeEntry->map_id,nodeEntry->x,nodeEntry->y,nodeEntry->z);
3150 else
3151 PSendSysMessage (LANG_TAXINODE_ENTRY_LIST_CONSOLE, id, name.c_str(), localeNames[loc],
3152 nodeEntry->map_id,nodeEntry->x,nodeEntry->y,nodeEntry->z);
3153 ++counter;
3157 if (counter == 0) // if counter == 0 then we found nth
3158 SendSysMessage(LANG_COMMAND_NOSPELLFOUND);
3159 return true;
3162 /** \brief GM command level 3 - Create a guild.
3164 * This command allows a GM (level 3) to create a guild.
3166 * The "args" parameter contains the name of the guild leader
3167 * and then the name of the guild.
3170 bool ChatHandler::HandleGuildCreateCommand(const char* args)
3172 if(!*args)
3173 return false;
3175 // if not guild name only (in "") then player name
3176 Player* target;
3177 if(!extractPlayerTarget(*args!='"' ? (char*)args : NULL, &target))
3178 return false;
3180 char* tailStr = *args!='"' ? strtok(NULL, "") : (char*)args;
3181 if(!tailStr)
3182 return false;
3184 char* guildStr = extractQuotedArg(tailStr);
3185 if(!guildStr)
3186 return false;
3188 std::string guildname = guildStr;
3190 if (target->GetGuildId())
3192 SendSysMessage (LANG_PLAYER_IN_GUILD);
3193 return true;
3196 Guild *guild = new Guild;
3197 if (!guild->create (target,guildname))
3199 delete guild;
3200 SendSysMessage (LANG_GUILD_NOT_CREATED);
3201 SetSentErrorMessage (true);
3202 return false;
3205 objmgr.AddGuild (guild);
3206 return true;
3209 bool ChatHandler::HandleGuildInviteCommand(const char *args)
3211 if(!*args)
3212 return false;
3214 // if not guild name only (in "") then player name
3215 uint64 target_guid;
3216 if(!extractPlayerTarget(*args!='"' ? (char*)args : NULL, NULL, &target_guid))
3217 return false;
3219 char* tailStr = *args!='"' ? strtok(NULL, "") : (char*)args;
3220 if(!tailStr)
3221 return false;
3223 char* guildStr = extractQuotedArg(tailStr);
3224 if(!guildStr)
3225 return false;
3227 std::string glName = guildStr;
3228 Guild* targetGuild = objmgr.GetGuildByName (glName);
3229 if (!targetGuild)
3230 return false;
3232 // player's guild membership checked in AddMember before add
3233 if (!targetGuild->AddMember (target_guid,targetGuild->GetLowestRank ()))
3234 return false;
3236 return true;
3239 bool ChatHandler::HandleGuildUninviteCommand(const char *args)
3241 Player* target;
3242 uint64 target_guid;
3243 if(!extractPlayerTarget((char*)args,&target,&target_guid))
3244 return false;
3246 uint32 glId = target ? target->GetGuildId () : Player::GetGuildIdFromDB (target_guid);
3247 if (!glId)
3248 return false;
3250 Guild* targetGuild = objmgr.GetGuildById (glId);
3251 if (!targetGuild)
3252 return false;
3254 targetGuild->DelMember (target_guid);
3255 return true;
3258 bool ChatHandler::HandleGuildRankCommand(const char *args)
3260 char* nameStr;
3261 char* rankStr;
3262 extractOptFirstArg((char*)args,&nameStr,&rankStr);
3263 if(!rankStr)
3264 return false;
3266 Player* target;
3267 uint64 target_guid;
3268 std::string target_name;
3269 if(!extractPlayerTarget(nameStr,&target,&target_guid,&target_name))
3270 return false;
3272 uint32 glId = target ? target->GetGuildId () : Player::GetGuildIdFromDB (target_guid);
3273 if (!glId)
3274 return false;
3276 Guild* targetGuild = objmgr.GetGuildById (glId);
3277 if (!targetGuild)
3278 return false;
3280 uint32 newrank = uint32 (atoi (rankStr));
3281 if (newrank > targetGuild->GetLowestRank ())
3282 return false;
3284 targetGuild->ChangeRank (target_guid,newrank);
3285 return true;
3288 bool ChatHandler::HandleGuildDeleteCommand(const char* args)
3290 if (!*args)
3291 return false;
3293 char* guildStr = extractQuotedArg((char*)args);
3294 if(!guildStr)
3295 return false;
3297 std::string gld = guildStr;
3299 Guild* targetGuild = objmgr.GetGuildByName (gld);
3300 if (!targetGuild)
3301 return false;
3303 targetGuild->Disband ();
3305 return true;
3308 bool ChatHandler::HandleGetDistanceCommand(const char* args)
3310 WorldObject* obj = NULL;
3312 if (*args)
3314 uint64 guid = extractGuidFromLink((char*)args);
3315 if(guid)
3316 obj = (WorldObject*)ObjectAccessor::GetObjectByTypeMask(*m_session->GetPlayer(),guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
3318 if(!obj)
3320 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3321 SetSentErrorMessage(true);
3322 return false;
3325 else
3327 obj = getSelectedUnit();
3329 if(!obj)
3331 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3332 SetSentErrorMessage(true);
3333 return false;
3337 PSendSysMessage(LANG_DISTANCE, m_session->GetPlayer()->GetDistance(obj),m_session->GetPlayer()->GetDistance2d(obj));
3339 return true;
3342 bool ChatHandler::HandleDieCommand(const char* /*args*/)
3344 Unit* target = getSelectedUnit();
3346 if(!target || !m_session->GetPlayer()->GetSelection())
3348 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3349 SetSentErrorMessage(true);
3350 return false;
3353 if(target->GetTypeId()==TYPEID_PLAYER)
3355 if(HasLowerSecurity((Player*)target,0,false))
3356 return false;
3359 if( target->isAlive() )
3361 m_session->GetPlayer()->DealDamage(target, target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
3364 return true;
3367 bool ChatHandler::HandleDamageCommand(const char * args)
3369 if (!*args)
3370 return false;
3372 Unit* target = getSelectedUnit();
3374 if (!target || !m_session->GetPlayer()->GetSelection())
3376 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3377 SetSentErrorMessage(true);
3378 return false;
3381 if (!target->isAlive())
3382 return true;
3384 char* damageStr = strtok((char*)args, " ");
3385 if (!damageStr)
3386 return false;
3388 int32 damage_int = atoi((char*)damageStr);
3389 if(damage_int <=0)
3390 return true;
3392 uint32 damage = damage_int;
3394 char* schoolStr = strtok((char*)NULL, " ");
3396 // flat melee damage without resistence/etc reduction
3397 if (!schoolStr)
3399 m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
3400 if (target != m_session->GetPlayer())
3401 m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, SPELL_SCHOOL_MASK_NORMAL, damage, 0, 0, VICTIMSTATE_NORMAL, 0);
3402 return true;
3405 uint32 school = schoolStr ? atoi((char*)schoolStr) : SPELL_SCHOOL_NORMAL;
3406 if(school >= MAX_SPELL_SCHOOL)
3407 return false;
3409 SpellSchoolMask schoolmask = SpellSchoolMask(1 << school);
3411 if ( schoolmask & SPELL_SCHOOL_MASK_NORMAL )
3412 damage = m_session->GetPlayer()->CalcArmorReducedDamage(target, damage);
3414 char* spellStr = strtok((char*)NULL, " ");
3416 // melee damage by specific school
3417 if (!spellStr)
3419 uint32 absorb = 0;
3420 uint32 resist = 0;
3422 m_session->GetPlayer()->CalcAbsorbResist(target,schoolmask, SPELL_DIRECT_DAMAGE, damage, &absorb, &resist);
3424 if (damage <= absorb + resist)
3425 return true;
3427 damage -= absorb + resist;
3429 m_session->GetPlayer()->DealDamageMods(target,damage,&absorb);
3430 m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, schoolmask, NULL, false);
3431 m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, schoolmask, damage, absorb, resist, VICTIMSTATE_NORMAL, 0);
3432 return true;
3435 // non-melee damage
3437 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
3438 uint32 spellid = extractSpellIdFromLink((char*)args);
3439 if (!spellid || !sSpellStore.LookupEntry(spellid))
3440 return false;
3442 m_session->GetPlayer()->SpellNonMeleeDamageLog(target, spellid, damage);
3443 return true;
3446 bool ChatHandler::HandleModifyArenaCommand(const char * args)
3448 if (!*args)
3449 return false;
3451 Player *target = getSelectedPlayer();
3452 if(!target)
3454 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3455 SetSentErrorMessage(true);
3456 return false;
3459 int32 amount = (uint32)atoi(args);
3461 target->ModifyArenaPoints(amount);
3463 PSendSysMessage(LANG_COMMAND_MODIFY_ARENA, GetNameLink(target).c_str(), target->GetArenaPoints());
3465 return true;
3468 bool ChatHandler::HandleReviveCommand(const char* args)
3470 Player* target;
3471 uint64 target_guid;
3472 if(!extractPlayerTarget((char*)args,&target,&target_guid))
3473 return false;
3475 if (target)
3477 target->ResurrectPlayer(0.5f);
3478 target->SpawnCorpseBones();
3479 target->SaveToDB();
3481 else
3482 // will resurrected at login without corpse
3483 ObjectAccessor::Instance().ConvertCorpseForPlayer(target_guid);
3485 return true;
3488 bool ChatHandler::HandleAuraCommand(const char* args)
3490 Unit *target = getSelectedUnit();
3491 if(!target)
3493 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3494 SetSentErrorMessage(true);
3495 return false;
3498 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
3499 uint32 spellID = extractSpellIdFromLink((char*)args);
3501 SpellEntry const *spellInfo = sSpellStore.LookupEntry( spellID );
3502 if(spellInfo)
3504 for(uint32 i = 0;i<3;++i)
3506 uint8 eff = spellInfo->Effect[i];
3507 if (eff>=TOTAL_SPELL_EFFECTS)
3508 continue;
3509 if( IsAreaAuraEffect(eff) ||
3510 eff == SPELL_EFFECT_APPLY_AURA ||
3511 eff == SPELL_EFFECT_PERSISTENT_AREA_AURA )
3513 Aura *Aur = CreateAura(spellInfo, i, NULL, target);
3514 target->AddAura(Aur);
3519 return true;
3522 bool ChatHandler::HandleUnAuraCommand(const char* args)
3524 Unit *target = getSelectedUnit();
3525 if(!target)
3527 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3528 SetSentErrorMessage(true);
3529 return false;
3532 std::string argstr = args;
3533 if (argstr == "all")
3535 target->RemoveAllAuras();
3536 return true;
3539 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
3540 uint32 spellID = extractSpellIdFromLink((char*)args);
3541 if(!spellID)
3542 return false;
3544 target->RemoveAurasDueToSpell(spellID);
3546 return true;
3549 bool ChatHandler::HandleLinkGraveCommand(const char* args)
3551 if(!*args)
3552 return false;
3554 char* px = strtok((char*)args, " ");
3555 if (!px)
3556 return false;
3558 uint32 g_id = (uint32)atoi(px);
3560 uint32 g_team;
3562 char* px2 = strtok(NULL, " ");
3564 if (!px2)
3565 g_team = 0;
3566 else if (strncmp(px2,"horde",6)==0)
3567 g_team = HORDE;
3568 else if (strncmp(px2,"alliance",9)==0)
3569 g_team = ALLIANCE;
3570 else
3571 return false;
3573 WorldSafeLocsEntry const* graveyard = sWorldSafeLocsStore.LookupEntry(g_id);
3575 if(!graveyard )
3577 PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST, g_id);
3578 SetSentErrorMessage(true);
3579 return false;
3582 Player* player = m_session->GetPlayer();
3584 uint32 zoneId = player->GetZoneId();
3586 AreaTableEntry const *areaEntry = GetAreaEntryByAreaID(zoneId);
3587 if(!areaEntry || areaEntry->zone !=0 )
3589 PSendSysMessage(LANG_COMMAND_GRAVEYARDWRONGZONE, g_id,zoneId);
3590 SetSentErrorMessage(true);
3591 return false;
3594 if(objmgr.AddGraveYardLink(g_id,zoneId,g_team))
3595 PSendSysMessage(LANG_COMMAND_GRAVEYARDLINKED, g_id,zoneId);
3596 else
3597 PSendSysMessage(LANG_COMMAND_GRAVEYARDALRLINKED, g_id,zoneId);
3599 return true;
3602 bool ChatHandler::HandleNearGraveCommand(const char* args)
3604 uint32 g_team;
3606 size_t argslen = strlen(args);
3608 if(!*args)
3609 g_team = 0;
3610 else if (strncmp((char*)args,"horde",argslen)==0)
3611 g_team = HORDE;
3612 else if (strncmp((char*)args,"alliance",argslen)==0)
3613 g_team = ALLIANCE;
3614 else
3615 return false;
3617 Player* player = m_session->GetPlayer();
3618 uint32 zone_id = player->GetZoneId();
3620 WorldSafeLocsEntry const* graveyard = objmgr.GetClosestGraveYard(
3621 player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(),player->GetMapId(),g_team);
3623 if(graveyard)
3625 uint32 g_id = graveyard->ID;
3627 GraveYardData const* data = objmgr.FindGraveYardData(g_id,zone_id);
3628 if (!data)
3630 PSendSysMessage(LANG_COMMAND_GRAVEYARDERROR,g_id);
3631 SetSentErrorMessage(true);
3632 return false;
3635 g_team = data->team;
3637 std::string team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_NOTEAM);
3639 if(g_team == 0)
3640 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ANY);
3641 else if(g_team == HORDE)
3642 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_HORDE);
3643 else if(g_team == ALLIANCE)
3644 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ALLIANCE);
3646 PSendSysMessage(LANG_COMMAND_GRAVEYARDNEAREST, g_id,team_name.c_str(),zone_id);
3648 else
3650 std::string team_name;
3652 if(g_team == 0)
3653 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ANY);
3654 else if(g_team == HORDE)
3655 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_HORDE);
3656 else if(g_team == ALLIANCE)
3657 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ALLIANCE);
3659 if(g_team == ~uint32(0))
3660 PSendSysMessage(LANG_COMMAND_ZONENOGRAVEYARDS, zone_id);
3661 else
3662 PSendSysMessage(LANG_COMMAND_ZONENOGRAFACTION, zone_id,team_name.c_str());
3665 return true;
3668 //-----------------------Npc Commands-----------------------
3669 bool ChatHandler::HandleNpcAllowMovementCommand(const char* /*args*/)
3671 if(sWorld.getAllowMovement())
3673 sWorld.SetAllowMovement(false);
3674 SendSysMessage(LANG_CREATURE_MOVE_DISABLED);
3676 else
3678 sWorld.SetAllowMovement(true);
3679 SendSysMessage(LANG_CREATURE_MOVE_ENABLED);
3681 return true;
3684 bool ChatHandler::HandleNpcChangeEntryCommand(const char *args)
3686 if (!*args)
3687 return false;
3689 uint32 newEntryNum = atoi(args);
3690 if(!newEntryNum)
3691 return false;
3693 Unit* unit = getSelectedUnit();
3694 if(!unit || unit->GetTypeId() != TYPEID_UNIT)
3696 SendSysMessage(LANG_SELECT_CREATURE);
3697 SetSentErrorMessage(true);
3698 return false;
3700 Creature* creature = (Creature*)unit;
3701 if(creature->UpdateEntry(newEntryNum))
3702 SendSysMessage(LANG_DONE);
3703 else
3704 SendSysMessage(LANG_ERROR);
3705 return true;
3708 bool ChatHandler::HandleNpcInfoCommand(const char* /*args*/)
3710 Creature* target = getSelectedCreature();
3712 if(!target)
3714 SendSysMessage(LANG_SELECT_CREATURE);
3715 SetSentErrorMessage(true);
3716 return false;
3719 uint32 faction = target->getFaction();
3720 uint32 npcflags = target->GetUInt32Value(UNIT_NPC_FLAGS);
3721 uint32 displayid = target->GetDisplayId();
3722 uint32 nativeid = target->GetNativeDisplayId();
3723 uint32 Entry = target->GetEntry();
3724 CreatureInfo const* cInfo = target->GetCreatureInfo();
3726 int32 curRespawnDelay = target->GetRespawnTimeEx()-time(NULL);
3727 if(curRespawnDelay < 0)
3728 curRespawnDelay = 0;
3729 std::string curRespawnDelayStr = secsToTimeString(curRespawnDelay,true);
3730 std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(),true);
3732 PSendSysMessage(LANG_NPCINFO_CHAR, target->GetDBTableGUIDLow(), faction, npcflags, Entry, displayid, nativeid);
3733 PSendSysMessage(LANG_NPCINFO_LEVEL, target->getLevel());
3734 PSendSysMessage(LANG_NPCINFO_HEALTH,target->GetCreateHealth(), target->GetMaxHealth(), target->GetHealth());
3735 PSendSysMessage(LANG_NPCINFO_FLAGS, target->GetUInt32Value(UNIT_FIELD_FLAGS), target->GetUInt32Value(UNIT_DYNAMIC_FLAGS), target->getFaction());
3736 PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES, defRespawnDelayStr.c_str(),curRespawnDelayStr.c_str());
3737 PSendSysMessage(LANG_NPCINFO_LOOT, cInfo->lootid,cInfo->pickpocketLootId,cInfo->SkinLootId);
3738 PSendSysMessage(LANG_NPCINFO_DUNGEON_ID, target->GetInstanceId());
3739 PSendSysMessage(LANG_NPCINFO_POSITION,float(target->GetPositionX()), float(target->GetPositionY()), float(target->GetPositionZ()));
3741 if ((npcflags & UNIT_NPC_FLAG_VENDOR) )
3743 SendSysMessage(LANG_NPCINFO_VENDOR);
3745 if ((npcflags & UNIT_NPC_FLAG_TRAINER) )
3747 SendSysMessage(LANG_NPCINFO_TRAINER);
3750 return true;
3753 //play npc emote
3754 bool ChatHandler::HandleNpcPlayEmoteCommand(const char* args)
3756 uint32 emote = atoi((char*)args);
3758 Creature* target = getSelectedCreature();
3759 if(!target)
3761 SendSysMessage(LANG_SELECT_CREATURE);
3762 SetSentErrorMessage(true);
3763 return false;
3766 target->SetUInt32Value(UNIT_NPC_EMOTESTATE,emote);
3768 return true;
3771 //TODO: NpcCommands that needs to be fixed :
3773 bool ChatHandler::HandleNpcAddWeaponCommand(const char* /*args*/)
3775 /*if (!*args)
3776 return false;
3778 uint64 guid = m_session->GetPlayer()->GetSelection();
3779 if (guid == 0)
3781 SendSysMessage(LANG_NO_SELECTION);
3782 return true;
3785 Creature *pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
3787 if(!pCreature)
3789 SendSysMessage(LANG_SELECT_CREATURE);
3790 return true;
3793 char* pSlotID = strtok((char*)args, " ");
3794 if (!pSlotID)
3795 return false;
3797 char* pItemID = strtok(NULL, " ");
3798 if (!pItemID)
3799 return false;
3801 uint32 ItemID = atoi(pItemID);
3802 uint32 SlotID = atoi(pSlotID);
3804 ItemPrototype* tmpItem = objmgr.GetItemPrototype(ItemID);
3806 bool added = false;
3807 if(tmpItem)
3809 switch(SlotID)
3811 case 1:
3812 pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, ItemID);
3813 added = true;
3814 break;
3815 case 2:
3816 pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_01, ItemID);
3817 added = true;
3818 break;
3819 case 3:
3820 pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_02, ItemID);
3821 added = true;
3822 break;
3823 default:
3824 PSendSysMessage(LANG_ITEM_SLOT_NOT_EXIST,SlotID);
3825 added = false;
3826 break;
3829 if(added)
3830 PSendSysMessage(LANG_ITEM_ADDED_TO_SLOT,ItemID,tmpItem->Name1,SlotID);
3832 else
3834 PSendSysMessage(LANG_ITEM_NOT_FOUND,ItemID);
3835 return true;
3838 return true;
3840 //----------------------------------------------------------
3842 bool ChatHandler::HandleExploreCheatCommand(const char* args)
3844 if (!*args)
3845 return false;
3847 int flag = atoi((char*)args);
3849 Player *chr = getSelectedPlayer();
3850 if (chr == NULL)
3852 SendSysMessage(LANG_NO_CHAR_SELECTED);
3853 SetSentErrorMessage(true);
3854 return false;
3857 if (flag != 0)
3859 PSendSysMessage(LANG_YOU_SET_EXPLORE_ALL, GetNameLink(chr).c_str());
3860 if (needReportToTarget(chr))
3861 ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_ALL,GetNameLink().c_str());
3863 else
3865 PSendSysMessage(LANG_YOU_SET_EXPLORE_NOTHING, GetNameLink(chr).c_str());
3866 if (needReportToTarget(chr))
3867 ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_NOTHING,GetNameLink().c_str());
3870 for (uint8 i=0; i<128; ++i)
3872 if (flag != 0)
3874 m_session->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i,0xFFFFFFFF);
3876 else
3878 m_session->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i,0);
3882 return true;
3885 bool ChatHandler::HandleHoverCommand(const char* args)
3887 char* px = strtok((char*)args, " ");
3888 uint32 flag;
3889 if (!px)
3890 flag = 1;
3891 else
3892 flag = atoi(px);
3894 m_session->GetPlayer()->SetHover(flag);
3896 if (flag)
3897 SendSysMessage(LANG_HOVER_ENABLED);
3898 else
3899 SendSysMessage(LANG_HOVER_DISABLED);
3901 return true;
3904 void ChatHandler::HandleCharacterLevel(Player* player, uint64 player_guid, uint32 oldlevel, uint32 newlevel)
3906 if(player)
3908 player->GiveLevel(newlevel);
3909 player->InitTalentForLevel();
3910 player->SetUInt32Value(PLAYER_XP,0);
3912 if(needReportToTarget(player))
3914 if(oldlevel == newlevel)
3915 ChatHandler(player).PSendSysMessage(LANG_YOURS_LEVEL_PROGRESS_RESET,GetNameLink().c_str());
3916 else if(oldlevel < newlevel)
3917 ChatHandler(player).PSendSysMessage(LANG_YOURS_LEVEL_UP,GetNameLink().c_str(),newlevel);
3918 else // if(oldlevel > newlevel)
3919 ChatHandler(player).PSendSysMessage(LANG_YOURS_LEVEL_DOWN,GetNameLink().c_str(),newlevel);
3922 else
3924 // update level and XP at level, all other will be updated at loading
3925 Tokens values;
3926 Player::LoadValuesArrayFromDB(values,player_guid);
3927 Player::SetUInt32ValueInArray(values,UNIT_FIELD_LEVEL,newlevel);
3928 Player::SetUInt32ValueInArray(values,PLAYER_XP,0);
3929 Player::SaveValuesArrayInDB(values,player_guid);
3933 bool ChatHandler::HandleCharacterLevelCommand(const char* args)
3935 char* nameStr;
3936 char* levelStr;
3937 extractOptFirstArg((char*)args,&nameStr,&levelStr);
3938 if(!levelStr)
3939 return false;
3941 // exception opt second arg: .character level $name
3942 if(isalpha(levelStr[0]))
3944 nameStr = levelStr;
3945 levelStr = NULL; // current level will used
3948 Player* target;
3949 uint64 target_guid;
3950 std::string target_name;
3951 if(!extractPlayerTarget(nameStr,&target,&target_guid,&target_name))
3952 return false;
3954 int32 oldlevel = target ? target->getLevel() : Player::GetUInt32ValueFromDB(UNIT_FIELD_LEVEL,target_guid);
3955 int32 newlevel = levelStr ? atoi(levelStr) : oldlevel;
3957 if(newlevel < 1)
3958 return false; // invalid level
3960 if(newlevel > STRONG_MAX_LEVEL) // hardcoded maximum level
3961 newlevel = STRONG_MAX_LEVEL;
3963 HandleCharacterLevel(target,target_guid,oldlevel,newlevel);
3965 if(!m_session || m_session->GetPlayer() != target) // including player==NULL
3967 std::string nameLink = playerLink(target_name);
3968 PSendSysMessage(LANG_YOU_CHANGE_LVL,nameLink.c_str(),newlevel);
3971 return true;
3974 bool ChatHandler::HandleLevelUpCommand(const char* args)
3976 char* nameStr;
3977 char* levelStr;
3978 extractOptFirstArg((char*)args,&nameStr,&levelStr);
3980 // exception opt second arg: .character level $name
3981 if(levelStr && isalpha(levelStr[0]))
3983 nameStr = levelStr;
3984 levelStr = NULL; // current level will used
3987 Player* target;
3988 uint64 target_guid;
3989 std::string target_name;
3990 if(!extractPlayerTarget(nameStr,&target,&target_guid,&target_name))
3991 return false;
3993 int32 oldlevel = target ? target->getLevel() : Player::GetUInt32ValueFromDB(UNIT_FIELD_LEVEL,target_guid);
3994 int32 addlevel = levelStr ? atoi(levelStr) : 1;
3995 int32 newlevel = oldlevel + addlevel;
3997 if(newlevel < 1)
3998 newlevel = 1;
4000 if(newlevel > STRONG_MAX_LEVEL) // hardcoded maximum level
4001 newlevel = STRONG_MAX_LEVEL;
4003 HandleCharacterLevel(target,target_guid,oldlevel,newlevel);
4005 if(!m_session || m_session->GetPlayer() != target) // including chr==NULL
4007 std::string nameLink = playerLink(target_name);
4008 PSendSysMessage(LANG_YOU_CHANGE_LVL,nameLink.c_str(),newlevel);
4011 return true;
4014 bool ChatHandler::HandleShowAreaCommand(const char* args)
4016 if (!*args)
4017 return false;
4019 Player *chr = getSelectedPlayer();
4020 if (chr == NULL)
4022 SendSysMessage(LANG_NO_CHAR_SELECTED);
4023 SetSentErrorMessage(true);
4024 return false;
4027 int area = GetAreaFlagByAreaID(atoi((char*)args));
4028 int offset = area / 32;
4029 uint32 val = (uint32)(1 << (area % 32));
4031 if(area<0 || offset >= 128)
4033 SendSysMessage(LANG_BAD_VALUE);
4034 SetSentErrorMessage(true);
4035 return false;
4038 uint32 currFields = chr->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset);
4039 chr->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields | val));
4041 SendSysMessage(LANG_EXPLORE_AREA);
4042 return true;
4045 bool ChatHandler::HandleHideAreaCommand(const char* args)
4047 if (!*args)
4048 return false;
4050 Player *chr = getSelectedPlayer();
4051 if (chr == NULL)
4053 SendSysMessage(LANG_NO_CHAR_SELECTED);
4054 SetSentErrorMessage(true);
4055 return false;
4058 int area = GetAreaFlagByAreaID(atoi((char*)args));
4059 int offset = area / 32;
4060 uint32 val = (uint32)(1 << (area % 32));
4062 if(area<0 || offset >= 128)
4064 SendSysMessage(LANG_BAD_VALUE);
4065 SetSentErrorMessage(true);
4066 return false;
4069 uint32 currFields = chr->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset);
4070 chr->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields ^ val));
4072 SendSysMessage(LANG_UNEXPLORE_AREA);
4073 return true;
4076 bool ChatHandler::HandleDebugUpdate(const char* args)
4078 if(!*args)
4079 return false;
4081 uint32 updateIndex;
4082 uint32 value;
4084 char* pUpdateIndex = strtok((char*)args, " ");
4086 Unit* chr = getSelectedUnit();
4087 if (chr == NULL)
4089 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
4090 SetSentErrorMessage(true);
4091 return false;
4094 if(!pUpdateIndex)
4096 return true;
4098 updateIndex = atoi(pUpdateIndex);
4099 //check updateIndex
4100 if(chr->GetTypeId() == TYPEID_PLAYER)
4102 if (updateIndex>=PLAYER_END) return true;
4104 else
4106 if (updateIndex>=UNIT_END) return true;
4109 char* pvalue = strtok(NULL, " ");
4110 if (!pvalue)
4112 value=chr->GetUInt32Value(updateIndex);
4114 PSendSysMessage(LANG_UPDATE, chr->GetGUIDLow(),updateIndex,value);
4115 return true;
4118 value=atoi(pvalue);
4120 PSendSysMessage(LANG_UPDATE_CHANGE, chr->GetGUIDLow(),updateIndex,value);
4122 chr->SetUInt32Value(updateIndex,value);
4124 return true;
4127 bool ChatHandler::HandleBankCommand(const char* /*args*/)
4129 m_session->SendShowBank( m_session->GetPlayer()->GetGUID() );
4131 return true;
4134 bool ChatHandler::HandleChangeWeather(const char* args)
4136 if(!*args)
4137 return false;
4139 //Weather is OFF
4140 if (!sWorld.getConfig(CONFIG_WEATHER))
4142 SendSysMessage(LANG_WEATHER_DISABLED);
4143 SetSentErrorMessage(true);
4144 return false;
4147 //*Change the weather of a cell
4148 char* px = strtok((char*)args, " ");
4149 char* py = strtok(NULL, " ");
4151 if (!px || !py)
4152 return false;
4154 uint32 type = (uint32)atoi(px); //0 to 3, 0: fine, 1: rain, 2: snow, 3: sand
4155 float grade = (float)atof(py); //0 to 1, sending -1 is instand good weather
4157 Player *player = m_session->GetPlayer();
4158 uint32 zoneid = player->GetZoneId();
4160 Weather* wth = sWorld.FindWeather(zoneid);
4162 if(!wth)
4163 wth = sWorld.AddWeather(zoneid);
4164 if(!wth)
4166 SendSysMessage(LANG_NO_WEATHER);
4167 SetSentErrorMessage(true);
4168 return false;
4171 wth->SetWeather(WeatherType(type), grade);
4173 return true;
4176 bool ChatHandler::HandleDebugSetValue(const char* args)
4178 if(!*args)
4179 return false;
4181 char* px = strtok((char*)args, " ");
4182 char* py = strtok(NULL, " ");
4183 char* pz = strtok(NULL, " ");
4185 if (!px || !py)
4186 return false;
4188 Unit* target = getSelectedUnit();
4189 if(!target)
4191 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
4192 SetSentErrorMessage(true);
4193 return false;
4196 uint64 guid = target->GetGUID();
4198 uint32 Opcode = (uint32)atoi(px);
4199 if(Opcode >= target->GetValuesCount())
4201 PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, GUID_LOPART(guid), target->GetValuesCount());
4202 return false;
4204 uint32 iValue;
4205 float fValue;
4206 bool isint32 = true;
4207 if(pz)
4208 isint32 = (bool)atoi(pz);
4209 if(isint32)
4211 iValue = (uint32)atoi(py);
4212 sLog.outDebug(GetMangosString(LANG_SET_UINT), GUID_LOPART(guid), Opcode, iValue);
4213 target->SetUInt32Value( Opcode , iValue );
4214 PSendSysMessage(LANG_SET_UINT_FIELD, GUID_LOPART(guid), Opcode,iValue);
4216 else
4218 fValue = (float)atof(py);
4219 sLog.outDebug(GetMangosString(LANG_SET_FLOAT), GUID_LOPART(guid), Opcode, fValue);
4220 target->SetFloatValue( Opcode , fValue );
4221 PSendSysMessage(LANG_SET_FLOAT_FIELD, GUID_LOPART(guid), Opcode,fValue);
4224 return true;
4227 bool ChatHandler::HandleDebugGetValue(const char* args)
4229 if(!*args)
4230 return false;
4232 char* px = strtok((char*)args, " ");
4233 char* pz = strtok(NULL, " ");
4235 if (!px)
4236 return false;
4238 Unit* target = getSelectedUnit();
4239 if(!target)
4241 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
4242 SetSentErrorMessage(true);
4243 return false;
4246 uint64 guid = target->GetGUID();
4248 uint32 Opcode = (uint32)atoi(px);
4249 if(Opcode >= target->GetValuesCount())
4251 PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, GUID_LOPART(guid), target->GetValuesCount());
4252 return false;
4254 uint32 iValue;
4255 float fValue;
4256 bool isint32 = true;
4257 if(pz)
4258 isint32 = (bool)atoi(pz);
4260 if(isint32)
4262 iValue = target->GetUInt32Value( Opcode );
4263 sLog.outDebug(GetMangosString(LANG_GET_UINT), GUID_LOPART(guid), Opcode, iValue);
4264 PSendSysMessage(LANG_GET_UINT_FIELD, GUID_LOPART(guid), Opcode, iValue);
4266 else
4268 fValue = target->GetFloatValue( Opcode );
4269 sLog.outDebug(GetMangosString(LANG_GET_FLOAT), GUID_LOPART(guid), Opcode, fValue);
4270 PSendSysMessage(LANG_GET_FLOAT_FIELD, GUID_LOPART(guid), Opcode, fValue);
4273 return true;
4276 bool ChatHandler::HandleSet32Bit(const char* args)
4278 if(!*args)
4279 return false;
4281 char* px = strtok((char*)args, " ");
4282 char* py = strtok(NULL, " ");
4284 if (!px || !py)
4285 return false;
4287 uint32 Opcode = (uint32)atoi(px);
4288 uint32 Value = (uint32)atoi(py);
4289 if (Value > 32) //uint32 = 32 bits
4290 return false;
4292 sLog.outDebug(GetMangosString(LANG_SET_32BIT), Opcode, Value);
4294 m_session->GetPlayer( )->SetUInt32Value( Opcode , 2^Value );
4296 PSendSysMessage(LANG_SET_32BIT_FIELD, Opcode,1);
4297 return true;
4300 bool ChatHandler::HandleDebugMod32Value(const char* args)
4302 if(!*args)
4303 return false;
4305 char* px = strtok((char*)args, " ");
4306 char* py = strtok(NULL, " ");
4308 if (!px || !py)
4309 return false;
4311 uint32 Opcode = (uint32)atoi(px);
4312 int Value = atoi(py);
4314 if(Opcode >= m_session->GetPlayer()->GetValuesCount())
4316 PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, m_session->GetPlayer()->GetGUIDLow(), m_session->GetPlayer( )->GetValuesCount());
4317 return false;
4320 sLog.outDebug(GetMangosString(LANG_CHANGE_32BIT), Opcode, Value);
4322 int CurrentValue = (int)m_session->GetPlayer( )->GetUInt32Value( Opcode );
4324 CurrentValue += Value;
4325 m_session->GetPlayer( )->SetUInt32Value( Opcode , (uint32)CurrentValue );
4327 PSendSysMessage(LANG_CHANGE_32BIT_FIELD, Opcode,CurrentValue);
4329 return true;
4332 bool ChatHandler::HandleTeleAddCommand(const char * args)
4334 if(!*args)
4335 return false;
4337 Player *player=m_session->GetPlayer();
4338 if (!player)
4339 return false;
4341 std::string name = args;
4343 if(objmgr.GetGameTele(name))
4345 SendSysMessage(LANG_COMMAND_TP_ALREADYEXIST);
4346 SetSentErrorMessage(true);
4347 return false;
4350 GameTele tele;
4351 tele.position_x = player->GetPositionX();
4352 tele.position_y = player->GetPositionY();
4353 tele.position_z = player->GetPositionZ();
4354 tele.orientation = player->GetOrientation();
4355 tele.mapId = player->GetMapId();
4356 tele.name = name;
4358 if(objmgr.AddGameTele(tele))
4360 SendSysMessage(LANG_COMMAND_TP_ADDED);
4362 else
4364 SendSysMessage(LANG_COMMAND_TP_ADDEDERR);
4365 SetSentErrorMessage(true);
4366 return false;
4369 return true;
4372 bool ChatHandler::HandleTeleDelCommand(const char * args)
4374 if(!*args)
4375 return false;
4377 std::string name = args;
4379 if(!objmgr.DeleteGameTele(name))
4381 SendSysMessage(LANG_COMMAND_TELE_NOTFOUND);
4382 SetSentErrorMessage(true);
4383 return false;
4386 SendSysMessage(LANG_COMMAND_TP_DELETED);
4387 return true;
4390 bool ChatHandler::HandleListAurasCommand (const char * /*args*/)
4392 Unit *unit = getSelectedUnit();
4393 if(!unit)
4395 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
4396 SetSentErrorMessage(true);
4397 return false;
4400 char const* talentStr = GetMangosString(LANG_TALENT);
4401 char const* passiveStr = GetMangosString(LANG_PASSIVE);
4403 Unit::AuraMap const& uAuras = unit->GetAuras();
4404 PSendSysMessage(LANG_COMMAND_TARGET_LISTAURAS, uAuras.size());
4405 for (Unit::AuraMap::const_iterator itr = uAuras.begin(); itr != uAuras.end(); ++itr)
4407 bool talent = GetTalentSpellCost(itr->second->GetId()) > 0;
4409 char const* name = itr->second->GetSpellProto()->SpellName[GetSessionDbcLocale()];
4411 if (m_session)
4413 std::ostringstream ss_name;
4414 ss_name << "|cffffffff|Hspell:" << itr->second->GetId() << "|h[" << name << "]|h|r";
4416 PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffIndex(),
4417 itr->second->GetModifier()->m_auraname, itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(),
4418 ss_name.str().c_str(),
4419 (itr->second->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
4420 IS_PLAYER_GUID(itr->second->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(itr->second->GetCasterGUID()));
4422 else
4424 PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffIndex(),
4425 itr->second->GetModifier()->m_auraname, itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(),
4426 name,
4427 (itr->second->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
4428 IS_PLAYER_GUID(itr->second->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(itr->second->GetCasterGUID()));
4431 for (int i = 0; i < TOTAL_AURAS; ++i)
4433 Unit::AuraList const& uAuraList = unit->GetAurasByType(AuraType(i));
4434 if (uAuraList.empty()) continue;
4435 PSendSysMessage(LANG_COMMAND_TARGET_LISTAURATYPE, uAuraList.size(), i);
4436 for (Unit::AuraList::const_iterator itr = uAuraList.begin(); itr != uAuraList.end(); ++itr)
4438 bool talent = GetTalentSpellCost((*itr)->GetId()) > 0;
4440 char const* name = (*itr)->GetSpellProto()->SpellName[GetSessionDbcLocale()];
4442 if (m_session)
4444 std::ostringstream ss_name;
4445 ss_name << "|cffffffff|Hspell:" << (*itr)->GetId() << "|h[" << name << "]|h|r";
4447 PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(),
4448 ss_name.str().c_str(),((*itr)->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
4449 IS_PLAYER_GUID((*itr)->GetCasterGUID()) ? "player" : "creature",GUID_LOPART((*itr)->GetCasterGUID()));
4451 else
4453 PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(),
4454 name,((*itr)->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
4455 IS_PLAYER_GUID((*itr)->GetCasterGUID()) ? "player" : "creature",GUID_LOPART((*itr)->GetCasterGUID()));
4459 return true;
4462 bool ChatHandler::HandleResetAchievementsCommand (const char * args)
4464 Player* target;
4465 uint64 target_guid;
4466 if (!extractPlayerTarget((char*)args,&target,&target_guid))
4467 return false;
4469 if(target)
4470 target->GetAchievementMgr().Reset();
4471 else
4472 AchievementMgr::DeleteFromDB(GUID_LOPART(target_guid));
4474 return true;
4477 bool ChatHandler::HandleResetHonorCommand (const char * args)
4479 Player* target;
4480 if (!extractPlayerTarget((char*)args,&target))
4481 return false;
4483 target->SetUInt32Value(PLAYER_FIELD_KILLS, 0);
4484 target->SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORBALE_KILLS, 0);
4485 target->SetUInt32Value(PLAYER_FIELD_HONOR_CURRENCY, 0);
4486 target->SetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, 0);
4487 target->SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, 0);
4488 target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL);
4490 return true;
4493 static bool HandleResetStatsOrLevelHelper(Player* player)
4495 PlayerInfo const *info = objmgr.GetPlayerInfo(player->getRace(), player->getClass());
4496 if(!info) return false;
4498 ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(player->getClass());
4499 if(!cEntry)
4501 sLog.outError("Class %u not found in DBC (Wrong DBC files?)",player->getClass());
4502 return false;
4505 uint8 powertype = cEntry->powerType;
4507 // reset m_form if no aura
4508 if(!player->HasAuraType(SPELL_AURA_MOD_SHAPESHIFT))
4509 player->m_form = FORM_NONE;
4511 player->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE );
4512 player->SetFloatValue(UNIT_FIELD_COMBATREACH, 1.5f );
4514 player->setFactionForRace(player->getRace());
4516 player->SetUInt32Value(UNIT_FIELD_BYTES_0, ( ( player->getRace() ) | ( player->getClass() << 8 ) | ( player->getGender() << 16 ) | ( powertype << 24 ) ) );
4518 // reset only if player not in some form;
4519 if(player->m_form==FORM_NONE)
4521 switch(player->getGender())
4523 case GENDER_FEMALE:
4524 player->SetDisplayId(info->displayId_f);
4525 player->SetNativeDisplayId(info->displayId_f);
4526 break;
4527 case GENDER_MALE:
4528 player->SetDisplayId(info->displayId_m);
4529 player->SetNativeDisplayId(info->displayId_m);
4530 break;
4531 default:
4532 break;
4536 player->SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP );
4537 player->SetByteValue(UNIT_FIELD_BYTES_2, 3, player->m_form);
4539 player->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
4541 //-1 is default value
4542 player->SetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, uint32(-1));
4544 //player->SetUInt32Value(PLAYER_FIELD_BYTES, 0xEEE00000 );
4545 return true;
4548 bool ChatHandler::HandleResetLevelCommand(const char * args)
4550 Player* target;
4551 if(!extractPlayerTarget((char*)args,&target))
4552 return false;
4554 if(!HandleResetStatsOrLevelHelper(target))
4555 return false;
4557 // set starting level
4558 uint32 start_level = target->getClass() != CLASS_DEATH_KNIGHT
4559 ? sWorld.getConfig(CONFIG_START_PLAYER_LEVEL)
4560 : sWorld.getConfig(CONFIG_START_HEROIC_PLAYER_LEVEL);
4562 target->SetLevel(start_level);
4563 target->InitRunes();
4564 target->InitStatsForLevel(true);
4565 target->InitTaxiNodesForLevel();
4566 target->InitGlyphsForLevel();
4567 target->InitTalentForLevel();
4568 target->SetUInt32Value(PLAYER_XP,0);
4570 // reset level for pet
4571 if(Pet* pet = target->GetPet())
4572 pet->SynchronizeLevelWithOwner();
4574 return true;
4577 bool ChatHandler::HandleResetStatsCommand(const char * args)
4579 Player* target;
4580 if (!extractPlayerTarget((char*)args,&target))
4581 return false;
4583 if (!HandleResetStatsOrLevelHelper(target))
4584 return false;
4586 target->InitRunes();
4587 target->InitStatsForLevel(true);
4588 target->InitTaxiNodesForLevel();
4589 target->InitGlyphsForLevel();
4590 target->InitTalentForLevel();
4592 return true;
4595 bool ChatHandler::HandleResetSpellsCommand(const char * args)
4597 Player* target;
4598 uint64 target_guid;
4599 std::string target_name;
4600 if(!extractPlayerTarget((char*)args,&target,&target_guid,&target_name))
4601 return false;
4603 if(target)
4605 target->resetSpells();
4607 ChatHandler(target).SendSysMessage(LANG_RESET_SPELLS);
4608 if(!m_session || m_session->GetPlayer()!=target)
4609 PSendSysMessage(LANG_RESET_SPELLS_ONLINE,GetNameLink(target).c_str());
4611 else
4613 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",uint32(AT_LOGIN_RESET_SPELLS), GUID_LOPART(target_guid));
4614 PSendSysMessage(LANG_RESET_SPELLS_OFFLINE,target_name.c_str());
4617 return true;
4620 bool ChatHandler::HandleResetTalentsCommand(const char * args)
4622 Player* target;
4623 uint64 target_guid;
4624 std::string target_name;
4625 if (!extractPlayerTarget((char*)args,&target,&target_guid,&target_name))
4626 return false;
4628 if (target)
4630 target->resetTalents(true);
4632 ChatHandler(target).SendSysMessage(LANG_RESET_TALENTS);
4633 if (!m_session || m_session->GetPlayer()!=target)
4634 PSendSysMessage(LANG_RESET_TALENTS_ONLINE,GetNameLink(target).c_str());
4636 return true;
4638 else if (target_guid)
4640 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",uint32(AT_LOGIN_RESET_TALENTS), GUID_LOPART(target_guid) );
4641 std::string nameLink = playerLink(target_name);
4642 PSendSysMessage(LANG_RESET_TALENTS_OFFLINE,nameLink.c_str());
4643 return true;
4646 // Try reset talenents as Hunter Pet
4647 Creature* creature = getSelectedCreature();
4648 if (creature && creature->isPet() && ((Pet *)creature)->getPetType() == HUNTER_PET)
4650 ((Pet *)creature)->resetTalents(true);
4651 Unit *owner = creature->GetOwner();
4652 if (owner && owner->GetTypeId() == TYPEID_PLAYER)
4654 Player* owner_player = (Player *)owner;
4655 ChatHandler(owner_player).SendSysMessage(LANG_RESET_PET_TALENTS);
4656 if(!m_session || m_session->GetPlayer()!=owner_player)
4657 PSendSysMessage(LANG_RESET_PET_TALENTS_ONLINE,GetNameLink(owner_player).c_str());
4659 return true;
4662 SendSysMessage(LANG_NO_CHAR_SELECTED);
4663 SetSentErrorMessage(true);
4664 return false;
4667 bool ChatHandler::HandleResetAllCommand(const char * args)
4669 if(!*args)
4670 return false;
4672 std::string casename = args;
4674 AtLoginFlags atLogin;
4676 // Command specially created as single command to prevent using short case names
4677 if(casename=="spells")
4679 atLogin = AT_LOGIN_RESET_SPELLS;
4680 sWorld.SendWorldText(LANG_RESETALL_SPELLS);
4681 if(!m_session)
4682 SendSysMessage(LANG_RESETALL_SPELLS);
4684 else if(casename=="talents")
4686 atLogin = AT_LOGIN_RESET_TALENTS;
4687 sWorld.SendWorldText(LANG_RESETALL_TALENTS);
4688 if(!m_session)
4689 SendSysMessage(LANG_RESETALL_TALENTS);
4691 else
4693 PSendSysMessage(LANG_RESETALL_UNKNOWN_CASE,args);
4694 SetSentErrorMessage(true);
4695 return false;
4698 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE (at_login & '%u') = '0'",atLogin,atLogin);
4699 HashMapHolder<Player>::MapType const& plist = ObjectAccessor::Instance().GetPlayers();
4700 for(HashMapHolder<Player>::MapType::const_iterator itr = plist.begin(); itr != plist.end(); ++itr)
4701 itr->second->SetAtLoginFlag(atLogin);
4703 return true;
4706 bool ChatHandler::HandleServerShutDownCancelCommand(const char* /*args*/)
4708 sWorld.ShutdownCancel();
4709 return true;
4712 bool ChatHandler::HandleServerShutDownCommand(const char* args)
4714 if(!*args)
4715 return false;
4717 char* time_str = strtok ((char*) args, " ");
4718 char* exitcode_str = strtok (NULL, "");
4720 int32 time = atoi (time_str);
4722 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4723 if ((time == 0 && (time_str[0]!='0' || time_str[1]!='\0')) || time < 0)
4724 return false;
4726 if (exitcode_str)
4728 int32 exitcode = atoi (exitcode_str);
4730 // Handle atoi() errors
4731 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4732 return false;
4734 // Exit code should be in range of 0-125, 126-255 is used
4735 // in many shells for their own return codes and code > 255
4736 // is not supported in many others
4737 if (exitcode < 0 || exitcode > 125)
4738 return false;
4740 sWorld.ShutdownServ (time, 0, exitcode);
4742 else
4743 sWorld.ShutdownServ(time,0,SHUTDOWN_EXIT_CODE);
4744 return true;
4747 bool ChatHandler::HandleServerRestartCommand(const char* args)
4749 if(!*args)
4750 return false;
4752 char* time_str = strtok ((char*) args, " ");
4753 char* exitcode_str = strtok (NULL, "");
4755 int32 time = atoi (time_str);
4757 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4758 if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0)
4759 return false;
4761 if (exitcode_str)
4763 int32 exitcode = atoi (exitcode_str);
4765 // Handle atoi() errors
4766 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4767 return false;
4769 // Exit code should be in range of 0-125, 126-255 is used
4770 // in many shells for their own return codes and code > 255
4771 // is not supported in many others
4772 if (exitcode < 0 || exitcode > 125)
4773 return false;
4775 sWorld.ShutdownServ (time, SHUTDOWN_MASK_RESTART, exitcode);
4777 else
4778 sWorld.ShutdownServ(time, SHUTDOWN_MASK_RESTART, RESTART_EXIT_CODE);
4779 return true;
4782 bool ChatHandler::HandleServerIdleRestartCommand(const char* args)
4784 if(!*args)
4785 return false;
4787 char* time_str = strtok ((char*) args, " ");
4788 char* exitcode_str = strtok (NULL, "");
4790 int32 time = atoi (time_str);
4792 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4793 if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0)
4794 return false;
4796 if (exitcode_str)
4798 int32 exitcode = atoi (exitcode_str);
4800 // Handle atoi() errors
4801 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4802 return false;
4804 // Exit code should be in range of 0-125, 126-255 is used
4805 // in many shells for their own return codes and code > 255
4806 // is not supported in many others
4807 if (exitcode < 0 || exitcode > 125)
4808 return false;
4810 sWorld.ShutdownServ (time, SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE, exitcode);
4812 else
4813 sWorld.ShutdownServ(time,SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE,RESTART_EXIT_CODE);
4814 return true;
4817 bool ChatHandler::HandleServerIdleShutDownCommand(const char* args)
4819 if(!*args)
4820 return false;
4822 char* time_str = strtok ((char*) args, " ");
4823 char* exitcode_str = strtok (NULL, "");
4825 int32 time = atoi (time_str);
4827 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4828 if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0)
4829 return false;
4831 if (exitcode_str)
4833 int32 exitcode = atoi (exitcode_str);
4835 // Handle atoi() errors
4836 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4837 return false;
4839 // Exit code should be in range of 0-125, 126-255 is used
4840 // in many shells for their own return codes and code > 255
4841 // is not supported in many others
4842 if (exitcode < 0 || exitcode > 125)
4843 return false;
4845 sWorld.ShutdownServ (time, SHUTDOWN_MASK_IDLE, exitcode);
4847 else
4848 sWorld.ShutdownServ(time,SHUTDOWN_MASK_IDLE,SHUTDOWN_EXIT_CODE);
4849 return true;
4852 bool ChatHandler::HandleQuestAdd(const char* args)
4854 Player* player = getSelectedPlayer();
4855 if(!player)
4857 SendSysMessage(LANG_NO_CHAR_SELECTED);
4858 SetSentErrorMessage(true);
4859 return false;
4862 // .addquest #entry'
4863 // number or [name] Shift-click form |color|Hquest:quest_id|h[name]|h|r
4864 char* cId = extractKeyFromLink((char*)args,"Hquest");
4865 if(!cId)
4866 return false;
4868 uint32 entry = atol(cId);
4870 Quest const* pQuest = objmgr.GetQuestTemplate(entry);
4872 if(!pQuest)
4874 PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND,entry);
4875 SetSentErrorMessage(true);
4876 return false;
4879 // check item starting quest (it can work incorrectly if added without item in inventory)
4880 for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
4882 ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype>(id);
4883 if (!pProto)
4884 continue;
4886 if (pProto->StartQuest == entry)
4888 PSendSysMessage(LANG_COMMAND_QUEST_STARTFROMITEM, entry, pProto->ItemId);
4889 SetSentErrorMessage(true);
4890 return false;
4894 // ok, normal (creature/GO starting) quest
4895 if( player->CanAddQuest( pQuest, true ) )
4897 player->AddQuest( pQuest, NULL );
4899 if ( player->CanCompleteQuest( entry ) )
4900 player->CompleteQuest( entry );
4903 return true;
4906 bool ChatHandler::HandleQuestRemove(const char* args)
4908 Player* player = getSelectedPlayer();
4909 if(!player)
4911 SendSysMessage(LANG_NO_CHAR_SELECTED);
4912 SetSentErrorMessage(true);
4913 return false;
4916 // .removequest #entry'
4917 // number or [name] Shift-click form |color|Hquest:quest_id|h[name]|h|r
4918 char* cId = extractKeyFromLink((char*)args,"Hquest");
4919 if(!cId)
4920 return false;
4922 uint32 entry = atol(cId);
4924 Quest const* pQuest = objmgr.GetQuestTemplate(entry);
4926 if(!pQuest)
4928 PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry);
4929 SetSentErrorMessage(true);
4930 return false;
4933 // remove all quest entries for 'entry' from quest log
4934 for(uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot )
4936 uint32 quest = player->GetQuestSlotQuestId(slot);
4937 if(quest==entry)
4939 player->SetQuestSlot(slot,0);
4941 // we ignore unequippable quest items in this case, its' still be equipped
4942 player->TakeQuestSourceItem( quest, false );
4946 // set quest status to not started (will updated in DB at next save)
4947 player->SetQuestStatus( entry, QUEST_STATUS_NONE);
4949 // reset rewarded for restart repeatable quest
4950 player->getQuestStatusMap()[entry].m_rewarded = false;
4952 SendSysMessage(LANG_COMMAND_QUEST_REMOVED);
4953 return true;
4956 bool ChatHandler::HandleQuestComplete(const char* args)
4958 Player* player = getSelectedPlayer();
4959 if(!player)
4961 SendSysMessage(LANG_NO_CHAR_SELECTED);
4962 SetSentErrorMessage(true);
4963 return false;
4966 // .quest complete #entry
4967 // number or [name] Shift-click form |color|Hquest:quest_id|h[name]|h|r
4968 char* cId = extractKeyFromLink((char*)args,"Hquest");
4969 if(!cId)
4970 return false;
4972 uint32 entry = atol(cId);
4974 Quest const* pQuest = objmgr.GetQuestTemplate(entry);
4976 // If player doesn't have the quest
4977 if(!pQuest || player->GetQuestStatus(entry) == QUEST_STATUS_NONE)
4979 PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry);
4980 SetSentErrorMessage(true);
4981 return false;
4984 // Add quest items for quests that require items
4985 for(uint8 x = 0; x < QUEST_OBJECTIVES_COUNT; ++x)
4987 uint32 id = pQuest->ReqItemId[x];
4988 uint32 count = pQuest->ReqItemCount[x];
4989 if(!id || !count)
4990 continue;
4992 uint32 curItemCount = player->GetItemCount(id,true);
4994 ItemPosCountVec dest;
4995 uint8 msg = player->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, id, count-curItemCount );
4996 if( msg == EQUIP_ERR_OK )
4998 Item* item = player->StoreNewItem( dest, id, true);
4999 player->SendNewItem(item,count-curItemCount,true,false);
5003 // All creature/GO slain/casted (not required, but otherwise it will display "Creature slain 0/10")
5004 for(uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
5006 uint32 creature = pQuest->ReqCreatureOrGOId[i];
5007 uint32 creaturecount = pQuest->ReqCreatureOrGOCount[i];
5009 if(uint32 spell_id = pQuest->ReqSpell[i])
5011 for(uint16 z = 0; z < creaturecount; ++z)
5012 player->CastedCreatureOrGO(creature,0,spell_id);
5014 else if(creature > 0)
5016 for(uint16 z = 0; z < creaturecount; ++z)
5017 player->KilledMonster(creature,0);
5019 else if(creature < 0)
5021 for(uint16 z = 0; z < creaturecount; ++z)
5022 player->CastedCreatureOrGO(creature,0,0);
5026 // If the quest requires reputation to complete
5027 if(uint32 repFaction = pQuest->GetRepObjectiveFaction())
5029 uint32 repValue = pQuest->GetRepObjectiveValue();
5030 uint32 curRep = player->GetReputationMgr().GetReputation(repFaction);
5031 if(curRep < repValue)
5032 if(FactionEntry const *factionEntry = sFactionStore.LookupEntry(repFaction))
5033 player->GetReputationMgr().SetReputation(factionEntry,repValue);
5036 // If the quest requires money
5037 int32 ReqOrRewMoney = pQuest->GetRewOrReqMoney();
5038 if(ReqOrRewMoney < 0)
5039 player->ModifyMoney(-ReqOrRewMoney);
5041 player->CompleteQuest(entry);
5042 return true;
5045 bool ChatHandler::HandleBanAccountCommand(const char* args)
5047 return HandleBanHelper(BAN_ACCOUNT,args);
5050 bool ChatHandler::HandleBanCharacterCommand(const char* args)
5052 return HandleBanHelper(BAN_CHARACTER,args);
5055 bool ChatHandler::HandleBanIPCommand(const char* args)
5057 return HandleBanHelper(BAN_IP,args);
5060 bool ChatHandler::HandleBanHelper(BanMode mode, const char* args)
5062 if (!*args)
5063 return false;
5065 char* cnameOrIP = strtok ((char*)args, " ");
5066 if (!cnameOrIP)
5067 return false;
5069 std::string nameOrIP = cnameOrIP;
5071 char* duration = strtok (NULL," ");
5072 if(!duration || !atoi(duration))
5073 return false;
5075 char* reason = strtok (NULL,"");
5076 if(!reason)
5077 return false;
5079 switch(mode)
5081 case BAN_ACCOUNT:
5082 if(!AccountMgr::normilizeString(nameOrIP))
5084 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,nameOrIP.c_str());
5085 SetSentErrorMessage(true);
5086 return false;
5088 break;
5089 case BAN_CHARACTER:
5090 if(!normalizePlayerName(nameOrIP))
5092 SendSysMessage(LANG_PLAYER_NOT_FOUND);
5093 SetSentErrorMessage(true);
5094 return false;
5096 break;
5097 case BAN_IP:
5098 if(!IsIPAddress(nameOrIP.c_str()))
5099 return false;
5100 break;
5103 switch(sWorld.BanAccount(mode, nameOrIP, duration, reason,m_session ? m_session->GetPlayerName() : ""))
5105 case BAN_SUCCESS:
5106 if(atoi(duration)>0)
5107 PSendSysMessage(LANG_BAN_YOUBANNED,nameOrIP.c_str(),secsToTimeString(TimeStringToSecs(duration),true).c_str(),reason);
5108 else
5109 PSendSysMessage(LANG_BAN_YOUPERMBANNED,nameOrIP.c_str(),reason);
5110 break;
5111 case BAN_SYNTAX_ERROR:
5112 return false;
5113 case BAN_NOTFOUND:
5114 switch(mode)
5116 default:
5117 PSendSysMessage(LANG_BAN_NOTFOUND,"account",nameOrIP.c_str());
5118 break;
5119 case BAN_CHARACTER:
5120 PSendSysMessage(LANG_BAN_NOTFOUND,"character",nameOrIP.c_str());
5121 break;
5122 case BAN_IP:
5123 PSendSysMessage(LANG_BAN_NOTFOUND,"ip",nameOrIP.c_str());
5124 break;
5126 SetSentErrorMessage(true);
5127 return false;
5130 return true;
5133 bool ChatHandler::HandleUnBanAccountCommand(const char* args)
5135 return HandleUnBanHelper(BAN_ACCOUNT,args);
5138 bool ChatHandler::HandleUnBanCharacterCommand(const char* args)
5140 return HandleUnBanHelper(BAN_CHARACTER,args);
5143 bool ChatHandler::HandleUnBanIPCommand(const char* args)
5145 return HandleUnBanHelper(BAN_IP,args);
5148 bool ChatHandler::HandleUnBanHelper(BanMode mode, const char* args)
5150 if (!*args)
5151 return false;
5153 char* cnameOrIP = strtok ((char*)args, " ");
5154 if(!cnameOrIP)
5155 return false;
5157 std::string nameOrIP = cnameOrIP;
5159 switch(mode)
5161 case BAN_ACCOUNT:
5162 if(!AccountMgr::normilizeString(nameOrIP))
5164 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,nameOrIP.c_str());
5165 SetSentErrorMessage(true);
5166 return false;
5168 break;
5169 case BAN_CHARACTER:
5170 if(!normalizePlayerName(nameOrIP))
5172 SendSysMessage(LANG_PLAYER_NOT_FOUND);
5173 SetSentErrorMessage(true);
5174 return false;
5176 break;
5177 case BAN_IP:
5178 if(!IsIPAddress(nameOrIP.c_str()))
5179 return false;
5180 break;
5183 if(sWorld.RemoveBanAccount(mode,nameOrIP))
5184 PSendSysMessage(LANG_UNBAN_UNBANNED,nameOrIP.c_str());
5185 else
5186 PSendSysMessage(LANG_UNBAN_ERROR,nameOrIP.c_str());
5188 return true;
5191 bool ChatHandler::HandleBanInfoAccountCommand(const char* args)
5193 if (!*args)
5194 return false;
5196 char* cname = strtok((char*)args, "");
5197 if(!cname)
5198 return false;
5200 std::string account_name = cname;
5201 if(!AccountMgr::normilizeString(account_name))
5203 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5204 SetSentErrorMessage(true);
5205 return false;
5208 uint32 accountid = accmgr.GetId(account_name);
5209 if(!accountid)
5211 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5212 return true;
5215 return HandleBanInfoHelper(accountid,account_name.c_str());
5218 bool ChatHandler::HandleBanInfoCharacterCommand(const char* args)
5220 Player* target;
5221 uint64 target_guid;
5222 if(!extractPlayerTarget((char*)args,&target,&target_guid))
5223 return false;
5225 uint32 accountid = target ? target->GetSession()->GetAccountId() : objmgr.GetPlayerAccountIdByGUID(target_guid);
5227 std::string accountname;
5228 if(!accmgr.GetName(accountid,accountname))
5230 PSendSysMessage(LANG_BANINFO_NOCHARACTER);
5231 return true;
5234 return HandleBanInfoHelper(accountid,accountname.c_str());
5237 bool ChatHandler::HandleBanInfoHelper(uint32 accountid, char const* accountname)
5239 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);
5240 if(!result)
5242 PSendSysMessage(LANG_BANINFO_NOACCOUNTBAN, accountname);
5243 return true;
5246 PSendSysMessage(LANG_BANINFO_BANHISTORY,accountname);
5249 Field* fields = result->Fetch();
5251 time_t unbandate = time_t(fields[3].GetUInt64());
5252 bool active = false;
5253 if(fields[2].GetBool() && (fields[1].GetUInt64() == (uint64)0 ||unbandate >= time(NULL)) )
5254 active = true;
5255 bool permanent = (fields[1].GetUInt64() == (uint64)0);
5256 std::string bantime = permanent?GetMangosString(LANG_BANINFO_INFINITE):secsToTimeString(fields[1].GetUInt64(), true);
5257 PSendSysMessage(LANG_BANINFO_HISTORYENTRY,
5258 fields[0].GetString(), bantime.c_str(), active ? GetMangosString(LANG_BANINFO_YES):GetMangosString(LANG_BANINFO_NO), fields[4].GetString(), fields[5].GetString());
5259 }while (result->NextRow());
5261 delete result;
5262 return true;
5265 bool ChatHandler::HandleBanInfoIPCommand(const char* args)
5267 if (!*args)
5268 return false;
5270 char* cIP = strtok ((char*)args, "");
5271 if(!cIP)
5272 return false;
5274 if (!IsIPAddress(cIP))
5275 return false;
5277 std::string IP = cIP;
5279 loginDatabase.escape_string(IP);
5280 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());
5281 if(!result)
5283 PSendSysMessage(LANG_BANINFO_NOIP);
5284 return true;
5287 Field *fields = result->Fetch();
5288 bool permanent = !fields[6].GetUInt64();
5289 PSendSysMessage(LANG_BANINFO_IPENTRY,
5290 fields[0].GetString(), fields[1].GetString(), permanent ? GetMangosString(LANG_BANINFO_NEVER):fields[2].GetString(),
5291 permanent ? GetMangosString(LANG_BANINFO_INFINITE):secsToTimeString(fields[3].GetUInt64(), true).c_str(), fields[4].GetString(), fields[5].GetString());
5292 delete result;
5293 return true;
5296 bool ChatHandler::HandleBanListCharacterCommand(const char* args)
5298 loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
5300 char* cFilter = strtok ((char*)args, " ");
5301 if(!cFilter)
5302 return false;
5304 std::string filter = cFilter;
5305 loginDatabase.escape_string(filter);
5306 QueryResult* result = CharacterDatabase.PQuery("SELECT account FROM characters WHERE name "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'"),filter.c_str());
5307 if (!result)
5309 PSendSysMessage(LANG_BANLIST_NOCHARACTER);
5310 return true;
5313 return HandleBanListHelper(result);
5316 bool ChatHandler::HandleBanListAccountCommand(const char* args)
5318 loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
5320 char* cFilter = strtok((char*)args, " ");
5321 std::string filter = cFilter ? cFilter : "";
5322 loginDatabase.escape_string(filter);
5324 QueryResult* result;
5326 if(filter.empty())
5328 result = loginDatabase.Query("SELECT account.id, username FROM account, account_banned"
5329 " WHERE account.id = account_banned.id AND active = 1 GROUP BY account.id");
5331 else
5333 result = loginDatabase.PQuery("SELECT account.id, username FROM account, account_banned"
5334 " WHERE account.id = account_banned.id AND active = 1 AND username "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")" GROUP BY account.id",
5335 filter.c_str());
5338 if (!result)
5340 PSendSysMessage(LANG_BANLIST_NOACCOUNT);
5341 return true;
5344 return HandleBanListHelper(result);
5347 bool ChatHandler::HandleBanListHelper(QueryResult* result)
5349 PSendSysMessage(LANG_BANLIST_MATCHINGACCOUNT);
5351 // Chat short output
5352 if(m_session)
5356 Field* fields = result->Fetch();
5357 uint32 accountid = fields[0].GetUInt32();
5359 QueryResult* banresult = loginDatabase.PQuery("SELECT account.username FROM account,account_banned WHERE account_banned.id='%u' AND account_banned.id=account.id",accountid);
5360 if(banresult)
5362 Field* fields2 = banresult->Fetch();
5363 PSendSysMessage("%s",fields2[0].GetString());
5364 delete banresult;
5366 } while (result->NextRow());
5368 // Console wide output
5369 else
5371 SendSysMessage(LANG_BANLIST_ACCOUNTS);
5372 SendSysMessage("===============================================================================");
5373 SendSysMessage(LANG_BANLIST_ACCOUNTS_HEADER);
5376 SendSysMessage("-------------------------------------------------------------------------------");
5377 Field *fields = result->Fetch();
5378 uint32 account_id = fields[0].GetUInt32 ();
5380 std::string account_name;
5382 // "account" case, name can be get in same query
5383 if(result->GetFieldCount() > 1)
5384 account_name = fields[1].GetCppString();
5385 // "character" case, name need extract from another DB
5386 else
5387 accmgr.GetName (account_id,account_name);
5389 // No SQL injection. id is uint32.
5390 QueryResult *banInfo = loginDatabase.PQuery("SELECT bandate,unbandate,bannedby,banreason FROM account_banned WHERE id = %u ORDER BY unbandate", account_id);
5391 if (banInfo)
5393 Field *fields2 = banInfo->Fetch();
5396 time_t t_ban = fields2[0].GetUInt64();
5397 tm* aTm_ban = localtime(&t_ban);
5399 if (fields2[0].GetUInt64() == fields2[1].GetUInt64())
5401 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|",
5402 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,
5403 fields2[2].GetString(),fields2[3].GetString());
5405 else
5407 time_t t_unban = fields2[1].GetUInt64();
5408 tm* aTm_unban = localtime(&t_unban);
5409 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|",
5410 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,
5411 aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min,
5412 fields2[2].GetString(),fields2[3].GetString());
5414 }while ( banInfo->NextRow() );
5415 delete banInfo;
5417 }while( result->NextRow() );
5418 SendSysMessage("===============================================================================");
5421 delete result;
5422 return true;
5425 bool ChatHandler::HandleBanListIPCommand(const char* args)
5427 loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
5429 char* cFilter = strtok((char*)args, " ");
5430 std::string filter = cFilter ? cFilter : "";
5431 loginDatabase.escape_string(filter);
5433 QueryResult* result;
5435 if(filter.empty())
5437 result = loginDatabase.Query ("SELECT ip,bandate,unbandate,bannedby,banreason FROM ip_banned"
5438 " WHERE (bandate=unbandate OR unbandate>UNIX_TIMESTAMP())"
5439 " ORDER BY unbandate" );
5441 else
5443 result = loginDatabase.PQuery( "SELECT ip,bandate,unbandate,bannedby,banreason FROM ip_banned"
5444 " WHERE (bandate=unbandate OR unbandate>UNIX_TIMESTAMP()) AND ip "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")
5445 " ORDER BY unbandate",filter.c_str() );
5448 if(!result)
5450 PSendSysMessage(LANG_BANLIST_NOIP);
5451 return true;
5454 PSendSysMessage(LANG_BANLIST_MATCHINGIP);
5455 // Chat short output
5456 if(m_session)
5460 Field* fields = result->Fetch();
5461 PSendSysMessage("%s",fields[0].GetString());
5462 } while (result->NextRow());
5464 // Console wide output
5465 else
5467 SendSysMessage(LANG_BANLIST_IPS);
5468 SendSysMessage("===============================================================================");
5469 SendSysMessage(LANG_BANLIST_IPS_HEADER);
5472 SendSysMessage("-------------------------------------------------------------------------------");
5473 Field *fields = result->Fetch();
5474 time_t t_ban = fields[1].GetUInt64();
5475 tm* aTm_ban = localtime(&t_ban);
5476 if ( fields[1].GetUInt64() == fields[2].GetUInt64() )
5478 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|",
5479 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,
5480 fields[3].GetString(), fields[4].GetString());
5482 else
5484 time_t t_unban = fields[2].GetUInt64();
5485 tm* aTm_unban = localtime(&t_unban);
5486 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|",
5487 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,
5488 aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min,
5489 fields[3].GetString(), fields[4].GetString());
5491 }while( result->NextRow() );
5492 SendSysMessage("===============================================================================");
5495 delete result;
5496 return true;
5499 bool ChatHandler::HandleRespawnCommand(const char* /*args*/)
5501 Player* pl = m_session->GetPlayer();
5503 // accept only explicitly selected target (not implicitly self targeting case)
5504 Unit* target = getSelectedUnit();
5505 if(pl->GetSelection() && target)
5507 if(target->GetTypeId()!=TYPEID_UNIT)
5509 SendSysMessage(LANG_SELECT_CREATURE);
5510 SetSentErrorMessage(true);
5511 return false;
5514 if(target->isDead())
5515 ((Creature*)target)->Respawn();
5516 return true;
5519 CellPair p(MaNGOS::ComputeCellPair(pl->GetPositionX(), pl->GetPositionY()));
5520 Cell cell(p);
5521 cell.data.Part.reserved = ALL_DISTRICT;
5522 cell.SetNoCreate();
5524 MaNGOS::RespawnDo u_do;
5525 MaNGOS::WorldObjectWorker<MaNGOS::RespawnDo> worker(pl,u_do);
5527 TypeContainerVisitor<MaNGOS::WorldObjectWorker<MaNGOS::RespawnDo>, GridTypeMapContainer > obj_worker(worker);
5528 CellLock<GridReadGuard> cell_lock(cell, p);
5529 cell_lock->Visit(cell_lock, obj_worker, *pl->GetMap());
5531 return true;
5534 bool ChatHandler::HandleGMFlyCommand(const char* args)
5536 if (!*args)
5537 return false;
5539 Player *target = getSelectedPlayer();
5540 if (!target)
5541 target = m_session->GetPlayer();
5543 WorldPacket data(12);
5544 if (strncmp(args, "on", 3) == 0)
5545 data.SetOpcode(SMSG_MOVE_SET_CAN_FLY);
5546 else if (strncmp(args, "off", 4) == 0)
5547 data.SetOpcode(SMSG_MOVE_UNSET_CAN_FLY);
5548 else
5550 SendSysMessage(LANG_USE_BOL);
5551 return false;
5553 data.append(target->GetPackGUID());
5554 data << uint32(0); // unknown
5555 target->SendMessageToSet(&data, true);
5556 PSendSysMessage(LANG_COMMAND_FLYMODE_STATUS, GetNameLink(target).c_str(), args);
5557 return true;
5560 bool ChatHandler::HandlePDumpLoadCommand(const char *args)
5562 if (!*args)
5563 return false;
5565 char * file = strtok((char*)args, " ");
5566 if(!file)
5567 return false;
5569 char * account = strtok(NULL, " ");
5570 if(!account)
5571 return false;
5573 std::string account_name = account;
5574 if(!AccountMgr::normilizeString(account_name))
5576 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5577 SetSentErrorMessage(true);
5578 return false;
5581 uint32 account_id = accmgr.GetId(account_name);
5582 if(!account_id)
5584 account_id = atoi(account); // use original string
5585 if(!account_id)
5587 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5588 SetSentErrorMessage(true);
5589 return false;
5593 if(!accmgr.GetName(account_id,account_name))
5595 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5596 SetSentErrorMessage(true);
5597 return false;
5600 char* guid_str = NULL;
5601 char* name_str = strtok(NULL, " ");
5603 std::string name;
5604 if(name_str)
5606 name = name_str;
5607 // normalize the name if specified and check if it exists
5608 if(!normalizePlayerName(name))
5610 PSendSysMessage(LANG_INVALID_CHARACTER_NAME);
5611 SetSentErrorMessage(true);
5612 return false;
5615 if(!ObjectMgr::IsValidName(name,true))
5617 PSendSysMessage(LANG_INVALID_CHARACTER_NAME);
5618 SetSentErrorMessage(true);
5619 return false;
5622 guid_str = strtok(NULL, " ");
5625 uint32 guid = 0;
5627 if(guid_str)
5629 guid = atoi(guid_str);
5630 if(!guid)
5632 PSendSysMessage(LANG_INVALID_CHARACTER_GUID);
5633 SetSentErrorMessage(true);
5634 return false;
5637 if(objmgr.GetPlayerAccountIdByGUID(guid))
5639 PSendSysMessage(LANG_CHARACTER_GUID_IN_USE,guid);
5640 SetSentErrorMessage(true);
5641 return false;
5645 switch(PlayerDumpReader().LoadDump(file, account_id, name, guid))
5647 case DUMP_SUCCESS:
5648 PSendSysMessage(LANG_COMMAND_IMPORT_SUCCESS);
5649 break;
5650 case DUMP_FILE_OPEN_ERROR:
5651 PSendSysMessage(LANG_FILE_OPEN_FAIL,file);
5652 SetSentErrorMessage(true);
5653 return false;
5654 case DUMP_FILE_BROKEN:
5655 PSendSysMessage(LANG_DUMP_BROKEN,file);
5656 SetSentErrorMessage(true);
5657 return false;
5658 case DUMP_TOO_MANY_CHARS:
5659 PSendSysMessage(LANG_ACCOUNT_CHARACTER_LIST_FULL,account_name.c_str(),account_id);
5660 SetSentErrorMessage(true);
5661 return false;
5662 default:
5663 PSendSysMessage(LANG_COMMAND_IMPORT_FAILED);
5664 SetSentErrorMessage(true);
5665 return false;
5668 return true;
5671 bool ChatHandler::HandlePDumpWriteCommand(const char *args)
5673 if (!*args)
5674 return false;
5676 char* file = strtok((char*)args, " ");
5677 char* p2 = strtok(NULL, " ");
5679 if(!file || !p2)
5680 return false;
5682 uint32 guid;
5683 // character name can't start from number
5684 if (isNumeric(p2[0]))
5685 guid = atoi(p2);
5686 else
5688 std::string name = extractPlayerNameFromLink(p2);
5689 if(name.empty())
5691 SendSysMessage(LANG_PLAYER_NOT_FOUND);
5692 SetSentErrorMessage(true);
5693 return false;
5696 guid = objmgr.GetPlayerGUIDByName(name);
5699 if(!objmgr.GetPlayerAccountIdByGUID(guid))
5701 PSendSysMessage(LANG_PLAYER_NOT_FOUND);
5702 SetSentErrorMessage(true);
5703 return false;
5706 switch(PlayerDumpWriter().WriteDump(file, guid))
5708 case DUMP_SUCCESS:
5709 PSendSysMessage(LANG_COMMAND_EXPORT_SUCCESS);
5710 break;
5711 case DUMP_FILE_OPEN_ERROR:
5712 PSendSysMessage(LANG_FILE_OPEN_FAIL,file);
5713 SetSentErrorMessage(true);
5714 return false;
5715 default:
5716 PSendSysMessage(LANG_COMMAND_EXPORT_FAILED);
5717 SetSentErrorMessage(true);
5718 return false;
5721 return true;
5724 bool ChatHandler::HandleMovegensCommand(const char* /*args*/)
5726 Unit* unit = getSelectedUnit();
5727 if(!unit)
5729 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5730 SetSentErrorMessage(true);
5731 return false;
5734 PSendSysMessage(LANG_MOVEGENS_LIST,(unit->GetTypeId()==TYPEID_PLAYER ? "Player" : "Creature" ),unit->GetGUIDLow());
5736 MotionMaster* mm = unit->GetMotionMaster();
5737 for(MotionMaster::const_iterator itr = mm->begin(); itr != mm->end(); ++itr)
5739 switch((*itr)->GetMovementGeneratorType())
5741 case IDLE_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_IDLE); break;
5742 case RANDOM_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_RANDOM); break;
5743 case WAYPOINT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_WAYPOINT); break;
5744 case ANIMAL_RANDOM_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_ANIMAL_RANDOM); break;
5745 case CONFUSED_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_CONFUSED); break;
5746 case TARGETED_MOTION_TYPE:
5748 if(unit->GetTypeId()==TYPEID_PLAYER)
5750 TargetedMovementGenerator<Player> const* mgen = static_cast<TargetedMovementGenerator<Player> const*>(*itr);
5751 Unit* target = mgen->GetTarget();
5752 if(target)
5753 PSendSysMessage(LANG_MOVEGENS_TARGETED_PLAYER,target->GetName(),target->GetGUIDLow());
5754 else
5755 SendSysMessage(LANG_MOVEGENS_TARGETED_NULL);
5757 else
5759 TargetedMovementGenerator<Creature> const* mgen = static_cast<TargetedMovementGenerator<Creature> const*>(*itr);
5760 Unit* target = mgen->GetTarget();
5761 if(target)
5762 PSendSysMessage(LANG_MOVEGENS_TARGETED_CREATURE,target->GetName(),target->GetGUIDLow());
5763 else
5764 SendSysMessage(LANG_MOVEGENS_TARGETED_NULL);
5766 break;
5768 case HOME_MOTION_TYPE:
5769 if(unit->GetTypeId()==TYPEID_UNIT)
5771 float x,y,z;
5772 (*itr)->GetDestination(x,y,z);
5773 PSendSysMessage(LANG_MOVEGENS_HOME_CREATURE,x,y,z);
5775 else
5776 SendSysMessage(LANG_MOVEGENS_HOME_PLAYER);
5777 break;
5778 case FLIGHT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_FLIGHT); break;
5779 case POINT_MOTION_TYPE:
5781 float x,y,z;
5782 (*itr)->GetDestination(x,y,z);
5783 PSendSysMessage(LANG_MOVEGENS_POINT,x,y,z);
5784 break;
5786 case FLEEING_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_FEAR); break;
5787 case DISTRACT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_DISTRACT); break;
5788 default:
5789 PSendSysMessage(LANG_MOVEGENS_UNKNOWN,(*itr)->GetMovementGeneratorType());
5790 break;
5793 return true;
5796 bool ChatHandler::HandleServerPLimitCommand(const char *args)
5798 if(*args)
5800 char* param = strtok((char*)args, " ");
5801 if(!param)
5802 return false;
5804 int l = strlen(param);
5806 if( strncmp(param,"player",l) == 0 )
5807 sWorld.SetPlayerLimit(-SEC_PLAYER);
5808 else if(strncmp(param,"moderator",l) == 0 )
5809 sWorld.SetPlayerLimit(-SEC_MODERATOR);
5810 else if(strncmp(param,"gamemaster",l) == 0 )
5811 sWorld.SetPlayerLimit(-SEC_GAMEMASTER);
5812 else if(strncmp(param,"administrator",l) == 0 )
5813 sWorld.SetPlayerLimit(-SEC_ADMINISTRATOR);
5814 else if(strncmp(param,"reset",l) == 0 )
5815 sWorld.SetPlayerLimit( sConfig.GetIntDefault("PlayerLimit", DEFAULT_PLAYER_LIMIT) );
5816 else
5818 int val = atoi(param);
5819 if(val < -SEC_ADMINISTRATOR) val = -SEC_ADMINISTRATOR;
5821 sWorld.SetPlayerLimit(val);
5824 // kick all low security level players
5825 if(sWorld.GetPlayerAmountLimit() > SEC_PLAYER)
5826 sWorld.KickAllLess(sWorld.GetPlayerSecurityLimit());
5829 uint32 pLimit = sWorld.GetPlayerAmountLimit();
5830 AccountTypes allowedAccountType = sWorld.GetPlayerSecurityLimit();
5831 char const* secName = "";
5832 switch(allowedAccountType)
5834 case SEC_PLAYER: secName = "Player"; break;
5835 case SEC_MODERATOR: secName = "Moderator"; break;
5836 case SEC_GAMEMASTER: secName = "Gamemaster"; break;
5837 case SEC_ADMINISTRATOR: secName = "Administrator"; break;
5838 default: secName = "<unknown>"; break;
5841 PSendSysMessage("Player limits: amount %u, min. security level %s.",pLimit,secName);
5843 return true;
5846 bool ChatHandler::HandleCastCommand(const char* args)
5848 if(!*args)
5849 return false;
5851 Unit* target = getSelectedUnit();
5853 if(!target)
5855 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5856 SetSentErrorMessage(true);
5857 return false;
5860 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5861 uint32 spell = extractSpellIdFromLink((char*)args);
5862 if(!spell)
5863 return false;
5865 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
5866 if(!spellInfo)
5867 return false;
5869 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
5871 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
5872 SetSentErrorMessage(true);
5873 return false;
5876 char* trig_str = strtok(NULL, " ");
5877 if(trig_str)
5879 int l = strlen(trig_str);
5880 if(strncmp(trig_str,"triggered",l) != 0 )
5881 return false;
5884 bool triggered = (trig_str != NULL);
5886 m_session->GetPlayer()->CastSpell(target,spell,triggered);
5888 return true;
5891 bool ChatHandler::HandleCastBackCommand(const char* args)
5893 Creature* caster = getSelectedCreature();
5895 if(!caster)
5897 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5898 SetSentErrorMessage(true);
5899 return false;
5902 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
5903 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5904 uint32 spell = extractSpellIdFromLink((char*)args);
5905 if(!spell || !sSpellStore.LookupEntry(spell))
5906 return false;
5908 char* trig_str = strtok(NULL, " ");
5909 if(trig_str)
5911 int l = strlen(trig_str);
5912 if(strncmp(trig_str,"triggered",l) != 0 )
5913 return false;
5916 bool triggered = (trig_str != NULL);
5918 // update orientation at server
5919 caster->SetOrientation(caster->GetAngle(m_session->GetPlayer()));
5921 // and client
5922 WorldPacket data;
5923 caster->BuildHeartBeatMsg(&data);
5924 caster->SendMessageToSet(&data,true);
5926 caster->CastSpell(m_session->GetPlayer(),spell,triggered);
5928 return true;
5931 bool ChatHandler::HandleCastDistCommand(const char* args)
5933 if(!*args)
5934 return false;
5936 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5937 uint32 spell = extractSpellIdFromLink((char*)args);
5938 if(!spell)
5939 return false;
5941 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
5942 if(!spellInfo)
5943 return false;
5945 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
5947 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
5948 SetSentErrorMessage(true);
5949 return false;
5952 char *distStr = strtok(NULL, " ");
5954 float dist = 0;
5956 if(distStr)
5957 sscanf(distStr, "%f", &dist);
5959 char* trig_str = strtok(NULL, " ");
5960 if(trig_str)
5962 int l = strlen(trig_str);
5963 if(strncmp(trig_str,"triggered",l) != 0 )
5964 return false;
5967 bool triggered = (trig_str != NULL);
5969 float x,y,z;
5970 m_session->GetPlayer()->GetClosePoint(x,y,z,dist);
5972 m_session->GetPlayer()->CastSpell(x,y,z,spell,triggered);
5973 return true;
5976 bool ChatHandler::HandleCastTargetCommand(const char* args)
5978 Creature* caster = getSelectedCreature();
5980 if(!caster)
5982 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5983 SetSentErrorMessage(true);
5984 return false;
5987 if(!caster->getVictim())
5989 SendSysMessage(LANG_SELECTED_TARGET_NOT_HAVE_VICTIM);
5990 SetSentErrorMessage(true);
5991 return false;
5994 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5995 uint32 spell = extractSpellIdFromLink((char*)args);
5996 if(!spell || !sSpellStore.LookupEntry(spell))
5997 return false;
5999 char* trig_str = strtok(NULL, " ");
6000 if(trig_str)
6002 int l = strlen(trig_str);
6003 if(strncmp(trig_str,"triggered",l) != 0 )
6004 return false;
6007 bool triggered = (trig_str != NULL);
6009 // update orientation at server
6010 caster->SetOrientation(caster->GetAngle(m_session->GetPlayer()));
6012 // and client
6013 WorldPacket data;
6014 caster->BuildHeartBeatMsg(&data);
6015 caster->SendMessageToSet(&data,true);
6017 caster->CastSpell(caster->getVictim(),spell,triggered);
6019 return true;
6023 ComeToMe command REQUIRED for 3rd party scripting library to have access to PointMovementGenerator
6024 Without this function 3rd party scripting library will get linking errors (unresolved external)
6025 when attempting to use the PointMovementGenerator
6027 bool ChatHandler::HandleComeToMeCommand(const char *args)
6029 Creature* caster = getSelectedCreature();
6031 if(!caster)
6033 SendSysMessage(LANG_SELECT_CREATURE);
6034 SetSentErrorMessage(true);
6035 return false;
6038 char* newFlagStr = strtok((char*)args, " ");
6040 if(!newFlagStr)
6041 return false;
6043 uint32 newFlags = atoi(newFlagStr);
6045 caster->SetUnitMovementFlags(newFlags);
6047 Player* pl = m_session->GetPlayer();
6049 caster->GetMotionMaster()->MovePoint(0, pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ());
6050 return true;
6053 bool ChatHandler::HandleCastSelfCommand(const char* args)
6055 if(!*args)
6056 return false;
6058 Unit* target = getSelectedUnit();
6060 if(!target)
6062 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
6063 SetSentErrorMessage(true);
6064 return false;
6067 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
6068 uint32 spell = extractSpellIdFromLink((char*)args);
6069 if(!spell)
6070 return false;
6072 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
6073 if(!spellInfo)
6074 return false;
6076 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
6078 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
6079 SetSentErrorMessage(true);
6080 return false;
6083 target->CastSpell(target,spell,false);
6085 return true;
6088 std::string GetTimeString(uint32 time)
6090 uint16 days = time / DAY, hours = (time % DAY) / HOUR, minute = (time % HOUR) / MINUTE;
6091 std::ostringstream ss;
6092 if(days) ss << days << "d ";
6093 if(hours) ss << hours << "h ";
6094 ss << minute << "m";
6095 return ss.str();
6098 bool ChatHandler::HandleInstanceListBindsCommand(const char* /*args*/)
6100 Player* player = getSelectedPlayer();
6101 if (!player) player = m_session->GetPlayer();
6102 uint32 counter = 0;
6103 for(uint8 i = 0; i < TOTAL_DIFFICULTIES; ++i)
6105 Player::BoundInstancesMap &binds = player->GetBoundInstances(i);
6106 for(Player::BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end(); ++itr)
6108 InstanceSave *save = itr->second.save;
6109 std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
6110 PSendSysMessage("map: %d inst: %d perm: %s diff: %s canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty() == DIFFICULTY_NORMAL ? "normal" : "heroic", save->CanReset() ? "yes" : "no", timeleft.c_str());
6111 counter++;
6114 PSendSysMessage("player binds: %d", counter);
6115 counter = 0;
6116 Group *group = player->GetGroup();
6117 if(group)
6119 for(uint8 i = 0; i < TOTAL_DIFFICULTIES; ++i)
6121 Group::BoundInstancesMap &binds = group->GetBoundInstances(i);
6122 for(Group::BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end(); ++itr)
6124 InstanceSave *save = itr->second.save;
6125 std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
6126 PSendSysMessage("map: %d inst: %d perm: %s diff: %s canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty() == DIFFICULTY_NORMAL ? "normal" : "heroic", save->CanReset() ? "yes" : "no", timeleft.c_str());
6127 counter++;
6131 PSendSysMessage("group binds: %d", counter);
6133 return true;
6136 bool ChatHandler::HandleInstanceUnbindCommand(const char* args)
6138 if(!*args)
6139 return false;
6141 std::string cmd = args;
6142 if(cmd == "all")
6144 Player* player = getSelectedPlayer();
6145 if (!player) player = m_session->GetPlayer();
6146 uint32 counter = 0;
6147 for(uint8 i = 0; i < TOTAL_DIFFICULTIES; ++i)
6149 Player::BoundInstancesMap &binds = player->GetBoundInstances(i);
6150 for(Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end();)
6152 if(itr->first != player->GetMapId())
6154 InstanceSave *save = itr->second.save;
6155 std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
6156 PSendSysMessage("unbinding map: %d inst: %d perm: %s diff: %s canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty() == DIFFICULTY_NORMAL ? "normal" : "heroic", save->CanReset() ? "yes" : "no", timeleft.c_str());
6157 player->UnbindInstance(itr, i);
6158 counter++;
6160 else
6161 ++itr;
6164 PSendSysMessage("instances unbound: %d", counter);
6166 return true;
6169 bool ChatHandler::HandleInstanceStatsCommand(const char* /*args*/)
6171 PSendSysMessage("instances loaded: %d", MapManager::Instance().GetNumInstances());
6172 PSendSysMessage("players in instances: %d", MapManager::Instance().GetNumPlayersInInstances());
6173 PSendSysMessage("instance saves: %d", sInstanceSaveManager.GetNumInstanceSaves());
6174 PSendSysMessage("players bound: %d", sInstanceSaveManager.GetNumBoundPlayersTotal());
6175 PSendSysMessage("groups bound: %d", sInstanceSaveManager.GetNumBoundGroupsTotal());
6176 return true;
6179 bool ChatHandler::HandleInstanceSaveDataCommand(const char * /*args*/)
6181 Player* pl = m_session->GetPlayer();
6183 Map* map = pl->GetMap();
6184 if (!map->IsDungeon())
6186 PSendSysMessage("Map is not a dungeon.");
6187 SetSentErrorMessage(true);
6188 return false;
6191 if (!((InstanceMap*)map)->GetInstanceData())
6193 PSendSysMessage("Map has no instance data.");
6194 SetSentErrorMessage(true);
6195 return false;
6198 ((InstanceMap*)map)->GetInstanceData()->SaveToDB();
6199 return true;
6202 /// Display the list of GMs
6203 bool ChatHandler::HandleGMListFullCommand(const char* /*args*/)
6205 ///- Get the accounts with GM Level >0
6206 QueryResult *result = loginDatabase.Query( "SELECT username,gmlevel FROM account WHERE gmlevel > 0" );
6207 if(result)
6209 SendSysMessage(LANG_GMLIST);
6210 SendSysMessage("========================");
6211 SendSysMessage(LANG_GMLIST_HEADER);
6212 SendSysMessage("========================");
6214 ///- Circle through them. Display username and GM level
6217 Field *fields = result->Fetch();
6218 PSendSysMessage("|%15s|%6s|", fields[0].GetString(),fields[1].GetString());
6219 }while( result->NextRow() );
6221 PSendSysMessage("========================");
6222 delete result;
6224 else
6225 PSendSysMessage(LANG_GMLIST_EMPTY);
6226 return true;
6229 /// Define the 'Message of the day' for the realm
6230 bool ChatHandler::HandleServerSetMotdCommand(const char* args)
6232 sWorld.SetMotd(args);
6233 PSendSysMessage(LANG_MOTD_NEW, args);
6234 return true;
6237 /// Set/Unset the expansion level for an account
6238 bool ChatHandler::HandleAccountSetAddonCommand(const char* args)
6240 ///- Get the command line arguments
6241 char *szAcc = strtok((char*)args," ");
6242 char *szExp = strtok(NULL," ");
6244 if(!szAcc)
6245 return false;
6247 std::string account_name;
6248 uint32 account_id;
6250 if(!szExp)
6252 Player* player = getSelectedPlayer();
6253 if(!player)
6254 return false;
6256 account_id = player->GetSession()->GetAccountId();
6257 accmgr.GetName(account_id,account_name);
6258 szExp = szAcc;
6260 else
6262 ///- Convert Account name to Upper Format
6263 account_name = szAcc;
6264 if(!AccountMgr::normilizeString(account_name))
6266 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
6267 SetSentErrorMessage(true);
6268 return false;
6271 account_id = accmgr.GetId(account_name);
6272 if(!account_id)
6274 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
6275 SetSentErrorMessage(true);
6276 return false;
6281 // Let set addon state only for lesser (strong) security level
6282 // or to self account
6283 if (m_session && m_session->GetAccountId () != account_id &&
6284 HasLowerSecurityAccount (NULL,account_id,true))
6285 return false;
6287 int lev=atoi(szExp); //get int anyway (0 if error)
6288 if(lev < 0)
6289 return false;
6291 // No SQL injection
6292 loginDatabase.PExecute("UPDATE account SET expansion = '%d' WHERE id = '%u'",lev,account_id);
6293 PSendSysMessage(LANG_ACCOUNT_SETADDON,account_name.c_str(),account_id,lev);
6294 return true;
6297 //Send items by mail
6298 bool ChatHandler::HandleSendItemsCommand(const char* args)
6300 // format: name "subject text" "mail text" item1[:count1] item2[:count2] ... item12[:count12]
6301 Player* receiver;
6302 uint64 receiver_guid;
6303 std::string receiver_name;
6304 if(!extractPlayerTarget((char*)args,&receiver,&receiver_guid,&receiver_name))
6305 return false;
6307 char* tail1 = strtok(NULL, "");
6308 if(!tail1)
6309 return false;
6311 char* msgSubject = extractQuotedArg(tail1);
6312 if (!msgSubject)
6313 return false;
6315 char* tail2 = strtok(NULL, "");
6316 if(!tail2)
6317 return false;
6319 char* msgText = extractQuotedArg(tail2);
6320 if (!msgText)
6321 return false;
6323 // msgSubject, msgText isn't NUL after prev. check
6324 std::string subject = msgSubject;
6325 std::string text = msgText;
6327 // extract items
6328 typedef std::pair<uint32,uint32> ItemPair;
6329 typedef std::list< ItemPair > ItemPairs;
6330 ItemPairs items;
6332 // get all tail string
6333 char* tail = strtok(NULL, "");
6335 // get from tail next item str
6336 while(char* itemStr = strtok(tail, " "))
6338 // and get new tail
6339 tail = strtok(NULL, "");
6341 // parse item str
6342 char* itemIdStr = strtok(itemStr, ":");
6343 char* itemCountStr = strtok(NULL, " ");
6345 uint32 item_id = atoi(itemIdStr);
6346 if(!item_id)
6347 return false;
6349 ItemPrototype const* item_proto = objmgr.GetItemPrototype(item_id);
6350 if(!item_proto)
6352 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
6353 SetSentErrorMessage(true);
6354 return false;
6357 uint32 item_count = itemCountStr ? atoi(itemCountStr) : 1;
6358 if(item_count < 1 || item_proto->MaxCount > 0 && item_count > uint32(item_proto->MaxCount))
6360 PSendSysMessage(LANG_COMMAND_INVALID_ITEM_COUNT, item_count,item_id);
6361 SetSentErrorMessage(true);
6362 return false;
6365 while(item_count > item_proto->GetMaxStackSize())
6367 items.push_back(ItemPair(item_id,item_proto->GetMaxStackSize()));
6368 item_count -= item_proto->GetMaxStackSize();
6371 items.push_back(ItemPair(item_id,item_count));
6373 if(items.size() > MAX_MAIL_ITEMS)
6375 PSendSysMessage(LANG_COMMAND_MAIL_ITEMS_LIMIT, MAX_MAIL_ITEMS);
6376 SetSentErrorMessage(true);
6377 return false;
6381 // from console show not existed sender
6382 uint32 sender_guidlo = m_session ? m_session->GetPlayer()->GetGUIDLow() : 0;
6384 uint32 messagetype = MAIL_NORMAL;
6385 uint32 stationery = MAIL_STATIONERY_GM;
6386 uint32 itemTextId = !text.empty() ? objmgr.CreateItemText( text ) : 0;
6388 // fill mail
6389 MailItemsInfo mi; // item list preparing
6391 for(ItemPairs::const_iterator itr = items.begin(); itr != items.end(); ++itr)
6393 if(Item* item = Item::CreateItem(itr->first,itr->second,m_session ? m_session->GetPlayer() : 0))
6395 item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted
6396 mi.AddItem(item->GetGUIDLow(), item->GetEntry(), item);
6400 WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, &mi, 0, 0, MAIL_CHECK_MASK_NONE);
6402 std::string nameLink = playerLink(receiver_name);
6403 PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
6404 return true;
6407 ///Send money by mail
6408 bool ChatHandler::HandleSendMoneyCommand(const char* args)
6410 /// format: name "subject text" "mail text" money
6412 Player* receiver;
6413 uint64 receiver_guid;
6414 std::string receiver_name;
6415 if(!extractPlayerTarget((char*)args,&receiver,&receiver_guid,&receiver_name))
6416 return false;
6418 char* tail1 = strtok(NULL, "");
6419 if (!tail1)
6420 return false;
6422 char* msgSubject = extractQuotedArg(tail1);
6423 if (!msgSubject)
6424 return false;
6426 char* tail2 = strtok(NULL, "");
6427 if (!tail2)
6428 return false;
6430 char* msgText = extractQuotedArg(tail2);
6431 if (!msgText)
6432 return false;
6434 char* money_str = strtok(NULL, "");
6435 int32 money = money_str ? atoi(money_str) : 0;
6436 if (money <= 0)
6437 return false;
6439 // msgSubject, msgText isn't NUL after prev. check
6440 std::string subject = msgSubject;
6441 std::string text = msgText;
6443 // from console show not existed sender
6444 uint32 sender_guidlo = m_session ? m_session->GetPlayer()->GetGUIDLow() : 0;
6446 uint32 messagetype = MAIL_NORMAL;
6447 uint32 stationery = MAIL_STATIONERY_GM;
6448 uint32 itemTextId = !text.empty() ? objmgr.CreateItemText( text ) : 0;
6450 WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, NULL, money, 0, MAIL_CHECK_MASK_NONE);
6452 std::string nameLink = playerLink(receiver_name);
6453 PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
6454 return true;
6457 /// Send a message to a player in game
6458 bool ChatHandler::HandleSendMessageCommand(const char* args)
6460 ///- Find the player
6461 Player *rPlayer;
6462 std::string rName;
6463 if(!extractPlayerTarget((char*)args,&rPlayer,NULL,&rName))
6464 return false;
6466 char* msg_str = strtok(NULL, "");
6467 if(!msg_str)
6468 return false;
6470 ///- Check that he is not logging out.
6471 if(rPlayer->GetSession()->isLogingOut())
6473 SendSysMessage(LANG_PLAYER_NOT_FOUND);
6474 SetSentErrorMessage(true);
6475 return false;
6478 ///- Send the message
6479 //Use SendAreaTriggerMessage for fastest delivery.
6480 rPlayer->GetSession()->SendAreaTriggerMessage("%s", msg_str);
6481 rPlayer->GetSession()->SendAreaTriggerMessage("|cffff0000[Message from administrator]:|r");
6483 //Confirmation message
6484 std::string nameLink = playerLink(rName);
6485 PSendSysMessage(LANG_SENDMESSAGE,nameLink.c_str(),msg_str);
6486 return true;
6489 bool ChatHandler::HandleFlushArenaPointsCommand(const char * /*args*/)
6491 sBattleGroundMgr.DistributeArenaPoints();
6492 return true;
6495 bool ChatHandler::HandleModifyGenderCommand(const char *args)
6497 if(!*args)
6498 return false;
6500 Player *player = getSelectedPlayer();
6502 if(!player)
6504 PSendSysMessage(LANG_PLAYER_NOT_FOUND);
6505 SetSentErrorMessage(true);
6506 return false;
6509 PlayerInfo const* info = objmgr.GetPlayerInfo(player->getRace(), player->getClass());
6510 if(!info)
6511 return false;
6513 char const* gender_str = (char*)args;
6514 int gender_len = strlen(gender_str);
6516 Gender gender;
6518 if(!strncmp(gender_str, "male", gender_len)) // MALE
6520 if(player->getGender() == GENDER_MALE)
6521 return true;
6523 gender = GENDER_MALE;
6525 else if (!strncmp(gender_str, "female", gender_len)) // FEMALE
6527 if(player->getGender() == GENDER_FEMALE)
6528 return true;
6530 gender = GENDER_FEMALE;
6532 else
6534 SendSysMessage(LANG_MUST_MALE_OR_FEMALE);
6535 SetSentErrorMessage(true);
6536 return false;
6539 // Set gender
6540 player->SetByteValue(UNIT_FIELD_BYTES_0, 2, gender);
6541 player->SetByteValue(PLAYER_BYTES_3, 0, gender);
6543 // Change display ID
6544 player->SetDisplayId(gender ? info->displayId_f : info->displayId_m);
6545 player->SetNativeDisplayId(gender ? info->displayId_f : info->displayId_m);
6547 char const* gender_full = gender ? "female" : "male";
6549 PSendSysMessage(LANG_YOU_CHANGE_GENDER, GetNameLink(player).c_str(), gender_full);
6551 if (needReportToTarget(player))
6552 ChatHandler(player).PSendSysMessage(LANG_YOUR_GENDER_CHANGED, gender_full, GetNameLink().c_str());
6554 return true;