[8590] Restore build at Unix/Linux.
[getmangos.git] / src / game / Level3.cpp
blob3e3e650821e4a304f44de4d8fec096063ce63337
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"
53 #include "DBCEnums.h"
55 //reload commands
56 bool ChatHandler::HandleReloadAllCommand(const char*)
58 HandleReloadSkillFishingBaseLevelCommand("");
60 HandleReloadAllAchievementCommand("");
61 HandleReloadAllAreaCommand("");
62 HandleReloadAllEventAICommand("");
63 HandleReloadAllLootCommand("");
64 HandleReloadAllNpcCommand("");
65 HandleReloadAllQuestCommand("");
66 HandleReloadAllSpellCommand("");
67 HandleReloadAllItemCommand("");
68 HandleReloadAllLocalesCommand("");
70 HandleReloadCommandCommand("");
71 HandleReloadReservedNameCommand("");
72 HandleReloadMangosStringCommand("");
73 HandleReloadGameTeleCommand("");
74 return true;
77 bool ChatHandler::HandleReloadAllAchievementCommand(const char*)
79 HandleReloadAchievementCriteriaDataCommand("");
80 HandleReloadAchievementRewardCommand("");
81 return true;
84 bool ChatHandler::HandleReloadAllAreaCommand(const char*)
86 //HandleReloadQuestAreaTriggersCommand(""); -- reloaded in HandleReloadAllQuestCommand
87 HandleReloadAreaTriggerTeleportCommand("");
88 HandleReloadAreaTriggerTavernCommand("");
89 HandleReloadGameGraveyardZoneCommand("");
90 return true;
93 bool ChatHandler::HandleReloadAllLootCommand(const char*)
95 sLog.outString( "Re-Loading Loot Tables..." );
96 LoadLootTables();
97 SendGlobalSysMessage("DB tables `*_loot_template` reloaded.");
98 return true;
101 bool ChatHandler::HandleReloadAllNpcCommand(const char* /*args*/)
103 HandleReloadNpcGossipCommand("a");
104 HandleReloadNpcOptionCommand("a");
105 HandleReloadNpcTrainerCommand("a");
106 HandleReloadNpcVendorCommand("a");
107 HandleReloadPointsOfInterestCommand("a");
108 HandleReloadSpellClickSpellsCommand("a");
109 return true;
112 bool ChatHandler::HandleReloadAllQuestCommand(const char* /*args*/)
114 HandleReloadQuestAreaTriggersCommand("a");
115 HandleReloadQuestTemplateCommand("a");
117 sLog.outString( "Re-Loading Quests Relations..." );
118 objmgr.LoadQuestRelations();
119 SendGlobalSysMessage("DB tables `*_questrelation` and `*_involvedrelation` reloaded.");
120 return true;
123 bool ChatHandler::HandleReloadAllScriptsCommand(const char*)
125 if(sWorld.IsScriptScheduled())
127 PSendSysMessage("DB scripts used currently, please attempt reload later.");
128 SetSentErrorMessage(true);
129 return false;
132 sLog.outString( "Re-Loading Scripts..." );
133 HandleReloadGameObjectScriptsCommand("a");
134 HandleReloadEventScriptsCommand("a");
135 HandleReloadQuestEndScriptsCommand("a");
136 HandleReloadQuestStartScriptsCommand("a");
137 HandleReloadSpellScriptsCommand("a");
138 SendGlobalSysMessage("DB tables `*_scripts` reloaded.");
139 HandleReloadDbScriptStringCommand("a");
140 return true;
143 bool ChatHandler::HandleReloadAllEventAICommand(const char*)
145 HandleReloadEventAITextsCommand("a");
146 HandleReloadEventAISummonsCommand("a");
147 HandleReloadEventAIScriptsCommand("a");
148 return true;
151 bool ChatHandler::HandleReloadAllSpellCommand(const char*)
153 HandleReloadSkillDiscoveryTemplateCommand("a");
154 HandleReloadSkillExtraItemTemplateCommand("a");
155 HandleReloadSpellAreaCommand("a");
156 HandleReloadSpellChainCommand("a");
157 HandleReloadSpellElixirCommand("a");
158 HandleReloadSpellLearnSpellCommand("a");
159 HandleReloadSpellProcEventCommand("a");
160 HandleReloadSpellBonusesCommand("a");
161 HandleReloadSpellProcItemEnchantCommand("a");
162 HandleReloadSpellScriptTargetCommand("a");
163 HandleReloadSpellTargetPositionCommand("a");
164 HandleReloadSpellThreatsCommand("a");
165 HandleReloadSpellPetAurasCommand("a");
166 return true;
169 bool ChatHandler::HandleReloadAllItemCommand(const char*)
171 HandleReloadPageTextsCommand("a");
172 HandleReloadItemEnchantementsCommand("a");
173 HandleReloadItemRequiredTragetCommand("a");
174 return true;
177 bool ChatHandler::HandleReloadAllLocalesCommand(const char* /*args*/)
179 HandleReloadLocalesAchievementRewardCommand("a");
180 HandleReloadLocalesCreatureCommand("a");
181 HandleReloadLocalesGameobjectCommand("a");
182 HandleReloadLocalesItemCommand("a");
183 HandleReloadLocalesNpcTextCommand("a");
184 HandleReloadLocalesPageTextCommand("a");
185 HandleReloadLocalesPointsOfInterestCommand("a");
186 HandleReloadLocalesQuestCommand("a");
187 return true;
190 bool ChatHandler::HandleReloadConfigCommand(const char* /*args*/)
192 sLog.outString( "Re-Loading config settings..." );
193 sWorld.LoadConfigSettings(true);
194 MapManager::Instance().InitializeVisibilityDistanceInfo();
195 SendGlobalSysMessage("World config settings reloaded.");
196 return true;
199 bool ChatHandler::HandleReloadAchievementCriteriaDataCommand(const char*)
201 sLog.outString( "Re-Loading Additional Achievement Criteria Data..." );
202 achievementmgr.LoadAchievementCriteriaData();
203 SendGlobalSysMessage("DB table `achievement_criteria_data` reloaded.");
204 return true;
207 bool ChatHandler::HandleReloadAchievementRewardCommand(const char*)
209 sLog.outString( "Re-Loading Achievement Reward Data..." );
210 achievementmgr.LoadRewards();
211 SendGlobalSysMessage("DB table `achievement_reward` reloaded.");
212 return true;
215 bool ChatHandler::HandleReloadAreaTriggerTavernCommand(const char*)
217 sLog.outString( "Re-Loading Tavern Area Triggers..." );
218 objmgr.LoadTavernAreaTriggers();
219 SendGlobalSysMessage("DB table `areatrigger_tavern` reloaded.");
220 return true;
223 bool ChatHandler::HandleReloadAreaTriggerTeleportCommand(const char*)
225 sLog.outString( "Re-Loading AreaTrigger teleport definitions..." );
226 objmgr.LoadAreaTriggerTeleports();
227 SendGlobalSysMessage("DB table `areatrigger_teleport` reloaded.");
228 return true;
231 bool ChatHandler::HandleReloadCommandCommand(const char*)
233 load_command_table = true;
234 SendGlobalSysMessage("DB table `command` will be reloaded at next chat command use.");
235 return true;
238 bool ChatHandler::HandleReloadCreatureQuestRelationsCommand(const char*)
240 sLog.outString( "Loading Quests Relations... (`creature_questrelation`)" );
241 objmgr.LoadCreatureQuestRelations();
242 SendGlobalSysMessage("DB table `creature_questrelation` (creature quest givers) reloaded.");
243 return true;
246 bool ChatHandler::HandleReloadCreatureQuestInvRelationsCommand(const char*)
248 sLog.outString( "Loading Quests Relations... (`creature_involvedrelation`)" );
249 objmgr.LoadCreatureInvolvedRelations();
250 SendGlobalSysMessage("DB table `creature_involvedrelation` (creature quest takers) reloaded.");
251 return true;
254 bool ChatHandler::HandleReloadGOQuestRelationsCommand(const char*)
256 sLog.outString( "Loading Quests Relations... (`gameobject_questrelation`)" );
257 objmgr.LoadGameobjectQuestRelations();
258 SendGlobalSysMessage("DB table `gameobject_questrelation` (gameobject quest givers) reloaded.");
259 return true;
262 bool ChatHandler::HandleReloadGOQuestInvRelationsCommand(const char*)
264 sLog.outString( "Loading Quests Relations... (`gameobject_involvedrelation`)" );
265 objmgr.LoadGameobjectInvolvedRelations();
266 SendGlobalSysMessage("DB table `gameobject_involvedrelation` (gameobject quest takers) reloaded.");
267 return true;
270 bool ChatHandler::HandleReloadQuestAreaTriggersCommand(const char*)
272 sLog.outString( "Re-Loading Quest Area Triggers..." );
273 objmgr.LoadQuestAreaTriggers();
274 SendGlobalSysMessage("DB table `areatrigger_involvedrelation` (quest area triggers) reloaded.");
275 return true;
278 bool ChatHandler::HandleReloadQuestTemplateCommand(const char*)
280 sLog.outString( "Re-Loading Quest Templates..." );
281 objmgr.LoadQuests();
282 SendGlobalSysMessage("DB table `quest_template` (quest definitions) reloaded.");
284 /// dependent also from `gameobject` but this table not reloaded anyway
285 sLog.outString( "Re-Loading GameObjects for quests..." );
286 objmgr.LoadGameObjectForQuests();
287 SendGlobalSysMessage("Data GameObjects for quests reloaded.");
288 return true;
291 bool ChatHandler::HandleReloadLootTemplatesCreatureCommand(const char*)
293 sLog.outString( "Re-Loading Loot Tables... (`creature_loot_template`)" );
294 LoadLootTemplates_Creature();
295 LootTemplates_Creature.CheckLootRefs();
296 SendGlobalSysMessage("DB table `creature_loot_template` reloaded.");
297 return true;
300 bool ChatHandler::HandleReloadLootTemplatesDisenchantCommand(const char*)
302 sLog.outString( "Re-Loading Loot Tables... (`disenchant_loot_template`)" );
303 LoadLootTemplates_Disenchant();
304 LootTemplates_Disenchant.CheckLootRefs();
305 SendGlobalSysMessage("DB table `disenchant_loot_template` reloaded.");
306 return true;
309 bool ChatHandler::HandleReloadLootTemplatesFishingCommand(const char*)
311 sLog.outString( "Re-Loading Loot Tables... (`fishing_loot_template`)" );
312 LoadLootTemplates_Fishing();
313 LootTemplates_Fishing.CheckLootRefs();
314 SendGlobalSysMessage("DB table `fishing_loot_template` reloaded.");
315 return true;
318 bool ChatHandler::HandleReloadLootTemplatesGameobjectCommand(const char*)
320 sLog.outString( "Re-Loading Loot Tables... (`gameobject_loot_template`)" );
321 LoadLootTemplates_Gameobject();
322 LootTemplates_Gameobject.CheckLootRefs();
323 SendGlobalSysMessage("DB table `gameobject_loot_template` reloaded.");
324 return true;
327 bool ChatHandler::HandleReloadLootTemplatesItemCommand(const char*)
329 sLog.outString( "Re-Loading Loot Tables... (`item_loot_template`)" );
330 LoadLootTemplates_Item();
331 LootTemplates_Item.CheckLootRefs();
332 SendGlobalSysMessage("DB table `item_loot_template` reloaded.");
333 return true;
336 bool ChatHandler::HandleReloadLootTemplatesMillingCommand(const char*)
338 sLog.outString( "Re-Loading Loot Tables... (`milling_loot_template`)" );
339 LoadLootTemplates_Milling();
340 LootTemplates_Milling.CheckLootRefs();
341 SendGlobalSysMessage("DB table `milling_loot_template` reloaded.");
342 return true;
345 bool ChatHandler::HandleReloadLootTemplatesPickpocketingCommand(const char*)
347 sLog.outString( "Re-Loading Loot Tables... (`pickpocketing_loot_template`)" );
348 LoadLootTemplates_Pickpocketing();
349 LootTemplates_Pickpocketing.CheckLootRefs();
350 SendGlobalSysMessage("DB table `pickpocketing_loot_template` reloaded.");
351 return true;
354 bool ChatHandler::HandleReloadLootTemplatesProspectingCommand(const char*)
356 sLog.outString( "Re-Loading Loot Tables... (`prospecting_loot_template`)" );
357 LoadLootTemplates_Prospecting();
358 LootTemplates_Prospecting.CheckLootRefs();
359 SendGlobalSysMessage("DB table `prospecting_loot_template` reloaded.");
360 return true;
363 bool ChatHandler::HandleReloadLootTemplatesQuestMailCommand(const char*)
365 sLog.outString( "Re-Loading Loot Tables... (`quest_mail_loot_template`)" );
366 LoadLootTemplates_QuestMail();
367 LootTemplates_QuestMail.CheckLootRefs();
368 SendGlobalSysMessage("DB table `quest_mail_loot_template` reloaded.");
369 return true;
372 bool ChatHandler::HandleReloadLootTemplatesReferenceCommand(const char*)
374 sLog.outString( "Re-Loading Loot Tables... (`reference_loot_template`)" );
375 LoadLootTemplates_Reference();
376 SendGlobalSysMessage("DB table `reference_loot_template` reloaded.");
377 return true;
380 bool ChatHandler::HandleReloadLootTemplatesSkinningCommand(const char*)
382 sLog.outString( "Re-Loading Loot Tables... (`skinning_loot_template`)" );
383 LoadLootTemplates_Skinning();
384 LootTemplates_Skinning.CheckLootRefs();
385 SendGlobalSysMessage("DB table `skinning_loot_template` reloaded.");
386 return true;
389 bool ChatHandler::HandleReloadLootTemplatesSpellCommand(const char*)
391 sLog.outString( "Re-Loading Loot Tables... (`spell_loot_template`)" );
392 LoadLootTemplates_Spell();
393 LootTemplates_Spell.CheckLootRefs();
394 SendGlobalSysMessage("DB table `spell_loot_template` reloaded.");
395 return true;
398 bool ChatHandler::HandleReloadMangosStringCommand(const char*)
400 sLog.outString( "Re-Loading mangos_string Table!" );
401 objmgr.LoadMangosStrings();
402 SendGlobalSysMessage("DB table `mangos_string` reloaded.");
403 return true;
406 bool ChatHandler::HandleReloadNpcOptionCommand(const char*)
408 sLog.outString( "Re-Loading `npc_option` Table!" );
409 objmgr.LoadNpcOptions();
410 SendGlobalSysMessage("DB table `npc_option` reloaded.");
411 return true;
414 bool ChatHandler::HandleReloadNpcGossipCommand(const char*)
416 sLog.outString( "Re-Loading `npc_gossip` Table!" );
417 objmgr.LoadNpcTextId();
418 SendGlobalSysMessage("DB table `npc_gossip` reloaded.");
419 return true;
422 bool ChatHandler::HandleReloadNpcTrainerCommand(const char*)
424 sLog.outString( "Re-Loading `npc_trainer` Table!" );
425 objmgr.LoadTrainerSpell();
426 SendGlobalSysMessage("DB table `npc_trainer` reloaded.");
427 return true;
430 bool ChatHandler::HandleReloadNpcVendorCommand(const char*)
432 sLog.outString( "Re-Loading `npc_vendor` Table!" );
433 objmgr.LoadVendors();
434 SendGlobalSysMessage("DB table `npc_vendor` reloaded.");
435 return true;
438 bool ChatHandler::HandleReloadPointsOfInterestCommand(const char*)
440 sLog.outString( "Re-Loading `points_of_interest` Table!" );
441 objmgr.LoadPointsOfInterest();
442 SendGlobalSysMessage("DB table `points_of_interest` reloaded.");
443 return true;
446 bool ChatHandler::HandleReloadSpellClickSpellsCommand(const char*)
448 sLog.outString( "Re-Loading `npc_spellclick_spells` Table!" );
449 objmgr.LoadNPCSpellClickSpells();
450 SendGlobalSysMessage("DB table `npc_spellclick_spells` reloaded.");
451 return true;
454 bool ChatHandler::HandleReloadReservedNameCommand(const char*)
456 sLog.outString( "Loading ReservedNames... (`reserved_name`)" );
457 objmgr.LoadReservedPlayersNames();
458 SendGlobalSysMessage("DB table `reserved_name` (player reserved names) reloaded.");
459 return true;
462 bool ChatHandler::HandleReloadSkillDiscoveryTemplateCommand(const char* /*args*/)
464 sLog.outString( "Re-Loading Skill Discovery Table..." );
465 LoadSkillDiscoveryTable();
466 SendGlobalSysMessage("DB table `skill_discovery_template` (recipes discovered at crafting) reloaded.");
467 return true;
470 bool ChatHandler::HandleReloadSkillExtraItemTemplateCommand(const char* /*args*/)
472 sLog.outString( "Re-Loading Skill Extra Item Table..." );
473 LoadSkillExtraItemTable();
474 SendGlobalSysMessage("DB table `skill_extra_item_template` (extra item creation when crafting) reloaded.");
475 return true;
478 bool ChatHandler::HandleReloadSkillFishingBaseLevelCommand(const char* /*args*/)
480 sLog.outString( "Re-Loading Skill Fishing base level requirements..." );
481 objmgr.LoadFishingBaseSkillLevel();
482 SendGlobalSysMessage("DB table `skill_fishing_base_level` (fishing base level for zone/subzone) reloaded.");
483 return true;
486 bool ChatHandler::HandleReloadSpellAreaCommand(const char*)
488 sLog.outString( "Re-Loading SpellArea Data..." );
489 spellmgr.LoadSpellAreas();
490 SendGlobalSysMessage("DB table `spell_area` (spell dependences from area/quest/auras state) reloaded.");
491 return true;
494 bool ChatHandler::HandleReloadSpellChainCommand(const char*)
496 sLog.outString( "Re-Loading Spell Chain Data... " );
497 spellmgr.LoadSpellChains();
498 SendGlobalSysMessage("DB table `spell_chain` (spell ranks) reloaded.");
499 return true;
502 bool ChatHandler::HandleReloadSpellElixirCommand(const char*)
504 sLog.outString( "Re-Loading Spell Elixir types..." );
505 spellmgr.LoadSpellElixirs();
506 SendGlobalSysMessage("DB table `spell_elixir` (spell elixir types) reloaded.");
507 return true;
510 bool ChatHandler::HandleReloadSpellLearnSpellCommand(const char*)
512 sLog.outString( "Re-Loading Spell Learn Spells..." );
513 spellmgr.LoadSpellLearnSpells();
514 SendGlobalSysMessage("DB table `spell_learn_spell` reloaded.");
515 return true;
518 bool ChatHandler::HandleReloadSpellProcEventCommand(const char*)
520 sLog.outString( "Re-Loading Spell Proc Event conditions..." );
521 spellmgr.LoadSpellProcEvents();
522 SendGlobalSysMessage("DB table `spell_proc_event` (spell proc trigger requirements) reloaded.");
523 return true;
526 bool ChatHandler::HandleReloadSpellBonusesCommand(const char*)
528 sLog.outString( "Re-Loading Spell Bonus Data..." );
529 spellmgr.LoadSpellBonusess();
530 SendGlobalSysMessage("DB table `spell_bonus_data` (spell damage/healing coefficients) reloaded.");
531 return true;
534 bool ChatHandler::HandleReloadSpellProcItemEnchantCommand(const char*)
536 sLog.outString( "Re-Loading Spell Proc Item Enchant..." );
537 spellmgr.LoadSpellProcItemEnchant();
538 SendGlobalSysMessage("DB table `spell_proc_item_enchant` (item enchantment ppm) reloaded.");
539 return true;
542 bool ChatHandler::HandleReloadSpellScriptTargetCommand(const char*)
544 sLog.outString( "Re-Loading SpellsScriptTarget..." );
545 spellmgr.LoadSpellScriptTarget();
546 SendGlobalSysMessage("DB table `spell_script_target` (spell targets selection in case specific creature/GO requirements) reloaded.");
547 return true;
550 bool ChatHandler::HandleReloadSpellTargetPositionCommand(const char*)
552 sLog.outString( "Re-Loading Spell target coordinates..." );
553 spellmgr.LoadSpellTargetPositions();
554 SendGlobalSysMessage("DB table `spell_target_position` (destination coordinates for spell targets) reloaded.");
555 return true;
558 bool ChatHandler::HandleReloadSpellThreatsCommand(const char*)
560 sLog.outString( "Re-Loading Aggro Spells Definitions...");
561 spellmgr.LoadSpellThreats();
562 SendGlobalSysMessage("DB table `spell_threat` (spell aggro definitions) reloaded.");
563 return true;
566 bool ChatHandler::HandleReloadSpellPetAurasCommand(const char*)
568 sLog.outString( "Re-Loading Spell pet auras...");
569 spellmgr.LoadSpellPetAuras();
570 SendGlobalSysMessage("DB table `spell_pet_auras` reloaded.");
571 return true;
574 bool ChatHandler::HandleReloadPageTextsCommand(const char*)
576 sLog.outString( "Re-Loading Page Texts..." );
577 objmgr.LoadPageTexts();
578 SendGlobalSysMessage("DB table `page_texts` reloaded.");
579 return true;
582 bool ChatHandler::HandleReloadItemEnchantementsCommand(const char*)
584 sLog.outString( "Re-Loading Item Random Enchantments Table..." );
585 LoadRandomEnchantmentsTable();
586 SendGlobalSysMessage("DB table `item_enchantment_template` reloaded.");
587 return true;
590 bool ChatHandler::HandleReloadItemRequiredTragetCommand(const char*)
592 sLog.outString( "Re-Loading Item Required Targets Table..." );
593 objmgr.LoadItemRequiredTarget();
594 SendGlobalSysMessage("DB table `item_required_target` reloaded.");
595 return true;
598 bool ChatHandler::HandleReloadBattleEventCommand(const char*)
600 sLog.outString( "Re-Loading BattleGround Eventindexes..." );
601 sBattleGroundMgr.LoadBattleEventIndexes();
602 SendGlobalSysMessage("DB table `gameobject_battleground` and `creature_battleground` reloaded.");
603 return true;
606 bool ChatHandler::HandleReloadGameObjectScriptsCommand(const char* arg)
608 if(sWorld.IsScriptScheduled())
610 SendSysMessage("DB scripts used currently, please attempt reload later.");
611 SetSentErrorMessage(true);
612 return false;
615 if(*arg!='a')
616 sLog.outString( "Re-Loading Scripts from `gameobject_scripts`...");
618 objmgr.LoadGameObjectScripts();
620 if(*arg!='a')
621 SendGlobalSysMessage("DB table `gameobject_scripts` reloaded.");
623 return true;
626 bool ChatHandler::HandleReloadEventScriptsCommand(const char* arg)
628 if(sWorld.IsScriptScheduled())
630 SendSysMessage("DB scripts used currently, please attempt reload later.");
631 SetSentErrorMessage(true);
632 return false;
635 if(*arg!='a')
636 sLog.outString( "Re-Loading Scripts from `event_scripts`...");
638 objmgr.LoadEventScripts();
640 if(*arg!='a')
641 SendGlobalSysMessage("DB table `event_scripts` reloaded.");
643 return true;
646 bool ChatHandler::HandleReloadEventAITextsCommand(const char* arg)
649 sLog.outString( "Re-Loading Texts from `creature_ai_texts`...");
650 CreatureEAI_Mgr.LoadCreatureEventAI_Texts();
651 SendGlobalSysMessage("DB table `creature_ai_texts` reloaded.");
652 return true;
655 bool ChatHandler::HandleReloadEventAISummonsCommand(const char* arg)
657 sLog.outString( "Re-Loading Summons from `creature_ai_summons`...");
658 CreatureEAI_Mgr.LoadCreatureEventAI_Summons();
659 SendGlobalSysMessage("DB table `creature_ai_summons` reloaded.");
660 return true;
663 bool ChatHandler::HandleReloadEventAIScriptsCommand(const char* arg)
665 sLog.outString( "Re-Loading Scripts from `creature_ai_scripts`...");
666 CreatureEAI_Mgr.LoadCreatureEventAI_Scripts();
667 SendGlobalSysMessage("DB table `creature_ai_scripts` reloaded.");
668 return true;
671 bool ChatHandler::HandleReloadQuestEndScriptsCommand(const char* arg)
673 if(sWorld.IsScriptScheduled())
675 SendSysMessage("DB scripts used currently, please attempt reload later.");
676 SetSentErrorMessage(true);
677 return false;
680 if(*arg!='a')
681 sLog.outString( "Re-Loading Scripts from `quest_end_scripts`...");
683 objmgr.LoadQuestEndScripts();
685 if(*arg!='a')
686 SendGlobalSysMessage("DB table `quest_end_scripts` reloaded.");
688 return true;
691 bool ChatHandler::HandleReloadQuestStartScriptsCommand(const char* arg)
693 if(sWorld.IsScriptScheduled())
695 SendSysMessage("DB scripts used currently, please attempt reload later.");
696 SetSentErrorMessage(true);
697 return false;
700 if(*arg!='a')
701 sLog.outString( "Re-Loading Scripts from `quest_start_scripts`...");
703 objmgr.LoadQuestStartScripts();
705 if(*arg!='a')
706 SendGlobalSysMessage("DB table `quest_start_scripts` reloaded.");
708 return true;
711 bool ChatHandler::HandleReloadSpellScriptsCommand(const char* arg)
713 if(sWorld.IsScriptScheduled())
715 SendSysMessage("DB scripts used currently, please attempt reload later.");
716 SetSentErrorMessage(true);
717 return false;
720 if(*arg!='a')
721 sLog.outString( "Re-Loading Scripts from `spell_scripts`...");
723 objmgr.LoadSpellScripts();
725 if(*arg!='a')
726 SendGlobalSysMessage("DB table `spell_scripts` reloaded.");
728 return true;
731 bool ChatHandler::HandleReloadDbScriptStringCommand(const char* /*arg*/)
733 sLog.outString( "Re-Loading Script strings from `db_script_string`...");
734 objmgr.LoadDbScriptStrings();
735 SendGlobalSysMessage("DB table `db_script_string` reloaded.");
736 return true;
739 bool ChatHandler::HandleReloadGameGraveyardZoneCommand(const char* /*arg*/)
741 sLog.outString( "Re-Loading Graveyard-zone links...");
743 objmgr.LoadGraveyardZones();
745 SendGlobalSysMessage("DB table `game_graveyard_zone` reloaded.");
747 return true;
750 bool ChatHandler::HandleReloadGameTeleCommand(const char* /*arg*/)
752 sLog.outString( "Re-Loading Game Tele coordinates...");
754 objmgr.LoadGameTele();
756 SendGlobalSysMessage("DB table `game_tele` reloaded.");
758 return true;
761 bool ChatHandler::HandleReloadLocalesAchievementRewardCommand(const char*)
763 sLog.outString( "Re-Loading Locales Achievement Reward Data..." );
764 achievementmgr.LoadRewardLocales();
765 SendGlobalSysMessage("DB table `locales_achievement_reward` reloaded.");
766 return true;
769 bool ChatHandler::HandleReloadLocalesCreatureCommand(const char* /*arg*/)
771 sLog.outString( "Re-Loading Locales Creature ...");
772 objmgr.LoadCreatureLocales();
773 SendGlobalSysMessage("DB table `locales_creature` reloaded.");
774 return true;
777 bool ChatHandler::HandleReloadLocalesGameobjectCommand(const char* /*arg*/)
779 sLog.outString( "Re-Loading Locales Gameobject ... ");
780 objmgr.LoadGameObjectLocales();
781 SendGlobalSysMessage("DB table `locales_gameobject` reloaded.");
782 return true;
785 bool ChatHandler::HandleReloadLocalesItemCommand(const char* /*arg*/)
787 sLog.outString( "Re-Loading Locales Item ... ");
788 objmgr.LoadItemLocales();
789 SendGlobalSysMessage("DB table `locales_item` reloaded.");
790 return true;
793 bool ChatHandler::HandleReloadLocalesNpcTextCommand(const char* /*arg*/)
795 sLog.outString( "Re-Loading Locales NPC Text ... ");
796 objmgr.LoadNpcTextLocales();
797 SendGlobalSysMessage("DB table `locales_npc_text` reloaded.");
798 return true;
801 bool ChatHandler::HandleReloadLocalesPageTextCommand(const char* /*arg*/)
803 sLog.outString( "Re-Loading Locales Page Text ... ");
804 objmgr.LoadPageTextLocales();
805 SendGlobalSysMessage("DB table `locales_page_text` reloaded.");
806 return true;
809 bool ChatHandler::HandleReloadLocalesPointsOfInterestCommand(const char* /*arg*/)
811 sLog.outString( "Re-Loading Locales Points Of Interest ... ");
812 objmgr.LoadPointOfInterestLocales();
813 SendGlobalSysMessage("DB table `locales_points_of_interest` reloaded.");
814 return true;
817 bool ChatHandler::HandleReloadLocalesQuestCommand(const char* /*arg*/)
819 sLog.outString( "Re-Loading Locales Quest ... ");
820 objmgr.LoadQuestLocales();
821 SendGlobalSysMessage("DB table `locales_quest` reloaded.");
822 return true;
825 bool ChatHandler::HandleLoadScriptsCommand(const char* args)
827 if(!LoadScriptingModule(args)) return true;
829 sWorld.SendWorldText(LANG_SCRIPTS_RELOADED);
830 return true;
833 bool ChatHandler::HandleAccountSetGmLevelCommand(const char* args)
835 char* arg1 = strtok((char*)args, " ");
836 if( !arg1 )
837 return false;
839 /// must be NULL if targeted syntax and must be not nULL if not targeted
840 char* arg2 = strtok(NULL, " ");
842 std::string targetAccountName;
843 uint32 targetAccountId = 0;
845 /// only target player different from self allowed (if targetPlayer!=NULL then not console)
846 Player* targetPlayer = getSelectedPlayer();
847 if(targetPlayer && m_session->GetPlayer()!=targetPlayer)
849 /// wrong command syntax or unexpected targeting
850 if(arg2)
851 return false;
853 /// security level expected in arg2 after this if.
854 arg2 = arg1;
856 targetAccountId = targetPlayer->GetSession()->GetAccountId();
857 accmgr.GetName(targetAccountId, targetAccountName);
859 else
861 /// wrong command syntax (second arg expected)
862 if(!arg2)
863 return false;
865 targetAccountName = arg1;
866 if (!AccountMgr::normalizeString(targetAccountName))
868 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,targetAccountName.c_str());
869 SetSentErrorMessage(true);
870 return false;
873 targetAccountId = accmgr.GetId(targetAccountName);
874 if(!targetAccountId)
876 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,targetAccountName.c_str());
877 SetSentErrorMessage(true);
878 return false;
882 int32 gm = (int32)atoi(arg2);
883 if ( gm < SEC_PLAYER || gm > SEC_ADMINISTRATOR )
885 SendSysMessage(LANG_BAD_VALUE);
886 SetSentErrorMessage(true);
887 return false;
890 /// can set security level only for target with less security and to less security that we have
891 /// This will reject self apply by specify account name
892 if(HasLowerSecurityAccount(NULL,targetAccountId,true))
893 return false;
895 /// account can't set security to same or grater level, need more power GM or console
896 AccountTypes plSecurity = m_session ? m_session->GetSecurity() : SEC_CONSOLE;
897 if (AccountTypes(gm) >= plSecurity )
899 SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
900 SetSentErrorMessage(true);
901 return false;
904 // This will prevent self apply by self target or no target
905 if(targetPlayer && m_session->GetPlayer()!=targetPlayer)
907 ChatHandler(targetPlayer).PSendSysMessage(LANG_YOURS_SECURITY_CHANGED,GetNameLink().c_str(), gm);
908 targetPlayer->GetSession()->SetSecurity(AccountTypes(gm));
911 PSendSysMessage(LANG_YOU_CHANGE_SECURITY, targetAccountName.c_str(), gm);
912 loginDatabase.PExecute("UPDATE account SET gmlevel = '%i' WHERE id = '%u'", gm, targetAccountId);
914 return true;
917 /// Set password for account
918 bool ChatHandler::HandleAccountSetPasswordCommand(const char* args)
920 if(!*args)
921 return false;
923 ///- Get the command line arguments
924 char *szAccount = strtok ((char*)args," ");
925 char *szPassword1 = strtok (NULL," ");
926 char *szPassword2 = strtok (NULL," ");
928 if (!szAccount||!szPassword1 || !szPassword2)
929 return false;
931 std::string account_name = szAccount;
932 if (!AccountMgr::normalizeString(account_name))
934 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
935 SetSentErrorMessage(true);
936 return false;
939 uint32 targetAccountId = accmgr.GetId(account_name);
940 if (!targetAccountId)
942 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
943 SetSentErrorMessage(true);
944 return false;
947 /// can set password only for target with less security
948 /// This is also reject self apply in fact
949 if(HasLowerSecurityAccount (NULL,targetAccountId,true))
950 return false;
952 if (strcmp(szPassword1,szPassword2))
954 SendSysMessage (LANG_NEW_PASSWORDS_NOT_MATCH);
955 SetSentErrorMessage (true);
956 return false;
959 AccountOpResult result = accmgr.ChangePassword(targetAccountId, szPassword1);
961 switch(result)
963 case AOR_OK:
964 SendSysMessage(LANG_COMMAND_PASSWORD);
965 break;
966 case AOR_NAME_NOT_EXIST:
967 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
968 SetSentErrorMessage(true);
969 return false;
970 case AOR_PASS_TOO_LONG:
971 SendSysMessage(LANG_PASSWORD_TOO_LONG);
972 SetSentErrorMessage(true);
973 return false;
974 default:
975 SendSysMessage(LANG_COMMAND_NOTCHANGEPASSWORD);
976 SetSentErrorMessage(true);
977 return false;
980 return true;
983 bool ChatHandler::HandleMaxSkillCommand(const char* /*args*/)
985 Player* SelectedPlayer = getSelectedPlayer();
986 if(!SelectedPlayer)
988 SendSysMessage(LANG_NO_CHAR_SELECTED);
989 SetSentErrorMessage(true);
990 return false;
993 // each skills that have max skill value dependent from level seted to current level max skill value
994 SelectedPlayer->UpdateSkillsToMaxSkillsForLevel();
995 return true;
998 bool ChatHandler::HandleSetSkillCommand(const char* args)
1000 // number or [name] Shift-click form |color|Hskill:skill_id|h[name]|h|r
1001 char* skill_p = extractKeyFromLink((char*)args,"Hskill");
1002 if(!skill_p)
1003 return false;
1005 char *level_p = strtok (NULL, " ");
1007 if( !level_p)
1008 return false;
1010 char *max_p = strtok (NULL, " ");
1012 int32 skill = atoi(skill_p);
1013 if (skill <= 0)
1015 PSendSysMessage(LANG_INVALID_SKILL_ID, skill);
1016 SetSentErrorMessage(true);
1017 return false;
1020 int32 level = atol (level_p);
1022 Player * target = getSelectedPlayer();
1023 if(!target)
1025 SendSysMessage(LANG_NO_CHAR_SELECTED);
1026 SetSentErrorMessage(true);
1027 return false;
1030 SkillLineEntry const* sl = sSkillLineStore.LookupEntry(skill);
1031 if(!sl)
1033 PSendSysMessage(LANG_INVALID_SKILL_ID, skill);
1034 SetSentErrorMessage(true);
1035 return false;
1038 std::string tNameLink = GetNameLink(target);
1040 if(!target->GetSkillValue(skill))
1042 PSendSysMessage(LANG_SET_SKILL_ERROR, tNameLink.c_str(), skill, sl->name[0]);
1043 SetSentErrorMessage(true);
1044 return false;
1047 int32 max = max_p ? atol (max_p) : target->GetPureMaxSkillValue(skill);
1049 if( level <= 0 || level > max || max <= 0 )
1050 return false;
1052 target->SetSkill(skill, level, max);
1053 PSendSysMessage(LANG_SET_SKILL, skill, sl->name[0], tNameLink.c_str(), level, max);
1055 return true;
1058 bool ChatHandler::HandleUnLearnCommand(const char* args)
1060 if (!*args)
1061 return false;
1063 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
1064 uint32 spell_id = extractSpellIdFromLink((char*)args);
1065 if(!spell_id)
1066 return false;
1068 char const* allStr = strtok(NULL," ");
1069 bool allRanks = allStr ? (strncmp(allStr, "all", strlen(allStr)) == 0) : false;
1071 Player* target = getSelectedPlayer();
1072 if(!target)
1074 SendSysMessage(LANG_NO_CHAR_SELECTED);
1075 SetSentErrorMessage(true);
1076 return false;
1079 if(allRanks)
1080 spell_id = spellmgr.GetFirstSpellInChain (spell_id);
1082 if (target->HasSpell(spell_id))
1083 target->removeSpell(spell_id,false,!allRanks);
1084 else
1085 SendSysMessage(LANG_FORGET_SPELL);
1087 if(GetTalentSpellCost(spell_id))
1088 target->SendTalentsInfoData(false);
1090 return true;
1093 bool ChatHandler::HandleCooldownCommand(const char* args)
1095 Player* target = getSelectedPlayer();
1096 if(!target)
1098 SendSysMessage(LANG_PLAYER_NOT_FOUND);
1099 SetSentErrorMessage(true);
1100 return false;
1103 std::string tNameLink = GetNameLink(target);
1105 if (!*args)
1107 target->RemoveAllSpellCooldown();
1108 PSendSysMessage(LANG_REMOVEALL_COOLDOWN, tNameLink.c_str());
1110 else
1112 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
1113 uint32 spell_id = extractSpellIdFromLink((char*)args);
1114 if(!spell_id)
1115 return false;
1117 if(!sSpellStore.LookupEntry(spell_id))
1119 PSendSysMessage(LANG_UNKNOWN_SPELL, target==m_session->GetPlayer() ? GetMangosString(LANG_YOU) : tNameLink.c_str());
1120 SetSentErrorMessage(true);
1121 return false;
1124 target->RemoveSpellCooldown(spell_id,true);
1125 PSendSysMessage(LANG_REMOVE_COOLDOWN, spell_id, target==m_session->GetPlayer() ? GetMangosString(LANG_YOU) : tNameLink.c_str());
1127 return true;
1130 bool ChatHandler::HandleLearnAllCommand(const char* /*args*/)
1132 static const char *allSpellList[] =
1134 "3365",
1135 "6233",
1136 "6247",
1137 "6246",
1138 "6477",
1139 "6478",
1140 "22810",
1141 "8386",
1142 "21651",
1143 "21652",
1144 "522",
1145 "7266",
1146 "8597",
1147 "2479",
1148 "22027",
1149 "6603",
1150 "5019",
1151 "133",
1152 "168",
1153 "227",
1154 "5009",
1155 "9078",
1156 "668",
1157 "203",
1158 "20599",
1159 "20600",
1160 "81",
1161 "20597",
1162 "20598",
1163 "20864",
1164 "1459",
1165 "5504",
1166 "587",
1167 "5143",
1168 "118",
1169 "5505",
1170 "597",
1171 "604",
1172 "1449",
1173 "1460",
1174 "2855",
1175 "1008",
1176 "475",
1177 "5506",
1178 "1463",
1179 "12824",
1180 "8437",
1181 "990",
1182 "5145",
1183 "8450",
1184 "1461",
1185 "759",
1186 "8494",
1187 "8455",
1188 "8438",
1189 "6127",
1190 "8416",
1191 "6129",
1192 "8451",
1193 "8495",
1194 "8439",
1195 "3552",
1196 "8417",
1197 "10138",
1198 "12825",
1199 "10169",
1200 "10156",
1201 "10144",
1202 "10191",
1203 "10201",
1204 "10211",
1205 "10053",
1206 "10173",
1207 "10139",
1208 "10145",
1209 "10192",
1210 "10170",
1211 "10202",
1212 "10054",
1213 "10174",
1214 "10193",
1215 "12826",
1216 "2136",
1217 "143",
1218 "145",
1219 "2137",
1220 "2120",
1221 "3140",
1222 "543",
1223 "2138",
1224 "2948",
1225 "8400",
1226 "2121",
1227 "8444",
1228 "8412",
1229 "8457",
1230 "8401",
1231 "8422",
1232 "8445",
1233 "8402",
1234 "8413",
1235 "8458",
1236 "8423",
1237 "8446",
1238 "10148",
1239 "10197",
1240 "10205",
1241 "10149",
1242 "10215",
1243 "10223",
1244 "10206",
1245 "10199",
1246 "10150",
1247 "10216",
1248 "10207",
1249 "10225",
1250 "10151",
1251 "116",
1252 "205",
1253 "7300",
1254 "122",
1255 "837",
1256 "10",
1257 "7301",
1258 "7322",
1259 "6143",
1260 "120",
1261 "865",
1262 "8406",
1263 "6141",
1264 "7302",
1265 "8461",
1266 "8407",
1267 "8492",
1268 "8427",
1269 "8408",
1270 "6131",
1271 "7320",
1272 "10159",
1273 "8462",
1274 "10185",
1275 "10179",
1276 "10160",
1277 "10180",
1278 "10219",
1279 "10186",
1280 "10177",
1281 "10230",
1282 "10181",
1283 "10161",
1284 "10187",
1285 "10220",
1286 "2018",
1287 "2663",
1288 "12260",
1289 "2660",
1290 "3115",
1291 "3326",
1292 "2665",
1293 "3116",
1294 "2738",
1295 "3293",
1296 "2661",
1297 "3319",
1298 "2662",
1299 "9983",
1300 "8880",
1301 "2737",
1302 "2739",
1303 "7408",
1304 "3320",
1305 "2666",
1306 "3323",
1307 "3324",
1308 "3294",
1309 "22723",
1310 "23219",
1311 "23220",
1312 "23221",
1313 "23228",
1314 "23338",
1315 "10788",
1316 "10790",
1317 "5611",
1318 "5016",
1319 "5609",
1320 "2060",
1321 "10963",
1322 "10964",
1323 "10965",
1324 "22593",
1325 "22594",
1326 "596",
1327 "996",
1328 "499",
1329 "768",
1330 "17002",
1331 "1448",
1332 "1082",
1333 "16979",
1334 "1079",
1335 "5215",
1336 "20484",
1337 "5221",
1338 "15590",
1339 "17007",
1340 "6795",
1341 "6807",
1342 "5487",
1343 "1446",
1344 "1066",
1345 "5421",
1346 "3139",
1347 "779",
1348 "6811",
1349 "6808",
1350 "1445",
1351 "5216",
1352 "1737",
1353 "5222",
1354 "5217",
1355 "1432",
1356 "6812",
1357 "9492",
1358 "5210",
1359 "3030",
1360 "1441",
1361 "783",
1362 "6801",
1363 "20739",
1364 "8944",
1365 "9491",
1366 "22569",
1367 "5226",
1368 "6786",
1369 "1433",
1370 "8973",
1371 "1828",
1372 "9495",
1373 "9006",
1374 "6794",
1375 "8993",
1376 "5203",
1377 "16914",
1378 "6784",
1379 "9635",
1380 "22830",
1381 "20722",
1382 "9748",
1383 "6790",
1384 "9753",
1385 "9493",
1386 "9752",
1387 "9831",
1388 "9825",
1389 "9822",
1390 "5204",
1391 "5401",
1392 "22831",
1393 "6793",
1394 "9845",
1395 "17401",
1396 "9882",
1397 "9868",
1398 "20749",
1399 "9893",
1400 "9899",
1401 "9895",
1402 "9832",
1403 "9902",
1404 "9909",
1405 "22832",
1406 "9828",
1407 "9851",
1408 "9883",
1409 "9869",
1410 "17406",
1411 "17402",
1412 "9914",
1413 "20750",
1414 "9897",
1415 "9848",
1416 "3127",
1417 "107",
1418 "204",
1419 "9116",
1420 "2457",
1421 "78",
1422 "18848",
1423 "331",
1424 "403",
1425 "2098",
1426 "1752",
1427 "11278",
1428 "11288",
1429 "11284",
1430 "6461",
1431 "2344",
1432 "2345",
1433 "6463",
1434 "2346",
1435 "2352",
1436 "775",
1437 "1434",
1438 "1612",
1439 "71",
1440 "2468",
1441 "2458",
1442 "2467",
1443 "7164",
1444 "7178",
1445 "7367",
1446 "7376",
1447 "7381",
1448 "21156",
1449 "5209",
1450 "3029",
1451 "5201",
1452 "9849",
1453 "9850",
1454 "20719",
1455 "22568",
1456 "22827",
1457 "22828",
1458 "22829",
1459 "6809",
1460 "8972",
1461 "9005",
1462 "9823",
1463 "9827",
1464 "6783",
1465 "9913",
1466 "6785",
1467 "6787",
1468 "9866",
1469 "9867",
1470 "9894",
1471 "9896",
1472 "6800",
1473 "8992",
1474 "9829",
1475 "9830",
1476 "780",
1477 "769",
1478 "6749",
1479 "6750",
1480 "9755",
1481 "9754",
1482 "9908",
1483 "20745",
1484 "20742",
1485 "20747",
1486 "20748",
1487 "9746",
1488 "9745",
1489 "9880",
1490 "9881",
1491 "5391",
1492 "842",
1493 "3025",
1494 "3031",
1495 "3287",
1496 "3329",
1497 "1945",
1498 "3559",
1499 "4933",
1500 "4934",
1501 "4935",
1502 "4936",
1503 "5142",
1504 "5390",
1505 "5392",
1506 "5404",
1507 "5420",
1508 "6405",
1509 "7293",
1510 "7965",
1511 "8041",
1512 "8153",
1513 "9033",
1514 "9034",
1515 //"9036", problems with ghost state
1516 "16421",
1517 "21653",
1518 "22660",
1519 "5225",
1520 "9846",
1521 "2426",
1522 "5916",
1523 "6634",
1524 //"6718", phasing stealth, annoying for learn all case.
1525 "6719",
1526 "8822",
1527 "9591",
1528 "9590",
1529 "10032",
1530 "17746",
1531 "17747",
1532 "8203",
1533 "11392",
1534 "12495",
1535 "16380",
1536 "23452",
1537 "4079",
1538 "4996",
1539 "4997",
1540 "4998",
1541 "4999",
1542 "5000",
1543 "6348",
1544 "6349",
1545 "6481",
1546 "6482",
1547 "6483",
1548 "6484",
1549 "11362",
1550 "11410",
1551 "11409",
1552 "12510",
1553 "12509",
1554 "12885",
1555 "13142",
1556 "21463",
1557 "23460",
1558 "11421",
1559 "11416",
1560 "11418",
1561 "1851",
1562 "10059",
1563 "11423",
1564 "11417",
1565 "11422",
1566 "11419",
1567 "11424",
1568 "11420",
1569 "27",
1570 "31",
1571 "33",
1572 "34",
1573 "35",
1574 "15125",
1575 "21127",
1576 "22950",
1577 "1180",
1578 "201",
1579 "12593",
1580 "12842",
1581 "16770",
1582 "6057",
1583 "12051",
1584 "18468",
1585 "12606",
1586 "12605",
1587 "18466",
1588 "12502",
1589 "12043",
1590 "15060",
1591 "12042",
1592 "12341",
1593 "12848",
1594 "12344",
1595 "12353",
1596 "18460",
1597 "11366",
1598 "12350",
1599 "12352",
1600 "13043",
1601 "11368",
1602 "11113",
1603 "12400",
1604 "11129",
1605 "16766",
1606 "12573",
1607 "15053",
1608 "12580",
1609 "12475",
1610 "12472",
1611 "12953",
1612 "12488",
1613 "11189",
1614 "12985",
1615 "12519",
1616 "16758",
1617 "11958",
1618 "12490",
1619 "11426",
1620 "3565",
1621 "3562",
1622 "18960",
1623 "3567",
1624 "3561",
1625 "3566",
1626 "3563",
1627 "1953",
1628 "2139",
1629 "12505",
1630 "13018",
1631 "12522",
1632 "12523",
1633 "5146",
1634 "5144",
1635 "5148",
1636 "8419",
1637 "8418",
1638 "10213",
1639 "10212",
1640 "10157",
1641 "12524",
1642 "13019",
1643 "12525",
1644 "13020",
1645 "12526",
1646 "13021",
1647 "18809",
1648 "13031",
1649 "13032",
1650 "13033",
1651 "4036",
1652 "3920",
1653 "3919",
1654 "3918",
1655 "7430",
1656 "3922",
1657 "3923",
1658 "7411",
1659 "7418",
1660 "7421",
1661 "13262",
1662 "7412",
1663 "7415",
1664 "7413",
1665 "7416",
1666 "13920",
1667 "13921",
1668 "7745",
1669 "7779",
1670 "7428",
1671 "7457",
1672 "7857",
1673 "7748",
1674 "7426",
1675 "13421",
1676 "7454",
1677 "13378",
1678 "7788",
1679 "14807",
1680 "14293",
1681 "7795",
1682 "6296",
1683 "20608",
1684 "755",
1685 "444",
1686 "427",
1687 "428",
1688 "442",
1689 "447",
1690 "3578",
1691 "3581",
1692 "19027",
1693 "3580",
1694 "665",
1695 "3579",
1696 "3577",
1697 "6755",
1698 "3576",
1699 "2575",
1700 "2577",
1701 "2578",
1702 "2579",
1703 "2580",
1704 "2656",
1705 "2657",
1706 "2576",
1707 "3564",
1708 "10248",
1709 "8388",
1710 "2659",
1711 "14891",
1712 "3308",
1713 "3307",
1714 "10097",
1715 "2658",
1716 "3569",
1717 "16153",
1718 "3304",
1719 "10098",
1720 "4037",
1721 "3929",
1722 "3931",
1723 "3926",
1724 "3924",
1725 "3930",
1726 "3977",
1727 "3925",
1728 "136",
1729 "228",
1730 "5487",
1731 "43",
1732 "202",
1736 int loop = 0;
1737 while(strcmp(allSpellList[loop], "0"))
1739 uint32 spell = atol((char*)allSpellList[loop++]);
1741 if (m_session->GetPlayer()->HasSpell(spell))
1742 continue;
1744 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
1745 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
1747 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
1748 continue;
1751 m_session->GetPlayer()->learnSpell(spell,false);
1754 SendSysMessage(LANG_COMMAND_LEARN_MANY_SPELLS);
1756 return true;
1759 bool ChatHandler::HandleLearnAllGMCommand(const char* /*args*/)
1761 static const char *gmSpellList[] =
1763 "24347", // Become A Fish, No Breath Bar
1764 "35132", // Visual Boom
1765 "38488", // Attack 4000-8000 AOE
1766 "38795", // Attack 2000 AOE + Slow Down 90%
1767 "15712", // Attack 200
1768 "1852", // GM Spell Silence
1769 "31899", // Kill
1770 "31924", // Kill
1771 "29878", // Kill My Self
1772 "26644", // More Kill
1774 "28550", //Invisible 24
1775 "23452", //Invisible + Target
1779 uint16 gmSpellIter = 0;
1780 while( strcmp(gmSpellList[gmSpellIter], "0") )
1782 uint32 spell = atol((char*)gmSpellList[gmSpellIter++]);
1784 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
1785 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
1787 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
1788 continue;
1791 m_session->GetPlayer()->learnSpell(spell,false);
1794 SendSysMessage(LANG_LEARNING_GM_SKILLS);
1795 return true;
1798 bool ChatHandler::HandleLearnAllMyClassCommand(const char* /*args*/)
1800 HandleLearnAllMySpellsCommand("");
1801 HandleLearnAllMyTalentsCommand("");
1802 return true;
1805 bool ChatHandler::HandleLearnAllMySpellsCommand(const char* /*args*/)
1807 ChrClassesEntry const* clsEntry = sChrClassesStore.LookupEntry(m_session->GetPlayer()->getClass());
1808 if(!clsEntry)
1809 return true;
1810 uint32 family = clsEntry->spellfamily;
1812 for (uint32 i = 0; i < sSpellStore.GetNumRows(); ++i)
1814 SpellEntry const *spellInfo = sSpellStore.LookupEntry(i);
1815 if(!spellInfo)
1816 continue;
1818 // skip server-side/triggered spells
1819 if(spellInfo->spellLevel==0)
1820 continue;
1822 // skip wrong class/race skills
1823 if(!m_session->GetPlayer()->IsSpellFitByClassAndRace(spellInfo->Id))
1824 continue;
1826 // skip other spell families
1827 if( spellInfo->SpellFamilyName != family)
1828 continue;
1830 // skip spells with first rank learned as talent (and all talents then also)
1831 uint32 first_rank = spellmgr.GetFirstSpellInChain(spellInfo->Id);
1832 if(GetTalentSpellCost(first_rank) > 0 )
1833 continue;
1835 // skip broken spells
1836 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
1837 continue;
1839 m_session->GetPlayer()->learnSpell(i,false);
1842 SendSysMessage(LANG_COMMAND_LEARN_CLASS_SPELLS);
1843 return true;
1846 bool ChatHandler::HandleLearnAllMyTalentsCommand(const char* /*args*/)
1848 Player* player = m_session->GetPlayer();
1849 uint32 classMask = player->getClassMask();
1851 for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
1853 TalentEntry const *talentInfo = sTalentStore.LookupEntry(i);
1854 if(!talentInfo)
1855 continue;
1857 TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab );
1858 if(!talentTabInfo)
1859 continue;
1861 if( (classMask & talentTabInfo->ClassMask) == 0 )
1862 continue;
1864 // search highest talent rank
1865 uint32 spellid = 0;
1867 for(int rank = MAX_TALENT_RANK-1; rank >= 0; --rank)
1869 if(talentInfo->RankID[rank]!=0)
1871 spellid = talentInfo->RankID[rank];
1872 break;
1876 if(!spellid) // ??? none spells in talent
1877 continue;
1879 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid);
1880 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
1881 continue;
1883 // learn highest rank of talent and learn all non-talent spell ranks (recursive by tree)
1884 player->learnSpellHighRank(spellid);
1887 SendSysMessage(LANG_COMMAND_LEARN_CLASS_TALENTS);
1888 return true;
1891 bool ChatHandler::HandleLearnAllMyPetTalentsCommand(const char* /*args*/)
1893 Player* player = m_session->GetPlayer();
1895 Pet* pet = player->GetPet();
1896 if(!pet)
1898 SendSysMessage(LANG_NO_PET_FOUND);
1899 SetSentErrorMessage(true);
1900 return false;
1903 CreatureInfo const *ci = pet->GetCreatureInfo();
1904 if(!ci)
1906 SendSysMessage(LANG_WRONG_PET_TYPE);
1907 SetSentErrorMessage(true);
1908 return false;
1911 CreatureFamilyEntry const *pet_family = sCreatureFamilyStore.LookupEntry(ci->family);
1912 if(!pet_family)
1914 SendSysMessage(LANG_WRONG_PET_TYPE);
1915 SetSentErrorMessage(true);
1916 return false;
1919 if(pet_family->petTalentType < 0) // not hunter pet
1921 SendSysMessage(LANG_WRONG_PET_TYPE);
1922 SetSentErrorMessage(true);
1923 return false;
1926 for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
1928 TalentEntry const *talentInfo = sTalentStore.LookupEntry(i);
1929 if(!talentInfo)
1930 continue;
1932 TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab );
1933 if(!talentTabInfo)
1934 continue;
1936 // prevent learn talent for different family (cheating)
1937 if(((1 << pet_family->petTalentType) & talentTabInfo->petTalentMask)==0)
1938 continue;
1940 // search highest talent rank
1941 uint32 spellid = 0;
1943 for(int rank = MAX_TALENT_RANK-1; rank >= 0; --rank)
1945 if(talentInfo->RankID[rank]!=0)
1947 spellid = talentInfo->RankID[rank];
1948 break;
1952 if(!spellid) // ??? none spells in talent
1953 continue;
1955 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid);
1956 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
1957 continue;
1959 // learn highest rank of talent and learn all non-talent spell ranks (recursive by tree)
1960 pet->learnSpellHighRank(spellid);
1963 SendSysMessage(LANG_COMMAND_LEARN_PET_TALENTS);
1964 return true;
1967 bool ChatHandler::HandleLearnAllLangCommand(const char* /*args*/)
1969 // skipping UNIVERSAL language (0)
1970 for(int i = 1; i < LANGUAGES_COUNT; ++i)
1971 m_session->GetPlayer()->learnSpell(lang_description[i].spell_id,false);
1973 SendSysMessage(LANG_COMMAND_LEARN_ALL_LANG);
1974 return true;
1977 bool ChatHandler::HandleLearnAllDefaultCommand(const char* args)
1979 Player* target;
1980 if(!extractPlayerTarget((char*)args,&target))
1981 return false;
1983 target->learnDefaultSpells();
1984 target->learnQuestRewardedSpells();
1986 PSendSysMessage(LANG_COMMAND_LEARN_ALL_DEFAULT_AND_QUEST,GetNameLink(target).c_str());
1987 return true;
1990 bool ChatHandler::HandleLearnCommand(const char* args)
1992 Player* targetPlayer = getSelectedPlayer();
1994 if(!targetPlayer)
1996 SendSysMessage(LANG_PLAYER_NOT_FOUND);
1997 SetSentErrorMessage(true);
1998 return false;
2001 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
2002 uint32 spell = extractSpellIdFromLink((char*)args);
2003 if(!spell || !sSpellStore.LookupEntry(spell))
2004 return false;
2006 char const* allStr = strtok(NULL," ");
2007 bool allRanks = allStr ? (strncmp(allStr, "all", strlen(allStr)) == 0) : false;
2009 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
2010 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
2012 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
2013 SetSentErrorMessage(true);
2014 return false;
2017 if (!allRanks && targetPlayer->HasSpell(spell))
2019 if(targetPlayer == m_session->GetPlayer())
2020 SendSysMessage(LANG_YOU_KNOWN_SPELL);
2021 else
2022 PSendSysMessage(LANG_TARGET_KNOWN_SPELL,GetNameLink(targetPlayer).c_str());
2023 SetSentErrorMessage(true);
2024 return false;
2027 if(allRanks)
2028 targetPlayer->learnSpellHighRank(spell);
2029 else
2030 targetPlayer->learnSpell(spell,false);
2032 uint32 first_spell = spellmgr.GetFirstSpellInChain(spell);
2033 if(GetTalentSpellCost(first_spell))
2034 targetPlayer->SendTalentsInfoData(false);
2036 return true;
2039 bool ChatHandler::HandleAddItemCommand(const char* args)
2041 if (!*args)
2042 return false;
2044 uint32 itemId = 0;
2046 if(args[0]=='[') // [name] manual form
2048 char* citemName = strtok((char*)args, "]");
2050 if(citemName && citemName[0])
2052 std::string itemName = citemName+1;
2053 WorldDatabase.escape_string(itemName);
2054 QueryResult *result = WorldDatabase.PQuery("SELECT entry FROM item_template WHERE name = '%s'", itemName.c_str());
2055 if (!result)
2057 PSendSysMessage(LANG_COMMAND_COULDNOTFIND, citemName+1);
2058 SetSentErrorMessage(true);
2059 return false;
2061 itemId = result->Fetch()->GetUInt16();
2062 delete result;
2064 else
2065 return false;
2067 else // item_id or [name] Shift-click form |color|Hitem:item_id:0:0:0|h[name]|h|r
2069 char* cId = extractKeyFromLink((char*)args,"Hitem");
2070 if(!cId)
2071 return false;
2072 itemId = atol(cId);
2075 char* ccount = strtok(NULL, " ");
2077 int32 count = 1;
2079 if (ccount)
2080 count = strtol(ccount, NULL, 10);
2082 if (count == 0)
2083 count = 1;
2085 Player* pl = m_session->GetPlayer();
2086 Player* plTarget = getSelectedPlayer();
2087 if(!plTarget)
2088 plTarget = pl;
2090 sLog.outDetail(GetMangosString(LANG_ADDITEM), itemId, count);
2092 ItemPrototype const *pProto = objmgr.GetItemPrototype(itemId);
2093 if(!pProto)
2095 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId);
2096 SetSentErrorMessage(true);
2097 return false;
2100 //Subtract
2101 if (count < 0)
2103 plTarget->DestroyItemCount(itemId, -count, true, false);
2104 PSendSysMessage(LANG_REMOVEITEM, itemId, -count, GetNameLink(plTarget).c_str());
2105 return true;
2108 //Adding items
2109 uint32 noSpaceForCount = 0;
2111 // check space and find places
2112 ItemPosCountVec dest;
2113 uint8 msg = plTarget->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, itemId, count, &noSpaceForCount );
2114 if( msg != EQUIP_ERR_OK ) // convert to possible store amount
2115 count -= noSpaceForCount;
2117 if( count == 0 || dest.empty()) // can't add any
2119 PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount );
2120 SetSentErrorMessage(true);
2121 return false;
2124 Item* item = plTarget->StoreNewItem( dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId));
2126 // remove binding (let GM give it to another player later)
2127 if(pl==plTarget)
2128 for(ItemPosCountVec::const_iterator itr = dest.begin(); itr != dest.end(); ++itr)
2129 if(Item* item1 = pl->GetItemByPos(itr->pos))
2130 item1->SetBinding( false );
2132 if(count > 0 && item)
2134 pl->SendNewItem(item,count,false,true);
2135 if(pl!=plTarget)
2136 plTarget->SendNewItem(item,count,true,false);
2139 if(noSpaceForCount > 0)
2140 PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount);
2142 return true;
2145 bool ChatHandler::HandleAddItemSetCommand(const char* args)
2147 if (!*args)
2148 return false;
2150 char* cId = extractKeyFromLink((char*)args,"Hitemset"); // number or [name] Shift-click form |color|Hitemset:itemset_id|h[name]|h|r
2151 if (!cId)
2152 return false;
2154 uint32 itemsetId = atol(cId);
2156 // prevent generation all items with itemset field value '0'
2157 if (itemsetId == 0)
2159 PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND,itemsetId);
2160 SetSentErrorMessage(true);
2161 return false;
2164 Player* pl = m_session->GetPlayer();
2165 Player* plTarget = getSelectedPlayer();
2166 if(!plTarget)
2167 plTarget = pl;
2169 sLog.outDetail(GetMangosString(LANG_ADDITEMSET), itemsetId);
2171 bool found = false;
2172 for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
2174 ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype>(id);
2175 if (!pProto)
2176 continue;
2178 if (pProto->ItemSet == itemsetId)
2180 found = true;
2181 ItemPosCountVec dest;
2182 uint8 msg = plTarget->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, pProto->ItemId, 1 );
2183 if (msg == EQUIP_ERR_OK)
2185 Item* item = plTarget->StoreNewItem( dest, pProto->ItemId, true);
2187 // remove binding (let GM give it to another player later)
2188 if (pl==plTarget)
2189 item->SetBinding( false );
2191 pl->SendNewItem(item,1,false,true);
2192 if (pl!=plTarget)
2193 plTarget->SendNewItem(item,1,true,false);
2195 else
2197 pl->SendEquipError( msg, NULL, NULL );
2198 PSendSysMessage(LANG_ITEM_CANNOT_CREATE, pProto->ItemId, 1);
2203 if (!found)
2205 PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND,itemsetId);
2207 SetSentErrorMessage(true);
2208 return false;
2211 return true;
2214 bool ChatHandler::HandleListItemCommand(const char* args)
2216 if(!*args)
2217 return false;
2219 char* cId = extractKeyFromLink((char*)args,"Hitem");
2220 if(!cId)
2221 return false;
2223 uint32 item_id = atol(cId);
2224 if(!item_id)
2226 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
2227 SetSentErrorMessage(true);
2228 return false;
2231 ItemPrototype const* itemProto = objmgr.GetItemPrototype(item_id);
2232 if(!itemProto)
2234 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
2235 SetSentErrorMessage(true);
2236 return false;
2239 char* c_count = strtok(NULL, " ");
2240 int count = c_count ? atol(c_count) : 10;
2242 if(count < 0)
2243 return false;
2245 QueryResult *result;
2247 // inventory case
2248 uint32 inv_count = 0;
2249 result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM character_inventory WHERE item_template='%u'",item_id);
2250 if(result)
2252 inv_count = (*result)[0].GetUInt32();
2253 delete result;
2256 result=CharacterDatabase.PQuery(
2257 // 0 1 2 3 4 5
2258 "SELECT ci.item, cibag.slot AS bag, ci.slot, ci.guid, characters.account,characters.name "
2259 "FROM character_inventory AS ci LEFT JOIN character_inventory AS cibag ON (cibag.item=ci.bag),characters "
2260 "WHERE ci.item_template='%u' AND ci.guid = characters.guid LIMIT %u ",
2261 item_id,uint32(count));
2263 if(result)
2267 Field *fields = result->Fetch();
2268 uint32 item_guid = fields[0].GetUInt32();
2269 uint32 item_bag = fields[1].GetUInt32();
2270 uint32 item_slot = fields[2].GetUInt32();
2271 uint32 owner_guid = fields[3].GetUInt32();
2272 uint32 owner_acc = fields[4].GetUInt32();
2273 std::string owner_name = fields[5].GetCppString();
2275 char const* item_pos = 0;
2276 if(Player::IsEquipmentPos(item_bag,item_slot))
2277 item_pos = "[equipped]";
2278 else if(Player::IsInventoryPos(item_bag,item_slot))
2279 item_pos = "[in inventory]";
2280 else if(Player::IsBankPos(item_bag,item_slot))
2281 item_pos = "[in bank]";
2282 else
2283 item_pos = "";
2285 PSendSysMessage(LANG_ITEMLIST_SLOT,
2286 item_guid,owner_name.c_str(),owner_guid,owner_acc,item_pos);
2287 } while (result->NextRow());
2289 int64 res_count = result->GetRowCount();
2291 delete result;
2293 if(count > res_count)
2294 count-=res_count;
2295 else if(count)
2296 count = 0;
2299 // mail case
2300 uint32 mail_count = 0;
2301 result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM mail_items WHERE item_template='%u'", item_id);
2302 if(result)
2304 mail_count = (*result)[0].GetUInt32();
2305 delete result;
2308 if(count > 0)
2310 result=CharacterDatabase.PQuery(
2311 // 0 1 2 3 4 5 6
2312 "SELECT mail_items.item_guid, mail.sender, mail.receiver, char_s.account, char_s.name, char_r.account, char_r.name "
2313 "FROM mail,mail_items,characters as char_s,characters as char_r "
2314 "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",
2315 item_id,uint32(count));
2317 else
2318 result = NULL;
2320 if(result)
2324 Field *fields = result->Fetch();
2325 uint32 item_guid = fields[0].GetUInt32();
2326 uint32 item_s = fields[1].GetUInt32();
2327 uint32 item_r = fields[2].GetUInt32();
2328 uint32 item_s_acc = fields[3].GetUInt32();
2329 std::string item_s_name = fields[4].GetCppString();
2330 uint32 item_r_acc = fields[5].GetUInt32();
2331 std::string item_r_name = fields[6].GetCppString();
2333 char const* item_pos = "[in mail]";
2335 PSendSysMessage(LANG_ITEMLIST_MAIL,
2336 item_guid,item_s_name.c_str(),item_s,item_s_acc,item_r_name.c_str(),item_r,item_r_acc,item_pos);
2337 } while (result->NextRow());
2339 int64 res_count = result->GetRowCount();
2341 delete result;
2343 if(count > res_count)
2344 count-=res_count;
2345 else if(count)
2346 count = 0;
2349 // auction case
2350 uint32 auc_count = 0;
2351 result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM auctionhouse WHERE item_template='%u'",item_id);
2352 if(result)
2354 auc_count = (*result)[0].GetUInt32();
2355 delete result;
2358 if(count > 0)
2360 result=CharacterDatabase.PQuery(
2361 // 0 1 2 3
2362 "SELECT auctionhouse.itemguid, auctionhouse.itemowner, characters.account, characters.name "
2363 "FROM auctionhouse,characters WHERE auctionhouse.item_template='%u' AND characters.guid = auctionhouse.itemowner LIMIT %u",
2364 item_id,uint32(count));
2366 else
2367 result = NULL;
2369 if(result)
2373 Field *fields = result->Fetch();
2374 uint32 item_guid = fields[0].GetUInt32();
2375 uint32 owner = fields[1].GetUInt32();
2376 uint32 owner_acc = fields[2].GetUInt32();
2377 std::string owner_name = fields[3].GetCppString();
2379 char const* item_pos = "[in auction]";
2381 PSendSysMessage(LANG_ITEMLIST_AUCTION, item_guid, owner_name.c_str(), owner, owner_acc,item_pos);
2382 } while (result->NextRow());
2384 delete result;
2387 // guild bank case
2388 uint32 guild_count = 0;
2389 result=CharacterDatabase.PQuery("SELECT COUNT(item_entry) FROM guild_bank_item WHERE item_entry='%u'",item_id);
2390 if(result)
2392 guild_count = (*result)[0].GetUInt32();
2393 delete result;
2396 result=CharacterDatabase.PQuery(
2397 // 0 1 2
2398 "SELECT gi.item_guid, gi.guildid, guild.name "
2399 "FROM guild_bank_item AS gi, guild WHERE gi.item_entry='%u' AND gi.guildid = guild.guildid LIMIT %u ",
2400 item_id,uint32(count));
2402 if(result)
2406 Field *fields = result->Fetch();
2407 uint32 item_guid = fields[0].GetUInt32();
2408 uint32 guild_guid = fields[1].GetUInt32();
2409 std::string guild_name = fields[2].GetCppString();
2411 char const* item_pos = "[in guild bank]";
2413 PSendSysMessage(LANG_ITEMLIST_GUILD,item_guid,guild_name.c_str(),guild_guid,item_pos);
2414 } while (result->NextRow());
2416 int64 res_count = result->GetRowCount();
2418 delete result;
2420 if(count > res_count)
2421 count-=res_count;
2422 else if(count)
2423 count = 0;
2426 if(inv_count+mail_count+auc_count+guild_count == 0)
2428 SendSysMessage(LANG_COMMAND_NOITEMFOUND);
2429 SetSentErrorMessage(true);
2430 return false;
2433 PSendSysMessage(LANG_COMMAND_LISTITEMMESSAGE,item_id,inv_count+mail_count+auc_count+guild_count,inv_count,mail_count,auc_count,guild_count);
2435 return true;
2438 bool ChatHandler::HandleListObjectCommand(const char* args)
2440 if(!*args)
2441 return false;
2443 // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r
2444 char* cId = extractKeyFromLink((char*)args,"Hgameobject_entry");
2445 if(!cId)
2446 return false;
2448 uint32 go_id = atol(cId);
2449 if(!go_id)
2451 PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id);
2452 SetSentErrorMessage(true);
2453 return false;
2456 GameObjectInfo const * gInfo = objmgr.GetGameObjectInfo(go_id);
2457 if(!gInfo)
2459 PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id);
2460 SetSentErrorMessage(true);
2461 return false;
2464 char* c_count = strtok(NULL, " ");
2465 int count = c_count ? atol(c_count) : 10;
2467 if(count < 0)
2468 return false;
2470 QueryResult *result;
2472 uint32 obj_count = 0;
2473 result=WorldDatabase.PQuery("SELECT COUNT(guid) FROM gameobject WHERE id='%u'",go_id);
2474 if(result)
2476 obj_count = (*result)[0].GetUInt32();
2477 delete result;
2480 if(m_session)
2482 Player* pl = m_session->GetPlayer();
2483 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",
2484 pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),go_id,uint32(count));
2486 else
2487 result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map FROM gameobject WHERE id = '%u' LIMIT %u",
2488 go_id,uint32(count));
2490 if (result)
2494 Field *fields = result->Fetch();
2495 uint32 guid = fields[0].GetUInt32();
2496 float x = fields[1].GetFloat();
2497 float y = fields[2].GetFloat();
2498 float z = fields[3].GetFloat();
2499 int mapid = fields[4].GetUInt16();
2501 if (m_session)
2502 PSendSysMessage(LANG_GO_LIST_CHAT, guid, guid, gInfo->name, x, y, z, mapid);
2503 else
2504 PSendSysMessage(LANG_GO_LIST_CONSOLE, guid, gInfo->name, x, y, z, mapid);
2505 } while (result->NextRow());
2507 delete result;
2510 PSendSysMessage(LANG_COMMAND_LISTOBJMESSAGE,go_id,obj_count);
2511 return true;
2514 bool ChatHandler::HandleListCreatureCommand(const char* args)
2516 if(!*args)
2517 return false;
2519 // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
2520 char* cId = extractKeyFromLink((char*)args,"Hcreature_entry");
2521 if(!cId)
2522 return false;
2524 uint32 cr_id = atol(cId);
2525 if(!cr_id)
2527 PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id);
2528 SetSentErrorMessage(true);
2529 return false;
2532 CreatureInfo const* cInfo = objmgr.GetCreatureTemplate(cr_id);
2533 if(!cInfo)
2535 PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id);
2536 SetSentErrorMessage(true);
2537 return false;
2540 char* c_count = strtok(NULL, " ");
2541 int count = c_count ? atol(c_count) : 10;
2543 if(count < 0)
2544 return false;
2546 QueryResult *result;
2548 uint32 cr_count = 0;
2549 result=WorldDatabase.PQuery("SELECT COUNT(guid) FROM creature WHERE id='%u'",cr_id);
2550 if(result)
2552 cr_count = (*result)[0].GetUInt32();
2553 delete result;
2556 if(m_session)
2558 Player* pl = m_session->GetPlayer();
2559 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",
2560 pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), cr_id,uint32(count));
2562 else
2563 result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map FROM creature WHERE id = '%u' LIMIT %u",
2564 cr_id,uint32(count));
2566 if (result)
2570 Field *fields = result->Fetch();
2571 uint32 guid = fields[0].GetUInt32();
2572 float x = fields[1].GetFloat();
2573 float y = fields[2].GetFloat();
2574 float z = fields[3].GetFloat();
2575 int mapid = fields[4].GetUInt16();
2577 if (m_session)
2578 PSendSysMessage(LANG_CREATURE_LIST_CHAT, guid, guid, cInfo->Name, x, y, z, mapid);
2579 else
2580 PSendSysMessage(LANG_CREATURE_LIST_CONSOLE, guid, cInfo->Name, x, y, z, mapid);
2581 } while (result->NextRow());
2583 delete result;
2586 PSendSysMessage(LANG_COMMAND_LISTCREATUREMESSAGE,cr_id,cr_count);
2587 return true;
2590 bool ChatHandler::HandleLookupItemCommand(const char* args)
2592 if(!*args)
2593 return false;
2595 std::string namepart = args;
2596 std::wstring wnamepart;
2598 // converting string that we try to find to lower case
2599 if(!Utf8toWStr(namepart,wnamepart))
2600 return false;
2602 wstrToLower(wnamepart);
2604 uint32 counter = 0;
2606 // Search in `item_template`
2607 for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
2609 ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype >(id);
2610 if(!pProto)
2611 continue;
2613 int loc_idx = GetSessionDbLocaleIndex();
2614 if ( loc_idx >= 0 )
2616 ItemLocale const *il = objmgr.GetItemLocale(pProto->ItemId);
2617 if (il)
2619 if (il->Name.size() > loc_idx && !il->Name[loc_idx].empty())
2621 std::string name = il->Name[loc_idx];
2623 if (Utf8FitTo(name, wnamepart))
2625 if (m_session)
2626 PSendSysMessage(LANG_ITEM_LIST_CHAT, id, id, name.c_str());
2627 else
2628 PSendSysMessage(LANG_ITEM_LIST_CONSOLE, id, name.c_str());
2629 ++counter;
2630 continue;
2636 std::string name = pProto->Name1;
2637 if(name.empty())
2638 continue;
2640 if (Utf8FitTo(name, wnamepart))
2642 if (m_session)
2643 PSendSysMessage(LANG_ITEM_LIST_CHAT, id, id, name.c_str());
2644 else
2645 PSendSysMessage(LANG_ITEM_LIST_CONSOLE, id, name.c_str());
2646 ++counter;
2650 if (counter==0)
2651 SendSysMessage(LANG_COMMAND_NOITEMFOUND);
2653 return true;
2656 bool ChatHandler::HandleLookupItemSetCommand(const char* args)
2658 if(!*args)
2659 return false;
2661 std::string namepart = args;
2662 std::wstring wnamepart;
2664 if(!Utf8toWStr(namepart,wnamepart))
2665 return false;
2667 // converting string that we try to find to lower case
2668 wstrToLower( wnamepart );
2670 uint32 counter = 0; // Counter for figure out that we found smth.
2672 // Search in ItemSet.dbc
2673 for (uint32 id = 0; id < sItemSetStore.GetNumRows(); id++)
2675 ItemSetEntry const *set = sItemSetStore.LookupEntry(id);
2676 if(set)
2678 int loc = GetSessionDbcLocale();
2679 std::string name = set->name[loc];
2680 if(name.empty())
2681 continue;
2683 if (!Utf8FitTo(name, wnamepart))
2685 loc = 0;
2686 for(; loc < MAX_LOCALE; ++loc)
2688 if(loc==GetSessionDbcLocale())
2689 continue;
2691 name = set->name[loc];
2692 if(name.empty())
2693 continue;
2695 if (Utf8FitTo(name, wnamepart))
2696 break;
2700 if(loc < MAX_LOCALE)
2702 // send item set in "id - [namedlink locale]" format
2703 if (m_session)
2704 PSendSysMessage(LANG_ITEMSET_LIST_CHAT,id,id,name.c_str(),localeNames[loc]);
2705 else
2706 PSendSysMessage(LANG_ITEMSET_LIST_CONSOLE,id,name.c_str(),localeNames[loc]);
2707 ++counter;
2711 if (counter == 0) // if counter == 0 then we found nth
2712 SendSysMessage(LANG_COMMAND_NOITEMSETFOUND);
2713 return true;
2716 bool ChatHandler::HandleLookupSkillCommand(const char* args)
2718 if(!*args)
2719 return false;
2721 // can be NULL in console call
2722 Player* target = getSelectedPlayer();
2724 std::string namepart = args;
2725 std::wstring wnamepart;
2727 if(!Utf8toWStr(namepart,wnamepart))
2728 return false;
2730 // converting string that we try to find to lower case
2731 wstrToLower( wnamepart );
2733 uint32 counter = 0; // Counter for figure out that we found smth.
2735 // Search in SkillLine.dbc
2736 for (uint32 id = 0; id < sSkillLineStore.GetNumRows(); id++)
2738 SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(id);
2739 if(skillInfo)
2741 int loc = GetSessionDbcLocale();
2742 std::string name = skillInfo->name[loc];
2743 if(name.empty())
2744 continue;
2746 if (!Utf8FitTo(name, wnamepart))
2748 loc = 0;
2749 for(; loc < MAX_LOCALE; ++loc)
2751 if(loc==GetSessionDbcLocale())
2752 continue;
2754 name = skillInfo->name[loc];
2755 if(name.empty())
2756 continue;
2758 if (Utf8FitTo(name, wnamepart))
2759 break;
2763 if(loc < MAX_LOCALE)
2765 char valStr[50] = "";
2766 char const* knownStr = "";
2767 if(target && target->HasSkill(id))
2769 knownStr = GetMangosString(LANG_KNOWN);
2770 uint32 curValue = target->GetPureSkillValue(id);
2771 uint32 maxValue = target->GetPureMaxSkillValue(id);
2772 uint32 permValue = target->GetSkillPermBonusValue(id);
2773 uint32 tempValue = target->GetSkillTempBonusValue(id);
2775 char const* valFormat = GetMangosString(LANG_SKILL_VALUES);
2776 snprintf(valStr,50,valFormat,curValue,maxValue,permValue,tempValue);
2779 // send skill in "id - [namedlink locale]" format
2780 if (m_session)
2781 PSendSysMessage(LANG_SKILL_LIST_CHAT,id,id,name.c_str(),localeNames[loc],knownStr,valStr);
2782 else
2783 PSendSysMessage(LANG_SKILL_LIST_CONSOLE,id,name.c_str(),localeNames[loc],knownStr,valStr);
2785 ++counter;
2789 if (counter == 0) // if counter == 0 then we found nth
2790 SendSysMessage(LANG_COMMAND_NOSKILLFOUND);
2791 return true;
2794 bool ChatHandler::HandleLookupSpellCommand(const char* args)
2796 if(!*args)
2797 return false;
2799 // can be NULL at console call
2800 Player* target = getSelectedPlayer();
2802 std::string namepart = args;
2803 std::wstring wnamepart;
2805 if(!Utf8toWStr(namepart,wnamepart))
2806 return false;
2808 // converting string that we try to find to lower case
2809 wstrToLower( wnamepart );
2811 uint32 counter = 0; // Counter for figure out that we found smth.
2813 // Search in Spell.dbc
2814 for (uint32 id = 0; id < sSpellStore.GetNumRows(); id++)
2816 SpellEntry const *spellInfo = sSpellStore.LookupEntry(id);
2817 if(spellInfo)
2819 int loc = GetSessionDbcLocale();
2820 std::string name = spellInfo->SpellName[loc];
2821 if(name.empty())
2822 continue;
2824 if (!Utf8FitTo(name, wnamepart))
2826 loc = 0;
2827 for(; loc < MAX_LOCALE; ++loc)
2829 if(loc==GetSessionDbcLocale())
2830 continue;
2832 name = spellInfo->SpellName[loc];
2833 if(name.empty())
2834 continue;
2836 if (Utf8FitTo(name, wnamepart))
2837 break;
2841 if(loc < MAX_LOCALE)
2843 bool known = target && target->HasSpell(id);
2844 bool learn = (spellInfo->Effect[0] == SPELL_EFFECT_LEARN_SPELL);
2846 uint32 talentCost = GetTalentSpellCost(id);
2848 bool talent = (talentCost > 0);
2849 bool passive = IsPassiveSpell(id);
2850 bool active = target && target->HasAura(id);
2852 // unit32 used to prevent interpreting uint8 as char at output
2853 // find rank of learned spell for learning spell, or talent rank
2854 uint32 rank = talentCost ? talentCost : spellmgr.GetSpellRank(learn ? spellInfo->EffectTriggerSpell[0] : id);
2856 // send spell in "id - [name, rank N] [talent] [passive] [learn] [known]" format
2857 std::ostringstream ss;
2858 if (m_session)
2859 ss << id << " - |cffffffff|Hspell:" << id << "|h[" << name;
2860 else
2861 ss << id << " - " << name;
2863 // include rank in link name
2864 if(rank)
2865 ss << GetMangosString(LANG_SPELL_RANK) << rank;
2867 if (m_session)
2868 ss << " " << localeNames[loc] << "]|h|r";
2869 else
2870 ss << " " << localeNames[loc];
2872 if(talent)
2873 ss << GetMangosString(LANG_TALENT);
2874 if(passive)
2875 ss << GetMangosString(LANG_PASSIVE);
2876 if(learn)
2877 ss << GetMangosString(LANG_LEARN);
2878 if(known)
2879 ss << GetMangosString(LANG_KNOWN);
2880 if(active)
2881 ss << GetMangosString(LANG_ACTIVE);
2883 SendSysMessage(ss.str().c_str());
2885 ++counter;
2889 if (counter == 0) // if counter == 0 then we found nth
2890 SendSysMessage(LANG_COMMAND_NOSPELLFOUND);
2891 return true;
2894 bool ChatHandler::HandleLookupQuestCommand(const char* args)
2896 if(!*args)
2897 return false;
2899 // can be NULL at console call
2900 Player* target = getSelectedPlayer();
2902 std::string namepart = args;
2903 std::wstring wnamepart;
2905 // converting string that we try to find to lower case
2906 if(!Utf8toWStr(namepart,wnamepart))
2907 return false;
2909 wstrToLower(wnamepart);
2911 uint32 counter = 0 ;
2913 ObjectMgr::QuestMap const& qTemplates = objmgr.GetQuestTemplates();
2914 for (ObjectMgr::QuestMap::const_iterator iter = qTemplates.begin(); iter != qTemplates.end(); ++iter)
2916 Quest * qinfo = iter->second;
2918 int loc_idx = GetSessionDbLocaleIndex();
2919 if ( loc_idx >= 0 )
2921 QuestLocale const *il = objmgr.GetQuestLocale(qinfo->GetQuestId());
2922 if (il)
2924 if (il->Title.size() > loc_idx && !il->Title[loc_idx].empty())
2926 std::string title = il->Title[loc_idx];
2928 if (Utf8FitTo(title, wnamepart))
2930 char const* statusStr = "";
2932 if(target)
2934 QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId());
2936 if(status == QUEST_STATUS_COMPLETE)
2938 if(target->GetQuestRewardStatus(qinfo->GetQuestId()))
2939 statusStr = GetMangosString(LANG_COMMAND_QUEST_REWARDED);
2940 else
2941 statusStr = GetMangosString(LANG_COMMAND_QUEST_COMPLETE);
2943 else if(status == QUEST_STATUS_INCOMPLETE)
2944 statusStr = GetMangosString(LANG_COMMAND_QUEST_ACTIVE);
2947 if (m_session)
2948 PSendSysMessage(LANG_QUEST_LIST_CHAT,qinfo->GetQuestId(),qinfo->GetQuestId(),qinfo->GetQuestLevel(),title.c_str(),statusStr);
2949 else
2950 PSendSysMessage(LANG_QUEST_LIST_CONSOLE,qinfo->GetQuestId(),title.c_str(),statusStr);
2951 ++counter;
2952 continue;
2958 std::string title = qinfo->GetTitle();
2959 if(title.empty())
2960 continue;
2962 if (Utf8FitTo(title, wnamepart))
2964 char const* statusStr = "";
2966 if(target)
2968 QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId());
2970 if(status == QUEST_STATUS_COMPLETE)
2972 if(target->GetQuestRewardStatus(qinfo->GetQuestId()))
2973 statusStr = GetMangosString(LANG_COMMAND_QUEST_REWARDED);
2974 else
2975 statusStr = GetMangosString(LANG_COMMAND_QUEST_COMPLETE);
2977 else if(status == QUEST_STATUS_INCOMPLETE)
2978 statusStr = GetMangosString(LANG_COMMAND_QUEST_ACTIVE);
2981 if (m_session)
2982 PSendSysMessage(LANG_QUEST_LIST_CHAT,qinfo->GetQuestId(),qinfo->GetQuestId(),qinfo->GetQuestLevel(),title.c_str(),statusStr);
2983 else
2984 PSendSysMessage(LANG_QUEST_LIST_CONSOLE,qinfo->GetQuestId(),title.c_str(),statusStr);
2986 ++counter;
2990 if (counter==0)
2991 SendSysMessage(LANG_COMMAND_NOQUESTFOUND);
2993 return true;
2996 bool ChatHandler::HandleLookupCreatureCommand(const char* args)
2998 if (!*args)
2999 return false;
3001 std::string namepart = args;
3002 std::wstring wnamepart;
3004 // converting string that we try to find to lower case
3005 if (!Utf8toWStr (namepart,wnamepart))
3006 return false;
3008 wstrToLower (wnamepart);
3010 uint32 counter = 0;
3012 for (uint32 id = 0; id< sCreatureStorage.MaxEntry; ++id)
3014 CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo> (id);
3015 if(!cInfo)
3016 continue;
3018 int loc_idx = GetSessionDbLocaleIndex();
3019 if (loc_idx >= 0)
3021 CreatureLocale const *cl = objmgr.GetCreatureLocale (id);
3022 if (cl)
3024 if (cl->Name.size() > loc_idx && !cl->Name[loc_idx].empty ())
3026 std::string name = cl->Name[loc_idx];
3028 if (Utf8FitTo (name, wnamepart))
3030 if (m_session)
3031 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CHAT, id, id, name.c_str ());
3032 else
3033 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CONSOLE, id, name.c_str ());
3034 ++counter;
3035 continue;
3041 std::string name = cInfo->Name;
3042 if (name.empty ())
3043 continue;
3045 if (Utf8FitTo(name, wnamepart))
3047 if (m_session)
3048 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CHAT, id, id, name.c_str ());
3049 else
3050 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CONSOLE, id, name.c_str ());
3051 ++counter;
3055 if (counter==0)
3056 SendSysMessage (LANG_COMMAND_NOCREATUREFOUND);
3058 return true;
3061 bool ChatHandler::HandleLookupObjectCommand(const char* args)
3063 if(!*args)
3064 return false;
3066 std::string namepart = args;
3067 std::wstring wnamepart;
3069 // converting string that we try to find to lower case
3070 if(!Utf8toWStr(namepart,wnamepart))
3071 return false;
3073 wstrToLower(wnamepart);
3075 uint32 counter = 0;
3077 for (uint32 id = 0; id< sGOStorage.MaxEntry; id++ )
3079 GameObjectInfo const* gInfo = sGOStorage.LookupEntry<GameObjectInfo>(id);
3080 if(!gInfo)
3081 continue;
3083 int loc_idx = GetSessionDbLocaleIndex();
3084 if ( loc_idx >= 0 )
3086 GameObjectLocale const *gl = objmgr.GetGameObjectLocale(id);
3087 if (gl)
3089 if (gl->Name.size() > loc_idx && !gl->Name[loc_idx].empty())
3091 std::string name = gl->Name[loc_idx];
3093 if (Utf8FitTo(name, wnamepart))
3095 if (m_session)
3096 PSendSysMessage(LANG_GO_ENTRY_LIST_CHAT, id, id, name.c_str());
3097 else
3098 PSendSysMessage(LANG_GO_ENTRY_LIST_CONSOLE, id, name.c_str());
3099 ++counter;
3100 continue;
3106 std::string name = gInfo->name;
3107 if(name.empty())
3108 continue;
3110 if(Utf8FitTo(name, wnamepart))
3112 if (m_session)
3113 PSendSysMessage(LANG_GO_ENTRY_LIST_CHAT, id, id, name.c_str());
3114 else
3115 PSendSysMessage(LANG_GO_ENTRY_LIST_CONSOLE, id, name.c_str());
3116 ++counter;
3120 if(counter==0)
3121 SendSysMessage(LANG_COMMAND_NOGAMEOBJECTFOUND);
3123 return true;
3126 bool ChatHandler::HandleLookupTaxiNodeCommand(const char * args)
3128 if(!*args)
3129 return false;
3131 std::string namepart = args;
3132 std::wstring wnamepart;
3134 if(!Utf8toWStr(namepart,wnamepart))
3135 return false;
3137 // converting string that we try to find to lower case
3138 wstrToLower( wnamepart );
3140 uint32 counter = 0; // Counter for figure out that we found smth.
3142 // Search in TaxiNodes.dbc
3143 for (uint32 id = 0; id < sTaxiNodesStore.GetNumRows(); id++)
3145 TaxiNodesEntry const *nodeEntry = sTaxiNodesStore.LookupEntry(id);
3146 if(nodeEntry)
3148 int loc = GetSessionDbcLocale();
3149 std::string name = nodeEntry->name[loc];
3150 if(name.empty())
3151 continue;
3153 if (!Utf8FitTo(name, wnamepart))
3155 loc = 0;
3156 for(; loc < MAX_LOCALE; ++loc)
3158 if(loc==GetSessionDbcLocale())
3159 continue;
3161 name = nodeEntry->name[loc];
3162 if(name.empty())
3163 continue;
3165 if (Utf8FitTo(name, wnamepart))
3166 break;
3170 if(loc < MAX_LOCALE)
3172 // send taxinode in "id - [name] (Map:m X:x Y:y Z:z)" format
3173 if (m_session)
3174 PSendSysMessage (LANG_TAXINODE_ENTRY_LIST_CHAT, id, id, name.c_str(),localeNames[loc],
3175 nodeEntry->map_id,nodeEntry->x,nodeEntry->y,nodeEntry->z);
3176 else
3177 PSendSysMessage (LANG_TAXINODE_ENTRY_LIST_CONSOLE, id, name.c_str(), localeNames[loc],
3178 nodeEntry->map_id,nodeEntry->x,nodeEntry->y,nodeEntry->z);
3179 ++counter;
3183 if (counter == 0) // if counter == 0 then we found nth
3184 SendSysMessage(LANG_COMMAND_NOTAXINODEFOUND);
3185 return true;
3188 /** \brief GM command level 3 - Create a guild.
3190 * This command allows a GM (level 3) to create a guild.
3192 * The "args" parameter contains the name of the guild leader
3193 * and then the name of the guild.
3196 bool ChatHandler::HandleGuildCreateCommand(const char* args)
3198 if(!*args)
3199 return false;
3201 // if not guild name only (in "") then player name
3202 Player* target;
3203 if(!extractPlayerTarget(*args!='"' ? (char*)args : NULL, &target))
3204 return false;
3206 char* tailStr = *args!='"' ? strtok(NULL, "") : (char*)args;
3207 if(!tailStr)
3208 return false;
3210 char* guildStr = extractQuotedArg(tailStr);
3211 if(!guildStr)
3212 return false;
3214 std::string guildname = guildStr;
3216 if (target->GetGuildId())
3218 SendSysMessage (LANG_PLAYER_IN_GUILD);
3219 return true;
3222 Guild *guild = new Guild;
3223 if (!guild->Create (target,guildname))
3225 delete guild;
3226 SendSysMessage (LANG_GUILD_NOT_CREATED);
3227 SetSentErrorMessage (true);
3228 return false;
3231 objmgr.AddGuild (guild);
3232 return true;
3235 bool ChatHandler::HandleGuildInviteCommand(const char *args)
3237 if(!*args)
3238 return false;
3240 // if not guild name only (in "") then player name
3241 uint64 target_guid;
3242 if(!extractPlayerTarget(*args!='"' ? (char*)args : NULL, NULL, &target_guid))
3243 return false;
3245 char* tailStr = *args!='"' ? strtok(NULL, "") : (char*)args;
3246 if(!tailStr)
3247 return false;
3249 char* guildStr = extractQuotedArg(tailStr);
3250 if(!guildStr)
3251 return false;
3253 std::string glName = guildStr;
3254 Guild* targetGuild = objmgr.GetGuildByName (glName);
3255 if (!targetGuild)
3256 return false;
3258 // player's guild membership checked in AddMember before add
3259 if (!targetGuild->AddMember (target_guid,targetGuild->GetLowestRank ()))
3260 return false;
3262 return true;
3265 bool ChatHandler::HandleGuildUninviteCommand(const char *args)
3267 Player* target;
3268 uint64 target_guid;
3269 if(!extractPlayerTarget((char*)args,&target,&target_guid))
3270 return false;
3272 uint32 glId = target ? target->GetGuildId () : Player::GetGuildIdFromDB (target_guid);
3273 if (!glId)
3274 return false;
3276 Guild* targetGuild = objmgr.GetGuildById (glId);
3277 if (!targetGuild)
3278 return false;
3280 targetGuild->DelMember (target_guid);
3281 return true;
3284 bool ChatHandler::HandleGuildRankCommand(const char *args)
3286 char* nameStr;
3287 char* rankStr;
3288 extractOptFirstArg((char*)args,&nameStr,&rankStr);
3289 if(!rankStr)
3290 return false;
3292 Player* target;
3293 uint64 target_guid;
3294 std::string target_name;
3295 if(!extractPlayerTarget(nameStr,&target,&target_guid,&target_name))
3296 return false;
3298 uint32 glId = target ? target->GetGuildId () : Player::GetGuildIdFromDB (target_guid);
3299 if (!glId)
3300 return false;
3302 Guild* targetGuild = objmgr.GetGuildById (glId);
3303 if (!targetGuild)
3304 return false;
3306 uint32 newrank = uint32 (atoi (rankStr));
3307 if (newrank > targetGuild->GetLowestRank ())
3308 return false;
3310 targetGuild->ChangeRank (target_guid,newrank);
3311 return true;
3314 bool ChatHandler::HandleGuildDeleteCommand(const char* args)
3316 if (!*args)
3317 return false;
3319 char* guildStr = extractQuotedArg((char*)args);
3320 if(!guildStr)
3321 return false;
3323 std::string gld = guildStr;
3325 Guild* targetGuild = objmgr.GetGuildByName (gld);
3326 if (!targetGuild)
3327 return false;
3329 targetGuild->Disband ();
3331 return true;
3334 bool ChatHandler::HandleGetDistanceCommand(const char* args)
3336 WorldObject* obj = NULL;
3338 if (*args)
3340 uint64 guid = extractGuidFromLink((char*)args);
3341 if(guid)
3342 obj = (WorldObject*)ObjectAccessor::GetObjectByTypeMask(*m_session->GetPlayer(),guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
3344 if(!obj)
3346 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3347 SetSentErrorMessage(true);
3348 return false;
3351 else
3353 obj = getSelectedUnit();
3355 if(!obj)
3357 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3358 SetSentErrorMessage(true);
3359 return false;
3363 PSendSysMessage(LANG_DISTANCE, m_session->GetPlayer()->GetDistance(obj),m_session->GetPlayer()->GetDistance2d(obj));
3365 return true;
3368 bool ChatHandler::HandleDieCommand(const char* /*args*/)
3370 Unit* target = getSelectedUnit();
3372 if(!target || !m_session->GetPlayer()->GetSelection())
3374 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3375 SetSentErrorMessage(true);
3376 return false;
3379 if(target->GetTypeId()==TYPEID_PLAYER)
3381 if(HasLowerSecurity((Player*)target,0,false))
3382 return false;
3385 if( target->isAlive() )
3387 m_session->GetPlayer()->DealDamage(target, target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
3390 return true;
3393 bool ChatHandler::HandleDamageCommand(const char * args)
3395 if (!*args)
3396 return false;
3398 Unit* target = getSelectedUnit();
3400 if (!target || !m_session->GetPlayer()->GetSelection())
3402 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3403 SetSentErrorMessage(true);
3404 return false;
3407 if (!target->isAlive())
3408 return true;
3410 char* damageStr = strtok((char*)args, " ");
3411 if (!damageStr)
3412 return false;
3414 int32 damage_int = atoi((char*)damageStr);
3415 if(damage_int <=0)
3416 return true;
3418 uint32 damage = damage_int;
3420 char* schoolStr = strtok((char*)NULL, " ");
3422 // flat melee damage without resistence/etc reduction
3423 if (!schoolStr)
3425 m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
3426 if (target != m_session->GetPlayer())
3427 m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, SPELL_SCHOOL_MASK_NORMAL, damage, 0, 0, VICTIMSTATE_NORMAL, 0);
3428 return true;
3431 uint32 school = schoolStr ? atoi((char*)schoolStr) : SPELL_SCHOOL_NORMAL;
3432 if(school >= MAX_SPELL_SCHOOL)
3433 return false;
3435 SpellSchoolMask schoolmask = SpellSchoolMask(1 << school);
3437 if ( schoolmask & SPELL_SCHOOL_MASK_NORMAL )
3438 damage = m_session->GetPlayer()->CalcArmorReducedDamage(target, damage);
3440 char* spellStr = strtok((char*)NULL, " ");
3442 // melee damage by specific school
3443 if (!spellStr)
3445 uint32 absorb = 0;
3446 uint32 resist = 0;
3448 m_session->GetPlayer()->CalcAbsorbResist(target,schoolmask, SPELL_DIRECT_DAMAGE, damage, &absorb, &resist);
3450 if (damage <= absorb + resist)
3451 return true;
3453 damage -= absorb + resist;
3455 m_session->GetPlayer()->DealDamageMods(target,damage,&absorb);
3456 m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, schoolmask, NULL, false);
3457 m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, schoolmask, damage, absorb, resist, VICTIMSTATE_NORMAL, 0);
3458 return true;
3461 // non-melee damage
3463 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
3464 uint32 spellid = extractSpellIdFromLink((char*)args);
3465 if (!spellid || !sSpellStore.LookupEntry(spellid))
3466 return false;
3468 m_session->GetPlayer()->SpellNonMeleeDamageLog(target, spellid, damage);
3469 return true;
3472 bool ChatHandler::HandleModifyArenaCommand(const char * args)
3474 if (!*args)
3475 return false;
3477 Player *target = getSelectedPlayer();
3478 if(!target)
3480 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3481 SetSentErrorMessage(true);
3482 return false;
3485 int32 amount = (uint32)atoi(args);
3487 target->ModifyArenaPoints(amount);
3489 PSendSysMessage(LANG_COMMAND_MODIFY_ARENA, GetNameLink(target).c_str(), target->GetArenaPoints());
3491 return true;
3494 bool ChatHandler::HandleReviveCommand(const char* args)
3496 Player* target;
3497 uint64 target_guid;
3498 if(!extractPlayerTarget((char*)args,&target,&target_guid))
3499 return false;
3501 if (target)
3503 target->ResurrectPlayer(0.5f);
3504 target->SpawnCorpseBones();
3505 target->SaveToDB();
3507 else
3508 // will resurrected at login without corpse
3509 ObjectAccessor::Instance().ConvertCorpseForPlayer(target_guid);
3511 return true;
3514 bool ChatHandler::HandleAuraCommand(const char* args)
3516 Unit *target = getSelectedUnit();
3517 if(!target)
3519 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3520 SetSentErrorMessage(true);
3521 return false;
3524 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
3525 uint32 spellID = extractSpellIdFromLink((char*)args);
3527 SpellEntry const *spellInfo = sSpellStore.LookupEntry( spellID );
3528 if(spellInfo)
3530 for(uint32 i = 0;i<3;++i)
3532 uint8 eff = spellInfo->Effect[i];
3533 if (eff>=TOTAL_SPELL_EFFECTS)
3534 continue;
3535 if( IsAreaAuraEffect(eff) ||
3536 eff == SPELL_EFFECT_APPLY_AURA ||
3537 eff == SPELL_EFFECT_PERSISTENT_AREA_AURA )
3539 Aura *Aur = CreateAura(spellInfo, i, NULL, target);
3540 target->AddAura(Aur);
3545 return true;
3548 bool ChatHandler::HandleUnAuraCommand(const char* args)
3550 Unit *target = getSelectedUnit();
3551 if(!target)
3553 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3554 SetSentErrorMessage(true);
3555 return false;
3558 std::string argstr = args;
3559 if (argstr == "all")
3561 target->RemoveAllAuras();
3562 return true;
3565 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
3566 uint32 spellID = extractSpellIdFromLink((char*)args);
3567 if(!spellID)
3568 return false;
3570 target->RemoveAurasDueToSpell(spellID);
3572 return true;
3575 bool ChatHandler::HandleLinkGraveCommand(const char* args)
3577 if(!*args)
3578 return false;
3580 char* px = strtok((char*)args, " ");
3581 if (!px)
3582 return false;
3584 uint32 g_id = (uint32)atoi(px);
3586 uint32 g_team;
3588 char* px2 = strtok(NULL, " ");
3590 if (!px2)
3591 g_team = 0;
3592 else if (strncmp(px2,"horde",6)==0)
3593 g_team = HORDE;
3594 else if (strncmp(px2,"alliance",9)==0)
3595 g_team = ALLIANCE;
3596 else
3597 return false;
3599 WorldSafeLocsEntry const* graveyard = sWorldSafeLocsStore.LookupEntry(g_id);
3601 if(!graveyard )
3603 PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST, g_id);
3604 SetSentErrorMessage(true);
3605 return false;
3608 Player* player = m_session->GetPlayer();
3610 uint32 zoneId = player->GetZoneId();
3612 AreaTableEntry const *areaEntry = GetAreaEntryByAreaID(zoneId);
3613 if(!areaEntry || areaEntry->zone !=0 )
3615 PSendSysMessage(LANG_COMMAND_GRAVEYARDWRONGZONE, g_id,zoneId);
3616 SetSentErrorMessage(true);
3617 return false;
3620 if(objmgr.AddGraveYardLink(g_id,zoneId,g_team))
3621 PSendSysMessage(LANG_COMMAND_GRAVEYARDLINKED, g_id,zoneId);
3622 else
3623 PSendSysMessage(LANG_COMMAND_GRAVEYARDALRLINKED, g_id,zoneId);
3625 return true;
3628 bool ChatHandler::HandleNearGraveCommand(const char* args)
3630 uint32 g_team;
3632 size_t argslen = strlen(args);
3634 if(!*args)
3635 g_team = 0;
3636 else if (strncmp((char*)args,"horde",argslen)==0)
3637 g_team = HORDE;
3638 else if (strncmp((char*)args,"alliance",argslen)==0)
3639 g_team = ALLIANCE;
3640 else
3641 return false;
3643 Player* player = m_session->GetPlayer();
3644 uint32 zone_id = player->GetZoneId();
3646 WorldSafeLocsEntry const* graveyard = objmgr.GetClosestGraveYard(
3647 player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(),player->GetMapId(),g_team);
3649 if(graveyard)
3651 uint32 g_id = graveyard->ID;
3653 GraveYardData const* data = objmgr.FindGraveYardData(g_id,zone_id);
3654 if (!data)
3656 PSendSysMessage(LANG_COMMAND_GRAVEYARDERROR,g_id);
3657 SetSentErrorMessage(true);
3658 return false;
3661 g_team = data->team;
3663 std::string team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_NOTEAM);
3665 if(g_team == 0)
3666 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ANY);
3667 else if(g_team == HORDE)
3668 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_HORDE);
3669 else if(g_team == ALLIANCE)
3670 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ALLIANCE);
3672 PSendSysMessage(LANG_COMMAND_GRAVEYARDNEAREST, g_id,team_name.c_str(),zone_id);
3674 else
3676 std::string team_name;
3678 if(g_team == 0)
3679 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ANY);
3680 else if(g_team == HORDE)
3681 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_HORDE);
3682 else if(g_team == ALLIANCE)
3683 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ALLIANCE);
3685 if(g_team == ~uint32(0))
3686 PSendSysMessage(LANG_COMMAND_ZONENOGRAVEYARDS, zone_id);
3687 else
3688 PSendSysMessage(LANG_COMMAND_ZONENOGRAFACTION, zone_id,team_name.c_str());
3691 return true;
3694 //-----------------------Npc Commands-----------------------
3695 bool ChatHandler::HandleNpcAllowMovementCommand(const char* /*args*/)
3697 if(sWorld.getAllowMovement())
3699 sWorld.SetAllowMovement(false);
3700 SendSysMessage(LANG_CREATURE_MOVE_DISABLED);
3702 else
3704 sWorld.SetAllowMovement(true);
3705 SendSysMessage(LANG_CREATURE_MOVE_ENABLED);
3707 return true;
3710 bool ChatHandler::HandleNpcChangeEntryCommand(const char *args)
3712 if (!*args)
3713 return false;
3715 uint32 newEntryNum = atoi(args);
3716 if(!newEntryNum)
3717 return false;
3719 Unit* unit = getSelectedUnit();
3720 if(!unit || unit->GetTypeId() != TYPEID_UNIT)
3722 SendSysMessage(LANG_SELECT_CREATURE);
3723 SetSentErrorMessage(true);
3724 return false;
3726 Creature* creature = (Creature*)unit;
3727 if(creature->UpdateEntry(newEntryNum))
3728 SendSysMessage(LANG_DONE);
3729 else
3730 SendSysMessage(LANG_ERROR);
3731 return true;
3734 bool ChatHandler::HandleNpcInfoCommand(const char* /*args*/)
3736 Creature* target = getSelectedCreature();
3738 if(!target)
3740 SendSysMessage(LANG_SELECT_CREATURE);
3741 SetSentErrorMessage(true);
3742 return false;
3745 uint32 faction = target->getFaction();
3746 uint32 npcflags = target->GetUInt32Value(UNIT_NPC_FLAGS);
3747 uint32 displayid = target->GetDisplayId();
3748 uint32 nativeid = target->GetNativeDisplayId();
3749 uint32 Entry = target->GetEntry();
3750 CreatureInfo const* cInfo = target->GetCreatureInfo();
3752 int32 curRespawnDelay = target->GetRespawnTimeEx()-time(NULL);
3753 if(curRespawnDelay < 0)
3754 curRespawnDelay = 0;
3755 std::string curRespawnDelayStr = secsToTimeString(curRespawnDelay,true);
3756 std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(),true);
3758 PSendSysMessage(LANG_NPCINFO_CHAR, target->GetDBTableGUIDLow(), faction, npcflags, Entry, displayid, nativeid);
3759 PSendSysMessage(LANG_NPCINFO_LEVEL, target->getLevel());
3760 PSendSysMessage(LANG_NPCINFO_HEALTH,target->GetCreateHealth(), target->GetMaxHealth(), target->GetHealth());
3761 PSendSysMessage(LANG_NPCINFO_FLAGS, target->GetUInt32Value(UNIT_FIELD_FLAGS), target->GetUInt32Value(UNIT_DYNAMIC_FLAGS), target->getFaction());
3762 PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES, defRespawnDelayStr.c_str(),curRespawnDelayStr.c_str());
3763 PSendSysMessage(LANG_NPCINFO_LOOT, cInfo->lootid,cInfo->pickpocketLootId,cInfo->SkinLootId);
3764 PSendSysMessage(LANG_NPCINFO_DUNGEON_ID, target->GetInstanceId());
3765 PSendSysMessage(LANG_NPCINFO_POSITION,float(target->GetPositionX()), float(target->GetPositionY()), float(target->GetPositionZ()));
3767 if ((npcflags & UNIT_NPC_FLAG_VENDOR) )
3769 SendSysMessage(LANG_NPCINFO_VENDOR);
3771 if ((npcflags & UNIT_NPC_FLAG_TRAINER) )
3773 SendSysMessage(LANG_NPCINFO_TRAINER);
3776 return true;
3779 //play npc emote
3780 bool ChatHandler::HandleNpcPlayEmoteCommand(const char* args)
3782 uint32 emote = atoi((char*)args);
3784 Creature* target = getSelectedCreature();
3785 if(!target)
3787 SendSysMessage(LANG_SELECT_CREATURE);
3788 SetSentErrorMessage(true);
3789 return false;
3792 target->SetUInt32Value(UNIT_NPC_EMOTESTATE,emote);
3794 return true;
3797 //TODO: NpcCommands that needs to be fixed :
3799 bool ChatHandler::HandleNpcAddWeaponCommand(const char* /*args*/)
3801 /*if (!*args)
3802 return false;
3804 uint64 guid = m_session->GetPlayer()->GetSelection();
3805 if (guid == 0)
3807 SendSysMessage(LANG_NO_SELECTION);
3808 return true;
3811 Creature *pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
3813 if(!pCreature)
3815 SendSysMessage(LANG_SELECT_CREATURE);
3816 return true;
3819 char* pSlotID = strtok((char*)args, " ");
3820 if (!pSlotID)
3821 return false;
3823 char* pItemID = strtok(NULL, " ");
3824 if (!pItemID)
3825 return false;
3827 uint32 ItemID = atoi(pItemID);
3828 uint32 SlotID = atoi(pSlotID);
3830 ItemPrototype* tmpItem = objmgr.GetItemPrototype(ItemID);
3832 bool added = false;
3833 if(tmpItem)
3835 switch(SlotID)
3837 case 1:
3838 pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, ItemID);
3839 added = true;
3840 break;
3841 case 2:
3842 pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_01, ItemID);
3843 added = true;
3844 break;
3845 case 3:
3846 pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_02, ItemID);
3847 added = true;
3848 break;
3849 default:
3850 PSendSysMessage(LANG_ITEM_SLOT_NOT_EXIST,SlotID);
3851 added = false;
3852 break;
3855 if(added)
3856 PSendSysMessage(LANG_ITEM_ADDED_TO_SLOT,ItemID,tmpItem->Name1,SlotID);
3858 else
3860 PSendSysMessage(LANG_ITEM_NOT_FOUND,ItemID);
3861 return true;
3864 return true;
3866 //----------------------------------------------------------
3868 bool ChatHandler::HandleExploreCheatCommand(const char* args)
3870 if (!*args)
3871 return false;
3873 int flag = atoi((char*)args);
3875 Player *chr = getSelectedPlayer();
3876 if (chr == NULL)
3878 SendSysMessage(LANG_NO_CHAR_SELECTED);
3879 SetSentErrorMessage(true);
3880 return false;
3883 if (flag != 0)
3885 PSendSysMessage(LANG_YOU_SET_EXPLORE_ALL, GetNameLink(chr).c_str());
3886 if (needReportToTarget(chr))
3887 ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_ALL,GetNameLink().c_str());
3889 else
3891 PSendSysMessage(LANG_YOU_SET_EXPLORE_NOTHING, GetNameLink(chr).c_str());
3892 if (needReportToTarget(chr))
3893 ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_NOTHING,GetNameLink().c_str());
3896 for (uint8 i=0; i<128; ++i)
3898 if (flag != 0)
3900 m_session->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i,0xFFFFFFFF);
3902 else
3904 m_session->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i,0);
3908 return true;
3911 bool ChatHandler::HandleHoverCommand(const char* args)
3913 char* px = strtok((char*)args, " ");
3914 uint32 flag;
3915 if (!px)
3916 flag = 1;
3917 else
3918 flag = atoi(px);
3920 m_session->GetPlayer()->SetHover(flag);
3922 if (flag)
3923 SendSysMessage(LANG_HOVER_ENABLED);
3924 else
3925 SendSysMessage(LANG_HOVER_DISABLED);
3927 return true;
3930 void ChatHandler::HandleCharacterLevel(Player* player, uint64 player_guid, uint32 oldlevel, uint32 newlevel)
3932 if(player)
3934 player->GiveLevel(newlevel);
3935 player->InitTalentForLevel();
3936 player->SetUInt32Value(PLAYER_XP,0);
3938 if(needReportToTarget(player))
3940 if(oldlevel == newlevel)
3941 ChatHandler(player).PSendSysMessage(LANG_YOURS_LEVEL_PROGRESS_RESET,GetNameLink().c_str());
3942 else if(oldlevel < newlevel)
3943 ChatHandler(player).PSendSysMessage(LANG_YOURS_LEVEL_UP,GetNameLink().c_str(),newlevel);
3944 else // if(oldlevel > newlevel)
3945 ChatHandler(player).PSendSysMessage(LANG_YOURS_LEVEL_DOWN,GetNameLink().c_str(),newlevel);
3948 else
3950 // update level and XP at level, all other will be updated at loading
3951 CharacterDatabase.PExecute("UPDATE characters SET level = '%u', xp = 0 WHERE guid = '%u'", newlevel, GUID_LOPART(player_guid));
3955 bool ChatHandler::HandleCharacterLevelCommand(const char* args)
3957 char* nameStr;
3958 char* levelStr;
3959 extractOptFirstArg((char*)args,&nameStr,&levelStr);
3960 if(!levelStr)
3961 return false;
3963 // exception opt second arg: .character level $name
3964 if(isalpha(levelStr[0]))
3966 nameStr = levelStr;
3967 levelStr = NULL; // current level will used
3970 Player* target;
3971 uint64 target_guid;
3972 std::string target_name;
3973 if(!extractPlayerTarget(nameStr,&target,&target_guid,&target_name))
3974 return false;
3976 int32 oldlevel = target ? target->getLevel() : Player::GetLevelFromDB(target_guid);
3977 int32 newlevel = levelStr ? atoi(levelStr) : oldlevel;
3979 if(newlevel < 1)
3980 return false; // invalid level
3982 if(newlevel > STRONG_MAX_LEVEL) // hardcoded maximum level
3983 newlevel = STRONG_MAX_LEVEL;
3985 HandleCharacterLevel(target,target_guid,oldlevel,newlevel);
3987 if(!m_session || m_session->GetPlayer() != target) // including player==NULL
3989 std::string nameLink = playerLink(target_name);
3990 PSendSysMessage(LANG_YOU_CHANGE_LVL,nameLink.c_str(),newlevel);
3993 return true;
3996 bool ChatHandler::HandleLevelUpCommand(const char* args)
3998 char* nameStr;
3999 char* levelStr;
4000 extractOptFirstArg((char*)args,&nameStr,&levelStr);
4002 // exception opt second arg: .character level $name
4003 if(levelStr && isalpha(levelStr[0]))
4005 nameStr = levelStr;
4006 levelStr = NULL; // current level will used
4009 Player* target;
4010 uint64 target_guid;
4011 std::string target_name;
4012 if(!extractPlayerTarget(nameStr,&target,&target_guid,&target_name))
4013 return false;
4015 int32 oldlevel = target ? target->getLevel() : Player::GetLevelFromDB(target_guid);
4016 int32 addlevel = levelStr ? atoi(levelStr) : 1;
4017 int32 newlevel = oldlevel + addlevel;
4019 if(newlevel < 1)
4020 newlevel = 1;
4022 if(newlevel > STRONG_MAX_LEVEL) // hardcoded maximum level
4023 newlevel = STRONG_MAX_LEVEL;
4025 HandleCharacterLevel(target,target_guid,oldlevel,newlevel);
4027 if(!m_session || m_session->GetPlayer() != target) // including chr==NULL
4029 std::string nameLink = playerLink(target_name);
4030 PSendSysMessage(LANG_YOU_CHANGE_LVL,nameLink.c_str(),newlevel);
4033 return true;
4036 bool ChatHandler::HandleShowAreaCommand(const char* args)
4038 if (!*args)
4039 return false;
4041 Player *chr = getSelectedPlayer();
4042 if (chr == NULL)
4044 SendSysMessage(LANG_NO_CHAR_SELECTED);
4045 SetSentErrorMessage(true);
4046 return false;
4049 int area = GetAreaFlagByAreaID(atoi((char*)args));
4050 int offset = area / 32;
4051 uint32 val = (uint32)(1 << (area % 32));
4053 if(area<0 || offset >= 128)
4055 SendSysMessage(LANG_BAD_VALUE);
4056 SetSentErrorMessage(true);
4057 return false;
4060 uint32 currFields = chr->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset);
4061 chr->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields | val));
4063 SendSysMessage(LANG_EXPLORE_AREA);
4064 return true;
4067 bool ChatHandler::HandleHideAreaCommand(const char* args)
4069 if (!*args)
4070 return false;
4072 Player *chr = getSelectedPlayer();
4073 if (chr == NULL)
4075 SendSysMessage(LANG_NO_CHAR_SELECTED);
4076 SetSentErrorMessage(true);
4077 return false;
4080 int area = GetAreaFlagByAreaID(atoi((char*)args));
4081 int offset = area / 32;
4082 uint32 val = (uint32)(1 << (area % 32));
4084 if(area<0 || offset >= 128)
4086 SendSysMessage(LANG_BAD_VALUE);
4087 SetSentErrorMessage(true);
4088 return false;
4091 uint32 currFields = chr->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset);
4092 chr->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields ^ val));
4094 SendSysMessage(LANG_UNEXPLORE_AREA);
4095 return true;
4098 bool ChatHandler::HandleBankCommand(const char* /*args*/)
4100 m_session->SendShowBank( m_session->GetPlayer()->GetGUID() );
4102 return true;
4105 bool ChatHandler::HandleChangeWeather(const char* args)
4107 if(!*args)
4108 return false;
4110 //Weather is OFF
4111 if (!sWorld.getConfig(CONFIG_WEATHER))
4113 SendSysMessage(LANG_WEATHER_DISABLED);
4114 SetSentErrorMessage(true);
4115 return false;
4118 //*Change the weather of a cell
4119 char* px = strtok((char*)args, " ");
4120 char* py = strtok(NULL, " ");
4122 if (!px || !py)
4123 return false;
4125 uint32 type = (uint32)atoi(px); //0 to 3, 0: fine, 1: rain, 2: snow, 3: sand
4126 float grade = (float)atof(py); //0 to 1, sending -1 is instand good weather
4128 Player *player = m_session->GetPlayer();
4129 uint32 zoneid = player->GetZoneId();
4131 Weather* wth = sWorld.FindWeather(zoneid);
4133 if(!wth)
4134 wth = sWorld.AddWeather(zoneid);
4135 if(!wth)
4137 SendSysMessage(LANG_NO_WEATHER);
4138 SetSentErrorMessage(true);
4139 return false;
4142 wth->SetWeather(WeatherType(type), grade);
4144 return true;
4147 bool ChatHandler::HandleTeleAddCommand(const char * args)
4149 if(!*args)
4150 return false;
4152 Player *player=m_session->GetPlayer();
4153 if (!player)
4154 return false;
4156 std::string name = args;
4158 if(objmgr.GetGameTele(name))
4160 SendSysMessage(LANG_COMMAND_TP_ALREADYEXIST);
4161 SetSentErrorMessage(true);
4162 return false;
4165 GameTele tele;
4166 tele.position_x = player->GetPositionX();
4167 tele.position_y = player->GetPositionY();
4168 tele.position_z = player->GetPositionZ();
4169 tele.orientation = player->GetOrientation();
4170 tele.mapId = player->GetMapId();
4171 tele.name = name;
4173 if(objmgr.AddGameTele(tele))
4175 SendSysMessage(LANG_COMMAND_TP_ADDED);
4177 else
4179 SendSysMessage(LANG_COMMAND_TP_ADDEDERR);
4180 SetSentErrorMessage(true);
4181 return false;
4184 return true;
4187 bool ChatHandler::HandleTeleDelCommand(const char * args)
4189 if(!*args)
4190 return false;
4192 std::string name = args;
4194 if(!objmgr.DeleteGameTele(name))
4196 SendSysMessage(LANG_COMMAND_TELE_NOTFOUND);
4197 SetSentErrorMessage(true);
4198 return false;
4201 SendSysMessage(LANG_COMMAND_TP_DELETED);
4202 return true;
4205 bool ChatHandler::HandleListAurasCommand (const char * /*args*/)
4207 Unit *unit = getSelectedUnit();
4208 if(!unit)
4210 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
4211 SetSentErrorMessage(true);
4212 return false;
4215 char const* talentStr = GetMangosString(LANG_TALENT);
4216 char const* passiveStr = GetMangosString(LANG_PASSIVE);
4218 Unit::AuraMap const& uAuras = unit->GetAuras();
4219 PSendSysMessage(LANG_COMMAND_TARGET_LISTAURAS, uAuras.size());
4220 for (Unit::AuraMap::const_iterator itr = uAuras.begin(); itr != uAuras.end(); ++itr)
4222 bool talent = GetTalentSpellCost(itr->second->GetId()) > 0;
4224 char const* name = itr->second->GetSpellProto()->SpellName[GetSessionDbcLocale()];
4226 if (m_session)
4228 std::ostringstream ss_name;
4229 ss_name << "|cffffffff|Hspell:" << itr->second->GetId() << "|h[" << name << "]|h|r";
4231 PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffIndex(),
4232 itr->second->GetModifier()->m_auraname, itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(),
4233 ss_name.str().c_str(),
4234 (itr->second->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
4235 IS_PLAYER_GUID(itr->second->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(itr->second->GetCasterGUID()));
4237 else
4239 PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffIndex(),
4240 itr->second->GetModifier()->m_auraname, itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(),
4241 name,
4242 (itr->second->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
4243 IS_PLAYER_GUID(itr->second->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(itr->second->GetCasterGUID()));
4246 for (int i = 0; i < TOTAL_AURAS; ++i)
4248 Unit::AuraList const& uAuraList = unit->GetAurasByType(AuraType(i));
4249 if (uAuraList.empty()) continue;
4250 PSendSysMessage(LANG_COMMAND_TARGET_LISTAURATYPE, uAuraList.size(), i);
4251 for (Unit::AuraList::const_iterator itr = uAuraList.begin(); itr != uAuraList.end(); ++itr)
4253 bool talent = GetTalentSpellCost((*itr)->GetId()) > 0;
4255 char const* name = (*itr)->GetSpellProto()->SpellName[GetSessionDbcLocale()];
4257 if (m_session)
4259 std::ostringstream ss_name;
4260 ss_name << "|cffffffff|Hspell:" << (*itr)->GetId() << "|h[" << name << "]|h|r";
4262 PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(),
4263 ss_name.str().c_str(),((*itr)->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
4264 IS_PLAYER_GUID((*itr)->GetCasterGUID()) ? "player" : "creature",GUID_LOPART((*itr)->GetCasterGUID()));
4266 else
4268 PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(),
4269 name,((*itr)->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
4270 IS_PLAYER_GUID((*itr)->GetCasterGUID()) ? "player" : "creature",GUID_LOPART((*itr)->GetCasterGUID()));
4274 return true;
4277 bool ChatHandler::HandleResetAchievementsCommand (const char * args)
4279 Player* target;
4280 uint64 target_guid;
4281 if (!extractPlayerTarget((char*)args,&target,&target_guid))
4282 return false;
4284 if(target)
4285 target->GetAchievementMgr().Reset();
4286 else
4287 AchievementMgr::DeleteFromDB(GUID_LOPART(target_guid));
4289 return true;
4292 bool ChatHandler::HandleResetHonorCommand (const char * args)
4294 Player* target;
4295 if (!extractPlayerTarget((char*)args,&target))
4296 return false;
4298 target->SetUInt32Value(PLAYER_FIELD_KILLS, 0);
4299 target->SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORBALE_KILLS, 0);
4300 target->SetUInt32Value(PLAYER_FIELD_HONOR_CURRENCY, 0);
4301 target->SetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, 0);
4302 target->SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, 0);
4303 target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL);
4305 return true;
4308 static bool HandleResetStatsOrLevelHelper(Player* player)
4310 ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(player->getClass());
4311 if(!cEntry)
4313 sLog.outError("Class %u not found in DBC (Wrong DBC files?)",player->getClass());
4314 return false;
4317 uint8 powertype = cEntry->powerType;
4319 // reset m_form if no aura
4320 if(!player->HasAuraType(SPELL_AURA_MOD_SHAPESHIFT))
4321 player->m_form = FORM_NONE;
4323 player->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE );
4324 player->SetFloatValue(UNIT_FIELD_COMBATREACH, 1.5f );
4326 player->setFactionForRace(player->getRace());
4328 player->SetUInt32Value(UNIT_FIELD_BYTES_0, ( ( player->getRace() ) | ( player->getClass() << 8 ) | ( player->getGender() << 16 ) | ( powertype << 24 ) ) );
4330 // reset only if player not in some form;
4331 if(player->m_form==FORM_NONE)
4332 player->InitDisplayIds();
4334 player->SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP );
4335 player->SetByteValue(UNIT_FIELD_BYTES_2, 3, player->m_form);
4337 player->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
4339 //-1 is default value
4340 player->SetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, uint32(-1));
4342 //player->SetUInt32Value(PLAYER_FIELD_BYTES, 0xEEE00000 );
4343 return true;
4346 bool ChatHandler::HandleResetLevelCommand(const char * args)
4348 Player* target;
4349 if(!extractPlayerTarget((char*)args,&target))
4350 return false;
4352 if(!HandleResetStatsOrLevelHelper(target))
4353 return false;
4355 // set starting level
4356 uint32 start_level = target->getClass() != CLASS_DEATH_KNIGHT
4357 ? sWorld.getConfig(CONFIG_START_PLAYER_LEVEL)
4358 : sWorld.getConfig(CONFIG_START_HEROIC_PLAYER_LEVEL);
4360 target->_ApplyAllLevelScaleItemMods(false);
4362 target->SetLevel(start_level);
4363 target->InitRunes();
4364 target->InitStatsForLevel(true);
4365 target->InitTaxiNodesForLevel();
4366 target->InitGlyphsForLevel();
4367 target->InitTalentForLevel();
4368 target->SetUInt32Value(PLAYER_XP,0);
4370 target->_ApplyAllLevelScaleItemMods(true);
4372 // reset level for pet
4373 if(Pet* pet = target->GetPet())
4374 pet->SynchronizeLevelWithOwner();
4376 return true;
4379 bool ChatHandler::HandleResetStatsCommand(const char * args)
4381 Player* target;
4382 if (!extractPlayerTarget((char*)args,&target))
4383 return false;
4385 if (!HandleResetStatsOrLevelHelper(target))
4386 return false;
4388 target->InitRunes();
4389 target->InitStatsForLevel(true);
4390 target->InitTaxiNodesForLevel();
4391 target->InitGlyphsForLevel();
4392 target->InitTalentForLevel();
4394 return true;
4397 bool ChatHandler::HandleResetSpellsCommand(const char * args)
4399 Player* target;
4400 uint64 target_guid;
4401 std::string target_name;
4402 if(!extractPlayerTarget((char*)args,&target,&target_guid,&target_name))
4403 return false;
4405 if(target)
4407 target->resetSpells();
4409 ChatHandler(target).SendSysMessage(LANG_RESET_SPELLS);
4410 if(!m_session || m_session->GetPlayer()!=target)
4411 PSendSysMessage(LANG_RESET_SPELLS_ONLINE,GetNameLink(target).c_str());
4413 else
4415 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",uint32(AT_LOGIN_RESET_SPELLS), GUID_LOPART(target_guid));
4416 PSendSysMessage(LANG_RESET_SPELLS_OFFLINE,target_name.c_str());
4419 return true;
4422 bool ChatHandler::HandleResetTalentsCommand(const char * args)
4424 Player* target;
4425 uint64 target_guid;
4426 std::string target_name;
4427 if (!extractPlayerTarget((char*)args,&target,&target_guid,&target_name))
4429 // Try reset talents as Hunter Pet
4430 Creature* creature = getSelectedCreature();
4431 if (!*args && creature && creature->isPet())
4433 Unit *owner = creature->GetOwner();
4434 if(owner && owner->GetTypeId() == TYPEID_PLAYER && ((Pet *)creature)->IsPermanentPetFor((Player*)owner))
4436 ((Pet *)creature)->resetTalents(true);
4437 ((Player*)owner)->SendTalentsInfoData(true);
4439 ChatHandler((Player*)owner).SendSysMessage(LANG_RESET_PET_TALENTS);
4440 if(!m_session || m_session->GetPlayer()!=((Player*)owner))
4441 PSendSysMessage(LANG_RESET_PET_TALENTS_ONLINE,GetNameLink((Player*)owner).c_str());
4443 return true;
4446 SendSysMessage(LANG_NO_CHAR_SELECTED);
4447 SetSentErrorMessage(true);
4448 return false;
4451 if (target)
4453 target->resetTalents(true);
4454 target->SendTalentsInfoData(false);
4455 ChatHandler(target).SendSysMessage(LANG_RESET_TALENTS);
4456 if (!m_session || m_session->GetPlayer()!=target)
4457 PSendSysMessage(LANG_RESET_TALENTS_ONLINE,GetNameLink(target).c_str());
4459 Pet* pet = target->GetPet();
4460 Pet::resetTalentsForAllPetsOf(target,pet);
4461 if(pet)
4462 target->SendTalentsInfoData(true);
4463 return true;
4465 else if (target_guid)
4467 uint32 at_flags = AT_LOGIN_NONE | AT_LOGIN_RESET_PET_TALENTS;
4468 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",at_flags, GUID_LOPART(target_guid) );
4469 std::string nameLink = playerLink(target_name);
4470 PSendSysMessage(LANG_RESET_TALENTS_OFFLINE,nameLink.c_str());
4471 return true;
4474 SendSysMessage(LANG_NO_CHAR_SELECTED);
4475 SetSentErrorMessage(true);
4476 return false;
4479 bool ChatHandler::HandleResetAllCommand(const char * args)
4481 if(!*args)
4482 return false;
4484 std::string casename = args;
4486 AtLoginFlags atLogin;
4488 // Command specially created as single command to prevent using short case names
4489 if(casename=="spells")
4491 atLogin = AT_LOGIN_RESET_SPELLS;
4492 sWorld.SendWorldText(LANG_RESETALL_SPELLS);
4493 if(!m_session)
4494 SendSysMessage(LANG_RESETALL_SPELLS);
4496 else if(casename=="talents")
4498 atLogin = AtLoginFlags(AT_LOGIN_RESET_TALENTS | AT_LOGIN_RESET_PET_TALENTS);
4499 sWorld.SendWorldText(LANG_RESETALL_TALENTS);
4500 if(!m_session)
4501 SendSysMessage(LANG_RESETALL_TALENTS);
4503 else
4505 PSendSysMessage(LANG_RESETALL_UNKNOWN_CASE,args);
4506 SetSentErrorMessage(true);
4507 return false;
4510 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE (at_login & '%u') = '0'",atLogin,atLogin);
4511 HashMapHolder<Player>::MapType const& plist = ObjectAccessor::Instance().GetPlayers();
4512 for(HashMapHolder<Player>::MapType::const_iterator itr = plist.begin(); itr != plist.end(); ++itr)
4513 itr->second->SetAtLoginFlag(atLogin);
4515 return true;
4518 bool ChatHandler::HandleServerShutDownCancelCommand(const char* /*args*/)
4520 sWorld.ShutdownCancel();
4521 return true;
4524 bool ChatHandler::HandleServerShutDownCommand(const char* args)
4526 if(!*args)
4527 return false;
4529 char* time_str = strtok ((char*) args, " ");
4530 char* exitcode_str = strtok (NULL, "");
4532 int32 time = atoi (time_str);
4534 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4535 if ((time == 0 && (time_str[0]!='0' || time_str[1]!='\0')) || time < 0)
4536 return false;
4538 if (exitcode_str)
4540 int32 exitcode = atoi (exitcode_str);
4542 // Handle atoi() errors
4543 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4544 return false;
4546 // Exit code should be in range of 0-125, 126-255 is used
4547 // in many shells for their own return codes and code > 255
4548 // is not supported in many others
4549 if (exitcode < 0 || exitcode > 125)
4550 return false;
4552 sWorld.ShutdownServ (time, 0, exitcode);
4554 else
4555 sWorld.ShutdownServ(time,0,SHUTDOWN_EXIT_CODE);
4556 return true;
4559 bool ChatHandler::HandleServerRestartCommand(const char* args)
4561 if(!*args)
4562 return false;
4564 char* time_str = strtok ((char*) args, " ");
4565 char* exitcode_str = strtok (NULL, "");
4567 int32 time = atoi (time_str);
4569 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4570 if ((time == 0 && (time_str[0]!='0' || time_str[1]!='\0')) || time < 0)
4571 return false;
4573 if (exitcode_str)
4575 int32 exitcode = atoi (exitcode_str);
4577 // Handle atoi() errors
4578 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4579 return false;
4581 // Exit code should be in range of 0-125, 126-255 is used
4582 // in many shells for their own return codes and code > 255
4583 // is not supported in many others
4584 if (exitcode < 0 || exitcode > 125)
4585 return false;
4587 sWorld.ShutdownServ (time, SHUTDOWN_MASK_RESTART, exitcode);
4589 else
4590 sWorld.ShutdownServ(time, SHUTDOWN_MASK_RESTART, RESTART_EXIT_CODE);
4591 return true;
4594 bool ChatHandler::HandleServerIdleRestartCommand(const char* args)
4596 if(!*args)
4597 return false;
4599 char* time_str = strtok ((char*) args, " ");
4600 char* exitcode_str = strtok (NULL, "");
4602 int32 time = atoi (time_str);
4604 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4605 if ((time == 0 && (time_str[0]!='0' || time_str[1]!='\0')) || time < 0)
4606 return false;
4608 if (exitcode_str)
4610 int32 exitcode = atoi (exitcode_str);
4612 // Handle atoi() errors
4613 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4614 return false;
4616 // Exit code should be in range of 0-125, 126-255 is used
4617 // in many shells for their own return codes and code > 255
4618 // is not supported in many others
4619 if (exitcode < 0 || exitcode > 125)
4620 return false;
4622 sWorld.ShutdownServ (time, SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE, exitcode);
4624 else
4625 sWorld.ShutdownServ(time,SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE,RESTART_EXIT_CODE);
4626 return true;
4629 bool ChatHandler::HandleServerIdleShutDownCommand(const char* args)
4631 if(!*args)
4632 return false;
4634 char* time_str = strtok ((char*) args, " ");
4635 char* exitcode_str = strtok (NULL, "");
4637 int32 time = atoi (time_str);
4639 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4640 if ((time == 0 && (time_str[0]!='0' || time_str[1]!='\0')) || time < 0)
4641 return false;
4643 if (exitcode_str)
4645 int32 exitcode = atoi (exitcode_str);
4647 // Handle atoi() errors
4648 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4649 return false;
4651 // Exit code should be in range of 0-125, 126-255 is used
4652 // in many shells for their own return codes and code > 255
4653 // is not supported in many others
4654 if (exitcode < 0 || exitcode > 125)
4655 return false;
4657 sWorld.ShutdownServ (time, SHUTDOWN_MASK_IDLE, exitcode);
4659 else
4660 sWorld.ShutdownServ(time,SHUTDOWN_MASK_IDLE,SHUTDOWN_EXIT_CODE);
4661 return true;
4664 bool ChatHandler::HandleQuestAdd(const char* args)
4666 Player* player = getSelectedPlayer();
4667 if(!player)
4669 SendSysMessage(LANG_NO_CHAR_SELECTED);
4670 SetSentErrorMessage(true);
4671 return false;
4674 // .addquest #entry'
4675 // number or [name] Shift-click form |color|Hquest:quest_id:quest_level|h[name]|h|r
4676 char* cId = extractKeyFromLink((char*)args,"Hquest");
4677 if(!cId)
4678 return false;
4680 uint32 entry = atol(cId);
4682 Quest const* pQuest = objmgr.GetQuestTemplate(entry);
4684 if(!pQuest)
4686 PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND,entry);
4687 SetSentErrorMessage(true);
4688 return false;
4691 // check item starting quest (it can work incorrectly if added without item in inventory)
4692 for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
4694 ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype>(id);
4695 if (!pProto)
4696 continue;
4698 if (pProto->StartQuest == entry)
4700 PSendSysMessage(LANG_COMMAND_QUEST_STARTFROMITEM, entry, pProto->ItemId);
4701 SetSentErrorMessage(true);
4702 return false;
4706 // ok, normal (creature/GO starting) quest
4707 if( player->CanAddQuest( pQuest, true ) )
4709 player->AddQuest( pQuest, NULL );
4711 if ( player->CanCompleteQuest( entry ) )
4712 player->CompleteQuest( entry );
4715 return true;
4718 bool ChatHandler::HandleQuestRemove(const char* args)
4720 Player* player = getSelectedPlayer();
4721 if(!player)
4723 SendSysMessage(LANG_NO_CHAR_SELECTED);
4724 SetSentErrorMessage(true);
4725 return false;
4728 // .removequest #entry'
4729 // number or [name] Shift-click form |color|Hquest:quest_id:quest_level|h[name]|h|r
4730 char* cId = extractKeyFromLink((char*)args,"Hquest");
4731 if(!cId)
4732 return false;
4734 uint32 entry = atol(cId);
4736 Quest const* pQuest = objmgr.GetQuestTemplate(entry);
4738 if(!pQuest)
4740 PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry);
4741 SetSentErrorMessage(true);
4742 return false;
4745 // remove all quest entries for 'entry' from quest log
4746 for(uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot )
4748 uint32 quest = player->GetQuestSlotQuestId(slot);
4749 if(quest==entry)
4751 player->SetQuestSlot(slot,0);
4753 // we ignore unequippable quest items in this case, its' still be equipped
4754 player->TakeQuestSourceItem( quest, false );
4758 // set quest status to not started (will updated in DB at next save)
4759 player->SetQuestStatus( entry, QUEST_STATUS_NONE);
4761 // reset rewarded for restart repeatable quest
4762 player->getQuestStatusMap()[entry].m_rewarded = false;
4764 SendSysMessage(LANG_COMMAND_QUEST_REMOVED);
4765 return true;
4768 bool ChatHandler::HandleQuestComplete(const char* args)
4770 Player* player = getSelectedPlayer();
4771 if(!player)
4773 SendSysMessage(LANG_NO_CHAR_SELECTED);
4774 SetSentErrorMessage(true);
4775 return false;
4778 // .quest complete #entry
4779 // number or [name] Shift-click form |color|Hquest:quest_id:quest_level|h[name]|h|r
4780 char* cId = extractKeyFromLink((char*)args,"Hquest");
4781 if(!cId)
4782 return false;
4784 uint32 entry = atol(cId);
4786 Quest const* pQuest = objmgr.GetQuestTemplate(entry);
4788 // If player doesn't have the quest
4789 if(!pQuest || player->GetQuestStatus(entry) == QUEST_STATUS_NONE)
4791 PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry);
4792 SetSentErrorMessage(true);
4793 return false;
4796 // Add quest items for quests that require items
4797 for(uint8 x = 0; x < QUEST_OBJECTIVES_COUNT; ++x)
4799 uint32 id = pQuest->ReqItemId[x];
4800 uint32 count = pQuest->ReqItemCount[x];
4801 if(!id || !count)
4802 continue;
4804 uint32 curItemCount = player->GetItemCount(id,true);
4806 ItemPosCountVec dest;
4807 uint8 msg = player->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, id, count-curItemCount );
4808 if( msg == EQUIP_ERR_OK )
4810 Item* item = player->StoreNewItem( dest, id, true);
4811 player->SendNewItem(item,count-curItemCount,true,false);
4815 // All creature/GO slain/casted (not required, but otherwise it will display "Creature slain 0/10")
4816 for(uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
4818 uint32 creature = pQuest->ReqCreatureOrGOId[i];
4819 uint32 creaturecount = pQuest->ReqCreatureOrGOCount[i];
4821 if(uint32 spell_id = pQuest->ReqSpell[i])
4823 for(uint16 z = 0; z < creaturecount; ++z)
4824 player->CastedCreatureOrGO(creature,0,spell_id);
4826 else if(creature > 0)
4828 if(CreatureInfo const* cInfo = objmgr.GetCreatureTemplate(creature))
4829 for(uint16 z = 0; z < creaturecount; ++z)
4830 player->KilledMonster(cInfo,0);
4832 else if(creature < 0)
4834 for(uint16 z = 0; z < creaturecount; ++z)
4835 player->CastedCreatureOrGO(creature,0,0);
4839 // If the quest requires reputation to complete
4840 if(uint32 repFaction = pQuest->GetRepObjectiveFaction())
4842 uint32 repValue = pQuest->GetRepObjectiveValue();
4843 uint32 curRep = player->GetReputationMgr().GetReputation(repFaction);
4844 if(curRep < repValue)
4845 if(FactionEntry const *factionEntry = sFactionStore.LookupEntry(repFaction))
4846 player->GetReputationMgr().SetReputation(factionEntry,repValue);
4849 // If the quest requires money
4850 int32 ReqOrRewMoney = pQuest->GetRewOrReqMoney();
4851 if(ReqOrRewMoney < 0)
4852 player->ModifyMoney(-ReqOrRewMoney);
4854 player->CompleteQuest(entry);
4855 return true;
4858 bool ChatHandler::HandleBanAccountCommand(const char* args)
4860 return HandleBanHelper(BAN_ACCOUNT,args);
4863 bool ChatHandler::HandleBanCharacterCommand(const char* args)
4865 return HandleBanHelper(BAN_CHARACTER,args);
4868 bool ChatHandler::HandleBanIPCommand(const char* args)
4870 return HandleBanHelper(BAN_IP,args);
4873 bool ChatHandler::HandleBanHelper(BanMode mode, const char* args)
4875 if (!*args)
4876 return false;
4878 char* cnameOrIP = strtok ((char*)args, " ");
4879 if (!cnameOrIP)
4880 return false;
4882 std::string nameOrIP = cnameOrIP;
4884 char* duration = strtok (NULL," ");
4885 if(!duration || !atoi(duration))
4886 return false;
4888 char* reason = strtok (NULL,"");
4889 if(!reason)
4890 return false;
4892 switch(mode)
4894 case BAN_ACCOUNT:
4895 if (!AccountMgr::normalizeString(nameOrIP))
4897 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,nameOrIP.c_str());
4898 SetSentErrorMessage(true);
4899 return false;
4901 break;
4902 case BAN_CHARACTER:
4903 if(!normalizePlayerName(nameOrIP))
4905 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4906 SetSentErrorMessage(true);
4907 return false;
4909 break;
4910 case BAN_IP:
4911 if(!IsIPAddress(nameOrIP.c_str()))
4912 return false;
4913 break;
4916 switch(sWorld.BanAccount(mode, nameOrIP, duration, reason,m_session ? m_session->GetPlayerName() : ""))
4918 case BAN_SUCCESS:
4919 if(atoi(duration)>0)
4920 PSendSysMessage(LANG_BAN_YOUBANNED,nameOrIP.c_str(),secsToTimeString(TimeStringToSecs(duration),true).c_str(),reason);
4921 else
4922 PSendSysMessage(LANG_BAN_YOUPERMBANNED,nameOrIP.c_str(),reason);
4923 break;
4924 case BAN_SYNTAX_ERROR:
4925 return false;
4926 case BAN_NOTFOUND:
4927 switch(mode)
4929 default:
4930 PSendSysMessage(LANG_BAN_NOTFOUND,"account",nameOrIP.c_str());
4931 break;
4932 case BAN_CHARACTER:
4933 PSendSysMessage(LANG_BAN_NOTFOUND,"character",nameOrIP.c_str());
4934 break;
4935 case BAN_IP:
4936 PSendSysMessage(LANG_BAN_NOTFOUND,"ip",nameOrIP.c_str());
4937 break;
4939 SetSentErrorMessage(true);
4940 return false;
4943 return true;
4946 bool ChatHandler::HandleUnBanAccountCommand(const char* args)
4948 return HandleUnBanHelper(BAN_ACCOUNT,args);
4951 bool ChatHandler::HandleUnBanCharacterCommand(const char* args)
4953 return HandleUnBanHelper(BAN_CHARACTER,args);
4956 bool ChatHandler::HandleUnBanIPCommand(const char* args)
4958 return HandleUnBanHelper(BAN_IP,args);
4961 bool ChatHandler::HandleUnBanHelper(BanMode mode, const char* args)
4963 if (!*args)
4964 return false;
4966 char* cnameOrIP = strtok ((char*)args, " ");
4967 if(!cnameOrIP)
4968 return false;
4970 std::string nameOrIP = cnameOrIP;
4972 switch(mode)
4974 case BAN_ACCOUNT:
4975 if (!AccountMgr::normalizeString(nameOrIP))
4977 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,nameOrIP.c_str());
4978 SetSentErrorMessage(true);
4979 return false;
4981 break;
4982 case BAN_CHARACTER:
4983 if(!normalizePlayerName(nameOrIP))
4985 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4986 SetSentErrorMessage(true);
4987 return false;
4989 break;
4990 case BAN_IP:
4991 if(!IsIPAddress(nameOrIP.c_str()))
4992 return false;
4993 break;
4996 if(sWorld.RemoveBanAccount(mode,nameOrIP))
4997 PSendSysMessage(LANG_UNBAN_UNBANNED,nameOrIP.c_str());
4998 else
4999 PSendSysMessage(LANG_UNBAN_ERROR,nameOrIP.c_str());
5001 return true;
5004 bool ChatHandler::HandleBanInfoAccountCommand(const char* args)
5006 if (!*args)
5007 return false;
5009 char* cname = strtok((char*)args, "");
5010 if (!cname)
5011 return false;
5013 std::string account_name = cname;
5014 if (!AccountMgr::normalizeString(account_name))
5016 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5017 SetSentErrorMessage(true);
5018 return false;
5021 uint32 accountid = accmgr.GetId(account_name);
5022 if (!accountid)
5024 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5025 return true;
5028 return HandleBanInfoHelper(accountid,account_name.c_str());
5031 bool ChatHandler::HandleBanInfoCharacterCommand(const char* args)
5033 Player* target;
5034 uint64 target_guid;
5035 if (!extractPlayerTarget((char*)args,&target,&target_guid))
5036 return false;
5038 uint32 accountid = target ? target->GetSession()->GetAccountId() : objmgr.GetPlayerAccountIdByGUID(target_guid);
5040 std::string accountname;
5041 if (!accmgr.GetName(accountid,accountname))
5043 PSendSysMessage(LANG_BANINFO_NOCHARACTER);
5044 return true;
5047 return HandleBanInfoHelper(accountid,accountname.c_str());
5050 bool ChatHandler::HandleBanInfoHelper(uint32 accountid, char const* accountname)
5052 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);
5053 if(!result)
5055 PSendSysMessage(LANG_BANINFO_NOACCOUNTBAN, accountname);
5056 return true;
5059 PSendSysMessage(LANG_BANINFO_BANHISTORY,accountname);
5062 Field* fields = result->Fetch();
5064 time_t unbandate = time_t(fields[3].GetUInt64());
5065 bool active = false;
5066 if(fields[2].GetBool() && (fields[1].GetUInt64() == (uint64)0 ||unbandate >= time(NULL)) )
5067 active = true;
5068 bool permanent = (fields[1].GetUInt64() == (uint64)0);
5069 std::string bantime = permanent?GetMangosString(LANG_BANINFO_INFINITE):secsToTimeString(fields[1].GetUInt64(), true);
5070 PSendSysMessage(LANG_BANINFO_HISTORYENTRY,
5071 fields[0].GetString(), bantime.c_str(), active ? GetMangosString(LANG_BANINFO_YES):GetMangosString(LANG_BANINFO_NO), fields[4].GetString(), fields[5].GetString());
5072 }while (result->NextRow());
5074 delete result;
5075 return true;
5078 bool ChatHandler::HandleBanInfoIPCommand(const char* args)
5080 if (!*args)
5081 return false;
5083 char* cIP = strtok ((char*)args, "");
5084 if(!cIP)
5085 return false;
5087 if (!IsIPAddress(cIP))
5088 return false;
5090 std::string IP = cIP;
5092 loginDatabase.escape_string(IP);
5093 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());
5094 if(!result)
5096 PSendSysMessage(LANG_BANINFO_NOIP);
5097 return true;
5100 Field *fields = result->Fetch();
5101 bool permanent = !fields[6].GetUInt64();
5102 PSendSysMessage(LANG_BANINFO_IPENTRY,
5103 fields[0].GetString(), fields[1].GetString(), permanent ? GetMangosString(LANG_BANINFO_NEVER):fields[2].GetString(),
5104 permanent ? GetMangosString(LANG_BANINFO_INFINITE):secsToTimeString(fields[3].GetUInt64(), true).c_str(), fields[4].GetString(), fields[5].GetString());
5105 delete result;
5106 return true;
5109 bool ChatHandler::HandleBanListCharacterCommand(const char* args)
5111 loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
5113 char* cFilter = strtok ((char*)args, " ");
5114 if(!cFilter)
5115 return false;
5117 std::string filter = cFilter;
5118 loginDatabase.escape_string(filter);
5119 QueryResult* result = CharacterDatabase.PQuery("SELECT account FROM characters WHERE name "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'"),filter.c_str());
5120 if (!result)
5122 PSendSysMessage(LANG_BANLIST_NOCHARACTER);
5123 return true;
5126 return HandleBanListHelper(result);
5129 bool ChatHandler::HandleBanListAccountCommand(const char* args)
5131 loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
5133 char* cFilter = strtok((char*)args, " ");
5134 std::string filter = cFilter ? cFilter : "";
5135 loginDatabase.escape_string(filter);
5137 QueryResult* result;
5139 if(filter.empty())
5141 result = loginDatabase.Query("SELECT account.id, username FROM account, account_banned"
5142 " WHERE account.id = account_banned.id AND active = 1 GROUP BY account.id");
5144 else
5146 result = loginDatabase.PQuery("SELECT account.id, username FROM account, account_banned"
5147 " WHERE account.id = account_banned.id AND active = 1 AND username "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")" GROUP BY account.id",
5148 filter.c_str());
5151 if (!result)
5153 PSendSysMessage(LANG_BANLIST_NOACCOUNT);
5154 return true;
5157 return HandleBanListHelper(result);
5160 bool ChatHandler::HandleBanListHelper(QueryResult* result)
5162 PSendSysMessage(LANG_BANLIST_MATCHINGACCOUNT);
5164 // Chat short output
5165 if(m_session)
5169 Field* fields = result->Fetch();
5170 uint32 accountid = fields[0].GetUInt32();
5172 QueryResult* banresult = loginDatabase.PQuery("SELECT account.username FROM account,account_banned WHERE account_banned.id='%u' AND account_banned.id=account.id",accountid);
5173 if(banresult)
5175 Field* fields2 = banresult->Fetch();
5176 PSendSysMessage("%s",fields2[0].GetString());
5177 delete banresult;
5179 } while (result->NextRow());
5181 // Console wide output
5182 else
5184 SendSysMessage(LANG_BANLIST_ACCOUNTS);
5185 SendSysMessage("===============================================================================");
5186 SendSysMessage(LANG_BANLIST_ACCOUNTS_HEADER);
5189 SendSysMessage("-------------------------------------------------------------------------------");
5190 Field *fields = result->Fetch();
5191 uint32 account_id = fields[0].GetUInt32 ();
5193 std::string account_name;
5195 // "account" case, name can be get in same query
5196 if(result->GetFieldCount() > 1)
5197 account_name = fields[1].GetCppString();
5198 // "character" case, name need extract from another DB
5199 else
5200 accmgr.GetName (account_id,account_name);
5202 // No SQL injection. id is uint32.
5203 QueryResult *banInfo = loginDatabase.PQuery("SELECT bandate,unbandate,bannedby,banreason FROM account_banned WHERE id = %u ORDER BY unbandate", account_id);
5204 if (banInfo)
5206 Field *fields2 = banInfo->Fetch();
5209 time_t t_ban = fields2[0].GetUInt64();
5210 tm* aTm_ban = localtime(&t_ban);
5212 if (fields2[0].GetUInt64() == fields2[1].GetUInt64())
5214 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|",
5215 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,
5216 fields2[2].GetString(),fields2[3].GetString());
5218 else
5220 time_t t_unban = fields2[1].GetUInt64();
5221 tm* aTm_unban = localtime(&t_unban);
5222 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|",
5223 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,
5224 aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min,
5225 fields2[2].GetString(),fields2[3].GetString());
5227 }while ( banInfo->NextRow() );
5228 delete banInfo;
5230 }while( result->NextRow() );
5231 SendSysMessage("===============================================================================");
5234 delete result;
5235 return true;
5238 bool ChatHandler::HandleBanListIPCommand(const char* args)
5240 loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
5242 char* cFilter = strtok((char*)args, " ");
5243 std::string filter = cFilter ? cFilter : "";
5244 loginDatabase.escape_string(filter);
5246 QueryResult* result;
5248 if(filter.empty())
5250 result = loginDatabase.Query ("SELECT ip,bandate,unbandate,bannedby,banreason FROM ip_banned"
5251 " WHERE (bandate=unbandate OR unbandate>UNIX_TIMESTAMP())"
5252 " ORDER BY unbandate" );
5254 else
5256 result = loginDatabase.PQuery( "SELECT ip,bandate,unbandate,bannedby,banreason FROM ip_banned"
5257 " WHERE (bandate=unbandate OR unbandate>UNIX_TIMESTAMP()) AND ip "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")
5258 " ORDER BY unbandate",filter.c_str() );
5261 if(!result)
5263 PSendSysMessage(LANG_BANLIST_NOIP);
5264 return true;
5267 PSendSysMessage(LANG_BANLIST_MATCHINGIP);
5268 // Chat short output
5269 if(m_session)
5273 Field* fields = result->Fetch();
5274 PSendSysMessage("%s",fields[0].GetString());
5275 } while (result->NextRow());
5277 // Console wide output
5278 else
5280 SendSysMessage(LANG_BANLIST_IPS);
5281 SendSysMessage("===============================================================================");
5282 SendSysMessage(LANG_BANLIST_IPS_HEADER);
5285 SendSysMessage("-------------------------------------------------------------------------------");
5286 Field *fields = result->Fetch();
5287 time_t t_ban = fields[1].GetUInt64();
5288 tm* aTm_ban = localtime(&t_ban);
5289 if ( fields[1].GetUInt64() == fields[2].GetUInt64() )
5291 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|",
5292 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,
5293 fields[3].GetString(), fields[4].GetString());
5295 else
5297 time_t t_unban = fields[2].GetUInt64();
5298 tm* aTm_unban = localtime(&t_unban);
5299 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|",
5300 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,
5301 aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min,
5302 fields[3].GetString(), fields[4].GetString());
5304 }while( result->NextRow() );
5305 SendSysMessage("===============================================================================");
5308 delete result;
5309 return true;
5312 bool ChatHandler::HandleRespawnCommand(const char* /*args*/)
5314 Player* pl = m_session->GetPlayer();
5316 // accept only explicitly selected target (not implicitly self targeting case)
5317 Unit* target = getSelectedUnit();
5318 if(pl->GetSelection() && target)
5320 if(target->GetTypeId()!=TYPEID_UNIT)
5322 SendSysMessage(LANG_SELECT_CREATURE);
5323 SetSentErrorMessage(true);
5324 return false;
5327 if(target->isDead())
5328 ((Creature*)target)->Respawn();
5329 return true;
5332 CellPair p(MaNGOS::ComputeCellPair(pl->GetPositionX(), pl->GetPositionY()));
5333 Cell cell(p);
5334 cell.data.Part.reserved = ALL_DISTRICT;
5335 cell.SetNoCreate();
5337 MaNGOS::RespawnDo u_do;
5338 MaNGOS::WorldObjectWorker<MaNGOS::RespawnDo> worker(pl,u_do);
5340 TypeContainerVisitor<MaNGOS::WorldObjectWorker<MaNGOS::RespawnDo>, GridTypeMapContainer > obj_worker(worker);
5341 CellLock<GridReadGuard> cell_lock(cell, p);
5342 cell_lock->Visit(cell_lock, obj_worker, *pl->GetMap());
5344 return true;
5347 bool ChatHandler::HandleGMFlyCommand(const char* args)
5349 if (!*args)
5350 return false;
5352 Player *target = getSelectedPlayer();
5353 if (!target)
5354 target = m_session->GetPlayer();
5356 WorldPacket data(12);
5357 if (strncmp(args, "on", 3) == 0)
5358 data.SetOpcode(SMSG_MOVE_SET_CAN_FLY);
5359 else if (strncmp(args, "off", 4) == 0)
5360 data.SetOpcode(SMSG_MOVE_UNSET_CAN_FLY);
5361 else
5363 SendSysMessage(LANG_USE_BOL);
5364 return false;
5366 data.append(target->GetPackGUID());
5367 data << uint32(0); // unknown
5368 target->SendMessageToSet(&data, true);
5369 PSendSysMessage(LANG_COMMAND_FLYMODE_STATUS, GetNameLink(target).c_str(), args);
5370 return true;
5373 bool ChatHandler::HandlePDumpLoadCommand(const char *args)
5375 if (!*args)
5376 return false;
5378 char * file = strtok((char*)args, " ");
5379 if (!file)
5380 return false;
5382 char * account = strtok(NULL, " ");
5383 if (!account)
5384 return false;
5386 std::string account_name = account;
5387 if (!AccountMgr::normalizeString(account_name))
5389 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5390 SetSentErrorMessage(true);
5391 return false;
5394 uint32 account_id = accmgr.GetId(account_name);
5395 if (!account_id)
5397 account_id = atoi(account); // use original string
5398 if (!account_id)
5400 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5401 SetSentErrorMessage(true);
5402 return false;
5406 if (!accmgr.GetName(account_id,account_name))
5408 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5409 SetSentErrorMessage(true);
5410 return false;
5413 char* guid_str = NULL;
5414 char* name_str = strtok(NULL, " ");
5416 std::string name;
5417 if (name_str)
5419 name = name_str;
5420 // normalize the name if specified and check if it exists
5421 if (!normalizePlayerName(name))
5423 PSendSysMessage(LANG_INVALID_CHARACTER_NAME);
5424 SetSentErrorMessage(true);
5425 return false;
5428 if (ObjectMgr::CheckPlayerName(name,true) != CHAR_NAME_SUCCESS)
5430 PSendSysMessage(LANG_INVALID_CHARACTER_NAME);
5431 SetSentErrorMessage(true);
5432 return false;
5435 guid_str = strtok(NULL, " ");
5438 uint32 guid = 0;
5440 if (guid_str)
5442 guid = atoi(guid_str);
5443 if (!guid)
5445 PSendSysMessage(LANG_INVALID_CHARACTER_GUID);
5446 SetSentErrorMessage(true);
5447 return false;
5450 if (objmgr.GetPlayerAccountIdByGUID(guid))
5452 PSendSysMessage(LANG_CHARACTER_GUID_IN_USE,guid);
5453 SetSentErrorMessage(true);
5454 return false;
5458 switch(PlayerDumpReader().LoadDump(file, account_id, name, guid))
5460 case DUMP_SUCCESS:
5461 PSendSysMessage(LANG_COMMAND_IMPORT_SUCCESS);
5462 break;
5463 case DUMP_FILE_OPEN_ERROR:
5464 PSendSysMessage(LANG_FILE_OPEN_FAIL,file);
5465 SetSentErrorMessage(true);
5466 return false;
5467 case DUMP_FILE_BROKEN:
5468 PSendSysMessage(LANG_DUMP_BROKEN,file);
5469 SetSentErrorMessage(true);
5470 return false;
5471 case DUMP_TOO_MANY_CHARS:
5472 PSendSysMessage(LANG_ACCOUNT_CHARACTER_LIST_FULL,account_name.c_str(),account_id);
5473 SetSentErrorMessage(true);
5474 return false;
5475 default:
5476 PSendSysMessage(LANG_COMMAND_IMPORT_FAILED);
5477 SetSentErrorMessage(true);
5478 return false;
5481 return true;
5484 bool ChatHandler::HandlePDumpWriteCommand(const char *args)
5486 if (!*args)
5487 return false;
5489 char* file = strtok((char*)args, " ");
5490 char* p2 = strtok(NULL, " ");
5492 if(!file || !p2)
5493 return false;
5495 uint32 guid;
5496 // character name can't start from number
5497 if (isNumeric(p2[0]))
5498 guid = atoi(p2);
5499 else
5501 std::string name = extractPlayerNameFromLink(p2);
5502 if(name.empty())
5504 SendSysMessage(LANG_PLAYER_NOT_FOUND);
5505 SetSentErrorMessage(true);
5506 return false;
5509 guid = objmgr.GetPlayerGUIDByName(name);
5512 if(!objmgr.GetPlayerAccountIdByGUID(guid))
5514 PSendSysMessage(LANG_PLAYER_NOT_FOUND);
5515 SetSentErrorMessage(true);
5516 return false;
5519 switch(PlayerDumpWriter().WriteDump(file, guid))
5521 case DUMP_SUCCESS:
5522 PSendSysMessage(LANG_COMMAND_EXPORT_SUCCESS);
5523 break;
5524 case DUMP_FILE_OPEN_ERROR:
5525 PSendSysMessage(LANG_FILE_OPEN_FAIL,file);
5526 SetSentErrorMessage(true);
5527 return false;
5528 default:
5529 PSendSysMessage(LANG_COMMAND_EXPORT_FAILED);
5530 SetSentErrorMessage(true);
5531 return false;
5534 return true;
5537 bool ChatHandler::HandleMovegensCommand(const char* /*args*/)
5539 Unit* unit = getSelectedUnit();
5540 if(!unit)
5542 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5543 SetSentErrorMessage(true);
5544 return false;
5547 PSendSysMessage(LANG_MOVEGENS_LIST,(unit->GetTypeId()==TYPEID_PLAYER ? "Player" : "Creature" ),unit->GetGUIDLow());
5549 MotionMaster* mm = unit->GetMotionMaster();
5550 for(MotionMaster::const_iterator itr = mm->begin(); itr != mm->end(); ++itr)
5552 switch((*itr)->GetMovementGeneratorType())
5554 case IDLE_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_IDLE); break;
5555 case RANDOM_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_RANDOM); break;
5556 case WAYPOINT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_WAYPOINT); break;
5557 case ANIMAL_RANDOM_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_ANIMAL_RANDOM); break;
5558 case CONFUSED_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_CONFUSED); break;
5559 case TARGETED_MOTION_TYPE:
5561 if(unit->GetTypeId()==TYPEID_PLAYER)
5563 TargetedMovementGenerator<Player> const* mgen = static_cast<TargetedMovementGenerator<Player> const*>(*itr);
5564 Unit* target = mgen->GetTarget();
5565 if(target)
5566 PSendSysMessage(LANG_MOVEGENS_TARGETED_PLAYER,target->GetName(),target->GetGUIDLow());
5567 else
5568 SendSysMessage(LANG_MOVEGENS_TARGETED_NULL);
5570 else
5572 TargetedMovementGenerator<Creature> const* mgen = static_cast<TargetedMovementGenerator<Creature> const*>(*itr);
5573 Unit* target = mgen->GetTarget();
5574 if(target)
5575 PSendSysMessage(LANG_MOVEGENS_TARGETED_CREATURE,target->GetName(),target->GetGUIDLow());
5576 else
5577 SendSysMessage(LANG_MOVEGENS_TARGETED_NULL);
5579 break;
5581 case HOME_MOTION_TYPE:
5582 if(unit->GetTypeId()==TYPEID_UNIT)
5584 float x,y,z;
5585 (*itr)->GetDestination(x,y,z);
5586 PSendSysMessage(LANG_MOVEGENS_HOME_CREATURE,x,y,z);
5588 else
5589 SendSysMessage(LANG_MOVEGENS_HOME_PLAYER);
5590 break;
5591 case FLIGHT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_FLIGHT); break;
5592 case POINT_MOTION_TYPE:
5594 float x,y,z;
5595 (*itr)->GetDestination(x,y,z);
5596 PSendSysMessage(LANG_MOVEGENS_POINT,x,y,z);
5597 break;
5599 case FLEEING_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_FEAR); break;
5600 case DISTRACT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_DISTRACT); break;
5601 default:
5602 PSendSysMessage(LANG_MOVEGENS_UNKNOWN,(*itr)->GetMovementGeneratorType());
5603 break;
5606 return true;
5609 bool ChatHandler::HandleServerPLimitCommand(const char *args)
5611 if(*args)
5613 char* param = strtok((char*)args, " ");
5614 if(!param)
5615 return false;
5617 int l = strlen(param);
5619 if( strncmp(param,"player",l) == 0 )
5620 sWorld.SetPlayerLimit(-SEC_PLAYER);
5621 else if(strncmp(param,"moderator",l) == 0 )
5622 sWorld.SetPlayerLimit(-SEC_MODERATOR);
5623 else if(strncmp(param,"gamemaster",l) == 0 )
5624 sWorld.SetPlayerLimit(-SEC_GAMEMASTER);
5625 else if(strncmp(param,"administrator",l) == 0 )
5626 sWorld.SetPlayerLimit(-SEC_ADMINISTRATOR);
5627 else if(strncmp(param,"reset",l) == 0 )
5628 sWorld.SetPlayerLimit( sConfig.GetIntDefault("PlayerLimit", DEFAULT_PLAYER_LIMIT) );
5629 else
5631 int val = atoi(param);
5632 if(val < -SEC_ADMINISTRATOR) val = -SEC_ADMINISTRATOR;
5634 sWorld.SetPlayerLimit(val);
5637 // kick all low security level players
5638 if(sWorld.GetPlayerAmountLimit() > SEC_PLAYER)
5639 sWorld.KickAllLess(sWorld.GetPlayerSecurityLimit());
5642 uint32 pLimit = sWorld.GetPlayerAmountLimit();
5643 AccountTypes allowedAccountType = sWorld.GetPlayerSecurityLimit();
5644 char const* secName = "";
5645 switch(allowedAccountType)
5647 case SEC_PLAYER: secName = "Player"; break;
5648 case SEC_MODERATOR: secName = "Moderator"; break;
5649 case SEC_GAMEMASTER: secName = "Gamemaster"; break;
5650 case SEC_ADMINISTRATOR: secName = "Administrator"; break;
5651 default: secName = "<unknown>"; break;
5654 PSendSysMessage("Player limits: amount %u, min. security level %s.",pLimit,secName);
5656 return true;
5659 bool ChatHandler::HandleCastCommand(const char* args)
5661 if(!*args)
5662 return false;
5664 Unit* target = getSelectedUnit();
5666 if(!target)
5668 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5669 SetSentErrorMessage(true);
5670 return false;
5673 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5674 uint32 spell = extractSpellIdFromLink((char*)args);
5675 if(!spell)
5676 return false;
5678 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
5679 if(!spellInfo)
5680 return false;
5682 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
5684 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
5685 SetSentErrorMessage(true);
5686 return false;
5689 char* trig_str = strtok(NULL, " ");
5690 if(trig_str)
5692 int l = strlen(trig_str);
5693 if(strncmp(trig_str,"triggered",l) != 0 )
5694 return false;
5697 bool triggered = (trig_str != NULL);
5699 m_session->GetPlayer()->CastSpell(target,spell,triggered);
5701 return true;
5704 bool ChatHandler::HandleCastBackCommand(const char* args)
5706 Creature* caster = getSelectedCreature();
5708 if(!caster)
5710 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5711 SetSentErrorMessage(true);
5712 return false;
5715 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
5716 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5717 uint32 spell = extractSpellIdFromLink((char*)args);
5718 if(!spell || !sSpellStore.LookupEntry(spell))
5719 return false;
5721 char* trig_str = strtok(NULL, " ");
5722 if(trig_str)
5724 int l = strlen(trig_str);
5725 if(strncmp(trig_str,"triggered",l) != 0 )
5726 return false;
5729 bool triggered = (trig_str != NULL);
5731 // update orientation at server
5732 caster->SetOrientation(caster->GetAngle(m_session->GetPlayer()));
5734 // and client
5735 WorldPacket data;
5736 caster->BuildHeartBeatMsg(&data);
5737 caster->SendMessageToSet(&data,true);
5739 caster->CastSpell(m_session->GetPlayer(),spell,triggered);
5741 return true;
5744 bool ChatHandler::HandleCastDistCommand(const char* args)
5746 if(!*args)
5747 return false;
5749 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5750 uint32 spell = extractSpellIdFromLink((char*)args);
5751 if(!spell)
5752 return false;
5754 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
5755 if(!spellInfo)
5756 return false;
5758 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
5760 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
5761 SetSentErrorMessage(true);
5762 return false;
5765 char *distStr = strtok(NULL, " ");
5767 float dist = 0;
5769 if(distStr)
5770 sscanf(distStr, "%f", &dist);
5772 char* trig_str = strtok(NULL, " ");
5773 if(trig_str)
5775 int l = strlen(trig_str);
5776 if(strncmp(trig_str,"triggered",l) != 0 )
5777 return false;
5780 bool triggered = (trig_str != NULL);
5782 float x,y,z;
5783 m_session->GetPlayer()->GetClosePoint(x,y,z,dist);
5785 m_session->GetPlayer()->CastSpell(x,y,z,spell,triggered);
5786 return true;
5789 bool ChatHandler::HandleCastTargetCommand(const char* args)
5791 Creature* caster = getSelectedCreature();
5793 if(!caster)
5795 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5796 SetSentErrorMessage(true);
5797 return false;
5800 if(!caster->getVictim())
5802 SendSysMessage(LANG_SELECTED_TARGET_NOT_HAVE_VICTIM);
5803 SetSentErrorMessage(true);
5804 return false;
5807 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5808 uint32 spell = extractSpellIdFromLink((char*)args);
5809 if(!spell || !sSpellStore.LookupEntry(spell))
5810 return false;
5812 char* trig_str = strtok(NULL, " ");
5813 if(trig_str)
5815 int l = strlen(trig_str);
5816 if(strncmp(trig_str,"triggered",l) != 0 )
5817 return false;
5820 bool triggered = (trig_str != NULL);
5822 // update orientation at server
5823 caster->SetOrientation(caster->GetAngle(m_session->GetPlayer()));
5825 // and client
5826 WorldPacket data;
5827 caster->BuildHeartBeatMsg(&data);
5828 caster->SendMessageToSet(&data,true);
5830 caster->CastSpell(caster->getVictim(),spell,triggered);
5832 return true;
5836 ComeToMe command REQUIRED for 3rd party scripting library to have access to PointMovementGenerator
5837 Without this function 3rd party scripting library will get linking errors (unresolved external)
5838 when attempting to use the PointMovementGenerator
5840 bool ChatHandler::HandleComeToMeCommand(const char *args)
5842 Creature* caster = getSelectedCreature();
5844 if(!caster)
5846 SendSysMessage(LANG_SELECT_CREATURE);
5847 SetSentErrorMessage(true);
5848 return false;
5851 char* newFlagStr = strtok((char*)args, " ");
5853 if(!newFlagStr)
5854 return false;
5856 uint32 newFlags = atoi(newFlagStr);
5858 caster->SetMonsterMoveFlags(MonsterMovementFlags(newFlags));
5860 Player* pl = m_session->GetPlayer();
5862 caster->GetMotionMaster()->MovePoint(0, pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ());
5863 return true;
5866 bool ChatHandler::HandleCastSelfCommand(const char* args)
5868 if(!*args)
5869 return false;
5871 Unit* target = getSelectedUnit();
5873 if(!target)
5875 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5876 SetSentErrorMessage(true);
5877 return false;
5880 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5881 uint32 spell = extractSpellIdFromLink((char*)args);
5882 if(!spell)
5883 return false;
5885 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
5886 if(!spellInfo)
5887 return false;
5889 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
5891 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
5892 SetSentErrorMessage(true);
5893 return false;
5896 target->CastSpell(target,spell,false);
5898 return true;
5901 std::string GetTimeString(uint32 time)
5903 uint16 days = time / DAY, hours = (time % DAY) / HOUR, minute = (time % HOUR) / MINUTE;
5904 std::ostringstream ss;
5905 if(days) ss << days << "d ";
5906 if(hours) ss << hours << "h ";
5907 ss << minute << "m";
5908 return ss.str();
5911 bool ChatHandler::HandleInstanceListBindsCommand(const char* /*args*/)
5913 Player* player = getSelectedPlayer();
5914 if (!player) player = m_session->GetPlayer();
5915 uint32 counter = 0;
5916 for(uint8 i = 0; i < MAX_DIFFICULTY; ++i)
5918 Player::BoundInstancesMap &binds = player->GetBoundInstances(Difficulty(i));
5919 for(Player::BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end(); ++itr)
5921 InstanceSave *save = itr->second.save;
5922 std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
5923 PSendSysMessage("map: %d inst: %d perm: %s diff: %s canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty() == DUNGEON_DIFFICULTY_NORMAL ? "normal" : "heroic", save->CanReset() ? "yes" : "no", timeleft.c_str());
5924 counter++;
5927 PSendSysMessage("player binds: %d", counter);
5928 counter = 0;
5929 Group *group = player->GetGroup();
5930 if(group)
5932 for(uint8 i = 0; i < MAX_DIFFICULTY; ++i)
5934 Group::BoundInstancesMap &binds = group->GetBoundInstances(Difficulty(i));
5935 for(Group::BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end(); ++itr)
5937 InstanceSave *save = itr->second.save;
5938 std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
5939 PSendSysMessage("map: %d inst: %d perm: %s diff: %s canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty() == DUNGEON_DIFFICULTY_NORMAL ? "normal" : "heroic", save->CanReset() ? "yes" : "no", timeleft.c_str());
5940 counter++;
5944 PSendSysMessage("group binds: %d", counter);
5946 return true;
5949 bool ChatHandler::HandleInstanceUnbindCommand(const char* args)
5951 if(!*args)
5952 return false;
5954 std::string cmd = args;
5955 if(cmd == "all")
5957 Player* player = getSelectedPlayer();
5958 if (!player) player = m_session->GetPlayer();
5959 uint32 counter = 0;
5960 for(uint8 i = 0; i < MAX_DIFFICULTY; ++i)
5962 Player::BoundInstancesMap &binds = player->GetBoundInstances(Difficulty(i));
5963 for(Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end();)
5965 if(itr->first != player->GetMapId())
5967 InstanceSave *save = itr->second.save;
5968 std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
5969 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() == DUNGEON_DIFFICULTY_NORMAL ? "normal" : "heroic", save->CanReset() ? "yes" : "no", timeleft.c_str());
5970 player->UnbindInstance(itr, Difficulty(i));
5971 counter++;
5973 else
5974 ++itr;
5977 PSendSysMessage("instances unbound: %d", counter);
5979 return true;
5982 bool ChatHandler::HandleInstanceStatsCommand(const char* /*args*/)
5984 PSendSysMessage("instances loaded: %d", MapManager::Instance().GetNumInstances());
5985 PSendSysMessage("players in instances: %d", MapManager::Instance().GetNumPlayersInInstances());
5986 PSendSysMessage("instance saves: %d", sInstanceSaveManager.GetNumInstanceSaves());
5987 PSendSysMessage("players bound: %d", sInstanceSaveManager.GetNumBoundPlayersTotal());
5988 PSendSysMessage("groups bound: %d", sInstanceSaveManager.GetNumBoundGroupsTotal());
5989 return true;
5992 bool ChatHandler::HandleInstanceSaveDataCommand(const char * /*args*/)
5994 Player* pl = m_session->GetPlayer();
5996 Map* map = pl->GetMap();
5997 if (!map->IsDungeon())
5999 PSendSysMessage("Map is not a dungeon.");
6000 SetSentErrorMessage(true);
6001 return false;
6004 if (!((InstanceMap*)map)->GetInstanceData())
6006 PSendSysMessage("Map has no instance data.");
6007 SetSentErrorMessage(true);
6008 return false;
6011 ((InstanceMap*)map)->GetInstanceData()->SaveToDB();
6012 return true;
6015 /// Display the list of GMs
6016 bool ChatHandler::HandleGMListFullCommand(const char* /*args*/)
6018 ///- Get the accounts with GM Level >0
6019 QueryResult *result = loginDatabase.Query( "SELECT username,gmlevel FROM account WHERE gmlevel > 0" );
6020 if(result)
6022 SendSysMessage(LANG_GMLIST);
6023 SendSysMessage("========================");
6024 SendSysMessage(LANG_GMLIST_HEADER);
6025 SendSysMessage("========================");
6027 ///- Circle through them. Display username and GM level
6030 Field *fields = result->Fetch();
6031 PSendSysMessage("|%15s|%6s|", fields[0].GetString(),fields[1].GetString());
6032 }while( result->NextRow() );
6034 PSendSysMessage("========================");
6035 delete result;
6037 else
6038 PSendSysMessage(LANG_GMLIST_EMPTY);
6039 return true;
6042 /// Define the 'Message of the day' for the realm
6043 bool ChatHandler::HandleServerSetMotdCommand(const char* args)
6045 sWorld.SetMotd(args);
6046 PSendSysMessage(LANG_MOTD_NEW, args);
6047 return true;
6050 /// Set/Unset the expansion level for an account
6051 bool ChatHandler::HandleAccountSetAddonCommand(const char* args)
6053 ///- Get the command line arguments
6054 char *szAcc = strtok((char*)args," ");
6055 char *szExp = strtok(NULL," ");
6057 if(!szAcc)
6058 return false;
6060 std::string account_name;
6061 uint32 account_id;
6063 if (!szExp)
6065 Player* player = getSelectedPlayer();
6066 if (!player)
6067 return false;
6069 account_id = player->GetSession()->GetAccountId();
6070 accmgr.GetName(account_id,account_name);
6071 szExp = szAcc;
6073 else
6075 ///- Convert Account name to Upper Format
6076 account_name = szAcc;
6077 if (!AccountMgr::normalizeString(account_name))
6079 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
6080 SetSentErrorMessage(true);
6081 return false;
6084 account_id = accmgr.GetId(account_name);
6085 if (!account_id)
6087 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
6088 SetSentErrorMessage(true);
6089 return false;
6094 // Let set addon state only for lesser (strong) security level
6095 // or to self account
6096 if (m_session && m_session->GetAccountId () != account_id &&
6097 HasLowerSecurityAccount (NULL,account_id,true))
6098 return false;
6100 int lev=atoi(szExp); //get int anyway (0 if error)
6101 if(lev < 0)
6102 return false;
6104 // No SQL injection
6105 loginDatabase.PExecute("UPDATE account SET expansion = '%d' WHERE id = '%u'",lev,account_id);
6106 PSendSysMessage(LANG_ACCOUNT_SETADDON,account_name.c_str(),account_id,lev);
6107 return true;
6110 //Send items by mail
6111 bool ChatHandler::HandleSendItemsCommand(const char* args)
6113 // format: name "subject text" "mail text" item1[:count1] item2[:count2] ... item12[:count12]
6114 Player* receiver;
6115 uint64 receiver_guid;
6116 std::string receiver_name;
6117 if(!extractPlayerTarget((char*)args,&receiver,&receiver_guid,&receiver_name))
6118 return false;
6120 char* tail1 = strtok(NULL, "");
6121 if(!tail1)
6122 return false;
6124 char* msgSubject = extractQuotedArg(tail1);
6125 if (!msgSubject)
6126 return false;
6128 char* tail2 = strtok(NULL, "");
6129 if(!tail2)
6130 return false;
6132 char* msgText = extractQuotedArg(tail2);
6133 if (!msgText)
6134 return false;
6136 // msgSubject, msgText isn't NUL after prev. check
6137 std::string subject = msgSubject;
6138 std::string text = msgText;
6140 // extract items
6141 typedef std::pair<uint32,uint32> ItemPair;
6142 typedef std::list< ItemPair > ItemPairs;
6143 ItemPairs items;
6145 // get all tail string
6146 char* tail = strtok(NULL, "");
6148 // get from tail next item str
6149 while(char* itemStr = strtok(tail, " "))
6151 // and get new tail
6152 tail = strtok(NULL, "");
6154 // parse item str
6155 char* itemIdStr = strtok(itemStr, ":");
6156 char* itemCountStr = strtok(NULL, " ");
6158 uint32 item_id = atoi(itemIdStr);
6159 if(!item_id)
6160 return false;
6162 ItemPrototype const* item_proto = objmgr.GetItemPrototype(item_id);
6163 if(!item_proto)
6165 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
6166 SetSentErrorMessage(true);
6167 return false;
6170 uint32 item_count = itemCountStr ? atoi(itemCountStr) : 1;
6171 if (item_count < 1 || (item_proto->MaxCount > 0 && item_count > uint32(item_proto->MaxCount)))
6173 PSendSysMessage(LANG_COMMAND_INVALID_ITEM_COUNT, item_count,item_id);
6174 SetSentErrorMessage(true);
6175 return false;
6178 while(item_count > item_proto->GetMaxStackSize())
6180 items.push_back(ItemPair(item_id,item_proto->GetMaxStackSize()));
6181 item_count -= item_proto->GetMaxStackSize();
6184 items.push_back(ItemPair(item_id,item_count));
6186 if(items.size() > MAX_MAIL_ITEMS)
6188 PSendSysMessage(LANG_COMMAND_MAIL_ITEMS_LIMIT, MAX_MAIL_ITEMS);
6189 SetSentErrorMessage(true);
6190 return false;
6194 // from console show not existed sender
6195 uint32 sender_guidlo = m_session ? m_session->GetPlayer()->GetGUIDLow() : 0;
6197 uint32 messagetype = MAIL_NORMAL;
6198 uint32 stationery = MAIL_STATIONERY_GM;
6199 uint32 itemTextId = !text.empty() ? objmgr.CreateItemText( text ) : 0;
6201 // fill mail
6202 MailItemsInfo mi; // item list preparing
6204 for(ItemPairs::const_iterator itr = items.begin(); itr != items.end(); ++itr)
6206 if(Item* item = Item::CreateItem(itr->first,itr->second,m_session ? m_session->GetPlayer() : 0))
6208 item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted
6209 mi.AddItem(item->GetGUIDLow(), item->GetEntry(), item);
6213 WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, &mi, 0, 0, MAIL_CHECK_MASK_NONE);
6215 std::string nameLink = playerLink(receiver_name);
6216 PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
6217 return true;
6220 ///Send money by mail
6221 bool ChatHandler::HandleSendMoneyCommand(const char* args)
6223 /// format: name "subject text" "mail text" money
6225 Player* receiver;
6226 uint64 receiver_guid;
6227 std::string receiver_name;
6228 if(!extractPlayerTarget((char*)args,&receiver,&receiver_guid,&receiver_name))
6229 return false;
6231 char* tail1 = strtok(NULL, "");
6232 if (!tail1)
6233 return false;
6235 char* msgSubject = extractQuotedArg(tail1);
6236 if (!msgSubject)
6237 return false;
6239 char* tail2 = strtok(NULL, "");
6240 if (!tail2)
6241 return false;
6243 char* msgText = extractQuotedArg(tail2);
6244 if (!msgText)
6245 return false;
6247 char* money_str = strtok(NULL, "");
6248 int32 money = money_str ? atoi(money_str) : 0;
6249 if (money <= 0)
6250 return false;
6252 // msgSubject, msgText isn't NUL after prev. check
6253 std::string subject = msgSubject;
6254 std::string text = msgText;
6256 // from console show not existed sender
6257 uint32 sender_guidlo = m_session ? m_session->GetPlayer()->GetGUIDLow() : 0;
6259 uint32 messagetype = MAIL_NORMAL;
6260 uint32 stationery = MAIL_STATIONERY_GM;
6261 uint32 itemTextId = !text.empty() ? objmgr.CreateItemText( text ) : 0;
6263 WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, NULL, money, 0, MAIL_CHECK_MASK_NONE);
6265 std::string nameLink = playerLink(receiver_name);
6266 PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
6267 return true;
6270 /// Send a message to a player in game
6271 bool ChatHandler::HandleSendMessageCommand(const char* args)
6273 ///- Find the player
6274 Player *rPlayer;
6275 if(!extractPlayerTarget((char*)args,&rPlayer))
6276 return false;
6278 char* msg_str = strtok(NULL, "");
6279 if(!msg_str)
6280 return false;
6282 ///- Check that he is not logging out.
6283 if(rPlayer->GetSession()->isLogingOut())
6285 SendSysMessage(LANG_PLAYER_NOT_FOUND);
6286 SetSentErrorMessage(true);
6287 return false;
6290 ///- Send the message
6291 //Use SendAreaTriggerMessage for fastest delivery.
6292 rPlayer->GetSession()->SendAreaTriggerMessage("%s", msg_str);
6293 rPlayer->GetSession()->SendAreaTriggerMessage("|cffff0000[Message from administrator]:|r");
6295 //Confirmation message
6296 std::string nameLink = GetNameLink(rPlayer);
6297 PSendSysMessage(LANG_SENDMESSAGE,nameLink.c_str(),msg_str);
6298 return true;
6301 bool ChatHandler::HandleFlushArenaPointsCommand(const char * /*args*/)
6303 sBattleGroundMgr.DistributeArenaPoints();
6304 return true;
6307 bool ChatHandler::HandleModifyGenderCommand(const char *args)
6309 if(!*args)
6310 return false;
6312 Player *player = getSelectedPlayer();
6314 if(!player)
6316 PSendSysMessage(LANG_PLAYER_NOT_FOUND);
6317 SetSentErrorMessage(true);
6318 return false;
6321 PlayerInfo const* info = objmgr.GetPlayerInfo(player->getRace(), player->getClass());
6322 if(!info)
6323 return false;
6325 char const* gender_str = (char*)args;
6326 int gender_len = strlen(gender_str);
6328 Gender gender;
6330 if(!strncmp(gender_str, "male", gender_len)) // MALE
6332 if(player->getGender() == GENDER_MALE)
6333 return true;
6335 gender = GENDER_MALE;
6337 else if (!strncmp(gender_str, "female", gender_len)) // FEMALE
6339 if(player->getGender() == GENDER_FEMALE)
6340 return true;
6342 gender = GENDER_FEMALE;
6344 else
6346 SendSysMessage(LANG_MUST_MALE_OR_FEMALE);
6347 SetSentErrorMessage(true);
6348 return false;
6351 // Set gender
6352 player->SetByteValue(UNIT_FIELD_BYTES_0, 2, gender);
6353 player->SetByteValue(PLAYER_BYTES_3, 0, gender);
6355 // Change display ID
6356 player->InitDisplayIds();
6358 char const* gender_full = gender ? "female" : "male";
6360 PSendSysMessage(LANG_YOU_CHANGE_GENDER, GetNameLink(player).c_str(), gender_full);
6362 if (needReportToTarget(player))
6363 ChatHandler(player).PSendSysMessage(LANG_YOUR_GENDER_CHANGED, gender_full, GetNameLink().c_str());
6365 return true;