[8483] Implement glyph 43361.
[getmangos.git] / src / game / Level3.cpp
blob6bd6a859d817a67be1237e7706ba1af900af25ea
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 HandleReloadSpellAreaCommand("a");
155 HandleReloadSpellChainCommand("a");
156 HandleReloadSpellElixirCommand("a");
157 HandleReloadSpellLearnSpellCommand("a");
158 HandleReloadSpellProcEventCommand("a");
159 HandleReloadSpellBonusesCommand("a");
160 HandleReloadSpellProcItemEnchantCommand("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 HandleReloadItemRequiredTragetCommand("a");
173 return true;
176 bool ChatHandler::HandleReloadAllLocalesCommand(const char* /*args*/)
178 HandleReloadLocalesAchievementRewardCommand("a");
179 HandleReloadLocalesCreatureCommand("a");
180 HandleReloadLocalesGameobjectCommand("a");
181 HandleReloadLocalesItemCommand("a");
182 HandleReloadLocalesNpcTextCommand("a");
183 HandleReloadLocalesPageTextCommand("a");
184 HandleReloadLocalesPointsOfInterestCommand("a");
185 HandleReloadLocalesQuestCommand("a");
186 return true;
189 bool ChatHandler::HandleReloadConfigCommand(const char* /*args*/)
191 sLog.outString( "Re-Loading config settings..." );
192 sWorld.LoadConfigSettings(true);
193 SendGlobalSysMessage("World config settings reloaded.");
194 return true;
197 bool ChatHandler::HandleReloadAchievementCriteriaDataCommand(const char*)
199 sLog.outString( "Re-Loading Additional Achievement Criteria Data..." );
200 achievementmgr.LoadAchievementCriteriaData();
201 SendGlobalSysMessage("DB table `achievement_criteria_data` reloaded.");
202 return true;
205 bool ChatHandler::HandleReloadAchievementRewardCommand(const char*)
207 sLog.outString( "Re-Loading Achievement Reward Data..." );
208 achievementmgr.LoadRewards();
209 SendGlobalSysMessage("DB table `achievement_reward` reloaded.");
210 return true;
213 bool ChatHandler::HandleReloadAreaTriggerTavernCommand(const char*)
215 sLog.outString( "Re-Loading Tavern Area Triggers..." );
216 objmgr.LoadTavernAreaTriggers();
217 SendGlobalSysMessage("DB table `areatrigger_tavern` reloaded.");
218 return true;
221 bool ChatHandler::HandleReloadAreaTriggerTeleportCommand(const char*)
223 sLog.outString( "Re-Loading AreaTrigger teleport definitions..." );
224 objmgr.LoadAreaTriggerTeleports();
225 SendGlobalSysMessage("DB table `areatrigger_teleport` reloaded.");
226 return true;
229 bool ChatHandler::HandleReloadCommandCommand(const char*)
231 load_command_table = true;
232 SendGlobalSysMessage("DB table `command` will be reloaded at next chat command use.");
233 return true;
236 bool ChatHandler::HandleReloadCreatureQuestRelationsCommand(const char*)
238 sLog.outString( "Loading Quests Relations... (`creature_questrelation`)" );
239 objmgr.LoadCreatureQuestRelations();
240 SendGlobalSysMessage("DB table `creature_questrelation` (creature quest givers) reloaded.");
241 return true;
244 bool ChatHandler::HandleReloadCreatureQuestInvRelationsCommand(const char*)
246 sLog.outString( "Loading Quests Relations... (`creature_involvedrelation`)" );
247 objmgr.LoadCreatureInvolvedRelations();
248 SendGlobalSysMessage("DB table `creature_involvedrelation` (creature quest takers) reloaded.");
249 return true;
252 bool ChatHandler::HandleReloadGOQuestRelationsCommand(const char*)
254 sLog.outString( "Loading Quests Relations... (`gameobject_questrelation`)" );
255 objmgr.LoadGameobjectQuestRelations();
256 SendGlobalSysMessage("DB table `gameobject_questrelation` (gameobject quest givers) reloaded.");
257 return true;
260 bool ChatHandler::HandleReloadGOQuestInvRelationsCommand(const char*)
262 sLog.outString( "Loading Quests Relations... (`gameobject_involvedrelation`)" );
263 objmgr.LoadGameobjectInvolvedRelations();
264 SendGlobalSysMessage("DB table `gameobject_involvedrelation` (gameobject quest takers) reloaded.");
265 return true;
268 bool ChatHandler::HandleReloadQuestAreaTriggersCommand(const char*)
270 sLog.outString( "Re-Loading Quest Area Triggers..." );
271 objmgr.LoadQuestAreaTriggers();
272 SendGlobalSysMessage("DB table `areatrigger_involvedrelation` (quest area triggers) reloaded.");
273 return true;
276 bool ChatHandler::HandleReloadQuestTemplateCommand(const char*)
278 sLog.outString( "Re-Loading Quest Templates..." );
279 objmgr.LoadQuests();
280 SendGlobalSysMessage("DB table `quest_template` (quest definitions) reloaded.");
282 /// dependent also from `gameobject` but this table not reloaded anyway
283 sLog.outString( "Re-Loading GameObjects for quests..." );
284 objmgr.LoadGameObjectForQuests();
285 SendGlobalSysMessage("Data GameObjects for quests reloaded.");
286 return true;
289 bool ChatHandler::HandleReloadLootTemplatesCreatureCommand(const char*)
291 sLog.outString( "Re-Loading Loot Tables... (`creature_loot_template`)" );
292 LoadLootTemplates_Creature();
293 LootTemplates_Creature.CheckLootRefs();
294 SendGlobalSysMessage("DB table `creature_loot_template` reloaded.");
295 return true;
298 bool ChatHandler::HandleReloadLootTemplatesDisenchantCommand(const char*)
300 sLog.outString( "Re-Loading Loot Tables... (`disenchant_loot_template`)" );
301 LoadLootTemplates_Disenchant();
302 LootTemplates_Disenchant.CheckLootRefs();
303 SendGlobalSysMessage("DB table `disenchant_loot_template` reloaded.");
304 return true;
307 bool ChatHandler::HandleReloadLootTemplatesFishingCommand(const char*)
309 sLog.outString( "Re-Loading Loot Tables... (`fishing_loot_template`)" );
310 LoadLootTemplates_Fishing();
311 LootTemplates_Fishing.CheckLootRefs();
312 SendGlobalSysMessage("DB table `fishing_loot_template` reloaded.");
313 return true;
316 bool ChatHandler::HandleReloadLootTemplatesGameobjectCommand(const char*)
318 sLog.outString( "Re-Loading Loot Tables... (`gameobject_loot_template`)" );
319 LoadLootTemplates_Gameobject();
320 LootTemplates_Gameobject.CheckLootRefs();
321 SendGlobalSysMessage("DB table `gameobject_loot_template` reloaded.");
322 return true;
325 bool ChatHandler::HandleReloadLootTemplatesItemCommand(const char*)
327 sLog.outString( "Re-Loading Loot Tables... (`item_loot_template`)" );
328 LoadLootTemplates_Item();
329 LootTemplates_Item.CheckLootRefs();
330 SendGlobalSysMessage("DB table `item_loot_template` reloaded.");
331 return true;
334 bool ChatHandler::HandleReloadLootTemplatesMillingCommand(const char*)
336 sLog.outString( "Re-Loading Loot Tables... (`milling_loot_template`)" );
337 LoadLootTemplates_Milling();
338 LootTemplates_Milling.CheckLootRefs();
339 SendGlobalSysMessage("DB table `milling_loot_template` reloaded.");
340 return true;
343 bool ChatHandler::HandleReloadLootTemplatesPickpocketingCommand(const char*)
345 sLog.outString( "Re-Loading Loot Tables... (`pickpocketing_loot_template`)" );
346 LoadLootTemplates_Pickpocketing();
347 LootTemplates_Pickpocketing.CheckLootRefs();
348 SendGlobalSysMessage("DB table `pickpocketing_loot_template` reloaded.");
349 return true;
352 bool ChatHandler::HandleReloadLootTemplatesProspectingCommand(const char*)
354 sLog.outString( "Re-Loading Loot Tables... (`prospecting_loot_template`)" );
355 LoadLootTemplates_Prospecting();
356 LootTemplates_Prospecting.CheckLootRefs();
357 SendGlobalSysMessage("DB table `prospecting_loot_template` reloaded.");
358 return true;
361 bool ChatHandler::HandleReloadLootTemplatesQuestMailCommand(const char*)
363 sLog.outString( "Re-Loading Loot Tables... (`quest_mail_loot_template`)" );
364 LoadLootTemplates_QuestMail();
365 LootTemplates_QuestMail.CheckLootRefs();
366 SendGlobalSysMessage("DB table `quest_mail_loot_template` reloaded.");
367 return true;
370 bool ChatHandler::HandleReloadLootTemplatesReferenceCommand(const char*)
372 sLog.outString( "Re-Loading Loot Tables... (`reference_loot_template`)" );
373 LoadLootTemplates_Reference();
374 SendGlobalSysMessage("DB table `reference_loot_template` reloaded.");
375 return true;
378 bool ChatHandler::HandleReloadLootTemplatesSkinningCommand(const char*)
380 sLog.outString( "Re-Loading Loot Tables... (`skinning_loot_template`)" );
381 LoadLootTemplates_Skinning();
382 LootTemplates_Skinning.CheckLootRefs();
383 SendGlobalSysMessage("DB table `skinning_loot_template` reloaded.");
384 return true;
387 bool ChatHandler::HandleReloadLootTemplatesSpellCommand(const char*)
389 sLog.outString( "Re-Loading Loot Tables... (`spell_loot_template`)" );
390 LoadLootTemplates_Spell();
391 LootTemplates_Spell.CheckLootRefs();
392 SendGlobalSysMessage("DB table `spell_loot_template` reloaded.");
393 return true;
396 bool ChatHandler::HandleReloadMangosStringCommand(const char*)
398 sLog.outString( "Re-Loading mangos_string Table!" );
399 objmgr.LoadMangosStrings();
400 SendGlobalSysMessage("DB table `mangos_string` reloaded.");
401 return true;
404 bool ChatHandler::HandleReloadNpcOptionCommand(const char*)
406 sLog.outString( "Re-Loading `npc_option` Table!" );
407 objmgr.LoadNpcOptions();
408 SendGlobalSysMessage("DB table `npc_option` reloaded.");
409 return true;
412 bool ChatHandler::HandleReloadNpcGossipCommand(const char*)
414 sLog.outString( "Re-Loading `npc_gossip` Table!" );
415 objmgr.LoadNpcTextId();
416 SendGlobalSysMessage("DB table `npc_gossip` reloaded.");
417 return true;
420 bool ChatHandler::HandleReloadNpcTrainerCommand(const char*)
422 sLog.outString( "Re-Loading `npc_trainer` Table!" );
423 objmgr.LoadTrainerSpell();
424 SendGlobalSysMessage("DB table `npc_trainer` reloaded.");
425 return true;
428 bool ChatHandler::HandleReloadNpcVendorCommand(const char*)
430 sLog.outString( "Re-Loading `npc_vendor` Table!" );
431 objmgr.LoadVendors();
432 SendGlobalSysMessage("DB table `npc_vendor` reloaded.");
433 return true;
436 bool ChatHandler::HandleReloadPointsOfInterestCommand(const char*)
438 sLog.outString( "Re-Loading `points_of_interest` Table!" );
439 objmgr.LoadPointsOfInterest();
440 SendGlobalSysMessage("DB table `points_of_interest` reloaded.");
441 return true;
444 bool ChatHandler::HandleReloadSpellClickSpellsCommand(const char*)
446 sLog.outString( "Re-Loading `npc_spellclick_spells` Table!" );
447 objmgr.LoadNPCSpellClickSpells();
448 SendGlobalSysMessage("DB table `npc_spellclick_spells` reloaded.");
449 return true;
452 bool ChatHandler::HandleReloadReservedNameCommand(const char*)
454 sLog.outString( "Loading ReservedNames... (`reserved_name`)" );
455 objmgr.LoadReservedPlayersNames();
456 SendGlobalSysMessage("DB table `reserved_name` (player reserved names) reloaded.");
457 return true;
460 bool ChatHandler::HandleReloadSkillDiscoveryTemplateCommand(const char* /*args*/)
462 sLog.outString( "Re-Loading Skill Discovery Table..." );
463 LoadSkillDiscoveryTable();
464 SendGlobalSysMessage("DB table `skill_discovery_template` (recipes discovered at crafting) reloaded.");
465 return true;
468 bool ChatHandler::HandleReloadSkillExtraItemTemplateCommand(const char* /*args*/)
470 sLog.outString( "Re-Loading Skill Extra Item Table..." );
471 LoadSkillExtraItemTable();
472 SendGlobalSysMessage("DB table `skill_extra_item_template` (extra item creation when crafting) reloaded.");
473 return true;
476 bool ChatHandler::HandleReloadSkillFishingBaseLevelCommand(const char* /*args*/)
478 sLog.outString( "Re-Loading Skill Fishing base level requirements..." );
479 objmgr.LoadFishingBaseSkillLevel();
480 SendGlobalSysMessage("DB table `skill_fishing_base_level` (fishing base level for zone/subzone) reloaded.");
481 return true;
484 bool ChatHandler::HandleReloadSpellAreaCommand(const char*)
486 sLog.outString( "Re-Loading SpellArea Data..." );
487 spellmgr.LoadSpellAreas();
488 SendGlobalSysMessage("DB table `spell_area` (spell dependences from area/quest/auras state) reloaded.");
489 return true;
492 bool ChatHandler::HandleReloadSpellChainCommand(const char*)
494 sLog.outString( "Re-Loading Spell Chain Data... " );
495 spellmgr.LoadSpellChains();
496 SendGlobalSysMessage("DB table `spell_chain` (spell ranks) reloaded.");
497 return true;
500 bool ChatHandler::HandleReloadSpellElixirCommand(const char*)
502 sLog.outString( "Re-Loading Spell Elixir types..." );
503 spellmgr.LoadSpellElixirs();
504 SendGlobalSysMessage("DB table `spell_elixir` (spell elixir types) reloaded.");
505 return true;
508 bool ChatHandler::HandleReloadSpellLearnSpellCommand(const char*)
510 sLog.outString( "Re-Loading Spell Learn Spells..." );
511 spellmgr.LoadSpellLearnSpells();
512 SendGlobalSysMessage("DB table `spell_learn_spell` reloaded.");
513 return true;
516 bool ChatHandler::HandleReloadSpellProcEventCommand(const char*)
518 sLog.outString( "Re-Loading Spell Proc Event conditions..." );
519 spellmgr.LoadSpellProcEvents();
520 SendGlobalSysMessage("DB table `spell_proc_event` (spell proc trigger requirements) reloaded.");
521 return true;
524 bool ChatHandler::HandleReloadSpellBonusesCommand(const char*)
526 sLog.outString( "Re-Loading Spell Bonus Data..." );
527 spellmgr.LoadSpellBonusess();
528 SendGlobalSysMessage("DB table `spell_bonus_data` (spell damage/healing coefficients) reloaded.");
529 return true;
532 bool ChatHandler::HandleReloadSpellProcItemEnchantCommand(const char*)
534 sLog.outString( "Re-Loading Spell Proc Item Enchant..." );
535 spellmgr.LoadSpellProcItemEnchant();
536 SendGlobalSysMessage("DB table `spell_proc_item_enchant` (item enchantment ppm) reloaded.");
537 return true;
540 bool ChatHandler::HandleReloadSpellScriptTargetCommand(const char*)
542 sLog.outString( "Re-Loading SpellsScriptTarget..." );
543 spellmgr.LoadSpellScriptTarget();
544 SendGlobalSysMessage("DB table `spell_script_target` (spell targets selection in case specific creature/GO requirements) reloaded.");
545 return true;
548 bool ChatHandler::HandleReloadSpellTargetPositionCommand(const char*)
550 sLog.outString( "Re-Loading Spell target coordinates..." );
551 spellmgr.LoadSpellTargetPositions();
552 SendGlobalSysMessage("DB table `spell_target_position` (destination coordinates for spell targets) reloaded.");
553 return true;
556 bool ChatHandler::HandleReloadSpellThreatsCommand(const char*)
558 sLog.outString( "Re-Loading Aggro Spells Definitions...");
559 spellmgr.LoadSpellThreats();
560 SendGlobalSysMessage("DB table `spell_threat` (spell aggro definitions) reloaded.");
561 return true;
564 bool ChatHandler::HandleReloadSpellPetAurasCommand(const char*)
566 sLog.outString( "Re-Loading Spell pet auras...");
567 spellmgr.LoadSpellPetAuras();
568 SendGlobalSysMessage("DB table `spell_pet_auras` reloaded.");
569 return true;
572 bool ChatHandler::HandleReloadPageTextsCommand(const char*)
574 sLog.outString( "Re-Loading Page Texts..." );
575 objmgr.LoadPageTexts();
576 SendGlobalSysMessage("DB table `page_texts` reloaded.");
577 return true;
580 bool ChatHandler::HandleReloadItemEnchantementsCommand(const char*)
582 sLog.outString( "Re-Loading Item Random Enchantments Table..." );
583 LoadRandomEnchantmentsTable();
584 SendGlobalSysMessage("DB table `item_enchantment_template` reloaded.");
585 return true;
588 bool ChatHandler::HandleReloadItemRequiredTragetCommand(const char*)
590 sLog.outString( "Re-Loading Item Required Targets Table..." );
591 objmgr.LoadItemRequiredTarget();
592 SendGlobalSysMessage("DB table `item_required_target` reloaded.");
593 return true;
596 bool ChatHandler::HandleReloadGameObjectScriptsCommand(const char* arg)
598 if(sWorld.IsScriptScheduled())
600 SendSysMessage("DB scripts used currently, please attempt reload later.");
601 SetSentErrorMessage(true);
602 return false;
605 if(*arg!='a')
606 sLog.outString( "Re-Loading Scripts from `gameobject_scripts`...");
608 objmgr.LoadGameObjectScripts();
610 if(*arg!='a')
611 SendGlobalSysMessage("DB table `gameobject_scripts` reloaded.");
613 return true;
616 bool ChatHandler::HandleReloadEventScriptsCommand(const char* arg)
618 if(sWorld.IsScriptScheduled())
620 SendSysMessage("DB scripts used currently, please attempt reload later.");
621 SetSentErrorMessage(true);
622 return false;
625 if(*arg!='a')
626 sLog.outString( "Re-Loading Scripts from `event_scripts`...");
628 objmgr.LoadEventScripts();
630 if(*arg!='a')
631 SendGlobalSysMessage("DB table `event_scripts` reloaded.");
633 return true;
636 bool ChatHandler::HandleReloadEventAITextsCommand(const char* arg)
639 sLog.outString( "Re-Loading Texts from `creature_ai_texts`...");
640 CreatureEAI_Mgr.LoadCreatureEventAI_Texts();
641 SendGlobalSysMessage("DB table `creature_ai_texts` reloaded.");
642 return true;
645 bool ChatHandler::HandleReloadEventAISummonsCommand(const char* arg)
647 sLog.outString( "Re-Loading Summons from `creature_ai_summons`...");
648 CreatureEAI_Mgr.LoadCreatureEventAI_Summons();
649 SendGlobalSysMessage("DB table `creature_ai_summons` reloaded.");
650 return true;
653 bool ChatHandler::HandleReloadEventAIScriptsCommand(const char* arg)
655 sLog.outString( "Re-Loading Scripts from `creature_ai_scripts`...");
656 CreatureEAI_Mgr.LoadCreatureEventAI_Scripts();
657 SendGlobalSysMessage("DB table `creature_ai_scripts` reloaded.");
658 return true;
661 bool ChatHandler::HandleReloadQuestEndScriptsCommand(const char* arg)
663 if(sWorld.IsScriptScheduled())
665 SendSysMessage("DB scripts used currently, please attempt reload later.");
666 SetSentErrorMessage(true);
667 return false;
670 if(*arg!='a')
671 sLog.outString( "Re-Loading Scripts from `quest_end_scripts`...");
673 objmgr.LoadQuestEndScripts();
675 if(*arg!='a')
676 SendGlobalSysMessage("DB table `quest_end_scripts` reloaded.");
678 return true;
681 bool ChatHandler::HandleReloadQuestStartScriptsCommand(const char* arg)
683 if(sWorld.IsScriptScheduled())
685 SendSysMessage("DB scripts used currently, please attempt reload later.");
686 SetSentErrorMessage(true);
687 return false;
690 if(*arg!='a')
691 sLog.outString( "Re-Loading Scripts from `quest_start_scripts`...");
693 objmgr.LoadQuestStartScripts();
695 if(*arg!='a')
696 SendGlobalSysMessage("DB table `quest_start_scripts` reloaded.");
698 return true;
701 bool ChatHandler::HandleReloadSpellScriptsCommand(const char* arg)
703 if(sWorld.IsScriptScheduled())
705 SendSysMessage("DB scripts used currently, please attempt reload later.");
706 SetSentErrorMessage(true);
707 return false;
710 if(*arg!='a')
711 sLog.outString( "Re-Loading Scripts from `spell_scripts`...");
713 objmgr.LoadSpellScripts();
715 if(*arg!='a')
716 SendGlobalSysMessage("DB table `spell_scripts` reloaded.");
718 return true;
721 bool ChatHandler::HandleReloadDbScriptStringCommand(const char* /*arg*/)
723 sLog.outString( "Re-Loading Script strings from `db_script_string`...");
724 objmgr.LoadDbScriptStrings();
725 SendGlobalSysMessage("DB table `db_script_string` reloaded.");
726 return true;
729 bool ChatHandler::HandleReloadGameGraveyardZoneCommand(const char* /*arg*/)
731 sLog.outString( "Re-Loading Graveyard-zone links...");
733 objmgr.LoadGraveyardZones();
735 SendGlobalSysMessage("DB table `game_graveyard_zone` reloaded.");
737 return true;
740 bool ChatHandler::HandleReloadGameTeleCommand(const char* /*arg*/)
742 sLog.outString( "Re-Loading Game Tele coordinates...");
744 objmgr.LoadGameTele();
746 SendGlobalSysMessage("DB table `game_tele` reloaded.");
748 return true;
751 bool ChatHandler::HandleReloadLocalesAchievementRewardCommand(const char*)
753 sLog.outString( "Re-Loading Locales Achievement Reward Data..." );
754 achievementmgr.LoadRewardLocales();
755 SendGlobalSysMessage("DB table `locales_achievement_reward` reloaded.");
756 return true;
759 bool ChatHandler::HandleReloadLocalesCreatureCommand(const char* /*arg*/)
761 sLog.outString( "Re-Loading Locales Creature ...");
762 objmgr.LoadCreatureLocales();
763 SendGlobalSysMessage("DB table `locales_creature` reloaded.");
764 return true;
767 bool ChatHandler::HandleReloadLocalesGameobjectCommand(const char* /*arg*/)
769 sLog.outString( "Re-Loading Locales Gameobject ... ");
770 objmgr.LoadGameObjectLocales();
771 SendGlobalSysMessage("DB table `locales_gameobject` reloaded.");
772 return true;
775 bool ChatHandler::HandleReloadLocalesItemCommand(const char* /*arg*/)
777 sLog.outString( "Re-Loading Locales Item ... ");
778 objmgr.LoadItemLocales();
779 SendGlobalSysMessage("DB table `locales_item` reloaded.");
780 return true;
783 bool ChatHandler::HandleReloadLocalesNpcTextCommand(const char* /*arg*/)
785 sLog.outString( "Re-Loading Locales NPC Text ... ");
786 objmgr.LoadNpcTextLocales();
787 SendGlobalSysMessage("DB table `locales_npc_text` reloaded.");
788 return true;
791 bool ChatHandler::HandleReloadLocalesPageTextCommand(const char* /*arg*/)
793 sLog.outString( "Re-Loading Locales Page Text ... ");
794 objmgr.LoadPageTextLocales();
795 SendGlobalSysMessage("DB table `locales_page_text` reloaded.");
796 return true;
799 bool ChatHandler::HandleReloadLocalesPointsOfInterestCommand(const char* /*arg*/)
801 sLog.outString( "Re-Loading Locales Points Of Interest ... ");
802 objmgr.LoadPointOfInterestLocales();
803 SendGlobalSysMessage("DB table `locales_points_of_interest` reloaded.");
804 return true;
807 bool ChatHandler::HandleReloadLocalesQuestCommand(const char* /*arg*/)
809 sLog.outString( "Re-Loading Locales Quest ... ");
810 objmgr.LoadQuestLocales();
811 SendGlobalSysMessage("DB table `locales_quest` reloaded.");
812 return true;
815 bool ChatHandler::HandleLoadScriptsCommand(const char* args)
817 if(!LoadScriptingModule(args)) return true;
819 sWorld.SendWorldText(LANG_SCRIPTS_RELOADED);
820 return true;
823 bool ChatHandler::HandleAccountSetGmLevelCommand(const char* args)
825 char* arg1 = strtok((char*)args, " ");
826 if( !arg1 )
827 return false;
829 /// must be NULL if targeted syntax and must be not nULL if not targeted
830 char* arg2 = strtok(NULL, " ");
832 std::string targetAccountName;
833 uint32 targetAccountId = 0;
835 /// only target player different from self allowed (if targetPlayer!=NULL then not console)
836 Player* targetPlayer = getSelectedPlayer();
837 if(targetPlayer && m_session->GetPlayer()!=targetPlayer)
839 /// wrong command syntax or unexpected targeting
840 if(arg2)
841 return false;
843 /// security level expected in arg2 after this if.
844 arg2 = arg1;
846 targetAccountId = targetPlayer->GetSession()->GetAccountId();
847 accmgr.GetName(targetAccountId, targetAccountName);
849 else
851 /// wrong command syntax (second arg expected)
852 if(!arg2)
853 return false;
855 targetAccountName = arg1;
856 if (!AccountMgr::normalizeString(targetAccountName))
858 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,targetAccountName.c_str());
859 SetSentErrorMessage(true);
860 return false;
863 targetAccountId = accmgr.GetId(targetAccountName);
864 if(!targetAccountId)
866 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,targetAccountName.c_str());
867 SetSentErrorMessage(true);
868 return false;
872 int32 gm = (int32)atoi(arg2);
873 if ( gm < SEC_PLAYER || gm > SEC_ADMINISTRATOR )
875 SendSysMessage(LANG_BAD_VALUE);
876 SetSentErrorMessage(true);
877 return false;
880 /// can set security level only for target with less security and to less security that we have
881 /// This will reject self apply by specify account name
882 if(HasLowerSecurityAccount(NULL,targetAccountId,true))
883 return false;
885 /// account can't set security to same or grater level, need more power GM or console
886 AccountTypes plSecurity = m_session ? m_session->GetSecurity() : SEC_CONSOLE;
887 if (AccountTypes(gm) >= plSecurity )
889 SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
890 SetSentErrorMessage(true);
891 return false;
894 // This will prevent self apply by self target or no target
895 if(targetPlayer && m_session->GetPlayer()!=targetPlayer)
897 ChatHandler(targetPlayer).PSendSysMessage(LANG_YOURS_SECURITY_CHANGED,GetNameLink().c_str(), gm);
898 targetPlayer->GetSession()->SetSecurity(AccountTypes(gm));
901 PSendSysMessage(LANG_YOU_CHANGE_SECURITY, targetAccountName.c_str(), gm);
902 loginDatabase.PExecute("UPDATE account SET gmlevel = '%i' WHERE id = '%u'", gm, targetAccountId);
904 return true;
907 /// Set password for account
908 bool ChatHandler::HandleAccountSetPasswordCommand(const char* args)
910 if(!*args)
911 return false;
913 ///- Get the command line arguments
914 char *szAccount = strtok ((char*)args," ");
915 char *szPassword1 = strtok (NULL," ");
916 char *szPassword2 = strtok (NULL," ");
918 if (!szAccount||!szPassword1 || !szPassword2)
919 return false;
921 std::string account_name = szAccount;
922 if (!AccountMgr::normalizeString(account_name))
924 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
925 SetSentErrorMessage(true);
926 return false;
929 uint32 targetAccountId = accmgr.GetId(account_name);
930 if (!targetAccountId)
932 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
933 SetSentErrorMessage(true);
934 return false;
937 /// can set password only for target with less security
938 /// This is also reject self apply in fact
939 if(HasLowerSecurityAccount (NULL,targetAccountId,true))
940 return false;
942 if (strcmp(szPassword1,szPassword2))
944 SendSysMessage (LANG_NEW_PASSWORDS_NOT_MATCH);
945 SetSentErrorMessage (true);
946 return false;
949 AccountOpResult result = accmgr.ChangePassword(targetAccountId, szPassword1);
951 switch(result)
953 case AOR_OK:
954 SendSysMessage(LANG_COMMAND_PASSWORD);
955 break;
956 case AOR_NAME_NOT_EXIST:
957 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
958 SetSentErrorMessage(true);
959 return false;
960 case AOR_PASS_TOO_LONG:
961 SendSysMessage(LANG_PASSWORD_TOO_LONG);
962 SetSentErrorMessage(true);
963 return false;
964 default:
965 SendSysMessage(LANG_COMMAND_NOTCHANGEPASSWORD);
966 SetSentErrorMessage(true);
967 return false;
970 return true;
973 bool ChatHandler::HandleMaxSkillCommand(const char* /*args*/)
975 Player* SelectedPlayer = getSelectedPlayer();
976 if(!SelectedPlayer)
978 SendSysMessage(LANG_NO_CHAR_SELECTED);
979 SetSentErrorMessage(true);
980 return false;
983 // each skills that have max skill value dependent from level seted to current level max skill value
984 SelectedPlayer->UpdateSkillsToMaxSkillsForLevel();
985 return true;
988 bool ChatHandler::HandleSetSkillCommand(const char* args)
990 // number or [name] Shift-click form |color|Hskill:skill_id|h[name]|h|r
991 char* skill_p = extractKeyFromLink((char*)args,"Hskill");
992 if(!skill_p)
993 return false;
995 char *level_p = strtok (NULL, " ");
997 if( !level_p)
998 return false;
1000 char *max_p = strtok (NULL, " ");
1002 int32 skill = atoi(skill_p);
1003 if (skill <= 0)
1005 PSendSysMessage(LANG_INVALID_SKILL_ID, skill);
1006 SetSentErrorMessage(true);
1007 return false;
1010 int32 level = atol (level_p);
1012 Player * target = getSelectedPlayer();
1013 if(!target)
1015 SendSysMessage(LANG_NO_CHAR_SELECTED);
1016 SetSentErrorMessage(true);
1017 return false;
1020 SkillLineEntry const* sl = sSkillLineStore.LookupEntry(skill);
1021 if(!sl)
1023 PSendSysMessage(LANG_INVALID_SKILL_ID, skill);
1024 SetSentErrorMessage(true);
1025 return false;
1028 std::string tNameLink = GetNameLink(target);
1030 if(!target->GetSkillValue(skill))
1032 PSendSysMessage(LANG_SET_SKILL_ERROR, tNameLink.c_str(), skill, sl->name[0]);
1033 SetSentErrorMessage(true);
1034 return false;
1037 int32 max = max_p ? atol (max_p) : target->GetPureMaxSkillValue(skill);
1039 if( level <= 0 || level > max || max <= 0 )
1040 return false;
1042 target->SetSkill(skill, level, max);
1043 PSendSysMessage(LANG_SET_SKILL, skill, sl->name[0], tNameLink.c_str(), level, max);
1045 return true;
1048 bool ChatHandler::HandleUnLearnCommand(const char* args)
1050 if (!*args)
1051 return false;
1053 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
1054 uint32 spell_id = extractSpellIdFromLink((char*)args);
1055 if(!spell_id)
1056 return false;
1058 char const* allStr = strtok(NULL," ");
1059 bool allRanks = allStr ? (strncmp(allStr, "all", strlen(allStr)) == 0) : false;
1061 Player* target = getSelectedPlayer();
1062 if(!target)
1064 SendSysMessage(LANG_NO_CHAR_SELECTED);
1065 SetSentErrorMessage(true);
1066 return false;
1069 if(allRanks)
1070 spell_id = spellmgr.GetFirstSpellInChain (spell_id);
1072 if (target->HasSpell(spell_id))
1073 target->removeSpell(spell_id,false,!allRanks);
1074 else
1075 SendSysMessage(LANG_FORGET_SPELL);
1077 if(GetTalentSpellCost(spell_id))
1078 target->SendTalentsInfoData(false);
1080 return true;
1083 bool ChatHandler::HandleCooldownCommand(const char* args)
1085 Player* target = getSelectedPlayer();
1086 if(!target)
1088 SendSysMessage(LANG_PLAYER_NOT_FOUND);
1089 SetSentErrorMessage(true);
1090 return false;
1093 std::string tNameLink = GetNameLink(target);
1095 if (!*args)
1097 target->RemoveAllSpellCooldown();
1098 PSendSysMessage(LANG_REMOVEALL_COOLDOWN, tNameLink.c_str());
1100 else
1102 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
1103 uint32 spell_id = extractSpellIdFromLink((char*)args);
1104 if(!spell_id)
1105 return false;
1107 if(!sSpellStore.LookupEntry(spell_id))
1109 PSendSysMessage(LANG_UNKNOWN_SPELL, target==m_session->GetPlayer() ? GetMangosString(LANG_YOU) : tNameLink.c_str());
1110 SetSentErrorMessage(true);
1111 return false;
1114 target->RemoveSpellCooldown(spell_id,true);
1115 PSendSysMessage(LANG_REMOVE_COOLDOWN, spell_id, target==m_session->GetPlayer() ? GetMangosString(LANG_YOU) : tNameLink.c_str());
1117 return true;
1120 bool ChatHandler::HandleLearnAllCommand(const char* /*args*/)
1122 static const char *allSpellList[] =
1124 "3365",
1125 "6233",
1126 "6247",
1127 "6246",
1128 "6477",
1129 "6478",
1130 "22810",
1131 "8386",
1132 "21651",
1133 "21652",
1134 "522",
1135 "7266",
1136 "8597",
1137 "2479",
1138 "22027",
1139 "6603",
1140 "5019",
1141 "133",
1142 "168",
1143 "227",
1144 "5009",
1145 "9078",
1146 "668",
1147 "203",
1148 "20599",
1149 "20600",
1150 "81",
1151 "20597",
1152 "20598",
1153 "20864",
1154 "1459",
1155 "5504",
1156 "587",
1157 "5143",
1158 "118",
1159 "5505",
1160 "597",
1161 "604",
1162 "1449",
1163 "1460",
1164 "2855",
1165 "1008",
1166 "475",
1167 "5506",
1168 "1463",
1169 "12824",
1170 "8437",
1171 "990",
1172 "5145",
1173 "8450",
1174 "1461",
1175 "759",
1176 "8494",
1177 "8455",
1178 "8438",
1179 "6127",
1180 "8416",
1181 "6129",
1182 "8451",
1183 "8495",
1184 "8439",
1185 "3552",
1186 "8417",
1187 "10138",
1188 "12825",
1189 "10169",
1190 "10156",
1191 "10144",
1192 "10191",
1193 "10201",
1194 "10211",
1195 "10053",
1196 "10173",
1197 "10139",
1198 "10145",
1199 "10192",
1200 "10170",
1201 "10202",
1202 "10054",
1203 "10174",
1204 "10193",
1205 "12826",
1206 "2136",
1207 "143",
1208 "145",
1209 "2137",
1210 "2120",
1211 "3140",
1212 "543",
1213 "2138",
1214 "2948",
1215 "8400",
1216 "2121",
1217 "8444",
1218 "8412",
1219 "8457",
1220 "8401",
1221 "8422",
1222 "8445",
1223 "8402",
1224 "8413",
1225 "8458",
1226 "8423",
1227 "8446",
1228 "10148",
1229 "10197",
1230 "10205",
1231 "10149",
1232 "10215",
1233 "10223",
1234 "10206",
1235 "10199",
1236 "10150",
1237 "10216",
1238 "10207",
1239 "10225",
1240 "10151",
1241 "116",
1242 "205",
1243 "7300",
1244 "122",
1245 "837",
1246 "10",
1247 "7301",
1248 "7322",
1249 "6143",
1250 "120",
1251 "865",
1252 "8406",
1253 "6141",
1254 "7302",
1255 "8461",
1256 "8407",
1257 "8492",
1258 "8427",
1259 "8408",
1260 "6131",
1261 "7320",
1262 "10159",
1263 "8462",
1264 "10185",
1265 "10179",
1266 "10160",
1267 "10180",
1268 "10219",
1269 "10186",
1270 "10177",
1271 "10230",
1272 "10181",
1273 "10161",
1274 "10187",
1275 "10220",
1276 "2018",
1277 "2663",
1278 "12260",
1279 "2660",
1280 "3115",
1281 "3326",
1282 "2665",
1283 "3116",
1284 "2738",
1285 "3293",
1286 "2661",
1287 "3319",
1288 "2662",
1289 "9983",
1290 "8880",
1291 "2737",
1292 "2739",
1293 "7408",
1294 "3320",
1295 "2666",
1296 "3323",
1297 "3324",
1298 "3294",
1299 "22723",
1300 "23219",
1301 "23220",
1302 "23221",
1303 "23228",
1304 "23338",
1305 "10788",
1306 "10790",
1307 "5611",
1308 "5016",
1309 "5609",
1310 "2060",
1311 "10963",
1312 "10964",
1313 "10965",
1314 "22593",
1315 "22594",
1316 "596",
1317 "996",
1318 "499",
1319 "768",
1320 "17002",
1321 "1448",
1322 "1082",
1323 "16979",
1324 "1079",
1325 "5215",
1326 "20484",
1327 "5221",
1328 "15590",
1329 "17007",
1330 "6795",
1331 "6807",
1332 "5487",
1333 "1446",
1334 "1066",
1335 "5421",
1336 "3139",
1337 "779",
1338 "6811",
1339 "6808",
1340 "1445",
1341 "5216",
1342 "1737",
1343 "5222",
1344 "5217",
1345 "1432",
1346 "6812",
1347 "9492",
1348 "5210",
1349 "3030",
1350 "1441",
1351 "783",
1352 "6801",
1353 "20739",
1354 "8944",
1355 "9491",
1356 "22569",
1357 "5226",
1358 "6786",
1359 "1433",
1360 "8973",
1361 "1828",
1362 "9495",
1363 "9006",
1364 "6794",
1365 "8993",
1366 "5203",
1367 "16914",
1368 "6784",
1369 "9635",
1370 "22830",
1371 "20722",
1372 "9748",
1373 "6790",
1374 "9753",
1375 "9493",
1376 "9752",
1377 "9831",
1378 "9825",
1379 "9822",
1380 "5204",
1381 "5401",
1382 "22831",
1383 "6793",
1384 "9845",
1385 "17401",
1386 "9882",
1387 "9868",
1388 "20749",
1389 "9893",
1390 "9899",
1391 "9895",
1392 "9832",
1393 "9902",
1394 "9909",
1395 "22832",
1396 "9828",
1397 "9851",
1398 "9883",
1399 "9869",
1400 "17406",
1401 "17402",
1402 "9914",
1403 "20750",
1404 "9897",
1405 "9848",
1406 "3127",
1407 "107",
1408 "204",
1409 "9116",
1410 "2457",
1411 "78",
1412 "18848",
1413 "331",
1414 "403",
1415 "2098",
1416 "1752",
1417 "11278",
1418 "11288",
1419 "11284",
1420 "6461",
1421 "2344",
1422 "2345",
1423 "6463",
1424 "2346",
1425 "2352",
1426 "775",
1427 "1434",
1428 "1612",
1429 "71",
1430 "2468",
1431 "2458",
1432 "2467",
1433 "7164",
1434 "7178",
1435 "7367",
1436 "7376",
1437 "7381",
1438 "21156",
1439 "5209",
1440 "3029",
1441 "5201",
1442 "9849",
1443 "9850",
1444 "20719",
1445 "22568",
1446 "22827",
1447 "22828",
1448 "22829",
1449 "6809",
1450 "8972",
1451 "9005",
1452 "9823",
1453 "9827",
1454 "6783",
1455 "9913",
1456 "6785",
1457 "6787",
1458 "9866",
1459 "9867",
1460 "9894",
1461 "9896",
1462 "6800",
1463 "8992",
1464 "9829",
1465 "9830",
1466 "780",
1467 "769",
1468 "6749",
1469 "6750",
1470 "9755",
1471 "9754",
1472 "9908",
1473 "20745",
1474 "20742",
1475 "20747",
1476 "20748",
1477 "9746",
1478 "9745",
1479 "9880",
1480 "9881",
1481 "5391",
1482 "842",
1483 "3025",
1484 "3031",
1485 "3287",
1486 "3329",
1487 "1945",
1488 "3559",
1489 "4933",
1490 "4934",
1491 "4935",
1492 "4936",
1493 "5142",
1494 "5390",
1495 "5392",
1496 "5404",
1497 "5420",
1498 "6405",
1499 "7293",
1500 "7965",
1501 "8041",
1502 "8153",
1503 "9033",
1504 "9034",
1505 //"9036", problems with ghost state
1506 "16421",
1507 "21653",
1508 "22660",
1509 "5225",
1510 "9846",
1511 "2426",
1512 "5916",
1513 "6634",
1514 //"6718", phasing stealth, annoying for learn all case.
1515 "6719",
1516 "8822",
1517 "9591",
1518 "9590",
1519 "10032",
1520 "17746",
1521 "17747",
1522 "8203",
1523 "11392",
1524 "12495",
1525 "16380",
1526 "23452",
1527 "4079",
1528 "4996",
1529 "4997",
1530 "4998",
1531 "4999",
1532 "5000",
1533 "6348",
1534 "6349",
1535 "6481",
1536 "6482",
1537 "6483",
1538 "6484",
1539 "11362",
1540 "11410",
1541 "11409",
1542 "12510",
1543 "12509",
1544 "12885",
1545 "13142",
1546 "21463",
1547 "23460",
1548 "11421",
1549 "11416",
1550 "11418",
1551 "1851",
1552 "10059",
1553 "11423",
1554 "11417",
1555 "11422",
1556 "11419",
1557 "11424",
1558 "11420",
1559 "27",
1560 "31",
1561 "33",
1562 "34",
1563 "35",
1564 "15125",
1565 "21127",
1566 "22950",
1567 "1180",
1568 "201",
1569 "12593",
1570 "12842",
1571 "16770",
1572 "6057",
1573 "12051",
1574 "18468",
1575 "12606",
1576 "12605",
1577 "18466",
1578 "12502",
1579 "12043",
1580 "15060",
1581 "12042",
1582 "12341",
1583 "12848",
1584 "12344",
1585 "12353",
1586 "18460",
1587 "11366",
1588 "12350",
1589 "12352",
1590 "13043",
1591 "11368",
1592 "11113",
1593 "12400",
1594 "11129",
1595 "16766",
1596 "12573",
1597 "15053",
1598 "12580",
1599 "12475",
1600 "12472",
1601 "12953",
1602 "12488",
1603 "11189",
1604 "12985",
1605 "12519",
1606 "16758",
1607 "11958",
1608 "12490",
1609 "11426",
1610 "3565",
1611 "3562",
1612 "18960",
1613 "3567",
1614 "3561",
1615 "3566",
1616 "3563",
1617 "1953",
1618 "2139",
1619 "12505",
1620 "13018",
1621 "12522",
1622 "12523",
1623 "5146",
1624 "5144",
1625 "5148",
1626 "8419",
1627 "8418",
1628 "10213",
1629 "10212",
1630 "10157",
1631 "12524",
1632 "13019",
1633 "12525",
1634 "13020",
1635 "12526",
1636 "13021",
1637 "18809",
1638 "13031",
1639 "13032",
1640 "13033",
1641 "4036",
1642 "3920",
1643 "3919",
1644 "3918",
1645 "7430",
1646 "3922",
1647 "3923",
1648 "7411",
1649 "7418",
1650 "7421",
1651 "13262",
1652 "7412",
1653 "7415",
1654 "7413",
1655 "7416",
1656 "13920",
1657 "13921",
1658 "7745",
1659 "7779",
1660 "7428",
1661 "7457",
1662 "7857",
1663 "7748",
1664 "7426",
1665 "13421",
1666 "7454",
1667 "13378",
1668 "7788",
1669 "14807",
1670 "14293",
1671 "7795",
1672 "6296",
1673 "20608",
1674 "755",
1675 "444",
1676 "427",
1677 "428",
1678 "442",
1679 "447",
1680 "3578",
1681 "3581",
1682 "19027",
1683 "3580",
1684 "665",
1685 "3579",
1686 "3577",
1687 "6755",
1688 "3576",
1689 "2575",
1690 "2577",
1691 "2578",
1692 "2579",
1693 "2580",
1694 "2656",
1695 "2657",
1696 "2576",
1697 "3564",
1698 "10248",
1699 "8388",
1700 "2659",
1701 "14891",
1702 "3308",
1703 "3307",
1704 "10097",
1705 "2658",
1706 "3569",
1707 "16153",
1708 "3304",
1709 "10098",
1710 "4037",
1711 "3929",
1712 "3931",
1713 "3926",
1714 "3924",
1715 "3930",
1716 "3977",
1717 "3925",
1718 "136",
1719 "228",
1720 "5487",
1721 "43",
1722 "202",
1726 int loop = 0;
1727 while(strcmp(allSpellList[loop], "0"))
1729 uint32 spell = atol((char*)allSpellList[loop++]);
1731 if (m_session->GetPlayer()->HasSpell(spell))
1732 continue;
1734 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
1735 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
1737 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
1738 continue;
1741 m_session->GetPlayer()->learnSpell(spell,false);
1744 SendSysMessage(LANG_COMMAND_LEARN_MANY_SPELLS);
1746 return true;
1749 bool ChatHandler::HandleLearnAllGMCommand(const char* /*args*/)
1751 static const char *gmSpellList[] =
1753 "24347", // Become A Fish, No Breath Bar
1754 "35132", // Visual Boom
1755 "38488", // Attack 4000-8000 AOE
1756 "38795", // Attack 2000 AOE + Slow Down 90%
1757 "15712", // Attack 200
1758 "1852", // GM Spell Silence
1759 "31899", // Kill
1760 "31924", // Kill
1761 "29878", // Kill My Self
1762 "26644", // More Kill
1764 "28550", //Invisible 24
1765 "23452", //Invisible + Target
1769 uint16 gmSpellIter = 0;
1770 while( strcmp(gmSpellList[gmSpellIter], "0") )
1772 uint32 spell = atol((char*)gmSpellList[gmSpellIter++]);
1774 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
1775 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
1777 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
1778 continue;
1781 m_session->GetPlayer()->learnSpell(spell,false);
1784 SendSysMessage(LANG_LEARNING_GM_SKILLS);
1785 return true;
1788 bool ChatHandler::HandleLearnAllMyClassCommand(const char* /*args*/)
1790 HandleLearnAllMySpellsCommand("");
1791 HandleLearnAllMyTalentsCommand("");
1792 return true;
1795 bool ChatHandler::HandleLearnAllMySpellsCommand(const char* /*args*/)
1797 ChrClassesEntry const* clsEntry = sChrClassesStore.LookupEntry(m_session->GetPlayer()->getClass());
1798 if(!clsEntry)
1799 return true;
1800 uint32 family = clsEntry->spellfamily;
1802 for (uint32 i = 0; i < sSpellStore.GetNumRows(); ++i)
1804 SpellEntry const *spellInfo = sSpellStore.LookupEntry(i);
1805 if(!spellInfo)
1806 continue;
1808 // skip server-side/triggered spells
1809 if(spellInfo->spellLevel==0)
1810 continue;
1812 // skip wrong class/race skills
1813 if(!m_session->GetPlayer()->IsSpellFitByClassAndRace(spellInfo->Id))
1814 continue;
1816 // skip other spell families
1817 if( spellInfo->SpellFamilyName != family)
1818 continue;
1820 // skip spells with first rank learned as talent (and all talents then also)
1821 uint32 first_rank = spellmgr.GetFirstSpellInChain(spellInfo->Id);
1822 if(GetTalentSpellCost(first_rank) > 0 )
1823 continue;
1825 // skip broken spells
1826 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
1827 continue;
1829 m_session->GetPlayer()->learnSpell(i,false);
1832 SendSysMessage(LANG_COMMAND_LEARN_CLASS_SPELLS);
1833 return true;
1836 bool ChatHandler::HandleLearnAllMyTalentsCommand(const char* /*args*/)
1838 Player* player = m_session->GetPlayer();
1839 uint32 classMask = player->getClassMask();
1841 for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
1843 TalentEntry const *talentInfo = sTalentStore.LookupEntry(i);
1844 if(!talentInfo)
1845 continue;
1847 TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab );
1848 if(!talentTabInfo)
1849 continue;
1851 if( (classMask & talentTabInfo->ClassMask) == 0 )
1852 continue;
1854 // search highest talent rank
1855 uint32 spellid = 0;
1857 for(int rank = MAX_TALENT_RANK-1; rank >= 0; --rank)
1859 if(talentInfo->RankID[rank]!=0)
1861 spellid = talentInfo->RankID[rank];
1862 break;
1866 if(!spellid) // ??? none spells in talent
1867 continue;
1869 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid);
1870 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
1871 continue;
1873 // learn highest rank of talent and learn all non-talent spell ranks (recursive by tree)
1874 player->learnSpellHighRank(spellid);
1877 SendSysMessage(LANG_COMMAND_LEARN_CLASS_TALENTS);
1878 return true;
1881 bool ChatHandler::HandleLearnAllMyPetTalentsCommand(const char* /*args*/)
1883 Player* player = m_session->GetPlayer();
1885 Pet* pet = player->GetPet();
1886 if(!pet)
1888 SendSysMessage(LANG_NO_PET_FOUND);
1889 SetSentErrorMessage(true);
1890 return false;
1893 CreatureInfo const *ci = pet->GetCreatureInfo();
1894 if(!ci)
1896 SendSysMessage(LANG_WRONG_PET_TYPE);
1897 SetSentErrorMessage(true);
1898 return false;
1901 CreatureFamilyEntry const *pet_family = sCreatureFamilyStore.LookupEntry(ci->family);
1902 if(!pet_family)
1904 SendSysMessage(LANG_WRONG_PET_TYPE);
1905 SetSentErrorMessage(true);
1906 return false;
1909 if(pet_family->petTalentType < 0) // not hunter pet
1911 SendSysMessage(LANG_WRONG_PET_TYPE);
1912 SetSentErrorMessage(true);
1913 return false;
1916 for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
1918 TalentEntry const *talentInfo = sTalentStore.LookupEntry(i);
1919 if(!talentInfo)
1920 continue;
1922 TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab );
1923 if(!talentTabInfo)
1924 continue;
1926 // prevent learn talent for different family (cheating)
1927 if(((1 << pet_family->petTalentType) & talentTabInfo->petTalentMask)==0)
1928 continue;
1930 // search highest talent rank
1931 uint32 spellid = 0;
1933 for(int rank = MAX_TALENT_RANK-1; rank >= 0; --rank)
1935 if(talentInfo->RankID[rank]!=0)
1937 spellid = talentInfo->RankID[rank];
1938 break;
1942 if(!spellid) // ??? none spells in talent
1943 continue;
1945 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid);
1946 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
1947 continue;
1949 // learn highest rank of talent and learn all non-talent spell ranks (recursive by tree)
1950 pet->learnSpellHighRank(spellid);
1953 SendSysMessage(LANG_COMMAND_LEARN_PET_TALENTS);
1954 return true;
1957 bool ChatHandler::HandleLearnAllLangCommand(const char* /*args*/)
1959 // skipping UNIVERSAL language (0)
1960 for(int i = 1; i < LANGUAGES_COUNT; ++i)
1961 m_session->GetPlayer()->learnSpell(lang_description[i].spell_id,false);
1963 SendSysMessage(LANG_COMMAND_LEARN_ALL_LANG);
1964 return true;
1967 bool ChatHandler::HandleLearnAllDefaultCommand(const char* args)
1969 Player* target;
1970 if(!extractPlayerTarget((char*)args,&target))
1971 return false;
1973 target->learnDefaultSpells();
1974 target->learnQuestRewardedSpells();
1976 PSendSysMessage(LANG_COMMAND_LEARN_ALL_DEFAULT_AND_QUEST,GetNameLink(target).c_str());
1977 return true;
1980 bool ChatHandler::HandleLearnCommand(const char* args)
1982 Player* targetPlayer = getSelectedPlayer();
1984 if(!targetPlayer)
1986 SendSysMessage(LANG_PLAYER_NOT_FOUND);
1987 SetSentErrorMessage(true);
1988 return false;
1991 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
1992 uint32 spell = extractSpellIdFromLink((char*)args);
1993 if(!spell || !sSpellStore.LookupEntry(spell))
1994 return false;
1996 char const* allStr = strtok(NULL," ");
1997 bool allRanks = allStr ? (strncmp(allStr, "all", strlen(allStr)) == 0) : false;
1999 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
2000 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
2002 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
2003 SetSentErrorMessage(true);
2004 return false;
2007 if (!allRanks && targetPlayer->HasSpell(spell))
2009 if(targetPlayer == m_session->GetPlayer())
2010 SendSysMessage(LANG_YOU_KNOWN_SPELL);
2011 else
2012 PSendSysMessage(LANG_TARGET_KNOWN_SPELL,GetNameLink(targetPlayer).c_str());
2013 SetSentErrorMessage(true);
2014 return false;
2017 if(allRanks)
2018 targetPlayer->learnSpellHighRank(spell);
2019 else
2020 targetPlayer->learnSpell(spell,false);
2022 uint32 first_spell = spellmgr.GetFirstSpellInChain(spell);
2023 if(GetTalentSpellCost(first_spell))
2024 targetPlayer->SendTalentsInfoData(false);
2026 return true;
2029 bool ChatHandler::HandleAddItemCommand(const char* args)
2031 if (!*args)
2032 return false;
2034 uint32 itemId = 0;
2036 if(args[0]=='[') // [name] manual form
2038 char* citemName = strtok((char*)args, "]");
2040 if(citemName && citemName[0])
2042 std::string itemName = citemName+1;
2043 WorldDatabase.escape_string(itemName);
2044 QueryResult *result = WorldDatabase.PQuery("SELECT entry FROM item_template WHERE name = '%s'", itemName.c_str());
2045 if (!result)
2047 PSendSysMessage(LANG_COMMAND_COULDNOTFIND, citemName+1);
2048 SetSentErrorMessage(true);
2049 return false;
2051 itemId = result->Fetch()->GetUInt16();
2052 delete result;
2054 else
2055 return false;
2057 else // item_id or [name] Shift-click form |color|Hitem:item_id:0:0:0|h[name]|h|r
2059 char* cId = extractKeyFromLink((char*)args,"Hitem");
2060 if(!cId)
2061 return false;
2062 itemId = atol(cId);
2065 char* ccount = strtok(NULL, " ");
2067 int32 count = 1;
2069 if (ccount)
2070 count = strtol(ccount, NULL, 10);
2072 if (count == 0)
2073 count = 1;
2075 Player* pl = m_session->GetPlayer();
2076 Player* plTarget = getSelectedPlayer();
2077 if(!plTarget)
2078 plTarget = pl;
2080 sLog.outDetail(GetMangosString(LANG_ADDITEM), itemId, count);
2082 ItemPrototype const *pProto = objmgr.GetItemPrototype(itemId);
2083 if(!pProto)
2085 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId);
2086 SetSentErrorMessage(true);
2087 return false;
2090 //Subtract
2091 if (count < 0)
2093 plTarget->DestroyItemCount(itemId, -count, true, false);
2094 PSendSysMessage(LANG_REMOVEITEM, itemId, -count, GetNameLink(plTarget).c_str());
2095 return true;
2098 //Adding items
2099 uint32 noSpaceForCount = 0;
2101 // check space and find places
2102 ItemPosCountVec dest;
2103 uint8 msg = plTarget->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, itemId, count, &noSpaceForCount );
2104 if( msg != EQUIP_ERR_OK ) // convert to possible store amount
2105 count -= noSpaceForCount;
2107 if( count == 0 || dest.empty()) // can't add any
2109 PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount );
2110 SetSentErrorMessage(true);
2111 return false;
2114 Item* item = plTarget->StoreNewItem( dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId));
2116 // remove binding (let GM give it to another player later)
2117 if(pl==plTarget)
2118 for(ItemPosCountVec::const_iterator itr = dest.begin(); itr != dest.end(); ++itr)
2119 if(Item* item1 = pl->GetItemByPos(itr->pos))
2120 item1->SetBinding( false );
2122 if(count > 0 && item)
2124 pl->SendNewItem(item,count,false,true);
2125 if(pl!=plTarget)
2126 plTarget->SendNewItem(item,count,true,false);
2129 if(noSpaceForCount > 0)
2130 PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount);
2132 return true;
2135 bool ChatHandler::HandleAddItemSetCommand(const char* args)
2137 if (!*args)
2138 return false;
2140 char* cId = extractKeyFromLink((char*)args,"Hitemset"); // number or [name] Shift-click form |color|Hitemset:itemset_id|h[name]|h|r
2141 if (!cId)
2142 return false;
2144 uint32 itemsetId = atol(cId);
2146 // prevent generation all items with itemset field value '0'
2147 if (itemsetId == 0)
2149 PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND,itemsetId);
2150 SetSentErrorMessage(true);
2151 return false;
2154 Player* pl = m_session->GetPlayer();
2155 Player* plTarget = getSelectedPlayer();
2156 if(!plTarget)
2157 plTarget = pl;
2159 sLog.outDetail(GetMangosString(LANG_ADDITEMSET), itemsetId);
2161 bool found = false;
2162 for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
2164 ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype>(id);
2165 if (!pProto)
2166 continue;
2168 if (pProto->ItemSet == itemsetId)
2170 found = true;
2171 ItemPosCountVec dest;
2172 uint8 msg = plTarget->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, pProto->ItemId, 1 );
2173 if (msg == EQUIP_ERR_OK)
2175 Item* item = plTarget->StoreNewItem( dest, pProto->ItemId, true);
2177 // remove binding (let GM give it to another player later)
2178 if (pl==plTarget)
2179 item->SetBinding( false );
2181 pl->SendNewItem(item,1,false,true);
2182 if (pl!=plTarget)
2183 plTarget->SendNewItem(item,1,true,false);
2185 else
2187 pl->SendEquipError( msg, NULL, NULL );
2188 PSendSysMessage(LANG_ITEM_CANNOT_CREATE, pProto->ItemId, 1);
2193 if (!found)
2195 PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND,itemsetId);
2197 SetSentErrorMessage(true);
2198 return false;
2201 return true;
2204 bool ChatHandler::HandleListItemCommand(const char* args)
2206 if(!*args)
2207 return false;
2209 char* cId = extractKeyFromLink((char*)args,"Hitem");
2210 if(!cId)
2211 return false;
2213 uint32 item_id = atol(cId);
2214 if(!item_id)
2216 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
2217 SetSentErrorMessage(true);
2218 return false;
2221 ItemPrototype const* itemProto = objmgr.GetItemPrototype(item_id);
2222 if(!itemProto)
2224 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
2225 SetSentErrorMessage(true);
2226 return false;
2229 char* c_count = strtok(NULL, " ");
2230 int count = c_count ? atol(c_count) : 10;
2232 if(count < 0)
2233 return false;
2235 QueryResult *result;
2237 // inventory case
2238 uint32 inv_count = 0;
2239 result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM character_inventory WHERE item_template='%u'",item_id);
2240 if(result)
2242 inv_count = (*result)[0].GetUInt32();
2243 delete result;
2246 result=CharacterDatabase.PQuery(
2247 // 0 1 2 3 4 5
2248 "SELECT ci.item, cibag.slot AS bag, ci.slot, ci.guid, characters.account,characters.name "
2249 "FROM character_inventory AS ci LEFT JOIN character_inventory AS cibag ON (cibag.item=ci.bag),characters "
2250 "WHERE ci.item_template='%u' AND ci.guid = characters.guid LIMIT %u ",
2251 item_id,uint32(count));
2253 if(result)
2257 Field *fields = result->Fetch();
2258 uint32 item_guid = fields[0].GetUInt32();
2259 uint32 item_bag = fields[1].GetUInt32();
2260 uint32 item_slot = fields[2].GetUInt32();
2261 uint32 owner_guid = fields[3].GetUInt32();
2262 uint32 owner_acc = fields[4].GetUInt32();
2263 std::string owner_name = fields[5].GetCppString();
2265 char const* item_pos = 0;
2266 if(Player::IsEquipmentPos(item_bag,item_slot))
2267 item_pos = "[equipped]";
2268 else if(Player::IsInventoryPos(item_bag,item_slot))
2269 item_pos = "[in inventory]";
2270 else if(Player::IsBankPos(item_bag,item_slot))
2271 item_pos = "[in bank]";
2272 else
2273 item_pos = "";
2275 PSendSysMessage(LANG_ITEMLIST_SLOT,
2276 item_guid,owner_name.c_str(),owner_guid,owner_acc,item_pos);
2277 } while (result->NextRow());
2279 int64 res_count = result->GetRowCount();
2281 delete result;
2283 if(count > res_count)
2284 count-=res_count;
2285 else if(count)
2286 count = 0;
2289 // mail case
2290 uint32 mail_count = 0;
2291 result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM mail_items WHERE item_template='%u'", item_id);
2292 if(result)
2294 mail_count = (*result)[0].GetUInt32();
2295 delete result;
2298 if(count > 0)
2300 result=CharacterDatabase.PQuery(
2301 // 0 1 2 3 4 5 6
2302 "SELECT mail_items.item_guid, mail.sender, mail.receiver, char_s.account, char_s.name, char_r.account, char_r.name "
2303 "FROM mail,mail_items,characters as char_s,characters as char_r "
2304 "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",
2305 item_id,uint32(count));
2307 else
2308 result = NULL;
2310 if(result)
2314 Field *fields = result->Fetch();
2315 uint32 item_guid = fields[0].GetUInt32();
2316 uint32 item_s = fields[1].GetUInt32();
2317 uint32 item_r = fields[2].GetUInt32();
2318 uint32 item_s_acc = fields[3].GetUInt32();
2319 std::string item_s_name = fields[4].GetCppString();
2320 uint32 item_r_acc = fields[5].GetUInt32();
2321 std::string item_r_name = fields[6].GetCppString();
2323 char const* item_pos = "[in mail]";
2325 PSendSysMessage(LANG_ITEMLIST_MAIL,
2326 item_guid,item_s_name.c_str(),item_s,item_s_acc,item_r_name.c_str(),item_r,item_r_acc,item_pos);
2327 } while (result->NextRow());
2329 int64 res_count = result->GetRowCount();
2331 delete result;
2333 if(count > res_count)
2334 count-=res_count;
2335 else if(count)
2336 count = 0;
2339 // auction case
2340 uint32 auc_count = 0;
2341 result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM auctionhouse WHERE item_template='%u'",item_id);
2342 if(result)
2344 auc_count = (*result)[0].GetUInt32();
2345 delete result;
2348 if(count > 0)
2350 result=CharacterDatabase.PQuery(
2351 // 0 1 2 3
2352 "SELECT auctionhouse.itemguid, auctionhouse.itemowner, characters.account, characters.name "
2353 "FROM auctionhouse,characters WHERE auctionhouse.item_template='%u' AND characters.guid = auctionhouse.itemowner LIMIT %u",
2354 item_id,uint32(count));
2356 else
2357 result = NULL;
2359 if(result)
2363 Field *fields = result->Fetch();
2364 uint32 item_guid = fields[0].GetUInt32();
2365 uint32 owner = fields[1].GetUInt32();
2366 uint32 owner_acc = fields[2].GetUInt32();
2367 std::string owner_name = fields[3].GetCppString();
2369 char const* item_pos = "[in auction]";
2371 PSendSysMessage(LANG_ITEMLIST_AUCTION, item_guid, owner_name.c_str(), owner, owner_acc,item_pos);
2372 } while (result->NextRow());
2374 delete result;
2377 // guild bank case
2378 uint32 guild_count = 0;
2379 result=CharacterDatabase.PQuery("SELECT COUNT(item_entry) FROM guild_bank_item WHERE item_entry='%u'",item_id);
2380 if(result)
2382 guild_count = (*result)[0].GetUInt32();
2383 delete result;
2386 result=CharacterDatabase.PQuery(
2387 // 0 1 2
2388 "SELECT gi.item_guid, gi.guildid, guild.name "
2389 "FROM guild_bank_item AS gi, guild WHERE gi.item_entry='%u' AND gi.guildid = guild.guildid LIMIT %u ",
2390 item_id,uint32(count));
2392 if(result)
2396 Field *fields = result->Fetch();
2397 uint32 item_guid = fields[0].GetUInt32();
2398 uint32 guild_guid = fields[1].GetUInt32();
2399 std::string guild_name = fields[2].GetCppString();
2401 char const* item_pos = "[in guild bank]";
2403 PSendSysMessage(LANG_ITEMLIST_GUILD,item_guid,guild_name.c_str(),guild_guid,item_pos);
2404 } while (result->NextRow());
2406 int64 res_count = result->GetRowCount();
2408 delete result;
2410 if(count > res_count)
2411 count-=res_count;
2412 else if(count)
2413 count = 0;
2416 if(inv_count+mail_count+auc_count+guild_count == 0)
2418 SendSysMessage(LANG_COMMAND_NOITEMFOUND);
2419 SetSentErrorMessage(true);
2420 return false;
2423 PSendSysMessage(LANG_COMMAND_LISTITEMMESSAGE,item_id,inv_count+mail_count+auc_count+guild_count,inv_count,mail_count,auc_count,guild_count);
2425 return true;
2428 bool ChatHandler::HandleListObjectCommand(const char* args)
2430 if(!*args)
2431 return false;
2433 // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r
2434 char* cId = extractKeyFromLink((char*)args,"Hgameobject_entry");
2435 if(!cId)
2436 return false;
2438 uint32 go_id = atol(cId);
2439 if(!go_id)
2441 PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id);
2442 SetSentErrorMessage(true);
2443 return false;
2446 GameObjectInfo const * gInfo = objmgr.GetGameObjectInfo(go_id);
2447 if(!gInfo)
2449 PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id);
2450 SetSentErrorMessage(true);
2451 return false;
2454 char* c_count = strtok(NULL, " ");
2455 int count = c_count ? atol(c_count) : 10;
2457 if(count < 0)
2458 return false;
2460 QueryResult *result;
2462 uint32 obj_count = 0;
2463 result=WorldDatabase.PQuery("SELECT COUNT(guid) FROM gameobject WHERE id='%u'",go_id);
2464 if(result)
2466 obj_count = (*result)[0].GetUInt32();
2467 delete result;
2470 if(m_session)
2472 Player* pl = m_session->GetPlayer();
2473 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",
2474 pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),go_id,uint32(count));
2476 else
2477 result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map FROM gameobject WHERE id = '%u' LIMIT %u",
2478 go_id,uint32(count));
2480 if (result)
2484 Field *fields = result->Fetch();
2485 uint32 guid = fields[0].GetUInt32();
2486 float x = fields[1].GetFloat();
2487 float y = fields[2].GetFloat();
2488 float z = fields[3].GetFloat();
2489 int mapid = fields[4].GetUInt16();
2491 if (m_session)
2492 PSendSysMessage(LANG_GO_LIST_CHAT, guid, guid, gInfo->name, x, y, z, mapid);
2493 else
2494 PSendSysMessage(LANG_GO_LIST_CONSOLE, guid, gInfo->name, x, y, z, mapid);
2495 } while (result->NextRow());
2497 delete result;
2500 PSendSysMessage(LANG_COMMAND_LISTOBJMESSAGE,go_id,obj_count);
2501 return true;
2504 bool ChatHandler::HandleListCreatureCommand(const char* args)
2506 if(!*args)
2507 return false;
2509 // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
2510 char* cId = extractKeyFromLink((char*)args,"Hcreature_entry");
2511 if(!cId)
2512 return false;
2514 uint32 cr_id = atol(cId);
2515 if(!cr_id)
2517 PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id);
2518 SetSentErrorMessage(true);
2519 return false;
2522 CreatureInfo const* cInfo = objmgr.GetCreatureTemplate(cr_id);
2523 if(!cInfo)
2525 PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id);
2526 SetSentErrorMessage(true);
2527 return false;
2530 char* c_count = strtok(NULL, " ");
2531 int count = c_count ? atol(c_count) : 10;
2533 if(count < 0)
2534 return false;
2536 QueryResult *result;
2538 uint32 cr_count = 0;
2539 result=WorldDatabase.PQuery("SELECT COUNT(guid) FROM creature WHERE id='%u'",cr_id);
2540 if(result)
2542 cr_count = (*result)[0].GetUInt32();
2543 delete result;
2546 if(m_session)
2548 Player* pl = m_session->GetPlayer();
2549 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",
2550 pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), cr_id,uint32(count));
2552 else
2553 result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map FROM creature WHERE id = '%u' LIMIT %u",
2554 cr_id,uint32(count));
2556 if (result)
2560 Field *fields = result->Fetch();
2561 uint32 guid = fields[0].GetUInt32();
2562 float x = fields[1].GetFloat();
2563 float y = fields[2].GetFloat();
2564 float z = fields[3].GetFloat();
2565 int mapid = fields[4].GetUInt16();
2567 if (m_session)
2568 PSendSysMessage(LANG_CREATURE_LIST_CHAT, guid, guid, cInfo->Name, x, y, z, mapid);
2569 else
2570 PSendSysMessage(LANG_CREATURE_LIST_CONSOLE, guid, cInfo->Name, x, y, z, mapid);
2571 } while (result->NextRow());
2573 delete result;
2576 PSendSysMessage(LANG_COMMAND_LISTCREATUREMESSAGE,cr_id,cr_count);
2577 return true;
2580 bool ChatHandler::HandleLookupItemCommand(const char* args)
2582 if(!*args)
2583 return false;
2585 std::string namepart = args;
2586 std::wstring wnamepart;
2588 // converting string that we try to find to lower case
2589 if(!Utf8toWStr(namepart,wnamepart))
2590 return false;
2592 wstrToLower(wnamepart);
2594 uint32 counter = 0;
2596 // Search in `item_template`
2597 for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
2599 ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype >(id);
2600 if(!pProto)
2601 continue;
2603 int loc_idx = GetSessionDbLocaleIndex();
2604 if ( loc_idx >= 0 )
2606 ItemLocale const *il = objmgr.GetItemLocale(pProto->ItemId);
2607 if (il)
2609 if (il->Name.size() > loc_idx && !il->Name[loc_idx].empty())
2611 std::string name = il->Name[loc_idx];
2613 if (Utf8FitTo(name, wnamepart))
2615 if (m_session)
2616 PSendSysMessage(LANG_ITEM_LIST_CHAT, id, id, name.c_str());
2617 else
2618 PSendSysMessage(LANG_ITEM_LIST_CONSOLE, id, name.c_str());
2619 ++counter;
2620 continue;
2626 std::string name = pProto->Name1;
2627 if(name.empty())
2628 continue;
2630 if (Utf8FitTo(name, wnamepart))
2632 if (m_session)
2633 PSendSysMessage(LANG_ITEM_LIST_CHAT, id, id, name.c_str());
2634 else
2635 PSendSysMessage(LANG_ITEM_LIST_CONSOLE, id, name.c_str());
2636 ++counter;
2640 if (counter==0)
2641 SendSysMessage(LANG_COMMAND_NOITEMFOUND);
2643 return true;
2646 bool ChatHandler::HandleLookupItemSetCommand(const char* args)
2648 if(!*args)
2649 return false;
2651 std::string namepart = args;
2652 std::wstring wnamepart;
2654 if(!Utf8toWStr(namepart,wnamepart))
2655 return false;
2657 // converting string that we try to find to lower case
2658 wstrToLower( wnamepart );
2660 uint32 counter = 0; // Counter for figure out that we found smth.
2662 // Search in ItemSet.dbc
2663 for (uint32 id = 0; id < sItemSetStore.GetNumRows(); id++)
2665 ItemSetEntry const *set = sItemSetStore.LookupEntry(id);
2666 if(set)
2668 int loc = GetSessionDbcLocale();
2669 std::string name = set->name[loc];
2670 if(name.empty())
2671 continue;
2673 if (!Utf8FitTo(name, wnamepart))
2675 loc = 0;
2676 for(; loc < MAX_LOCALE; ++loc)
2678 if(loc==GetSessionDbcLocale())
2679 continue;
2681 name = set->name[loc];
2682 if(name.empty())
2683 continue;
2685 if (Utf8FitTo(name, wnamepart))
2686 break;
2690 if(loc < MAX_LOCALE)
2692 // send item set in "id - [namedlink locale]" format
2693 if (m_session)
2694 PSendSysMessage(LANG_ITEMSET_LIST_CHAT,id,id,name.c_str(),localeNames[loc]);
2695 else
2696 PSendSysMessage(LANG_ITEMSET_LIST_CONSOLE,id,name.c_str(),localeNames[loc]);
2697 ++counter;
2701 if (counter == 0) // if counter == 0 then we found nth
2702 SendSysMessage(LANG_COMMAND_NOITEMSETFOUND);
2703 return true;
2706 bool ChatHandler::HandleLookupSkillCommand(const char* args)
2708 if(!*args)
2709 return false;
2711 // can be NULL in console call
2712 Player* target = getSelectedPlayer();
2714 std::string namepart = args;
2715 std::wstring wnamepart;
2717 if(!Utf8toWStr(namepart,wnamepart))
2718 return false;
2720 // converting string that we try to find to lower case
2721 wstrToLower( wnamepart );
2723 uint32 counter = 0; // Counter for figure out that we found smth.
2725 // Search in SkillLine.dbc
2726 for (uint32 id = 0; id < sSkillLineStore.GetNumRows(); id++)
2728 SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(id);
2729 if(skillInfo)
2731 int loc = GetSessionDbcLocale();
2732 std::string name = skillInfo->name[loc];
2733 if(name.empty())
2734 continue;
2736 if (!Utf8FitTo(name, wnamepart))
2738 loc = 0;
2739 for(; loc < MAX_LOCALE; ++loc)
2741 if(loc==GetSessionDbcLocale())
2742 continue;
2744 name = skillInfo->name[loc];
2745 if(name.empty())
2746 continue;
2748 if (Utf8FitTo(name, wnamepart))
2749 break;
2753 if(loc < MAX_LOCALE)
2755 char valStr[50] = "";
2756 char const* knownStr = "";
2757 if(target && target->HasSkill(id))
2759 knownStr = GetMangosString(LANG_KNOWN);
2760 uint32 curValue = target->GetPureSkillValue(id);
2761 uint32 maxValue = target->GetPureMaxSkillValue(id);
2762 uint32 permValue = target->GetSkillPermBonusValue(id);
2763 uint32 tempValue = target->GetSkillTempBonusValue(id);
2765 char const* valFormat = GetMangosString(LANG_SKILL_VALUES);
2766 snprintf(valStr,50,valFormat,curValue,maxValue,permValue,tempValue);
2769 // send skill in "id - [namedlink locale]" format
2770 if (m_session)
2771 PSendSysMessage(LANG_SKILL_LIST_CHAT,id,id,name.c_str(),localeNames[loc],knownStr,valStr);
2772 else
2773 PSendSysMessage(LANG_SKILL_LIST_CONSOLE,id,name.c_str(),localeNames[loc],knownStr,valStr);
2775 ++counter;
2779 if (counter == 0) // if counter == 0 then we found nth
2780 SendSysMessage(LANG_COMMAND_NOSKILLFOUND);
2781 return true;
2784 bool ChatHandler::HandleLookupSpellCommand(const char* args)
2786 if(!*args)
2787 return false;
2789 // can be NULL at console call
2790 Player* target = getSelectedPlayer();
2792 std::string namepart = args;
2793 std::wstring wnamepart;
2795 if(!Utf8toWStr(namepart,wnamepart))
2796 return false;
2798 // converting string that we try to find to lower case
2799 wstrToLower( wnamepart );
2801 uint32 counter = 0; // Counter for figure out that we found smth.
2803 // Search in Spell.dbc
2804 for (uint32 id = 0; id < sSpellStore.GetNumRows(); id++)
2806 SpellEntry const *spellInfo = sSpellStore.LookupEntry(id);
2807 if(spellInfo)
2809 int loc = GetSessionDbcLocale();
2810 std::string name = spellInfo->SpellName[loc];
2811 if(name.empty())
2812 continue;
2814 if (!Utf8FitTo(name, wnamepart))
2816 loc = 0;
2817 for(; loc < MAX_LOCALE; ++loc)
2819 if(loc==GetSessionDbcLocale())
2820 continue;
2822 name = spellInfo->SpellName[loc];
2823 if(name.empty())
2824 continue;
2826 if (Utf8FitTo(name, wnamepart))
2827 break;
2831 if(loc < MAX_LOCALE)
2833 bool known = target && target->HasSpell(id);
2834 bool learn = (spellInfo->Effect[0] == SPELL_EFFECT_LEARN_SPELL);
2836 uint32 talentCost = GetTalentSpellCost(id);
2838 bool talent = (talentCost > 0);
2839 bool passive = IsPassiveSpell(id);
2840 bool active = target && target->HasAura(id);
2842 // unit32 used to prevent interpreting uint8 as char at output
2843 // find rank of learned spell for learning spell, or talent rank
2844 uint32 rank = talentCost ? talentCost : spellmgr.GetSpellRank(learn ? spellInfo->EffectTriggerSpell[0] : id);
2846 // send spell in "id - [name, rank N] [talent] [passive] [learn] [known]" format
2847 std::ostringstream ss;
2848 if (m_session)
2849 ss << id << " - |cffffffff|Hspell:" << id << "|h[" << name;
2850 else
2851 ss << id << " - " << name;
2853 // include rank in link name
2854 if(rank)
2855 ss << GetMangosString(LANG_SPELL_RANK) << rank;
2857 if (m_session)
2858 ss << " " << localeNames[loc] << "]|h|r";
2859 else
2860 ss << " " << localeNames[loc];
2862 if(talent)
2863 ss << GetMangosString(LANG_TALENT);
2864 if(passive)
2865 ss << GetMangosString(LANG_PASSIVE);
2866 if(learn)
2867 ss << GetMangosString(LANG_LEARN);
2868 if(known)
2869 ss << GetMangosString(LANG_KNOWN);
2870 if(active)
2871 ss << GetMangosString(LANG_ACTIVE);
2873 SendSysMessage(ss.str().c_str());
2875 ++counter;
2879 if (counter == 0) // if counter == 0 then we found nth
2880 SendSysMessage(LANG_COMMAND_NOSPELLFOUND);
2881 return true;
2884 bool ChatHandler::HandleLookupQuestCommand(const char* args)
2886 if(!*args)
2887 return false;
2889 // can be NULL at console call
2890 Player* target = getSelectedPlayer();
2892 std::string namepart = args;
2893 std::wstring wnamepart;
2895 // converting string that we try to find to lower case
2896 if(!Utf8toWStr(namepart,wnamepart))
2897 return false;
2899 wstrToLower(wnamepart);
2901 uint32 counter = 0 ;
2903 ObjectMgr::QuestMap const& qTemplates = objmgr.GetQuestTemplates();
2904 for (ObjectMgr::QuestMap::const_iterator iter = qTemplates.begin(); iter != qTemplates.end(); ++iter)
2906 Quest * qinfo = iter->second;
2908 int loc_idx = GetSessionDbLocaleIndex();
2909 if ( loc_idx >= 0 )
2911 QuestLocale const *il = objmgr.GetQuestLocale(qinfo->GetQuestId());
2912 if (il)
2914 if (il->Title.size() > loc_idx && !il->Title[loc_idx].empty())
2916 std::string title = il->Title[loc_idx];
2918 if (Utf8FitTo(title, wnamepart))
2920 char const* statusStr = "";
2922 if(target)
2924 QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId());
2926 if(status == QUEST_STATUS_COMPLETE)
2928 if(target->GetQuestRewardStatus(qinfo->GetQuestId()))
2929 statusStr = GetMangosString(LANG_COMMAND_QUEST_REWARDED);
2930 else
2931 statusStr = GetMangosString(LANG_COMMAND_QUEST_COMPLETE);
2933 else if(status == QUEST_STATUS_INCOMPLETE)
2934 statusStr = GetMangosString(LANG_COMMAND_QUEST_ACTIVE);
2937 if (m_session)
2938 PSendSysMessage(LANG_QUEST_LIST_CHAT,qinfo->GetQuestId(),qinfo->GetQuestId(),qinfo->GetQuestLevel(),title.c_str(),statusStr);
2939 else
2940 PSendSysMessage(LANG_QUEST_LIST_CONSOLE,qinfo->GetQuestId(),title.c_str(),statusStr);
2941 ++counter;
2942 continue;
2948 std::string title = qinfo->GetTitle();
2949 if(title.empty())
2950 continue;
2952 if (Utf8FitTo(title, wnamepart))
2954 char const* statusStr = "";
2956 if(target)
2958 QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId());
2960 if(status == QUEST_STATUS_COMPLETE)
2962 if(target->GetQuestRewardStatus(qinfo->GetQuestId()))
2963 statusStr = GetMangosString(LANG_COMMAND_QUEST_REWARDED);
2964 else
2965 statusStr = GetMangosString(LANG_COMMAND_QUEST_COMPLETE);
2967 else if(status == QUEST_STATUS_INCOMPLETE)
2968 statusStr = GetMangosString(LANG_COMMAND_QUEST_ACTIVE);
2971 if (m_session)
2972 PSendSysMessage(LANG_QUEST_LIST_CHAT,qinfo->GetQuestId(),qinfo->GetQuestId(),qinfo->GetQuestLevel(),title.c_str(),statusStr);
2973 else
2974 PSendSysMessage(LANG_QUEST_LIST_CONSOLE,qinfo->GetQuestId(),title.c_str(),statusStr);
2976 ++counter;
2980 if (counter==0)
2981 SendSysMessage(LANG_COMMAND_NOQUESTFOUND);
2983 return true;
2986 bool ChatHandler::HandleLookupCreatureCommand(const char* args)
2988 if (!*args)
2989 return false;
2991 std::string namepart = args;
2992 std::wstring wnamepart;
2994 // converting string that we try to find to lower case
2995 if (!Utf8toWStr (namepart,wnamepart))
2996 return false;
2998 wstrToLower (wnamepart);
3000 uint32 counter = 0;
3002 for (uint32 id = 0; id< sCreatureStorage.MaxEntry; ++id)
3004 CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo> (id);
3005 if(!cInfo)
3006 continue;
3008 int loc_idx = GetSessionDbLocaleIndex();
3009 if (loc_idx >= 0)
3011 CreatureLocale const *cl = objmgr.GetCreatureLocale (id);
3012 if (cl)
3014 if (cl->Name.size() > loc_idx && !cl->Name[loc_idx].empty ())
3016 std::string name = cl->Name[loc_idx];
3018 if (Utf8FitTo (name, wnamepart))
3020 if (m_session)
3021 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CHAT, id, id, name.c_str ());
3022 else
3023 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CONSOLE, id, name.c_str ());
3024 ++counter;
3025 continue;
3031 std::string name = cInfo->Name;
3032 if (name.empty ())
3033 continue;
3035 if (Utf8FitTo(name, wnamepart))
3037 if (m_session)
3038 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CHAT, id, id, name.c_str ());
3039 else
3040 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CONSOLE, id, name.c_str ());
3041 ++counter;
3045 if (counter==0)
3046 SendSysMessage (LANG_COMMAND_NOCREATUREFOUND);
3048 return true;
3051 bool ChatHandler::HandleLookupObjectCommand(const char* args)
3053 if(!*args)
3054 return false;
3056 std::string namepart = args;
3057 std::wstring wnamepart;
3059 // converting string that we try to find to lower case
3060 if(!Utf8toWStr(namepart,wnamepart))
3061 return false;
3063 wstrToLower(wnamepart);
3065 uint32 counter = 0;
3067 for (uint32 id = 0; id< sGOStorage.MaxEntry; id++ )
3069 GameObjectInfo const* gInfo = sGOStorage.LookupEntry<GameObjectInfo>(id);
3070 if(!gInfo)
3071 continue;
3073 int loc_idx = GetSessionDbLocaleIndex();
3074 if ( loc_idx >= 0 )
3076 GameObjectLocale const *gl = objmgr.GetGameObjectLocale(id);
3077 if (gl)
3079 if (gl->Name.size() > loc_idx && !gl->Name[loc_idx].empty())
3081 std::string name = gl->Name[loc_idx];
3083 if (Utf8FitTo(name, wnamepart))
3085 if (m_session)
3086 PSendSysMessage(LANG_GO_ENTRY_LIST_CHAT, id, id, name.c_str());
3087 else
3088 PSendSysMessage(LANG_GO_ENTRY_LIST_CONSOLE, id, name.c_str());
3089 ++counter;
3090 continue;
3096 std::string name = gInfo->name;
3097 if(name.empty())
3098 continue;
3100 if(Utf8FitTo(name, wnamepart))
3102 if (m_session)
3103 PSendSysMessage(LANG_GO_ENTRY_LIST_CHAT, id, id, name.c_str());
3104 else
3105 PSendSysMessage(LANG_GO_ENTRY_LIST_CONSOLE, id, name.c_str());
3106 ++counter;
3110 if(counter==0)
3111 SendSysMessage(LANG_COMMAND_NOGAMEOBJECTFOUND);
3113 return true;
3116 bool ChatHandler::HandleLookupTaxiNodeCommand(const char * args)
3118 if(!*args)
3119 return false;
3121 std::string namepart = args;
3122 std::wstring wnamepart;
3124 if(!Utf8toWStr(namepart,wnamepart))
3125 return false;
3127 // converting string that we try to find to lower case
3128 wstrToLower( wnamepart );
3130 uint32 counter = 0; // Counter for figure out that we found smth.
3132 // Search in TaxiNodes.dbc
3133 for (uint32 id = 0; id < sTaxiNodesStore.GetNumRows(); id++)
3135 TaxiNodesEntry const *nodeEntry = sTaxiNodesStore.LookupEntry(id);
3136 if(nodeEntry)
3138 int loc = GetSessionDbcLocale();
3139 std::string name = nodeEntry->name[loc];
3140 if(name.empty())
3141 continue;
3143 if (!Utf8FitTo(name, wnamepart))
3145 loc = 0;
3146 for(; loc < MAX_LOCALE; ++loc)
3148 if(loc==GetSessionDbcLocale())
3149 continue;
3151 name = nodeEntry->name[loc];
3152 if(name.empty())
3153 continue;
3155 if (Utf8FitTo(name, wnamepart))
3156 break;
3160 if(loc < MAX_LOCALE)
3162 // send taxinode in "id - [name] (Map:m X:x Y:y Z:z)" format
3163 if (m_session)
3164 PSendSysMessage (LANG_TAXINODE_ENTRY_LIST_CHAT, id, id, name.c_str(),localeNames[loc],
3165 nodeEntry->map_id,nodeEntry->x,nodeEntry->y,nodeEntry->z);
3166 else
3167 PSendSysMessage (LANG_TAXINODE_ENTRY_LIST_CONSOLE, id, name.c_str(), localeNames[loc],
3168 nodeEntry->map_id,nodeEntry->x,nodeEntry->y,nodeEntry->z);
3169 ++counter;
3173 if (counter == 0) // if counter == 0 then we found nth
3174 SendSysMessage(LANG_COMMAND_NOTAXINODEFOUND);
3175 return true;
3178 /** \brief GM command level 3 - Create a guild.
3180 * This command allows a GM (level 3) to create a guild.
3182 * The "args" parameter contains the name of the guild leader
3183 * and then the name of the guild.
3186 bool ChatHandler::HandleGuildCreateCommand(const char* args)
3188 if(!*args)
3189 return false;
3191 // if not guild name only (in "") then player name
3192 Player* target;
3193 if(!extractPlayerTarget(*args!='"' ? (char*)args : NULL, &target))
3194 return false;
3196 char* tailStr = *args!='"' ? strtok(NULL, "") : (char*)args;
3197 if(!tailStr)
3198 return false;
3200 char* guildStr = extractQuotedArg(tailStr);
3201 if(!guildStr)
3202 return false;
3204 std::string guildname = guildStr;
3206 if (target->GetGuildId())
3208 SendSysMessage (LANG_PLAYER_IN_GUILD);
3209 return true;
3212 Guild *guild = new Guild;
3213 if (!guild->Create (target,guildname))
3215 delete guild;
3216 SendSysMessage (LANG_GUILD_NOT_CREATED);
3217 SetSentErrorMessage (true);
3218 return false;
3221 objmgr.AddGuild (guild);
3222 return true;
3225 bool ChatHandler::HandleGuildInviteCommand(const char *args)
3227 if(!*args)
3228 return false;
3230 // if not guild name only (in "") then player name
3231 uint64 target_guid;
3232 if(!extractPlayerTarget(*args!='"' ? (char*)args : NULL, NULL, &target_guid))
3233 return false;
3235 char* tailStr = *args!='"' ? strtok(NULL, "") : (char*)args;
3236 if(!tailStr)
3237 return false;
3239 char* guildStr = extractQuotedArg(tailStr);
3240 if(!guildStr)
3241 return false;
3243 std::string glName = guildStr;
3244 Guild* targetGuild = objmgr.GetGuildByName (glName);
3245 if (!targetGuild)
3246 return false;
3248 // player's guild membership checked in AddMember before add
3249 if (!targetGuild->AddMember (target_guid,targetGuild->GetLowestRank ()))
3250 return false;
3252 return true;
3255 bool ChatHandler::HandleGuildUninviteCommand(const char *args)
3257 Player* target;
3258 uint64 target_guid;
3259 if(!extractPlayerTarget((char*)args,&target,&target_guid))
3260 return false;
3262 uint32 glId = target ? target->GetGuildId () : Player::GetGuildIdFromDB (target_guid);
3263 if (!glId)
3264 return false;
3266 Guild* targetGuild = objmgr.GetGuildById (glId);
3267 if (!targetGuild)
3268 return false;
3270 targetGuild->DelMember (target_guid);
3271 return true;
3274 bool ChatHandler::HandleGuildRankCommand(const char *args)
3276 char* nameStr;
3277 char* rankStr;
3278 extractOptFirstArg((char*)args,&nameStr,&rankStr);
3279 if(!rankStr)
3280 return false;
3282 Player* target;
3283 uint64 target_guid;
3284 std::string target_name;
3285 if(!extractPlayerTarget(nameStr,&target,&target_guid,&target_name))
3286 return false;
3288 uint32 glId = target ? target->GetGuildId () : Player::GetGuildIdFromDB (target_guid);
3289 if (!glId)
3290 return false;
3292 Guild* targetGuild = objmgr.GetGuildById (glId);
3293 if (!targetGuild)
3294 return false;
3296 uint32 newrank = uint32 (atoi (rankStr));
3297 if (newrank > targetGuild->GetLowestRank ())
3298 return false;
3300 targetGuild->ChangeRank (target_guid,newrank);
3301 return true;
3304 bool ChatHandler::HandleGuildDeleteCommand(const char* args)
3306 if (!*args)
3307 return false;
3309 char* guildStr = extractQuotedArg((char*)args);
3310 if(!guildStr)
3311 return false;
3313 std::string gld = guildStr;
3315 Guild* targetGuild = objmgr.GetGuildByName (gld);
3316 if (!targetGuild)
3317 return false;
3319 targetGuild->Disband ();
3321 return true;
3324 bool ChatHandler::HandleGetDistanceCommand(const char* args)
3326 WorldObject* obj = NULL;
3328 if (*args)
3330 uint64 guid = extractGuidFromLink((char*)args);
3331 if(guid)
3332 obj = (WorldObject*)ObjectAccessor::GetObjectByTypeMask(*m_session->GetPlayer(),guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
3334 if(!obj)
3336 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3337 SetSentErrorMessage(true);
3338 return false;
3341 else
3343 obj = getSelectedUnit();
3345 if(!obj)
3347 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3348 SetSentErrorMessage(true);
3349 return false;
3353 PSendSysMessage(LANG_DISTANCE, m_session->GetPlayer()->GetDistance(obj),m_session->GetPlayer()->GetDistance2d(obj));
3355 return true;
3358 bool ChatHandler::HandleDieCommand(const char* /*args*/)
3360 Unit* target = getSelectedUnit();
3362 if(!target || !m_session->GetPlayer()->GetSelection())
3364 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3365 SetSentErrorMessage(true);
3366 return false;
3369 if(target->GetTypeId()==TYPEID_PLAYER)
3371 if(HasLowerSecurity((Player*)target,0,false))
3372 return false;
3375 if( target->isAlive() )
3377 m_session->GetPlayer()->DealDamage(target, target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
3380 return true;
3383 bool ChatHandler::HandleDamageCommand(const char * args)
3385 if (!*args)
3386 return false;
3388 Unit* target = getSelectedUnit();
3390 if (!target || !m_session->GetPlayer()->GetSelection())
3392 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3393 SetSentErrorMessage(true);
3394 return false;
3397 if (!target->isAlive())
3398 return true;
3400 char* damageStr = strtok((char*)args, " ");
3401 if (!damageStr)
3402 return false;
3404 int32 damage_int = atoi((char*)damageStr);
3405 if(damage_int <=0)
3406 return true;
3408 uint32 damage = damage_int;
3410 char* schoolStr = strtok((char*)NULL, " ");
3412 // flat melee damage without resistence/etc reduction
3413 if (!schoolStr)
3415 m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
3416 if (target != m_session->GetPlayer())
3417 m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, SPELL_SCHOOL_MASK_NORMAL, damage, 0, 0, VICTIMSTATE_NORMAL, 0);
3418 return true;
3421 uint32 school = schoolStr ? atoi((char*)schoolStr) : SPELL_SCHOOL_NORMAL;
3422 if(school >= MAX_SPELL_SCHOOL)
3423 return false;
3425 SpellSchoolMask schoolmask = SpellSchoolMask(1 << school);
3427 if ( schoolmask & SPELL_SCHOOL_MASK_NORMAL )
3428 damage = m_session->GetPlayer()->CalcArmorReducedDamage(target, damage);
3430 char* spellStr = strtok((char*)NULL, " ");
3432 // melee damage by specific school
3433 if (!spellStr)
3435 uint32 absorb = 0;
3436 uint32 resist = 0;
3438 m_session->GetPlayer()->CalcAbsorbResist(target,schoolmask, SPELL_DIRECT_DAMAGE, damage, &absorb, &resist);
3440 if (damage <= absorb + resist)
3441 return true;
3443 damage -= absorb + resist;
3445 m_session->GetPlayer()->DealDamageMods(target,damage,&absorb);
3446 m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, schoolmask, NULL, false);
3447 m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, schoolmask, damage, absorb, resist, VICTIMSTATE_NORMAL, 0);
3448 return true;
3451 // non-melee damage
3453 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
3454 uint32 spellid = extractSpellIdFromLink((char*)args);
3455 if (!spellid || !sSpellStore.LookupEntry(spellid))
3456 return false;
3458 m_session->GetPlayer()->SpellNonMeleeDamageLog(target, spellid, damage);
3459 return true;
3462 bool ChatHandler::HandleModifyArenaCommand(const char * args)
3464 if (!*args)
3465 return false;
3467 Player *target = getSelectedPlayer();
3468 if(!target)
3470 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3471 SetSentErrorMessage(true);
3472 return false;
3475 int32 amount = (uint32)atoi(args);
3477 target->ModifyArenaPoints(amount);
3479 PSendSysMessage(LANG_COMMAND_MODIFY_ARENA, GetNameLink(target).c_str(), target->GetArenaPoints());
3481 return true;
3484 bool ChatHandler::HandleReviveCommand(const char* args)
3486 Player* target;
3487 uint64 target_guid;
3488 if(!extractPlayerTarget((char*)args,&target,&target_guid))
3489 return false;
3491 if (target)
3493 target->ResurrectPlayer(0.5f);
3494 target->SpawnCorpseBones();
3495 target->SaveToDB();
3497 else
3498 // will resurrected at login without corpse
3499 ObjectAccessor::Instance().ConvertCorpseForPlayer(target_guid);
3501 return true;
3504 bool ChatHandler::HandleAuraCommand(const char* args)
3506 Unit *target = getSelectedUnit();
3507 if(!target)
3509 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3510 SetSentErrorMessage(true);
3511 return false;
3514 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
3515 uint32 spellID = extractSpellIdFromLink((char*)args);
3517 SpellEntry const *spellInfo = sSpellStore.LookupEntry( spellID );
3518 if(spellInfo)
3520 for(uint32 i = 0;i<3;++i)
3522 uint8 eff = spellInfo->Effect[i];
3523 if (eff>=TOTAL_SPELL_EFFECTS)
3524 continue;
3525 if( IsAreaAuraEffect(eff) ||
3526 eff == SPELL_EFFECT_APPLY_AURA ||
3527 eff == SPELL_EFFECT_PERSISTENT_AREA_AURA )
3529 Aura *Aur = CreateAura(spellInfo, i, NULL, target);
3530 target->AddAura(Aur);
3535 return true;
3538 bool ChatHandler::HandleUnAuraCommand(const char* args)
3540 Unit *target = getSelectedUnit();
3541 if(!target)
3543 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3544 SetSentErrorMessage(true);
3545 return false;
3548 std::string argstr = args;
3549 if (argstr == "all")
3551 target->RemoveAllAuras();
3552 return true;
3555 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
3556 uint32 spellID = extractSpellIdFromLink((char*)args);
3557 if(!spellID)
3558 return false;
3560 target->RemoveAurasDueToSpell(spellID);
3562 return true;
3565 bool ChatHandler::HandleLinkGraveCommand(const char* args)
3567 if(!*args)
3568 return false;
3570 char* px = strtok((char*)args, " ");
3571 if (!px)
3572 return false;
3574 uint32 g_id = (uint32)atoi(px);
3576 uint32 g_team;
3578 char* px2 = strtok(NULL, " ");
3580 if (!px2)
3581 g_team = 0;
3582 else if (strncmp(px2,"horde",6)==0)
3583 g_team = HORDE;
3584 else if (strncmp(px2,"alliance",9)==0)
3585 g_team = ALLIANCE;
3586 else
3587 return false;
3589 WorldSafeLocsEntry const* graveyard = sWorldSafeLocsStore.LookupEntry(g_id);
3591 if(!graveyard )
3593 PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST, g_id);
3594 SetSentErrorMessage(true);
3595 return false;
3598 Player* player = m_session->GetPlayer();
3600 uint32 zoneId = player->GetZoneId();
3602 AreaTableEntry const *areaEntry = GetAreaEntryByAreaID(zoneId);
3603 if(!areaEntry || areaEntry->zone !=0 )
3605 PSendSysMessage(LANG_COMMAND_GRAVEYARDWRONGZONE, g_id,zoneId);
3606 SetSentErrorMessage(true);
3607 return false;
3610 if(objmgr.AddGraveYardLink(g_id,zoneId,g_team))
3611 PSendSysMessage(LANG_COMMAND_GRAVEYARDLINKED, g_id,zoneId);
3612 else
3613 PSendSysMessage(LANG_COMMAND_GRAVEYARDALRLINKED, g_id,zoneId);
3615 return true;
3618 bool ChatHandler::HandleNearGraveCommand(const char* args)
3620 uint32 g_team;
3622 size_t argslen = strlen(args);
3624 if(!*args)
3625 g_team = 0;
3626 else if (strncmp((char*)args,"horde",argslen)==0)
3627 g_team = HORDE;
3628 else if (strncmp((char*)args,"alliance",argslen)==0)
3629 g_team = ALLIANCE;
3630 else
3631 return false;
3633 Player* player = m_session->GetPlayer();
3634 uint32 zone_id = player->GetZoneId();
3636 WorldSafeLocsEntry const* graveyard = objmgr.GetClosestGraveYard(
3637 player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(),player->GetMapId(),g_team);
3639 if(graveyard)
3641 uint32 g_id = graveyard->ID;
3643 GraveYardData const* data = objmgr.FindGraveYardData(g_id,zone_id);
3644 if (!data)
3646 PSendSysMessage(LANG_COMMAND_GRAVEYARDERROR,g_id);
3647 SetSentErrorMessage(true);
3648 return false;
3651 g_team = data->team;
3653 std::string team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_NOTEAM);
3655 if(g_team == 0)
3656 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ANY);
3657 else if(g_team == HORDE)
3658 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_HORDE);
3659 else if(g_team == ALLIANCE)
3660 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ALLIANCE);
3662 PSendSysMessage(LANG_COMMAND_GRAVEYARDNEAREST, g_id,team_name.c_str(),zone_id);
3664 else
3666 std::string team_name;
3668 if(g_team == 0)
3669 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ANY);
3670 else if(g_team == HORDE)
3671 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_HORDE);
3672 else if(g_team == ALLIANCE)
3673 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ALLIANCE);
3675 if(g_team == ~uint32(0))
3676 PSendSysMessage(LANG_COMMAND_ZONENOGRAVEYARDS, zone_id);
3677 else
3678 PSendSysMessage(LANG_COMMAND_ZONENOGRAFACTION, zone_id,team_name.c_str());
3681 return true;
3684 //-----------------------Npc Commands-----------------------
3685 bool ChatHandler::HandleNpcAllowMovementCommand(const char* /*args*/)
3687 if(sWorld.getAllowMovement())
3689 sWorld.SetAllowMovement(false);
3690 SendSysMessage(LANG_CREATURE_MOVE_DISABLED);
3692 else
3694 sWorld.SetAllowMovement(true);
3695 SendSysMessage(LANG_CREATURE_MOVE_ENABLED);
3697 return true;
3700 bool ChatHandler::HandleNpcChangeEntryCommand(const char *args)
3702 if (!*args)
3703 return false;
3705 uint32 newEntryNum = atoi(args);
3706 if(!newEntryNum)
3707 return false;
3709 Unit* unit = getSelectedUnit();
3710 if(!unit || unit->GetTypeId() != TYPEID_UNIT)
3712 SendSysMessage(LANG_SELECT_CREATURE);
3713 SetSentErrorMessage(true);
3714 return false;
3716 Creature* creature = (Creature*)unit;
3717 if(creature->UpdateEntry(newEntryNum))
3718 SendSysMessage(LANG_DONE);
3719 else
3720 SendSysMessage(LANG_ERROR);
3721 return true;
3724 bool ChatHandler::HandleNpcInfoCommand(const char* /*args*/)
3726 Creature* target = getSelectedCreature();
3728 if(!target)
3730 SendSysMessage(LANG_SELECT_CREATURE);
3731 SetSentErrorMessage(true);
3732 return false;
3735 uint32 faction = target->getFaction();
3736 uint32 npcflags = target->GetUInt32Value(UNIT_NPC_FLAGS);
3737 uint32 displayid = target->GetDisplayId();
3738 uint32 nativeid = target->GetNativeDisplayId();
3739 uint32 Entry = target->GetEntry();
3740 CreatureInfo const* cInfo = target->GetCreatureInfo();
3742 int32 curRespawnDelay = target->GetRespawnTimeEx()-time(NULL);
3743 if(curRespawnDelay < 0)
3744 curRespawnDelay = 0;
3745 std::string curRespawnDelayStr = secsToTimeString(curRespawnDelay,true);
3746 std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(),true);
3748 PSendSysMessage(LANG_NPCINFO_CHAR, target->GetDBTableGUIDLow(), faction, npcflags, Entry, displayid, nativeid);
3749 PSendSysMessage(LANG_NPCINFO_LEVEL, target->getLevel());
3750 PSendSysMessage(LANG_NPCINFO_HEALTH,target->GetCreateHealth(), target->GetMaxHealth(), target->GetHealth());
3751 PSendSysMessage(LANG_NPCINFO_FLAGS, target->GetUInt32Value(UNIT_FIELD_FLAGS), target->GetUInt32Value(UNIT_DYNAMIC_FLAGS), target->getFaction());
3752 PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES, defRespawnDelayStr.c_str(),curRespawnDelayStr.c_str());
3753 PSendSysMessage(LANG_NPCINFO_LOOT, cInfo->lootid,cInfo->pickpocketLootId,cInfo->SkinLootId);
3754 PSendSysMessage(LANG_NPCINFO_DUNGEON_ID, target->GetInstanceId());
3755 PSendSysMessage(LANG_NPCINFO_POSITION,float(target->GetPositionX()), float(target->GetPositionY()), float(target->GetPositionZ()));
3757 if ((npcflags & UNIT_NPC_FLAG_VENDOR) )
3759 SendSysMessage(LANG_NPCINFO_VENDOR);
3761 if ((npcflags & UNIT_NPC_FLAG_TRAINER) )
3763 SendSysMessage(LANG_NPCINFO_TRAINER);
3766 return true;
3769 //play npc emote
3770 bool ChatHandler::HandleNpcPlayEmoteCommand(const char* args)
3772 uint32 emote = atoi((char*)args);
3774 Creature* target = getSelectedCreature();
3775 if(!target)
3777 SendSysMessage(LANG_SELECT_CREATURE);
3778 SetSentErrorMessage(true);
3779 return false;
3782 target->SetUInt32Value(UNIT_NPC_EMOTESTATE,emote);
3784 return true;
3787 //TODO: NpcCommands that needs to be fixed :
3789 bool ChatHandler::HandleNpcAddWeaponCommand(const char* /*args*/)
3791 /*if (!*args)
3792 return false;
3794 uint64 guid = m_session->GetPlayer()->GetSelection();
3795 if (guid == 0)
3797 SendSysMessage(LANG_NO_SELECTION);
3798 return true;
3801 Creature *pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
3803 if(!pCreature)
3805 SendSysMessage(LANG_SELECT_CREATURE);
3806 return true;
3809 char* pSlotID = strtok((char*)args, " ");
3810 if (!pSlotID)
3811 return false;
3813 char* pItemID = strtok(NULL, " ");
3814 if (!pItemID)
3815 return false;
3817 uint32 ItemID = atoi(pItemID);
3818 uint32 SlotID = atoi(pSlotID);
3820 ItemPrototype* tmpItem = objmgr.GetItemPrototype(ItemID);
3822 bool added = false;
3823 if(tmpItem)
3825 switch(SlotID)
3827 case 1:
3828 pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, ItemID);
3829 added = true;
3830 break;
3831 case 2:
3832 pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_01, ItemID);
3833 added = true;
3834 break;
3835 case 3:
3836 pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_02, ItemID);
3837 added = true;
3838 break;
3839 default:
3840 PSendSysMessage(LANG_ITEM_SLOT_NOT_EXIST,SlotID);
3841 added = false;
3842 break;
3845 if(added)
3846 PSendSysMessage(LANG_ITEM_ADDED_TO_SLOT,ItemID,tmpItem->Name1,SlotID);
3848 else
3850 PSendSysMessage(LANG_ITEM_NOT_FOUND,ItemID);
3851 return true;
3854 return true;
3856 //----------------------------------------------------------
3858 bool ChatHandler::HandleExploreCheatCommand(const char* args)
3860 if (!*args)
3861 return false;
3863 int flag = atoi((char*)args);
3865 Player *chr = getSelectedPlayer();
3866 if (chr == NULL)
3868 SendSysMessage(LANG_NO_CHAR_SELECTED);
3869 SetSentErrorMessage(true);
3870 return false;
3873 if (flag != 0)
3875 PSendSysMessage(LANG_YOU_SET_EXPLORE_ALL, GetNameLink(chr).c_str());
3876 if (needReportToTarget(chr))
3877 ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_ALL,GetNameLink().c_str());
3879 else
3881 PSendSysMessage(LANG_YOU_SET_EXPLORE_NOTHING, GetNameLink(chr).c_str());
3882 if (needReportToTarget(chr))
3883 ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_NOTHING,GetNameLink().c_str());
3886 for (uint8 i=0; i<128; ++i)
3888 if (flag != 0)
3890 m_session->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i,0xFFFFFFFF);
3892 else
3894 m_session->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i,0);
3898 return true;
3901 bool ChatHandler::HandleHoverCommand(const char* args)
3903 char* px = strtok((char*)args, " ");
3904 uint32 flag;
3905 if (!px)
3906 flag = 1;
3907 else
3908 flag = atoi(px);
3910 m_session->GetPlayer()->SetHover(flag);
3912 if (flag)
3913 SendSysMessage(LANG_HOVER_ENABLED);
3914 else
3915 SendSysMessage(LANG_HOVER_DISABLED);
3917 return true;
3920 void ChatHandler::HandleCharacterLevel(Player* player, uint64 player_guid, uint32 oldlevel, uint32 newlevel)
3922 if(player)
3924 player->GiveLevel(newlevel);
3925 player->InitTalentForLevel();
3926 player->SetUInt32Value(PLAYER_XP,0);
3928 if(needReportToTarget(player))
3930 if(oldlevel == newlevel)
3931 ChatHandler(player).PSendSysMessage(LANG_YOURS_LEVEL_PROGRESS_RESET,GetNameLink().c_str());
3932 else if(oldlevel < newlevel)
3933 ChatHandler(player).PSendSysMessage(LANG_YOURS_LEVEL_UP,GetNameLink().c_str(),newlevel);
3934 else // if(oldlevel > newlevel)
3935 ChatHandler(player).PSendSysMessage(LANG_YOURS_LEVEL_DOWN,GetNameLink().c_str(),newlevel);
3938 else
3940 // update level and XP at level, all other will be updated at loading
3941 CharacterDatabase.PExecute("UPDATE characters SET level = '%u', xp = 0 WHERE guid = '%u'", newlevel, GUID_LOPART(player_guid));
3945 bool ChatHandler::HandleCharacterLevelCommand(const char* args)
3947 char* nameStr;
3948 char* levelStr;
3949 extractOptFirstArg((char*)args,&nameStr,&levelStr);
3950 if(!levelStr)
3951 return false;
3953 // exception opt second arg: .character level $name
3954 if(isalpha(levelStr[0]))
3956 nameStr = levelStr;
3957 levelStr = NULL; // current level will used
3960 Player* target;
3961 uint64 target_guid;
3962 std::string target_name;
3963 if(!extractPlayerTarget(nameStr,&target,&target_guid,&target_name))
3964 return false;
3966 int32 oldlevel = target ? target->getLevel() : Player::GetLevelFromDB(target_guid);
3967 int32 newlevel = levelStr ? atoi(levelStr) : oldlevel;
3969 if(newlevel < 1)
3970 return false; // invalid level
3972 if(newlevel > STRONG_MAX_LEVEL) // hardcoded maximum level
3973 newlevel = STRONG_MAX_LEVEL;
3975 HandleCharacterLevel(target,target_guid,oldlevel,newlevel);
3977 if(!m_session || m_session->GetPlayer() != target) // including player==NULL
3979 std::string nameLink = playerLink(target_name);
3980 PSendSysMessage(LANG_YOU_CHANGE_LVL,nameLink.c_str(),newlevel);
3983 return true;
3986 bool ChatHandler::HandleLevelUpCommand(const char* args)
3988 char* nameStr;
3989 char* levelStr;
3990 extractOptFirstArg((char*)args,&nameStr,&levelStr);
3992 // exception opt second arg: .character level $name
3993 if(levelStr && isalpha(levelStr[0]))
3995 nameStr = levelStr;
3996 levelStr = NULL; // current level will used
3999 Player* target;
4000 uint64 target_guid;
4001 std::string target_name;
4002 if(!extractPlayerTarget(nameStr,&target,&target_guid,&target_name))
4003 return false;
4005 int32 oldlevel = target ? target->getLevel() : Player::GetLevelFromDB(target_guid);
4006 int32 addlevel = levelStr ? atoi(levelStr) : 1;
4007 int32 newlevel = oldlevel + addlevel;
4009 if(newlevel < 1)
4010 newlevel = 1;
4012 if(newlevel > STRONG_MAX_LEVEL) // hardcoded maximum level
4013 newlevel = STRONG_MAX_LEVEL;
4015 HandleCharacterLevel(target,target_guid,oldlevel,newlevel);
4017 if(!m_session || m_session->GetPlayer() != target) // including chr==NULL
4019 std::string nameLink = playerLink(target_name);
4020 PSendSysMessage(LANG_YOU_CHANGE_LVL,nameLink.c_str(),newlevel);
4023 return true;
4026 bool ChatHandler::HandleShowAreaCommand(const char* args)
4028 if (!*args)
4029 return false;
4031 Player *chr = getSelectedPlayer();
4032 if (chr == NULL)
4034 SendSysMessage(LANG_NO_CHAR_SELECTED);
4035 SetSentErrorMessage(true);
4036 return false;
4039 int area = GetAreaFlagByAreaID(atoi((char*)args));
4040 int offset = area / 32;
4041 uint32 val = (uint32)(1 << (area % 32));
4043 if(area<0 || offset >= 128)
4045 SendSysMessage(LANG_BAD_VALUE);
4046 SetSentErrorMessage(true);
4047 return false;
4050 uint32 currFields = chr->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset);
4051 chr->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields | val));
4053 SendSysMessage(LANG_EXPLORE_AREA);
4054 return true;
4057 bool ChatHandler::HandleHideAreaCommand(const char* args)
4059 if (!*args)
4060 return false;
4062 Player *chr = getSelectedPlayer();
4063 if (chr == NULL)
4065 SendSysMessage(LANG_NO_CHAR_SELECTED);
4066 SetSentErrorMessage(true);
4067 return false;
4070 int area = GetAreaFlagByAreaID(atoi((char*)args));
4071 int offset = area / 32;
4072 uint32 val = (uint32)(1 << (area % 32));
4074 if(area<0 || offset >= 128)
4076 SendSysMessage(LANG_BAD_VALUE);
4077 SetSentErrorMessage(true);
4078 return false;
4081 uint32 currFields = chr->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset);
4082 chr->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields ^ val));
4084 SendSysMessage(LANG_UNEXPLORE_AREA);
4085 return true;
4088 bool ChatHandler::HandleBankCommand(const char* /*args*/)
4090 m_session->SendShowBank( m_session->GetPlayer()->GetGUID() );
4092 return true;
4095 bool ChatHandler::HandleChangeWeather(const char* args)
4097 if(!*args)
4098 return false;
4100 //Weather is OFF
4101 if (!sWorld.getConfig(CONFIG_WEATHER))
4103 SendSysMessage(LANG_WEATHER_DISABLED);
4104 SetSentErrorMessage(true);
4105 return false;
4108 //*Change the weather of a cell
4109 char* px = strtok((char*)args, " ");
4110 char* py = strtok(NULL, " ");
4112 if (!px || !py)
4113 return false;
4115 uint32 type = (uint32)atoi(px); //0 to 3, 0: fine, 1: rain, 2: snow, 3: sand
4116 float grade = (float)atof(py); //0 to 1, sending -1 is instand good weather
4118 Player *player = m_session->GetPlayer();
4119 uint32 zoneid = player->GetZoneId();
4121 Weather* wth = sWorld.FindWeather(zoneid);
4123 if(!wth)
4124 wth = sWorld.AddWeather(zoneid);
4125 if(!wth)
4127 SendSysMessage(LANG_NO_WEATHER);
4128 SetSentErrorMessage(true);
4129 return false;
4132 wth->SetWeather(WeatherType(type), grade);
4134 return true;
4137 bool ChatHandler::HandleSet32Bit(const char* args)
4139 if(!*args)
4140 return false;
4142 char* px = strtok((char*)args, " ");
4143 char* py = strtok(NULL, " ");
4145 if (!px || !py)
4146 return false;
4148 uint32 Opcode = (uint32)atoi(px);
4149 uint32 Value = (uint32)atoi(py);
4150 if (Value > 32) //uint32 = 32 bits
4151 return false;
4153 sLog.outDebug(GetMangosString(LANG_SET_32BIT), Opcode, Value);
4155 m_session->GetPlayer( )->SetUInt32Value( Opcode , 2^Value );
4157 PSendSysMessage(LANG_SET_32BIT_FIELD, Opcode,1);
4158 return true;
4161 bool ChatHandler::HandleTeleAddCommand(const char * args)
4163 if(!*args)
4164 return false;
4166 Player *player=m_session->GetPlayer();
4167 if (!player)
4168 return false;
4170 std::string name = args;
4172 if(objmgr.GetGameTele(name))
4174 SendSysMessage(LANG_COMMAND_TP_ALREADYEXIST);
4175 SetSentErrorMessage(true);
4176 return false;
4179 GameTele tele;
4180 tele.position_x = player->GetPositionX();
4181 tele.position_y = player->GetPositionY();
4182 tele.position_z = player->GetPositionZ();
4183 tele.orientation = player->GetOrientation();
4184 tele.mapId = player->GetMapId();
4185 tele.name = name;
4187 if(objmgr.AddGameTele(tele))
4189 SendSysMessage(LANG_COMMAND_TP_ADDED);
4191 else
4193 SendSysMessage(LANG_COMMAND_TP_ADDEDERR);
4194 SetSentErrorMessage(true);
4195 return false;
4198 return true;
4201 bool ChatHandler::HandleTeleDelCommand(const char * args)
4203 if(!*args)
4204 return false;
4206 std::string name = args;
4208 if(!objmgr.DeleteGameTele(name))
4210 SendSysMessage(LANG_COMMAND_TELE_NOTFOUND);
4211 SetSentErrorMessage(true);
4212 return false;
4215 SendSysMessage(LANG_COMMAND_TP_DELETED);
4216 return true;
4219 bool ChatHandler::HandleListAurasCommand (const char * /*args*/)
4221 Unit *unit = getSelectedUnit();
4222 if(!unit)
4224 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
4225 SetSentErrorMessage(true);
4226 return false;
4229 char const* talentStr = GetMangosString(LANG_TALENT);
4230 char const* passiveStr = GetMangosString(LANG_PASSIVE);
4232 Unit::AuraMap const& uAuras = unit->GetAuras();
4233 PSendSysMessage(LANG_COMMAND_TARGET_LISTAURAS, uAuras.size());
4234 for (Unit::AuraMap::const_iterator itr = uAuras.begin(); itr != uAuras.end(); ++itr)
4236 bool talent = GetTalentSpellCost(itr->second->GetId()) > 0;
4238 char const* name = itr->second->GetSpellProto()->SpellName[GetSessionDbcLocale()];
4240 if (m_session)
4242 std::ostringstream ss_name;
4243 ss_name << "|cffffffff|Hspell:" << itr->second->GetId() << "|h[" << name << "]|h|r";
4245 PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffIndex(),
4246 itr->second->GetModifier()->m_auraname, itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(),
4247 ss_name.str().c_str(),
4248 (itr->second->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
4249 IS_PLAYER_GUID(itr->second->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(itr->second->GetCasterGUID()));
4251 else
4253 PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffIndex(),
4254 itr->second->GetModifier()->m_auraname, itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(),
4255 name,
4256 (itr->second->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
4257 IS_PLAYER_GUID(itr->second->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(itr->second->GetCasterGUID()));
4260 for (int i = 0; i < TOTAL_AURAS; ++i)
4262 Unit::AuraList const& uAuraList = unit->GetAurasByType(AuraType(i));
4263 if (uAuraList.empty()) continue;
4264 PSendSysMessage(LANG_COMMAND_TARGET_LISTAURATYPE, uAuraList.size(), i);
4265 for (Unit::AuraList::const_iterator itr = uAuraList.begin(); itr != uAuraList.end(); ++itr)
4267 bool talent = GetTalentSpellCost((*itr)->GetId()) > 0;
4269 char const* name = (*itr)->GetSpellProto()->SpellName[GetSessionDbcLocale()];
4271 if (m_session)
4273 std::ostringstream ss_name;
4274 ss_name << "|cffffffff|Hspell:" << (*itr)->GetId() << "|h[" << name << "]|h|r";
4276 PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(),
4277 ss_name.str().c_str(),((*itr)->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
4278 IS_PLAYER_GUID((*itr)->GetCasterGUID()) ? "player" : "creature",GUID_LOPART((*itr)->GetCasterGUID()));
4280 else
4282 PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(),
4283 name,((*itr)->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
4284 IS_PLAYER_GUID((*itr)->GetCasterGUID()) ? "player" : "creature",GUID_LOPART((*itr)->GetCasterGUID()));
4288 return true;
4291 bool ChatHandler::HandleResetAchievementsCommand (const char * args)
4293 Player* target;
4294 uint64 target_guid;
4295 if (!extractPlayerTarget((char*)args,&target,&target_guid))
4296 return false;
4298 if(target)
4299 target->GetAchievementMgr().Reset();
4300 else
4301 AchievementMgr::DeleteFromDB(GUID_LOPART(target_guid));
4303 return true;
4306 bool ChatHandler::HandleResetHonorCommand (const char * args)
4308 Player* target;
4309 if (!extractPlayerTarget((char*)args,&target))
4310 return false;
4312 target->SetUInt32Value(PLAYER_FIELD_KILLS, 0);
4313 target->SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORBALE_KILLS, 0);
4314 target->SetUInt32Value(PLAYER_FIELD_HONOR_CURRENCY, 0);
4315 target->SetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, 0);
4316 target->SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, 0);
4317 target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL);
4319 return true;
4322 static bool HandleResetStatsOrLevelHelper(Player* player)
4324 ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(player->getClass());
4325 if(!cEntry)
4327 sLog.outError("Class %u not found in DBC (Wrong DBC files?)",player->getClass());
4328 return false;
4331 uint8 powertype = cEntry->powerType;
4333 // reset m_form if no aura
4334 if(!player->HasAuraType(SPELL_AURA_MOD_SHAPESHIFT))
4335 player->m_form = FORM_NONE;
4337 player->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE );
4338 player->SetFloatValue(UNIT_FIELD_COMBATREACH, 1.5f );
4340 player->setFactionForRace(player->getRace());
4342 player->SetUInt32Value(UNIT_FIELD_BYTES_0, ( ( player->getRace() ) | ( player->getClass() << 8 ) | ( player->getGender() << 16 ) | ( powertype << 24 ) ) );
4344 // reset only if player not in some form;
4345 if(player->m_form==FORM_NONE)
4346 player->InitDisplayIds();
4348 player->SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP );
4349 player->SetByteValue(UNIT_FIELD_BYTES_2, 3, player->m_form);
4351 player->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
4353 //-1 is default value
4354 player->SetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, uint32(-1));
4356 //player->SetUInt32Value(PLAYER_FIELD_BYTES, 0xEEE00000 );
4357 return true;
4360 bool ChatHandler::HandleResetLevelCommand(const char * args)
4362 Player* target;
4363 if(!extractPlayerTarget((char*)args,&target))
4364 return false;
4366 if(!HandleResetStatsOrLevelHelper(target))
4367 return false;
4369 // set starting level
4370 uint32 start_level = target->getClass() != CLASS_DEATH_KNIGHT
4371 ? sWorld.getConfig(CONFIG_START_PLAYER_LEVEL)
4372 : sWorld.getConfig(CONFIG_START_HEROIC_PLAYER_LEVEL);
4374 target->_ApplyAllLevelScaleItemMods(false);
4376 target->SetLevel(start_level);
4377 target->InitRunes();
4378 target->InitStatsForLevel(true);
4379 target->InitTaxiNodesForLevel();
4380 target->InitGlyphsForLevel();
4381 target->InitTalentForLevel();
4382 target->SetUInt32Value(PLAYER_XP,0);
4384 target->_ApplyAllLevelScaleItemMods(true);
4386 // reset level for pet
4387 if(Pet* pet = target->GetPet())
4388 pet->SynchronizeLevelWithOwner();
4390 return true;
4393 bool ChatHandler::HandleResetStatsCommand(const char * args)
4395 Player* target;
4396 if (!extractPlayerTarget((char*)args,&target))
4397 return false;
4399 if (!HandleResetStatsOrLevelHelper(target))
4400 return false;
4402 target->InitRunes();
4403 target->InitStatsForLevel(true);
4404 target->InitTaxiNodesForLevel();
4405 target->InitGlyphsForLevel();
4406 target->InitTalentForLevel();
4408 return true;
4411 bool ChatHandler::HandleResetSpellsCommand(const char * args)
4413 Player* target;
4414 uint64 target_guid;
4415 std::string target_name;
4416 if(!extractPlayerTarget((char*)args,&target,&target_guid,&target_name))
4417 return false;
4419 if(target)
4421 target->resetSpells();
4423 ChatHandler(target).SendSysMessage(LANG_RESET_SPELLS);
4424 if(!m_session || m_session->GetPlayer()!=target)
4425 PSendSysMessage(LANG_RESET_SPELLS_ONLINE,GetNameLink(target).c_str());
4427 else
4429 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",uint32(AT_LOGIN_RESET_SPELLS), GUID_LOPART(target_guid));
4430 PSendSysMessage(LANG_RESET_SPELLS_OFFLINE,target_name.c_str());
4433 return true;
4436 bool ChatHandler::HandleResetTalentsCommand(const char * args)
4438 Player* target;
4439 uint64 target_guid;
4440 std::string target_name;
4441 if (!extractPlayerTarget((char*)args,&target,&target_guid,&target_name))
4443 // Try reset talents as Hunter Pet
4444 Creature* creature = getSelectedCreature();
4445 if (!*args && creature && creature->isPet())
4447 Unit *owner = creature->GetOwner();
4448 if(owner && owner->GetTypeId() == TYPEID_PLAYER && ((Pet *)creature)->IsPermanentPetFor((Player*)owner))
4450 ((Pet *)creature)->resetTalents(true);
4451 ((Player*)owner)->SendTalentsInfoData(true);
4453 ChatHandler((Player*)owner).SendSysMessage(LANG_RESET_PET_TALENTS);
4454 if(!m_session || m_session->GetPlayer()!=((Player*)owner))
4455 PSendSysMessage(LANG_RESET_PET_TALENTS_ONLINE,GetNameLink((Player*)owner).c_str());
4457 return true;
4460 SendSysMessage(LANG_NO_CHAR_SELECTED);
4461 SetSentErrorMessage(true);
4462 return false;
4465 if (target)
4467 target->resetTalents(true);
4468 target->SendTalentsInfoData(false);
4469 ChatHandler(target).SendSysMessage(LANG_RESET_TALENTS);
4470 if (!m_session || m_session->GetPlayer()!=target)
4471 PSendSysMessage(LANG_RESET_TALENTS_ONLINE,GetNameLink(target).c_str());
4473 Pet* pet = target->GetPet();
4474 Pet::resetTalentsForAllPetsOf(target,pet);
4475 if(pet)
4476 target->SendTalentsInfoData(true);
4477 return true;
4479 else if (target_guid)
4481 uint32 at_flags = AT_LOGIN_NONE | AT_LOGIN_RESET_PET_TALENTS;
4482 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",at_flags, GUID_LOPART(target_guid) );
4483 std::string nameLink = playerLink(target_name);
4484 PSendSysMessage(LANG_RESET_TALENTS_OFFLINE,nameLink.c_str());
4485 return true;
4488 SendSysMessage(LANG_NO_CHAR_SELECTED);
4489 SetSentErrorMessage(true);
4490 return false;
4493 bool ChatHandler::HandleResetAllCommand(const char * args)
4495 if(!*args)
4496 return false;
4498 std::string casename = args;
4500 AtLoginFlags atLogin;
4502 // Command specially created as single command to prevent using short case names
4503 if(casename=="spells")
4505 atLogin = AT_LOGIN_RESET_SPELLS;
4506 sWorld.SendWorldText(LANG_RESETALL_SPELLS);
4507 if(!m_session)
4508 SendSysMessage(LANG_RESETALL_SPELLS);
4510 else if(casename=="talents")
4512 atLogin = AtLoginFlags(AT_LOGIN_RESET_TALENTS | AT_LOGIN_RESET_PET_TALENTS);
4513 sWorld.SendWorldText(LANG_RESETALL_TALENTS);
4514 if(!m_session)
4515 SendSysMessage(LANG_RESETALL_TALENTS);
4517 else
4519 PSendSysMessage(LANG_RESETALL_UNKNOWN_CASE,args);
4520 SetSentErrorMessage(true);
4521 return false;
4524 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE (at_login & '%u') = '0'",atLogin,atLogin);
4525 HashMapHolder<Player>::MapType const& plist = ObjectAccessor::Instance().GetPlayers();
4526 for(HashMapHolder<Player>::MapType::const_iterator itr = plist.begin(); itr != plist.end(); ++itr)
4527 itr->second->SetAtLoginFlag(atLogin);
4529 return true;
4532 bool ChatHandler::HandleServerShutDownCancelCommand(const char* /*args*/)
4534 sWorld.ShutdownCancel();
4535 return true;
4538 bool ChatHandler::HandleServerShutDownCommand(const char* args)
4540 if(!*args)
4541 return false;
4543 char* time_str = strtok ((char*) args, " ");
4544 char* exitcode_str = strtok (NULL, "");
4546 int32 time = atoi (time_str);
4548 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4549 if ((time == 0 && (time_str[0]!='0' || time_str[1]!='\0')) || time < 0)
4550 return false;
4552 if (exitcode_str)
4554 int32 exitcode = atoi (exitcode_str);
4556 // Handle atoi() errors
4557 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4558 return false;
4560 // Exit code should be in range of 0-125, 126-255 is used
4561 // in many shells for their own return codes and code > 255
4562 // is not supported in many others
4563 if (exitcode < 0 || exitcode > 125)
4564 return false;
4566 sWorld.ShutdownServ (time, 0, exitcode);
4568 else
4569 sWorld.ShutdownServ(time,0,SHUTDOWN_EXIT_CODE);
4570 return true;
4573 bool ChatHandler::HandleServerRestartCommand(const char* args)
4575 if(!*args)
4576 return false;
4578 char* time_str = strtok ((char*) args, " ");
4579 char* exitcode_str = strtok (NULL, "");
4581 int32 time = atoi (time_str);
4583 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4584 if ((time == 0 && (time_str[0]!='0' || time_str[1]!='\0')) || time < 0)
4585 return false;
4587 if (exitcode_str)
4589 int32 exitcode = atoi (exitcode_str);
4591 // Handle atoi() errors
4592 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4593 return false;
4595 // Exit code should be in range of 0-125, 126-255 is used
4596 // in many shells for their own return codes and code > 255
4597 // is not supported in many others
4598 if (exitcode < 0 || exitcode > 125)
4599 return false;
4601 sWorld.ShutdownServ (time, SHUTDOWN_MASK_RESTART, exitcode);
4603 else
4604 sWorld.ShutdownServ(time, SHUTDOWN_MASK_RESTART, RESTART_EXIT_CODE);
4605 return true;
4608 bool ChatHandler::HandleServerIdleRestartCommand(const char* args)
4610 if(!*args)
4611 return false;
4613 char* time_str = strtok ((char*) args, " ");
4614 char* exitcode_str = strtok (NULL, "");
4616 int32 time = atoi (time_str);
4618 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4619 if ((time == 0 && (time_str[0]!='0' || time_str[1]!='\0')) || time < 0)
4620 return false;
4622 if (exitcode_str)
4624 int32 exitcode = atoi (exitcode_str);
4626 // Handle atoi() errors
4627 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4628 return false;
4630 // Exit code should be in range of 0-125, 126-255 is used
4631 // in many shells for their own return codes and code > 255
4632 // is not supported in many others
4633 if (exitcode < 0 || exitcode > 125)
4634 return false;
4636 sWorld.ShutdownServ (time, SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE, exitcode);
4638 else
4639 sWorld.ShutdownServ(time,SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE,RESTART_EXIT_CODE);
4640 return true;
4643 bool ChatHandler::HandleServerIdleShutDownCommand(const char* args)
4645 if(!*args)
4646 return false;
4648 char* time_str = strtok ((char*) args, " ");
4649 char* exitcode_str = strtok (NULL, "");
4651 int32 time = atoi (time_str);
4653 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4654 if ((time == 0 && (time_str[0]!='0' || time_str[1]!='\0')) || time < 0)
4655 return false;
4657 if (exitcode_str)
4659 int32 exitcode = atoi (exitcode_str);
4661 // Handle atoi() errors
4662 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4663 return false;
4665 // Exit code should be in range of 0-125, 126-255 is used
4666 // in many shells for their own return codes and code > 255
4667 // is not supported in many others
4668 if (exitcode < 0 || exitcode > 125)
4669 return false;
4671 sWorld.ShutdownServ (time, SHUTDOWN_MASK_IDLE, exitcode);
4673 else
4674 sWorld.ShutdownServ(time,SHUTDOWN_MASK_IDLE,SHUTDOWN_EXIT_CODE);
4675 return true;
4678 bool ChatHandler::HandleQuestAdd(const char* args)
4680 Player* player = getSelectedPlayer();
4681 if(!player)
4683 SendSysMessage(LANG_NO_CHAR_SELECTED);
4684 SetSentErrorMessage(true);
4685 return false;
4688 // .addquest #entry'
4689 // number or [name] Shift-click form |color|Hquest:quest_id:quest_level|h[name]|h|r
4690 char* cId = extractKeyFromLink((char*)args,"Hquest");
4691 if(!cId)
4692 return false;
4694 uint32 entry = atol(cId);
4696 Quest const* pQuest = objmgr.GetQuestTemplate(entry);
4698 if(!pQuest)
4700 PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND,entry);
4701 SetSentErrorMessage(true);
4702 return false;
4705 // check item starting quest (it can work incorrectly if added without item in inventory)
4706 for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
4708 ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype>(id);
4709 if (!pProto)
4710 continue;
4712 if (pProto->StartQuest == entry)
4714 PSendSysMessage(LANG_COMMAND_QUEST_STARTFROMITEM, entry, pProto->ItemId);
4715 SetSentErrorMessage(true);
4716 return false;
4720 // ok, normal (creature/GO starting) quest
4721 if( player->CanAddQuest( pQuest, true ) )
4723 player->AddQuest( pQuest, NULL );
4725 if ( player->CanCompleteQuest( entry ) )
4726 player->CompleteQuest( entry );
4729 return true;
4732 bool ChatHandler::HandleQuestRemove(const char* args)
4734 Player* player = getSelectedPlayer();
4735 if(!player)
4737 SendSysMessage(LANG_NO_CHAR_SELECTED);
4738 SetSentErrorMessage(true);
4739 return false;
4742 // .removequest #entry'
4743 // number or [name] Shift-click form |color|Hquest:quest_id:quest_level|h[name]|h|r
4744 char* cId = extractKeyFromLink((char*)args,"Hquest");
4745 if(!cId)
4746 return false;
4748 uint32 entry = atol(cId);
4750 Quest const* pQuest = objmgr.GetQuestTemplate(entry);
4752 if(!pQuest)
4754 PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry);
4755 SetSentErrorMessage(true);
4756 return false;
4759 // remove all quest entries for 'entry' from quest log
4760 for(uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot )
4762 uint32 quest = player->GetQuestSlotQuestId(slot);
4763 if(quest==entry)
4765 player->SetQuestSlot(slot,0);
4767 // we ignore unequippable quest items in this case, its' still be equipped
4768 player->TakeQuestSourceItem( quest, false );
4772 // set quest status to not started (will updated in DB at next save)
4773 player->SetQuestStatus( entry, QUEST_STATUS_NONE);
4775 // reset rewarded for restart repeatable quest
4776 player->getQuestStatusMap()[entry].m_rewarded = false;
4778 SendSysMessage(LANG_COMMAND_QUEST_REMOVED);
4779 return true;
4782 bool ChatHandler::HandleQuestComplete(const char* args)
4784 Player* player = getSelectedPlayer();
4785 if(!player)
4787 SendSysMessage(LANG_NO_CHAR_SELECTED);
4788 SetSentErrorMessage(true);
4789 return false;
4792 // .quest complete #entry
4793 // number or [name] Shift-click form |color|Hquest:quest_id:quest_level|h[name]|h|r
4794 char* cId = extractKeyFromLink((char*)args,"Hquest");
4795 if(!cId)
4796 return false;
4798 uint32 entry = atol(cId);
4800 Quest const* pQuest = objmgr.GetQuestTemplate(entry);
4802 // If player doesn't have the quest
4803 if(!pQuest || player->GetQuestStatus(entry) == QUEST_STATUS_NONE)
4805 PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry);
4806 SetSentErrorMessage(true);
4807 return false;
4810 // Add quest items for quests that require items
4811 for(uint8 x = 0; x < QUEST_OBJECTIVES_COUNT; ++x)
4813 uint32 id = pQuest->ReqItemId[x];
4814 uint32 count = pQuest->ReqItemCount[x];
4815 if(!id || !count)
4816 continue;
4818 uint32 curItemCount = player->GetItemCount(id,true);
4820 ItemPosCountVec dest;
4821 uint8 msg = player->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, id, count-curItemCount );
4822 if( msg == EQUIP_ERR_OK )
4824 Item* item = player->StoreNewItem( dest, id, true);
4825 player->SendNewItem(item,count-curItemCount,true,false);
4829 // All creature/GO slain/casted (not required, but otherwise it will display "Creature slain 0/10")
4830 for(uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
4832 uint32 creature = pQuest->ReqCreatureOrGOId[i];
4833 uint32 creaturecount = pQuest->ReqCreatureOrGOCount[i];
4835 if(uint32 spell_id = pQuest->ReqSpell[i])
4837 for(uint16 z = 0; z < creaturecount; ++z)
4838 player->CastedCreatureOrGO(creature,0,spell_id);
4840 else if(creature > 0)
4842 if(CreatureInfo const* cInfo = objmgr.GetCreatureTemplate(creature))
4843 for(uint16 z = 0; z < creaturecount; ++z)
4844 player->KilledMonster(cInfo,0);
4846 else if(creature < 0)
4848 for(uint16 z = 0; z < creaturecount; ++z)
4849 player->CastedCreatureOrGO(creature,0,0);
4853 // If the quest requires reputation to complete
4854 if(uint32 repFaction = pQuest->GetRepObjectiveFaction())
4856 uint32 repValue = pQuest->GetRepObjectiveValue();
4857 uint32 curRep = player->GetReputationMgr().GetReputation(repFaction);
4858 if(curRep < repValue)
4859 if(FactionEntry const *factionEntry = sFactionStore.LookupEntry(repFaction))
4860 player->GetReputationMgr().SetReputation(factionEntry,repValue);
4863 // If the quest requires money
4864 int32 ReqOrRewMoney = pQuest->GetRewOrReqMoney();
4865 if(ReqOrRewMoney < 0)
4866 player->ModifyMoney(-ReqOrRewMoney);
4868 player->CompleteQuest(entry);
4869 return true;
4872 bool ChatHandler::HandleBanAccountCommand(const char* args)
4874 return HandleBanHelper(BAN_ACCOUNT,args);
4877 bool ChatHandler::HandleBanCharacterCommand(const char* args)
4879 return HandleBanHelper(BAN_CHARACTER,args);
4882 bool ChatHandler::HandleBanIPCommand(const char* args)
4884 return HandleBanHelper(BAN_IP,args);
4887 bool ChatHandler::HandleBanHelper(BanMode mode, const char* args)
4889 if (!*args)
4890 return false;
4892 char* cnameOrIP = strtok ((char*)args, " ");
4893 if (!cnameOrIP)
4894 return false;
4896 std::string nameOrIP = cnameOrIP;
4898 char* duration = strtok (NULL," ");
4899 if(!duration || !atoi(duration))
4900 return false;
4902 char* reason = strtok (NULL,"");
4903 if(!reason)
4904 return false;
4906 switch(mode)
4908 case BAN_ACCOUNT:
4909 if (!AccountMgr::normalizeString(nameOrIP))
4911 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,nameOrIP.c_str());
4912 SetSentErrorMessage(true);
4913 return false;
4915 break;
4916 case BAN_CHARACTER:
4917 if(!normalizePlayerName(nameOrIP))
4919 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4920 SetSentErrorMessage(true);
4921 return false;
4923 break;
4924 case BAN_IP:
4925 if(!IsIPAddress(nameOrIP.c_str()))
4926 return false;
4927 break;
4930 switch(sWorld.BanAccount(mode, nameOrIP, duration, reason,m_session ? m_session->GetPlayerName() : ""))
4932 case BAN_SUCCESS:
4933 if(atoi(duration)>0)
4934 PSendSysMessage(LANG_BAN_YOUBANNED,nameOrIP.c_str(),secsToTimeString(TimeStringToSecs(duration),true).c_str(),reason);
4935 else
4936 PSendSysMessage(LANG_BAN_YOUPERMBANNED,nameOrIP.c_str(),reason);
4937 break;
4938 case BAN_SYNTAX_ERROR:
4939 return false;
4940 case BAN_NOTFOUND:
4941 switch(mode)
4943 default:
4944 PSendSysMessage(LANG_BAN_NOTFOUND,"account",nameOrIP.c_str());
4945 break;
4946 case BAN_CHARACTER:
4947 PSendSysMessage(LANG_BAN_NOTFOUND,"character",nameOrIP.c_str());
4948 break;
4949 case BAN_IP:
4950 PSendSysMessage(LANG_BAN_NOTFOUND,"ip",nameOrIP.c_str());
4951 break;
4953 SetSentErrorMessage(true);
4954 return false;
4957 return true;
4960 bool ChatHandler::HandleUnBanAccountCommand(const char* args)
4962 return HandleUnBanHelper(BAN_ACCOUNT,args);
4965 bool ChatHandler::HandleUnBanCharacterCommand(const char* args)
4967 return HandleUnBanHelper(BAN_CHARACTER,args);
4970 bool ChatHandler::HandleUnBanIPCommand(const char* args)
4972 return HandleUnBanHelper(BAN_IP,args);
4975 bool ChatHandler::HandleUnBanHelper(BanMode mode, const char* args)
4977 if (!*args)
4978 return false;
4980 char* cnameOrIP = strtok ((char*)args, " ");
4981 if(!cnameOrIP)
4982 return false;
4984 std::string nameOrIP = cnameOrIP;
4986 switch(mode)
4988 case BAN_ACCOUNT:
4989 if (!AccountMgr::normalizeString(nameOrIP))
4991 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,nameOrIP.c_str());
4992 SetSentErrorMessage(true);
4993 return false;
4995 break;
4996 case BAN_CHARACTER:
4997 if(!normalizePlayerName(nameOrIP))
4999 SendSysMessage(LANG_PLAYER_NOT_FOUND);
5000 SetSentErrorMessage(true);
5001 return false;
5003 break;
5004 case BAN_IP:
5005 if(!IsIPAddress(nameOrIP.c_str()))
5006 return false;
5007 break;
5010 if(sWorld.RemoveBanAccount(mode,nameOrIP))
5011 PSendSysMessage(LANG_UNBAN_UNBANNED,nameOrIP.c_str());
5012 else
5013 PSendSysMessage(LANG_UNBAN_ERROR,nameOrIP.c_str());
5015 return true;
5018 bool ChatHandler::HandleBanInfoAccountCommand(const char* args)
5020 if (!*args)
5021 return false;
5023 char* cname = strtok((char*)args, "");
5024 if (!cname)
5025 return false;
5027 std::string account_name = cname;
5028 if (!AccountMgr::normalizeString(account_name))
5030 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5031 SetSentErrorMessage(true);
5032 return false;
5035 uint32 accountid = accmgr.GetId(account_name);
5036 if (!accountid)
5038 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5039 return true;
5042 return HandleBanInfoHelper(accountid,account_name.c_str());
5045 bool ChatHandler::HandleBanInfoCharacterCommand(const char* args)
5047 Player* target;
5048 uint64 target_guid;
5049 if (!extractPlayerTarget((char*)args,&target,&target_guid))
5050 return false;
5052 uint32 accountid = target ? target->GetSession()->GetAccountId() : objmgr.GetPlayerAccountIdByGUID(target_guid);
5054 std::string accountname;
5055 if (!accmgr.GetName(accountid,accountname))
5057 PSendSysMessage(LANG_BANINFO_NOCHARACTER);
5058 return true;
5061 return HandleBanInfoHelper(accountid,accountname.c_str());
5064 bool ChatHandler::HandleBanInfoHelper(uint32 accountid, char const* accountname)
5066 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);
5067 if(!result)
5069 PSendSysMessage(LANG_BANINFO_NOACCOUNTBAN, accountname);
5070 return true;
5073 PSendSysMessage(LANG_BANINFO_BANHISTORY,accountname);
5076 Field* fields = result->Fetch();
5078 time_t unbandate = time_t(fields[3].GetUInt64());
5079 bool active = false;
5080 if(fields[2].GetBool() && (fields[1].GetUInt64() == (uint64)0 ||unbandate >= time(NULL)) )
5081 active = true;
5082 bool permanent = (fields[1].GetUInt64() == (uint64)0);
5083 std::string bantime = permanent?GetMangosString(LANG_BANINFO_INFINITE):secsToTimeString(fields[1].GetUInt64(), true);
5084 PSendSysMessage(LANG_BANINFO_HISTORYENTRY,
5085 fields[0].GetString(), bantime.c_str(), active ? GetMangosString(LANG_BANINFO_YES):GetMangosString(LANG_BANINFO_NO), fields[4].GetString(), fields[5].GetString());
5086 }while (result->NextRow());
5088 delete result;
5089 return true;
5092 bool ChatHandler::HandleBanInfoIPCommand(const char* args)
5094 if (!*args)
5095 return false;
5097 char* cIP = strtok ((char*)args, "");
5098 if(!cIP)
5099 return false;
5101 if (!IsIPAddress(cIP))
5102 return false;
5104 std::string IP = cIP;
5106 loginDatabase.escape_string(IP);
5107 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());
5108 if(!result)
5110 PSendSysMessage(LANG_BANINFO_NOIP);
5111 return true;
5114 Field *fields = result->Fetch();
5115 bool permanent = !fields[6].GetUInt64();
5116 PSendSysMessage(LANG_BANINFO_IPENTRY,
5117 fields[0].GetString(), fields[1].GetString(), permanent ? GetMangosString(LANG_BANINFO_NEVER):fields[2].GetString(),
5118 permanent ? GetMangosString(LANG_BANINFO_INFINITE):secsToTimeString(fields[3].GetUInt64(), true).c_str(), fields[4].GetString(), fields[5].GetString());
5119 delete result;
5120 return true;
5123 bool ChatHandler::HandleBanListCharacterCommand(const char* args)
5125 loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
5127 char* cFilter = strtok ((char*)args, " ");
5128 if(!cFilter)
5129 return false;
5131 std::string filter = cFilter;
5132 loginDatabase.escape_string(filter);
5133 QueryResult* result = CharacterDatabase.PQuery("SELECT account FROM characters WHERE name "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'"),filter.c_str());
5134 if (!result)
5136 PSendSysMessage(LANG_BANLIST_NOCHARACTER);
5137 return true;
5140 return HandleBanListHelper(result);
5143 bool ChatHandler::HandleBanListAccountCommand(const char* args)
5145 loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
5147 char* cFilter = strtok((char*)args, " ");
5148 std::string filter = cFilter ? cFilter : "";
5149 loginDatabase.escape_string(filter);
5151 QueryResult* result;
5153 if(filter.empty())
5155 result = loginDatabase.Query("SELECT account.id, username FROM account, account_banned"
5156 " WHERE account.id = account_banned.id AND active = 1 GROUP BY account.id");
5158 else
5160 result = loginDatabase.PQuery("SELECT account.id, username FROM account, account_banned"
5161 " WHERE account.id = account_banned.id AND active = 1 AND username "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")" GROUP BY account.id",
5162 filter.c_str());
5165 if (!result)
5167 PSendSysMessage(LANG_BANLIST_NOACCOUNT);
5168 return true;
5171 return HandleBanListHelper(result);
5174 bool ChatHandler::HandleBanListHelper(QueryResult* result)
5176 PSendSysMessage(LANG_BANLIST_MATCHINGACCOUNT);
5178 // Chat short output
5179 if(m_session)
5183 Field* fields = result->Fetch();
5184 uint32 accountid = fields[0].GetUInt32();
5186 QueryResult* banresult = loginDatabase.PQuery("SELECT account.username FROM account,account_banned WHERE account_banned.id='%u' AND account_banned.id=account.id",accountid);
5187 if(banresult)
5189 Field* fields2 = banresult->Fetch();
5190 PSendSysMessage("%s",fields2[0].GetString());
5191 delete banresult;
5193 } while (result->NextRow());
5195 // Console wide output
5196 else
5198 SendSysMessage(LANG_BANLIST_ACCOUNTS);
5199 SendSysMessage("===============================================================================");
5200 SendSysMessage(LANG_BANLIST_ACCOUNTS_HEADER);
5203 SendSysMessage("-------------------------------------------------------------------------------");
5204 Field *fields = result->Fetch();
5205 uint32 account_id = fields[0].GetUInt32 ();
5207 std::string account_name;
5209 // "account" case, name can be get in same query
5210 if(result->GetFieldCount() > 1)
5211 account_name = fields[1].GetCppString();
5212 // "character" case, name need extract from another DB
5213 else
5214 accmgr.GetName (account_id,account_name);
5216 // No SQL injection. id is uint32.
5217 QueryResult *banInfo = loginDatabase.PQuery("SELECT bandate,unbandate,bannedby,banreason FROM account_banned WHERE id = %u ORDER BY unbandate", account_id);
5218 if (banInfo)
5220 Field *fields2 = banInfo->Fetch();
5223 time_t t_ban = fields2[0].GetUInt64();
5224 tm* aTm_ban = localtime(&t_ban);
5226 if (fields2[0].GetUInt64() == fields2[1].GetUInt64())
5228 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|",
5229 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,
5230 fields2[2].GetString(),fields2[3].GetString());
5232 else
5234 time_t t_unban = fields2[1].GetUInt64();
5235 tm* aTm_unban = localtime(&t_unban);
5236 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|",
5237 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,
5238 aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min,
5239 fields2[2].GetString(),fields2[3].GetString());
5241 }while ( banInfo->NextRow() );
5242 delete banInfo;
5244 }while( result->NextRow() );
5245 SendSysMessage("===============================================================================");
5248 delete result;
5249 return true;
5252 bool ChatHandler::HandleBanListIPCommand(const char* args)
5254 loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
5256 char* cFilter = strtok((char*)args, " ");
5257 std::string filter = cFilter ? cFilter : "";
5258 loginDatabase.escape_string(filter);
5260 QueryResult* result;
5262 if(filter.empty())
5264 result = loginDatabase.Query ("SELECT ip,bandate,unbandate,bannedby,banreason FROM ip_banned"
5265 " WHERE (bandate=unbandate OR unbandate>UNIX_TIMESTAMP())"
5266 " ORDER BY unbandate" );
5268 else
5270 result = loginDatabase.PQuery( "SELECT ip,bandate,unbandate,bannedby,banreason FROM ip_banned"
5271 " WHERE (bandate=unbandate OR unbandate>UNIX_TIMESTAMP()) AND ip "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")
5272 " ORDER BY unbandate",filter.c_str() );
5275 if(!result)
5277 PSendSysMessage(LANG_BANLIST_NOIP);
5278 return true;
5281 PSendSysMessage(LANG_BANLIST_MATCHINGIP);
5282 // Chat short output
5283 if(m_session)
5287 Field* fields = result->Fetch();
5288 PSendSysMessage("%s",fields[0].GetString());
5289 } while (result->NextRow());
5291 // Console wide output
5292 else
5294 SendSysMessage(LANG_BANLIST_IPS);
5295 SendSysMessage("===============================================================================");
5296 SendSysMessage(LANG_BANLIST_IPS_HEADER);
5299 SendSysMessage("-------------------------------------------------------------------------------");
5300 Field *fields = result->Fetch();
5301 time_t t_ban = fields[1].GetUInt64();
5302 tm* aTm_ban = localtime(&t_ban);
5303 if ( fields[1].GetUInt64() == fields[2].GetUInt64() )
5305 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|",
5306 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,
5307 fields[3].GetString(), fields[4].GetString());
5309 else
5311 time_t t_unban = fields[2].GetUInt64();
5312 tm* aTm_unban = localtime(&t_unban);
5313 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|",
5314 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,
5315 aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min,
5316 fields[3].GetString(), fields[4].GetString());
5318 }while( result->NextRow() );
5319 SendSysMessage("===============================================================================");
5322 delete result;
5323 return true;
5326 bool ChatHandler::HandleRespawnCommand(const char* /*args*/)
5328 Player* pl = m_session->GetPlayer();
5330 // accept only explicitly selected target (not implicitly self targeting case)
5331 Unit* target = getSelectedUnit();
5332 if(pl->GetSelection() && target)
5334 if(target->GetTypeId()!=TYPEID_UNIT)
5336 SendSysMessage(LANG_SELECT_CREATURE);
5337 SetSentErrorMessage(true);
5338 return false;
5341 if(target->isDead())
5342 ((Creature*)target)->Respawn();
5343 return true;
5346 CellPair p(MaNGOS::ComputeCellPair(pl->GetPositionX(), pl->GetPositionY()));
5347 Cell cell(p);
5348 cell.data.Part.reserved = ALL_DISTRICT;
5349 cell.SetNoCreate();
5351 MaNGOS::RespawnDo u_do;
5352 MaNGOS::WorldObjectWorker<MaNGOS::RespawnDo> worker(pl,u_do);
5354 TypeContainerVisitor<MaNGOS::WorldObjectWorker<MaNGOS::RespawnDo>, GridTypeMapContainer > obj_worker(worker);
5355 CellLock<GridReadGuard> cell_lock(cell, p);
5356 cell_lock->Visit(cell_lock, obj_worker, *pl->GetMap());
5358 return true;
5361 bool ChatHandler::HandleGMFlyCommand(const char* args)
5363 if (!*args)
5364 return false;
5366 Player *target = getSelectedPlayer();
5367 if (!target)
5368 target = m_session->GetPlayer();
5370 WorldPacket data(12);
5371 if (strncmp(args, "on", 3) == 0)
5372 data.SetOpcode(SMSG_MOVE_SET_CAN_FLY);
5373 else if (strncmp(args, "off", 4) == 0)
5374 data.SetOpcode(SMSG_MOVE_UNSET_CAN_FLY);
5375 else
5377 SendSysMessage(LANG_USE_BOL);
5378 return false;
5380 data.append(target->GetPackGUID());
5381 data << uint32(0); // unknown
5382 target->SendMessageToSet(&data, true);
5383 PSendSysMessage(LANG_COMMAND_FLYMODE_STATUS, GetNameLink(target).c_str(), args);
5384 return true;
5387 bool ChatHandler::HandlePDumpLoadCommand(const char *args)
5389 if (!*args)
5390 return false;
5392 char * file = strtok((char*)args, " ");
5393 if (!file)
5394 return false;
5396 char * account = strtok(NULL, " ");
5397 if (!account)
5398 return false;
5400 std::string account_name = account;
5401 if (!AccountMgr::normalizeString(account_name))
5403 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5404 SetSentErrorMessage(true);
5405 return false;
5408 uint32 account_id = accmgr.GetId(account_name);
5409 if (!account_id)
5411 account_id = atoi(account); // use original string
5412 if (!account_id)
5414 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5415 SetSentErrorMessage(true);
5416 return false;
5420 if (!accmgr.GetName(account_id,account_name))
5422 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5423 SetSentErrorMessage(true);
5424 return false;
5427 char* guid_str = NULL;
5428 char* name_str = strtok(NULL, " ");
5430 std::string name;
5431 if (name_str)
5433 name = name_str;
5434 // normalize the name if specified and check if it exists
5435 if (!normalizePlayerName(name))
5437 PSendSysMessage(LANG_INVALID_CHARACTER_NAME);
5438 SetSentErrorMessage(true);
5439 return false;
5442 if (ObjectMgr::CheckPlayerName(name,true) != CHAR_NAME_SUCCESS)
5444 PSendSysMessage(LANG_INVALID_CHARACTER_NAME);
5445 SetSentErrorMessage(true);
5446 return false;
5449 guid_str = strtok(NULL, " ");
5452 uint32 guid = 0;
5454 if (guid_str)
5456 guid = atoi(guid_str);
5457 if (!guid)
5459 PSendSysMessage(LANG_INVALID_CHARACTER_GUID);
5460 SetSentErrorMessage(true);
5461 return false;
5464 if (objmgr.GetPlayerAccountIdByGUID(guid))
5466 PSendSysMessage(LANG_CHARACTER_GUID_IN_USE,guid);
5467 SetSentErrorMessage(true);
5468 return false;
5472 switch(PlayerDumpReader().LoadDump(file, account_id, name, guid))
5474 case DUMP_SUCCESS:
5475 PSendSysMessage(LANG_COMMAND_IMPORT_SUCCESS);
5476 break;
5477 case DUMP_FILE_OPEN_ERROR:
5478 PSendSysMessage(LANG_FILE_OPEN_FAIL,file);
5479 SetSentErrorMessage(true);
5480 return false;
5481 case DUMP_FILE_BROKEN:
5482 PSendSysMessage(LANG_DUMP_BROKEN,file);
5483 SetSentErrorMessage(true);
5484 return false;
5485 case DUMP_TOO_MANY_CHARS:
5486 PSendSysMessage(LANG_ACCOUNT_CHARACTER_LIST_FULL,account_name.c_str(),account_id);
5487 SetSentErrorMessage(true);
5488 return false;
5489 default:
5490 PSendSysMessage(LANG_COMMAND_IMPORT_FAILED);
5491 SetSentErrorMessage(true);
5492 return false;
5495 return true;
5498 bool ChatHandler::HandlePDumpWriteCommand(const char *args)
5500 if (!*args)
5501 return false;
5503 char* file = strtok((char*)args, " ");
5504 char* p2 = strtok(NULL, " ");
5506 if(!file || !p2)
5507 return false;
5509 uint32 guid;
5510 // character name can't start from number
5511 if (isNumeric(p2[0]))
5512 guid = atoi(p2);
5513 else
5515 std::string name = extractPlayerNameFromLink(p2);
5516 if(name.empty())
5518 SendSysMessage(LANG_PLAYER_NOT_FOUND);
5519 SetSentErrorMessage(true);
5520 return false;
5523 guid = objmgr.GetPlayerGUIDByName(name);
5526 if(!objmgr.GetPlayerAccountIdByGUID(guid))
5528 PSendSysMessage(LANG_PLAYER_NOT_FOUND);
5529 SetSentErrorMessage(true);
5530 return false;
5533 switch(PlayerDumpWriter().WriteDump(file, guid))
5535 case DUMP_SUCCESS:
5536 PSendSysMessage(LANG_COMMAND_EXPORT_SUCCESS);
5537 break;
5538 case DUMP_FILE_OPEN_ERROR:
5539 PSendSysMessage(LANG_FILE_OPEN_FAIL,file);
5540 SetSentErrorMessage(true);
5541 return false;
5542 default:
5543 PSendSysMessage(LANG_COMMAND_EXPORT_FAILED);
5544 SetSentErrorMessage(true);
5545 return false;
5548 return true;
5551 bool ChatHandler::HandleMovegensCommand(const char* /*args*/)
5553 Unit* unit = getSelectedUnit();
5554 if(!unit)
5556 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5557 SetSentErrorMessage(true);
5558 return false;
5561 PSendSysMessage(LANG_MOVEGENS_LIST,(unit->GetTypeId()==TYPEID_PLAYER ? "Player" : "Creature" ),unit->GetGUIDLow());
5563 MotionMaster* mm = unit->GetMotionMaster();
5564 for(MotionMaster::const_iterator itr = mm->begin(); itr != mm->end(); ++itr)
5566 switch((*itr)->GetMovementGeneratorType())
5568 case IDLE_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_IDLE); break;
5569 case RANDOM_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_RANDOM); break;
5570 case WAYPOINT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_WAYPOINT); break;
5571 case ANIMAL_RANDOM_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_ANIMAL_RANDOM); break;
5572 case CONFUSED_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_CONFUSED); break;
5573 case TARGETED_MOTION_TYPE:
5575 if(unit->GetTypeId()==TYPEID_PLAYER)
5577 TargetedMovementGenerator<Player> const* mgen = static_cast<TargetedMovementGenerator<Player> const*>(*itr);
5578 Unit* target = mgen->GetTarget();
5579 if(target)
5580 PSendSysMessage(LANG_MOVEGENS_TARGETED_PLAYER,target->GetName(),target->GetGUIDLow());
5581 else
5582 SendSysMessage(LANG_MOVEGENS_TARGETED_NULL);
5584 else
5586 TargetedMovementGenerator<Creature> const* mgen = static_cast<TargetedMovementGenerator<Creature> const*>(*itr);
5587 Unit* target = mgen->GetTarget();
5588 if(target)
5589 PSendSysMessage(LANG_MOVEGENS_TARGETED_CREATURE,target->GetName(),target->GetGUIDLow());
5590 else
5591 SendSysMessage(LANG_MOVEGENS_TARGETED_NULL);
5593 break;
5595 case HOME_MOTION_TYPE:
5596 if(unit->GetTypeId()==TYPEID_UNIT)
5598 float x,y,z;
5599 (*itr)->GetDestination(x,y,z);
5600 PSendSysMessage(LANG_MOVEGENS_HOME_CREATURE,x,y,z);
5602 else
5603 SendSysMessage(LANG_MOVEGENS_HOME_PLAYER);
5604 break;
5605 case FLIGHT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_FLIGHT); break;
5606 case POINT_MOTION_TYPE:
5608 float x,y,z;
5609 (*itr)->GetDestination(x,y,z);
5610 PSendSysMessage(LANG_MOVEGENS_POINT,x,y,z);
5611 break;
5613 case FLEEING_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_FEAR); break;
5614 case DISTRACT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_DISTRACT); break;
5615 default:
5616 PSendSysMessage(LANG_MOVEGENS_UNKNOWN,(*itr)->GetMovementGeneratorType());
5617 break;
5620 return true;
5623 bool ChatHandler::HandleServerPLimitCommand(const char *args)
5625 if(*args)
5627 char* param = strtok((char*)args, " ");
5628 if(!param)
5629 return false;
5631 int l = strlen(param);
5633 if( strncmp(param,"player",l) == 0 )
5634 sWorld.SetPlayerLimit(-SEC_PLAYER);
5635 else if(strncmp(param,"moderator",l) == 0 )
5636 sWorld.SetPlayerLimit(-SEC_MODERATOR);
5637 else if(strncmp(param,"gamemaster",l) == 0 )
5638 sWorld.SetPlayerLimit(-SEC_GAMEMASTER);
5639 else if(strncmp(param,"administrator",l) == 0 )
5640 sWorld.SetPlayerLimit(-SEC_ADMINISTRATOR);
5641 else if(strncmp(param,"reset",l) == 0 )
5642 sWorld.SetPlayerLimit( sConfig.GetIntDefault("PlayerLimit", DEFAULT_PLAYER_LIMIT) );
5643 else
5645 int val = atoi(param);
5646 if(val < -SEC_ADMINISTRATOR) val = -SEC_ADMINISTRATOR;
5648 sWorld.SetPlayerLimit(val);
5651 // kick all low security level players
5652 if(sWorld.GetPlayerAmountLimit() > SEC_PLAYER)
5653 sWorld.KickAllLess(sWorld.GetPlayerSecurityLimit());
5656 uint32 pLimit = sWorld.GetPlayerAmountLimit();
5657 AccountTypes allowedAccountType = sWorld.GetPlayerSecurityLimit();
5658 char const* secName = "";
5659 switch(allowedAccountType)
5661 case SEC_PLAYER: secName = "Player"; break;
5662 case SEC_MODERATOR: secName = "Moderator"; break;
5663 case SEC_GAMEMASTER: secName = "Gamemaster"; break;
5664 case SEC_ADMINISTRATOR: secName = "Administrator"; break;
5665 default: secName = "<unknown>"; break;
5668 PSendSysMessage("Player limits: amount %u, min. security level %s.",pLimit,secName);
5670 return true;
5673 bool ChatHandler::HandleCastCommand(const char* args)
5675 if(!*args)
5676 return false;
5678 Unit* target = getSelectedUnit();
5680 if(!target)
5682 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5683 SetSentErrorMessage(true);
5684 return false;
5687 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5688 uint32 spell = extractSpellIdFromLink((char*)args);
5689 if(!spell)
5690 return false;
5692 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
5693 if(!spellInfo)
5694 return false;
5696 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
5698 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
5699 SetSentErrorMessage(true);
5700 return false;
5703 char* trig_str = strtok(NULL, " ");
5704 if(trig_str)
5706 int l = strlen(trig_str);
5707 if(strncmp(trig_str,"triggered",l) != 0 )
5708 return false;
5711 bool triggered = (trig_str != NULL);
5713 m_session->GetPlayer()->CastSpell(target,spell,triggered);
5715 return true;
5718 bool ChatHandler::HandleCastBackCommand(const char* args)
5720 Creature* caster = getSelectedCreature();
5722 if(!caster)
5724 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5725 SetSentErrorMessage(true);
5726 return false;
5729 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
5730 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5731 uint32 spell = extractSpellIdFromLink((char*)args);
5732 if(!spell || !sSpellStore.LookupEntry(spell))
5733 return false;
5735 char* trig_str = strtok(NULL, " ");
5736 if(trig_str)
5738 int l = strlen(trig_str);
5739 if(strncmp(trig_str,"triggered",l) != 0 )
5740 return false;
5743 bool triggered = (trig_str != NULL);
5745 // update orientation at server
5746 caster->SetOrientation(caster->GetAngle(m_session->GetPlayer()));
5748 // and client
5749 WorldPacket data;
5750 caster->BuildHeartBeatMsg(&data);
5751 caster->SendMessageToSet(&data,true);
5753 caster->CastSpell(m_session->GetPlayer(),spell,triggered);
5755 return true;
5758 bool ChatHandler::HandleCastDistCommand(const char* args)
5760 if(!*args)
5761 return false;
5763 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5764 uint32 spell = extractSpellIdFromLink((char*)args);
5765 if(!spell)
5766 return false;
5768 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
5769 if(!spellInfo)
5770 return false;
5772 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
5774 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
5775 SetSentErrorMessage(true);
5776 return false;
5779 char *distStr = strtok(NULL, " ");
5781 float dist = 0;
5783 if(distStr)
5784 sscanf(distStr, "%f", &dist);
5786 char* trig_str = strtok(NULL, " ");
5787 if(trig_str)
5789 int l = strlen(trig_str);
5790 if(strncmp(trig_str,"triggered",l) != 0 )
5791 return false;
5794 bool triggered = (trig_str != NULL);
5796 float x,y,z;
5797 m_session->GetPlayer()->GetClosePoint(x,y,z,dist);
5799 m_session->GetPlayer()->CastSpell(x,y,z,spell,triggered);
5800 return true;
5803 bool ChatHandler::HandleCastTargetCommand(const char* args)
5805 Creature* caster = getSelectedCreature();
5807 if(!caster)
5809 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5810 SetSentErrorMessage(true);
5811 return false;
5814 if(!caster->getVictim())
5816 SendSysMessage(LANG_SELECTED_TARGET_NOT_HAVE_VICTIM);
5817 SetSentErrorMessage(true);
5818 return false;
5821 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5822 uint32 spell = extractSpellIdFromLink((char*)args);
5823 if(!spell || !sSpellStore.LookupEntry(spell))
5824 return false;
5826 char* trig_str = strtok(NULL, " ");
5827 if(trig_str)
5829 int l = strlen(trig_str);
5830 if(strncmp(trig_str,"triggered",l) != 0 )
5831 return false;
5834 bool triggered = (trig_str != NULL);
5836 // update orientation at server
5837 caster->SetOrientation(caster->GetAngle(m_session->GetPlayer()));
5839 // and client
5840 WorldPacket data;
5841 caster->BuildHeartBeatMsg(&data);
5842 caster->SendMessageToSet(&data,true);
5844 caster->CastSpell(caster->getVictim(),spell,triggered);
5846 return true;
5850 ComeToMe command REQUIRED for 3rd party scripting library to have access to PointMovementGenerator
5851 Without this function 3rd party scripting library will get linking errors (unresolved external)
5852 when attempting to use the PointMovementGenerator
5854 bool ChatHandler::HandleComeToMeCommand(const char *args)
5856 Creature* caster = getSelectedCreature();
5858 if(!caster)
5860 SendSysMessage(LANG_SELECT_CREATURE);
5861 SetSentErrorMessage(true);
5862 return false;
5865 char* newFlagStr = strtok((char*)args, " ");
5867 if(!newFlagStr)
5868 return false;
5870 uint32 newFlags = atoi(newFlagStr);
5872 caster->SetMonsterMoveFlags(MonsterMovementFlags(newFlags));
5874 Player* pl = m_session->GetPlayer();
5876 caster->GetMotionMaster()->MovePoint(0, pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ());
5877 return true;
5880 bool ChatHandler::HandleCastSelfCommand(const char* args)
5882 if(!*args)
5883 return false;
5885 Unit* target = getSelectedUnit();
5887 if(!target)
5889 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5890 SetSentErrorMessage(true);
5891 return false;
5894 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5895 uint32 spell = extractSpellIdFromLink((char*)args);
5896 if(!spell)
5897 return false;
5899 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
5900 if(!spellInfo)
5901 return false;
5903 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
5905 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
5906 SetSentErrorMessage(true);
5907 return false;
5910 target->CastSpell(target,spell,false);
5912 return true;
5915 std::string GetTimeString(uint32 time)
5917 uint16 days = time / DAY, hours = (time % DAY) / HOUR, minute = (time % HOUR) / MINUTE;
5918 std::ostringstream ss;
5919 if(days) ss << days << "d ";
5920 if(hours) ss << hours << "h ";
5921 ss << minute << "m";
5922 return ss.str();
5925 bool ChatHandler::HandleInstanceListBindsCommand(const char* /*args*/)
5927 Player* player = getSelectedPlayer();
5928 if (!player) player = m_session->GetPlayer();
5929 uint32 counter = 0;
5930 for(uint8 i = 0; i < TOTAL_DIFFICULTIES; ++i)
5932 Player::BoundInstancesMap &binds = player->GetBoundInstances(i);
5933 for(Player::BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end(); ++itr)
5935 InstanceSave *save = itr->second.save;
5936 std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
5937 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());
5938 counter++;
5941 PSendSysMessage("player binds: %d", counter);
5942 counter = 0;
5943 Group *group = player->GetGroup();
5944 if(group)
5946 for(uint8 i = 0; i < TOTAL_DIFFICULTIES; ++i)
5948 Group::BoundInstancesMap &binds = group->GetBoundInstances(i);
5949 for(Group::BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end(); ++itr)
5951 InstanceSave *save = itr->second.save;
5952 std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
5953 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());
5954 counter++;
5958 PSendSysMessage("group binds: %d", counter);
5960 return true;
5963 bool ChatHandler::HandleInstanceUnbindCommand(const char* args)
5965 if(!*args)
5966 return false;
5968 std::string cmd = args;
5969 if(cmd == "all")
5971 Player* player = getSelectedPlayer();
5972 if (!player) player = m_session->GetPlayer();
5973 uint32 counter = 0;
5974 for(uint8 i = 0; i < TOTAL_DIFFICULTIES; ++i)
5976 Player::BoundInstancesMap &binds = player->GetBoundInstances(i);
5977 for(Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end();)
5979 if(itr->first != player->GetMapId())
5981 InstanceSave *save = itr->second.save;
5982 std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
5983 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());
5984 player->UnbindInstance(itr, i);
5985 counter++;
5987 else
5988 ++itr;
5991 PSendSysMessage("instances unbound: %d", counter);
5993 return true;
5996 bool ChatHandler::HandleInstanceStatsCommand(const char* /*args*/)
5998 PSendSysMessage("instances loaded: %d", MapManager::Instance().GetNumInstances());
5999 PSendSysMessage("players in instances: %d", MapManager::Instance().GetNumPlayersInInstances());
6000 PSendSysMessage("instance saves: %d", sInstanceSaveManager.GetNumInstanceSaves());
6001 PSendSysMessage("players bound: %d", sInstanceSaveManager.GetNumBoundPlayersTotal());
6002 PSendSysMessage("groups bound: %d", sInstanceSaveManager.GetNumBoundGroupsTotal());
6003 return true;
6006 bool ChatHandler::HandleInstanceSaveDataCommand(const char * /*args*/)
6008 Player* pl = m_session->GetPlayer();
6010 Map* map = pl->GetMap();
6011 if (!map->IsDungeon())
6013 PSendSysMessage("Map is not a dungeon.");
6014 SetSentErrorMessage(true);
6015 return false;
6018 if (!((InstanceMap*)map)->GetInstanceData())
6020 PSendSysMessage("Map has no instance data.");
6021 SetSentErrorMessage(true);
6022 return false;
6025 ((InstanceMap*)map)->GetInstanceData()->SaveToDB();
6026 return true;
6029 /// Display the list of GMs
6030 bool ChatHandler::HandleGMListFullCommand(const char* /*args*/)
6032 ///- Get the accounts with GM Level >0
6033 QueryResult *result = loginDatabase.Query( "SELECT username,gmlevel FROM account WHERE gmlevel > 0" );
6034 if(result)
6036 SendSysMessage(LANG_GMLIST);
6037 SendSysMessage("========================");
6038 SendSysMessage(LANG_GMLIST_HEADER);
6039 SendSysMessage("========================");
6041 ///- Circle through them. Display username and GM level
6044 Field *fields = result->Fetch();
6045 PSendSysMessage("|%15s|%6s|", fields[0].GetString(),fields[1].GetString());
6046 }while( result->NextRow() );
6048 PSendSysMessage("========================");
6049 delete result;
6051 else
6052 PSendSysMessage(LANG_GMLIST_EMPTY);
6053 return true;
6056 /// Define the 'Message of the day' for the realm
6057 bool ChatHandler::HandleServerSetMotdCommand(const char* args)
6059 sWorld.SetMotd(args);
6060 PSendSysMessage(LANG_MOTD_NEW, args);
6061 return true;
6064 /// Set/Unset the expansion level for an account
6065 bool ChatHandler::HandleAccountSetAddonCommand(const char* args)
6067 ///- Get the command line arguments
6068 char *szAcc = strtok((char*)args," ");
6069 char *szExp = strtok(NULL," ");
6071 if(!szAcc)
6072 return false;
6074 std::string account_name;
6075 uint32 account_id;
6077 if (!szExp)
6079 Player* player = getSelectedPlayer();
6080 if (!player)
6081 return false;
6083 account_id = player->GetSession()->GetAccountId();
6084 accmgr.GetName(account_id,account_name);
6085 szExp = szAcc;
6087 else
6089 ///- Convert Account name to Upper Format
6090 account_name = szAcc;
6091 if (!AccountMgr::normalizeString(account_name))
6093 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
6094 SetSentErrorMessage(true);
6095 return false;
6098 account_id = accmgr.GetId(account_name);
6099 if (!account_id)
6101 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
6102 SetSentErrorMessage(true);
6103 return false;
6108 // Let set addon state only for lesser (strong) security level
6109 // or to self account
6110 if (m_session && m_session->GetAccountId () != account_id &&
6111 HasLowerSecurityAccount (NULL,account_id,true))
6112 return false;
6114 int lev=atoi(szExp); //get int anyway (0 if error)
6115 if(lev < 0)
6116 return false;
6118 // No SQL injection
6119 loginDatabase.PExecute("UPDATE account SET expansion = '%d' WHERE id = '%u'",lev,account_id);
6120 PSendSysMessage(LANG_ACCOUNT_SETADDON,account_name.c_str(),account_id,lev);
6121 return true;
6124 //Send items by mail
6125 bool ChatHandler::HandleSendItemsCommand(const char* args)
6127 // format: name "subject text" "mail text" item1[:count1] item2[:count2] ... item12[:count12]
6128 Player* receiver;
6129 uint64 receiver_guid;
6130 std::string receiver_name;
6131 if(!extractPlayerTarget((char*)args,&receiver,&receiver_guid,&receiver_name))
6132 return false;
6134 char* tail1 = strtok(NULL, "");
6135 if(!tail1)
6136 return false;
6138 char* msgSubject = extractQuotedArg(tail1);
6139 if (!msgSubject)
6140 return false;
6142 char* tail2 = strtok(NULL, "");
6143 if(!tail2)
6144 return false;
6146 char* msgText = extractQuotedArg(tail2);
6147 if (!msgText)
6148 return false;
6150 // msgSubject, msgText isn't NUL after prev. check
6151 std::string subject = msgSubject;
6152 std::string text = msgText;
6154 // extract items
6155 typedef std::pair<uint32,uint32> ItemPair;
6156 typedef std::list< ItemPair > ItemPairs;
6157 ItemPairs items;
6159 // get all tail string
6160 char* tail = strtok(NULL, "");
6162 // get from tail next item str
6163 while(char* itemStr = strtok(tail, " "))
6165 // and get new tail
6166 tail = strtok(NULL, "");
6168 // parse item str
6169 char* itemIdStr = strtok(itemStr, ":");
6170 char* itemCountStr = strtok(NULL, " ");
6172 uint32 item_id = atoi(itemIdStr);
6173 if(!item_id)
6174 return false;
6176 ItemPrototype const* item_proto = objmgr.GetItemPrototype(item_id);
6177 if(!item_proto)
6179 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
6180 SetSentErrorMessage(true);
6181 return false;
6184 uint32 item_count = itemCountStr ? atoi(itemCountStr) : 1;
6185 if (item_count < 1 || (item_proto->MaxCount > 0 && item_count > uint32(item_proto->MaxCount)))
6187 PSendSysMessage(LANG_COMMAND_INVALID_ITEM_COUNT, item_count,item_id);
6188 SetSentErrorMessage(true);
6189 return false;
6192 while(item_count > item_proto->GetMaxStackSize())
6194 items.push_back(ItemPair(item_id,item_proto->GetMaxStackSize()));
6195 item_count -= item_proto->GetMaxStackSize();
6198 items.push_back(ItemPair(item_id,item_count));
6200 if(items.size() > MAX_MAIL_ITEMS)
6202 PSendSysMessage(LANG_COMMAND_MAIL_ITEMS_LIMIT, MAX_MAIL_ITEMS);
6203 SetSentErrorMessage(true);
6204 return false;
6208 // from console show not existed sender
6209 uint32 sender_guidlo = m_session ? m_session->GetPlayer()->GetGUIDLow() : 0;
6211 uint32 messagetype = MAIL_NORMAL;
6212 uint32 stationery = MAIL_STATIONERY_GM;
6213 uint32 itemTextId = !text.empty() ? objmgr.CreateItemText( text ) : 0;
6215 // fill mail
6216 MailItemsInfo mi; // item list preparing
6218 for(ItemPairs::const_iterator itr = items.begin(); itr != items.end(); ++itr)
6220 if(Item* item = Item::CreateItem(itr->first,itr->second,m_session ? m_session->GetPlayer() : 0))
6222 item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted
6223 mi.AddItem(item->GetGUIDLow(), item->GetEntry(), item);
6227 WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, &mi, 0, 0, MAIL_CHECK_MASK_NONE);
6229 std::string nameLink = playerLink(receiver_name);
6230 PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
6231 return true;
6234 ///Send money by mail
6235 bool ChatHandler::HandleSendMoneyCommand(const char* args)
6237 /// format: name "subject text" "mail text" money
6239 Player* receiver;
6240 uint64 receiver_guid;
6241 std::string receiver_name;
6242 if(!extractPlayerTarget((char*)args,&receiver,&receiver_guid,&receiver_name))
6243 return false;
6245 char* tail1 = strtok(NULL, "");
6246 if (!tail1)
6247 return false;
6249 char* msgSubject = extractQuotedArg(tail1);
6250 if (!msgSubject)
6251 return false;
6253 char* tail2 = strtok(NULL, "");
6254 if (!tail2)
6255 return false;
6257 char* msgText = extractQuotedArg(tail2);
6258 if (!msgText)
6259 return false;
6261 char* money_str = strtok(NULL, "");
6262 int32 money = money_str ? atoi(money_str) : 0;
6263 if (money <= 0)
6264 return false;
6266 // msgSubject, msgText isn't NUL after prev. check
6267 std::string subject = msgSubject;
6268 std::string text = msgText;
6270 // from console show not existed sender
6271 uint32 sender_guidlo = m_session ? m_session->GetPlayer()->GetGUIDLow() : 0;
6273 uint32 messagetype = MAIL_NORMAL;
6274 uint32 stationery = MAIL_STATIONERY_GM;
6275 uint32 itemTextId = !text.empty() ? objmgr.CreateItemText( text ) : 0;
6277 WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, NULL, money, 0, MAIL_CHECK_MASK_NONE);
6279 std::string nameLink = playerLink(receiver_name);
6280 PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
6281 return true;
6284 /// Send a message to a player in game
6285 bool ChatHandler::HandleSendMessageCommand(const char* args)
6287 ///- Find the player
6288 Player *rPlayer;
6289 if(!extractPlayerTarget((char*)args,&rPlayer))
6290 return false;
6292 char* msg_str = strtok(NULL, "");
6293 if(!msg_str)
6294 return false;
6296 ///- Check that he is not logging out.
6297 if(rPlayer->GetSession()->isLogingOut())
6299 SendSysMessage(LANG_PLAYER_NOT_FOUND);
6300 SetSentErrorMessage(true);
6301 return false;
6304 ///- Send the message
6305 //Use SendAreaTriggerMessage for fastest delivery.
6306 rPlayer->GetSession()->SendAreaTriggerMessage("%s", msg_str);
6307 rPlayer->GetSession()->SendAreaTriggerMessage("|cffff0000[Message from administrator]:|r");
6309 //Confirmation message
6310 std::string nameLink = GetNameLink(rPlayer);
6311 PSendSysMessage(LANG_SENDMESSAGE,nameLink.c_str(),msg_str);
6312 return true;
6315 bool ChatHandler::HandleFlushArenaPointsCommand(const char * /*args*/)
6317 sBattleGroundMgr.DistributeArenaPoints();
6318 return true;
6321 bool ChatHandler::HandleModifyGenderCommand(const char *args)
6323 if(!*args)
6324 return false;
6326 Player *player = getSelectedPlayer();
6328 if(!player)
6330 PSendSysMessage(LANG_PLAYER_NOT_FOUND);
6331 SetSentErrorMessage(true);
6332 return false;
6335 PlayerInfo const* info = objmgr.GetPlayerInfo(player->getRace(), player->getClass());
6336 if(!info)
6337 return false;
6339 char const* gender_str = (char*)args;
6340 int gender_len = strlen(gender_str);
6342 Gender gender;
6344 if(!strncmp(gender_str, "male", gender_len)) // MALE
6346 if(player->getGender() == GENDER_MALE)
6347 return true;
6349 gender = GENDER_MALE;
6351 else if (!strncmp(gender_str, "female", gender_len)) // FEMALE
6353 if(player->getGender() == GENDER_FEMALE)
6354 return true;
6356 gender = GENDER_FEMALE;
6358 else
6360 SendSysMessage(LANG_MUST_MALE_OR_FEMALE);
6361 SetSentErrorMessage(true);
6362 return false;
6365 // Set gender
6366 player->SetByteValue(UNIT_FIELD_BYTES_0, 2, gender);
6367 player->SetByteValue(PLAYER_BYTES_3, 0, gender);
6369 // Change display ID
6370 player->InitDisplayIds();
6372 char const* gender_full = gender ? "female" : "male";
6374 PSendSysMessage(LANG_YOU_CHANGE_GENDER, GetNameLink(player).c_str(), gender_full);
6376 if (needReportToTarget(player))
6377 ChatHandler(player).PSendSysMessage(LANG_YOUR_GENDER_CHANGED, gender_full, GetNameLink().c_str());
6379 return true;