[8769] Implement mails sending at player levelup.
[getmangos.git] / src / game / Level3.cpp
blobc4d65f6bb65511f0d4990c5390947ac6c7e9f40f
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 HandleReloadMailLevelRewardCommand("");
71 HandleReloadCommandCommand("");
72 HandleReloadReservedNameCommand("");
73 HandleReloadMangosStringCommand("");
74 HandleReloadGameTeleCommand("");
75 return true;
78 bool ChatHandler::HandleReloadAllAchievementCommand(const char*)
80 HandleReloadAchievementCriteriaRequirementCommand("");
81 HandleReloadAchievementRewardCommand("");
82 return true;
85 bool ChatHandler::HandleReloadAllAreaCommand(const char*)
87 //HandleReloadQuestAreaTriggersCommand(""); -- reloaded in HandleReloadAllQuestCommand
88 HandleReloadAreaTriggerTeleportCommand("");
89 HandleReloadAreaTriggerTavernCommand("");
90 HandleReloadGameGraveyardZoneCommand("");
91 return true;
94 bool ChatHandler::HandleReloadAllLootCommand(const char*)
96 sLog.outString( "Re-Loading Loot Tables..." );
97 LoadLootTables();
98 SendGlobalSysMessage("DB tables `*_loot_template` reloaded.");
99 return true;
102 bool ChatHandler::HandleReloadAllNpcCommand(const char* /*args*/)
104 HandleReloadNpcGossipCommand("a");
105 HandleReloadNpcOptionCommand("a");
106 HandleReloadNpcTrainerCommand("a");
107 HandleReloadNpcVendorCommand("a");
108 HandleReloadPointsOfInterestCommand("a");
109 HandleReloadSpellClickSpellsCommand("a");
110 return true;
113 bool ChatHandler::HandleReloadAllQuestCommand(const char* /*args*/)
115 HandleReloadQuestAreaTriggersCommand("a");
116 HandleReloadQuestTemplateCommand("a");
118 sLog.outString( "Re-Loading Quests Relations..." );
119 objmgr.LoadQuestRelations();
120 SendGlobalSysMessage("DB tables `*_questrelation` and `*_involvedrelation` reloaded.");
121 return true;
124 bool ChatHandler::HandleReloadAllScriptsCommand(const char*)
126 if(sWorld.IsScriptScheduled())
128 PSendSysMessage("DB scripts used currently, please attempt reload later.");
129 SetSentErrorMessage(true);
130 return false;
133 sLog.outString( "Re-Loading Scripts..." );
134 HandleReloadGameObjectScriptsCommand("a");
135 HandleReloadEventScriptsCommand("a");
136 HandleReloadQuestEndScriptsCommand("a");
137 HandleReloadQuestStartScriptsCommand("a");
138 HandleReloadSpellScriptsCommand("a");
139 SendGlobalSysMessage("DB tables `*_scripts` reloaded.");
140 HandleReloadDbScriptStringCommand("a");
141 return true;
144 bool ChatHandler::HandleReloadAllEventAICommand(const char*)
146 HandleReloadEventAITextsCommand("a");
147 HandleReloadEventAISummonsCommand("a");
148 HandleReloadEventAIScriptsCommand("a");
149 return true;
152 bool ChatHandler::HandleReloadAllSpellCommand(const char*)
154 HandleReloadSkillDiscoveryTemplateCommand("a");
155 HandleReloadSkillExtraItemTemplateCommand("a");
156 HandleReloadSpellAreaCommand("a");
157 HandleReloadSpellChainCommand("a");
158 HandleReloadSpellElixirCommand("a");
159 HandleReloadSpellLearnSpellCommand("a");
160 HandleReloadSpellProcEventCommand("a");
161 HandleReloadSpellBonusesCommand("a");
162 HandleReloadSpellProcItemEnchantCommand("a");
163 HandleReloadSpellScriptTargetCommand("a");
164 HandleReloadSpellTargetPositionCommand("a");
165 HandleReloadSpellThreatsCommand("a");
166 HandleReloadSpellPetAurasCommand("a");
167 return true;
170 bool ChatHandler::HandleReloadAllItemCommand(const char*)
172 HandleReloadPageTextsCommand("a");
173 HandleReloadItemEnchantementsCommand("a");
174 HandleReloadItemRequiredTragetCommand("a");
175 return true;
178 bool ChatHandler::HandleReloadAllLocalesCommand(const char* /*args*/)
180 HandleReloadLocalesAchievementRewardCommand("a");
181 HandleReloadLocalesCreatureCommand("a");
182 HandleReloadLocalesGameobjectCommand("a");
183 HandleReloadLocalesItemCommand("a");
184 HandleReloadLocalesNpcTextCommand("a");
185 HandleReloadLocalesPageTextCommand("a");
186 HandleReloadLocalesPointsOfInterestCommand("a");
187 HandleReloadLocalesQuestCommand("a");
188 return true;
191 bool ChatHandler::HandleReloadConfigCommand(const char* /*args*/)
193 sLog.outString( "Re-Loading config settings..." );
194 sWorld.LoadConfigSettings(true);
195 MapManager::Instance().InitializeVisibilityDistanceInfo();
196 SendGlobalSysMessage("World config settings reloaded.");
197 return true;
200 bool ChatHandler::HandleReloadAchievementCriteriaRequirementCommand(const char*)
202 sLog.outString( "Re-Loading Additional Achievement Criteria Requirements Data..." );
203 achievementmgr.LoadAchievementCriteriaRequirements();
204 SendGlobalSysMessage("DB table `achievement_criteria_requirement` reloaded.");
205 return true;
208 bool ChatHandler::HandleReloadAchievementRewardCommand(const char*)
210 sLog.outString( "Re-Loading Achievement Reward Data..." );
211 achievementmgr.LoadRewards();
212 SendGlobalSysMessage("DB table `achievement_reward` reloaded.");
213 return true;
216 bool ChatHandler::HandleReloadAreaTriggerTavernCommand(const char*)
218 sLog.outString( "Re-Loading Tavern Area Triggers..." );
219 objmgr.LoadTavernAreaTriggers();
220 SendGlobalSysMessage("DB table `areatrigger_tavern` reloaded.");
221 return true;
224 bool ChatHandler::HandleReloadAreaTriggerTeleportCommand(const char*)
226 sLog.outString( "Re-Loading AreaTrigger teleport definitions..." );
227 objmgr.LoadAreaTriggerTeleports();
228 SendGlobalSysMessage("DB table `areatrigger_teleport` reloaded.");
229 return true;
232 bool ChatHandler::HandleReloadCommandCommand(const char*)
234 load_command_table = true;
235 SendGlobalSysMessage("DB table `command` will be reloaded at next chat command use.");
236 return true;
239 bool ChatHandler::HandleReloadCreatureQuestRelationsCommand(const char*)
241 sLog.outString( "Loading Quests Relations... (`creature_questrelation`)" );
242 objmgr.LoadCreatureQuestRelations();
243 SendGlobalSysMessage("DB table `creature_questrelation` (creature quest givers) reloaded.");
244 return true;
247 bool ChatHandler::HandleReloadCreatureQuestInvRelationsCommand(const char*)
249 sLog.outString( "Loading Quests Relations... (`creature_involvedrelation`)" );
250 objmgr.LoadCreatureInvolvedRelations();
251 SendGlobalSysMessage("DB table `creature_involvedrelation` (creature quest takers) reloaded.");
252 return true;
255 bool ChatHandler::HandleReloadGOQuestRelationsCommand(const char*)
257 sLog.outString( "Loading Quests Relations... (`gameobject_questrelation`)" );
258 objmgr.LoadGameobjectQuestRelations();
259 SendGlobalSysMessage("DB table `gameobject_questrelation` (gameobject quest givers) reloaded.");
260 return true;
263 bool ChatHandler::HandleReloadGOQuestInvRelationsCommand(const char*)
265 sLog.outString( "Loading Quests Relations... (`gameobject_involvedrelation`)" );
266 objmgr.LoadGameobjectInvolvedRelations();
267 SendGlobalSysMessage("DB table `gameobject_involvedrelation` (gameobject quest takers) reloaded.");
268 return true;
271 bool ChatHandler::HandleReloadQuestAreaTriggersCommand(const char*)
273 sLog.outString( "Re-Loading Quest Area Triggers..." );
274 objmgr.LoadQuestAreaTriggers();
275 SendGlobalSysMessage("DB table `areatrigger_involvedrelation` (quest area triggers) reloaded.");
276 return true;
279 bool ChatHandler::HandleReloadQuestTemplateCommand(const char*)
281 sLog.outString( "Re-Loading Quest Templates..." );
282 objmgr.LoadQuests();
283 SendGlobalSysMessage("DB table `quest_template` (quest definitions) reloaded.");
285 /// dependent also from `gameobject` but this table not reloaded anyway
286 sLog.outString( "Re-Loading GameObjects for quests..." );
287 objmgr.LoadGameObjectForQuests();
288 SendGlobalSysMessage("Data GameObjects for quests reloaded.");
289 return true;
292 bool ChatHandler::HandleReloadLootTemplatesCreatureCommand(const char*)
294 sLog.outString( "Re-Loading Loot Tables... (`creature_loot_template`)" );
295 LoadLootTemplates_Creature();
296 LootTemplates_Creature.CheckLootRefs();
297 SendGlobalSysMessage("DB table `creature_loot_template` reloaded.");
298 return true;
301 bool ChatHandler::HandleReloadLootTemplatesDisenchantCommand(const char*)
303 sLog.outString( "Re-Loading Loot Tables... (`disenchant_loot_template`)" );
304 LoadLootTemplates_Disenchant();
305 LootTemplates_Disenchant.CheckLootRefs();
306 SendGlobalSysMessage("DB table `disenchant_loot_template` reloaded.");
307 return true;
310 bool ChatHandler::HandleReloadLootTemplatesFishingCommand(const char*)
312 sLog.outString( "Re-Loading Loot Tables... (`fishing_loot_template`)" );
313 LoadLootTemplates_Fishing();
314 LootTemplates_Fishing.CheckLootRefs();
315 SendGlobalSysMessage("DB table `fishing_loot_template` reloaded.");
316 return true;
319 bool ChatHandler::HandleReloadLootTemplatesGameobjectCommand(const char*)
321 sLog.outString( "Re-Loading Loot Tables... (`gameobject_loot_template`)" );
322 LoadLootTemplates_Gameobject();
323 LootTemplates_Gameobject.CheckLootRefs();
324 SendGlobalSysMessage("DB table `gameobject_loot_template` reloaded.");
325 return true;
328 bool ChatHandler::HandleReloadLootTemplatesItemCommand(const char*)
330 sLog.outString( "Re-Loading Loot Tables... (`item_loot_template`)" );
331 LoadLootTemplates_Item();
332 LootTemplates_Item.CheckLootRefs();
333 SendGlobalSysMessage("DB table `item_loot_template` reloaded.");
334 return true;
337 bool ChatHandler::HandleReloadLootTemplatesMillingCommand(const char*)
339 sLog.outString( "Re-Loading Loot Tables... (`milling_loot_template`)" );
340 LoadLootTemplates_Milling();
341 LootTemplates_Milling.CheckLootRefs();
342 SendGlobalSysMessage("DB table `milling_loot_template` reloaded.");
343 return true;
346 bool ChatHandler::HandleReloadLootTemplatesPickpocketingCommand(const char*)
348 sLog.outString( "Re-Loading Loot Tables... (`pickpocketing_loot_template`)" );
349 LoadLootTemplates_Pickpocketing();
350 LootTemplates_Pickpocketing.CheckLootRefs();
351 SendGlobalSysMessage("DB table `pickpocketing_loot_template` reloaded.");
352 return true;
355 bool ChatHandler::HandleReloadLootTemplatesProspectingCommand(const char*)
357 sLog.outString( "Re-Loading Loot Tables... (`prospecting_loot_template`)" );
358 LoadLootTemplates_Prospecting();
359 LootTemplates_Prospecting.CheckLootRefs();
360 SendGlobalSysMessage("DB table `prospecting_loot_template` reloaded.");
361 return true;
364 bool ChatHandler::HandleReloadLootTemplatesMailCommand(const char*)
366 sLog.outString( "Re-Loading Loot Tables... (`mail_loot_template`)" );
367 LoadLootTemplates_Mail();
368 LootTemplates_Mail.CheckLootRefs();
369 SendGlobalSysMessage("DB table `mail_loot_template` reloaded.");
370 return true;
373 bool ChatHandler::HandleReloadLootTemplatesReferenceCommand(const char*)
375 sLog.outString( "Re-Loading Loot Tables... (`reference_loot_template`)" );
376 LoadLootTemplates_Reference();
377 SendGlobalSysMessage("DB table `reference_loot_template` reloaded.");
378 return true;
381 bool ChatHandler::HandleReloadLootTemplatesSkinningCommand(const char*)
383 sLog.outString( "Re-Loading Loot Tables... (`skinning_loot_template`)" );
384 LoadLootTemplates_Skinning();
385 LootTemplates_Skinning.CheckLootRefs();
386 SendGlobalSysMessage("DB table `skinning_loot_template` reloaded.");
387 return true;
390 bool ChatHandler::HandleReloadLootTemplatesSpellCommand(const char*)
392 sLog.outString( "Re-Loading Loot Tables... (`spell_loot_template`)" );
393 LoadLootTemplates_Spell();
394 LootTemplates_Spell.CheckLootRefs();
395 SendGlobalSysMessage("DB table `spell_loot_template` reloaded.");
396 return true;
399 bool ChatHandler::HandleReloadMangosStringCommand(const char*)
401 sLog.outString( "Re-Loading mangos_string Table!" );
402 objmgr.LoadMangosStrings();
403 SendGlobalSysMessage("DB table `mangos_string` reloaded.");
404 return true;
407 bool ChatHandler::HandleReloadNpcOptionCommand(const char*)
409 sLog.outString( "Re-Loading `npc_option` Table!" );
410 objmgr.LoadNpcOptions();
411 SendGlobalSysMessage("DB table `npc_option` reloaded.");
412 return true;
415 bool ChatHandler::HandleReloadNpcGossipCommand(const char*)
417 sLog.outString( "Re-Loading `npc_gossip` Table!" );
418 objmgr.LoadNpcTextId();
419 SendGlobalSysMessage("DB table `npc_gossip` reloaded.");
420 return true;
423 bool ChatHandler::HandleReloadNpcTrainerCommand(const char*)
425 sLog.outString( "Re-Loading `npc_trainer` Table!" );
426 objmgr.LoadTrainerSpell();
427 SendGlobalSysMessage("DB table `npc_trainer` reloaded.");
428 return true;
431 bool ChatHandler::HandleReloadNpcVendorCommand(const char*)
433 sLog.outString( "Re-Loading `npc_vendor` Table!" );
434 objmgr.LoadVendors();
435 SendGlobalSysMessage("DB table `npc_vendor` reloaded.");
436 return true;
439 bool ChatHandler::HandleReloadPointsOfInterestCommand(const char*)
441 sLog.outString( "Re-Loading `points_of_interest` Table!" );
442 objmgr.LoadPointsOfInterest();
443 SendGlobalSysMessage("DB table `points_of_interest` reloaded.");
444 return true;
447 bool ChatHandler::HandleReloadSpellClickSpellsCommand(const char*)
449 sLog.outString( "Re-Loading `npc_spellclick_spells` Table!" );
450 objmgr.LoadNPCSpellClickSpells();
451 SendGlobalSysMessage("DB table `npc_spellclick_spells` reloaded.");
452 return true;
455 bool ChatHandler::HandleReloadReservedNameCommand(const char*)
457 sLog.outString( "Loading ReservedNames... (`reserved_name`)" );
458 objmgr.LoadReservedPlayersNames();
459 SendGlobalSysMessage("DB table `reserved_name` (player reserved names) reloaded.");
460 return true;
463 bool ChatHandler::HandleReloadSkillDiscoveryTemplateCommand(const char* /*args*/)
465 sLog.outString( "Re-Loading Skill Discovery Table..." );
466 LoadSkillDiscoveryTable();
467 SendGlobalSysMessage("DB table `skill_discovery_template` (recipes discovered at crafting) reloaded.");
468 return true;
471 bool ChatHandler::HandleReloadSkillExtraItemTemplateCommand(const char* /*args*/)
473 sLog.outString( "Re-Loading Skill Extra Item Table..." );
474 LoadSkillExtraItemTable();
475 SendGlobalSysMessage("DB table `skill_extra_item_template` (extra item creation when crafting) reloaded.");
476 return true;
479 bool ChatHandler::HandleReloadSkillFishingBaseLevelCommand(const char* /*args*/)
481 sLog.outString( "Re-Loading Skill Fishing base level requirements..." );
482 objmgr.LoadFishingBaseSkillLevel();
483 SendGlobalSysMessage("DB table `skill_fishing_base_level` (fishing base level for zone/subzone) reloaded.");
484 return true;
487 bool ChatHandler::HandleReloadSpellAreaCommand(const char*)
489 sLog.outString( "Re-Loading SpellArea Data..." );
490 spellmgr.LoadSpellAreas();
491 SendGlobalSysMessage("DB table `spell_area` (spell dependences from area/quest/auras state) reloaded.");
492 return true;
495 bool ChatHandler::HandleReloadSpellChainCommand(const char*)
497 sLog.outString( "Re-Loading Spell Chain Data... " );
498 spellmgr.LoadSpellChains();
499 SendGlobalSysMessage("DB table `spell_chain` (spell ranks) reloaded.");
500 return true;
503 bool ChatHandler::HandleReloadSpellElixirCommand(const char*)
505 sLog.outString( "Re-Loading Spell Elixir types..." );
506 spellmgr.LoadSpellElixirs();
507 SendGlobalSysMessage("DB table `spell_elixir` (spell elixir types) reloaded.");
508 return true;
511 bool ChatHandler::HandleReloadSpellLearnSpellCommand(const char*)
513 sLog.outString( "Re-Loading Spell Learn Spells..." );
514 spellmgr.LoadSpellLearnSpells();
515 SendGlobalSysMessage("DB table `spell_learn_spell` reloaded.");
516 return true;
519 bool ChatHandler::HandleReloadSpellProcEventCommand(const char*)
521 sLog.outString( "Re-Loading Spell Proc Event conditions..." );
522 spellmgr.LoadSpellProcEvents();
523 SendGlobalSysMessage("DB table `spell_proc_event` (spell proc trigger requirements) reloaded.");
524 return true;
527 bool ChatHandler::HandleReloadSpellBonusesCommand(const char*)
529 sLog.outString( "Re-Loading Spell Bonus Data..." );
530 spellmgr.LoadSpellBonusess();
531 SendGlobalSysMessage("DB table `spell_bonus_data` (spell damage/healing coefficients) reloaded.");
532 return true;
535 bool ChatHandler::HandleReloadSpellProcItemEnchantCommand(const char*)
537 sLog.outString( "Re-Loading Spell Proc Item Enchant..." );
538 spellmgr.LoadSpellProcItemEnchant();
539 SendGlobalSysMessage("DB table `spell_proc_item_enchant` (item enchantment ppm) reloaded.");
540 return true;
543 bool ChatHandler::HandleReloadSpellScriptTargetCommand(const char*)
545 sLog.outString( "Re-Loading SpellsScriptTarget..." );
546 spellmgr.LoadSpellScriptTarget();
547 SendGlobalSysMessage("DB table `spell_script_target` (spell targets selection in case specific creature/GO requirements) reloaded.");
548 return true;
551 bool ChatHandler::HandleReloadSpellTargetPositionCommand(const char*)
553 sLog.outString( "Re-Loading Spell target coordinates..." );
554 spellmgr.LoadSpellTargetPositions();
555 SendGlobalSysMessage("DB table `spell_target_position` (destination coordinates for spell targets) reloaded.");
556 return true;
559 bool ChatHandler::HandleReloadSpellThreatsCommand(const char*)
561 sLog.outString( "Re-Loading Aggro Spells Definitions...");
562 spellmgr.LoadSpellThreats();
563 SendGlobalSysMessage("DB table `spell_threat` (spell aggro definitions) reloaded.");
564 return true;
567 bool ChatHandler::HandleReloadSpellPetAurasCommand(const char*)
569 sLog.outString( "Re-Loading Spell pet auras...");
570 spellmgr.LoadSpellPetAuras();
571 SendGlobalSysMessage("DB table `spell_pet_auras` reloaded.");
572 return true;
575 bool ChatHandler::HandleReloadPageTextsCommand(const char*)
577 sLog.outString( "Re-Loading Page Texts..." );
578 objmgr.LoadPageTexts();
579 SendGlobalSysMessage("DB table `page_texts` reloaded.");
580 return true;
583 bool ChatHandler::HandleReloadItemEnchantementsCommand(const char*)
585 sLog.outString( "Re-Loading Item Random Enchantments Table..." );
586 LoadRandomEnchantmentsTable();
587 SendGlobalSysMessage("DB table `item_enchantment_template` reloaded.");
588 return true;
591 bool ChatHandler::HandleReloadItemRequiredTragetCommand(const char*)
593 sLog.outString( "Re-Loading Item Required Targets Table..." );
594 objmgr.LoadItemRequiredTarget();
595 SendGlobalSysMessage("DB table `item_required_target` reloaded.");
596 return true;
599 bool ChatHandler::HandleReloadBattleEventCommand(const char*)
601 sLog.outString( "Re-Loading BattleGround Eventindexes..." );
602 sBattleGroundMgr.LoadBattleEventIndexes();
603 SendGlobalSysMessage("DB table `gameobject_battleground` and `creature_battleground` reloaded.");
604 return true;
607 bool ChatHandler::HandleReloadGameObjectScriptsCommand(const char* arg)
609 if(sWorld.IsScriptScheduled())
611 SendSysMessage("DB scripts used currently, please attempt reload later.");
612 SetSentErrorMessage(true);
613 return false;
616 if(*arg!='a')
617 sLog.outString( "Re-Loading Scripts from `gameobject_scripts`...");
619 objmgr.LoadGameObjectScripts();
621 if(*arg!='a')
622 SendGlobalSysMessage("DB table `gameobject_scripts` reloaded.");
624 return true;
627 bool ChatHandler::HandleReloadEventScriptsCommand(const char* arg)
629 if(sWorld.IsScriptScheduled())
631 SendSysMessage("DB scripts used currently, please attempt reload later.");
632 SetSentErrorMessage(true);
633 return false;
636 if(*arg!='a')
637 sLog.outString( "Re-Loading Scripts from `event_scripts`...");
639 objmgr.LoadEventScripts();
641 if(*arg!='a')
642 SendGlobalSysMessage("DB table `event_scripts` reloaded.");
644 return true;
647 bool ChatHandler::HandleReloadEventAITextsCommand(const char* arg)
650 sLog.outString( "Re-Loading Texts from `creature_ai_texts`...");
651 CreatureEAI_Mgr.LoadCreatureEventAI_Texts(true);
652 SendGlobalSysMessage("DB table `creature_ai_texts` reloaded.");
653 return true;
656 bool ChatHandler::HandleReloadEventAISummonsCommand(const char* arg)
658 sLog.outString( "Re-Loading Summons from `creature_ai_summons`...");
659 CreatureEAI_Mgr.LoadCreatureEventAI_Summons(true);
660 SendGlobalSysMessage("DB table `creature_ai_summons` reloaded.");
661 return true;
664 bool ChatHandler::HandleReloadEventAIScriptsCommand(const char* arg)
666 sLog.outString( "Re-Loading Scripts from `creature_ai_scripts`...");
667 CreatureEAI_Mgr.LoadCreatureEventAI_Scripts();
668 SendGlobalSysMessage("DB table `creature_ai_scripts` reloaded.");
669 return true;
672 bool ChatHandler::HandleReloadQuestEndScriptsCommand(const char* arg)
674 if(sWorld.IsScriptScheduled())
676 SendSysMessage("DB scripts used currently, please attempt reload later.");
677 SetSentErrorMessage(true);
678 return false;
681 if(*arg!='a')
682 sLog.outString( "Re-Loading Scripts from `quest_end_scripts`...");
684 objmgr.LoadQuestEndScripts();
686 if(*arg!='a')
687 SendGlobalSysMessage("DB table `quest_end_scripts` reloaded.");
689 return true;
692 bool ChatHandler::HandleReloadQuestStartScriptsCommand(const char* arg)
694 if(sWorld.IsScriptScheduled())
696 SendSysMessage("DB scripts used currently, please attempt reload later.");
697 SetSentErrorMessage(true);
698 return false;
701 if(*arg!='a')
702 sLog.outString( "Re-Loading Scripts from `quest_start_scripts`...");
704 objmgr.LoadQuestStartScripts();
706 if(*arg!='a')
707 SendGlobalSysMessage("DB table `quest_start_scripts` reloaded.");
709 return true;
712 bool ChatHandler::HandleReloadSpellScriptsCommand(const char* arg)
714 if(sWorld.IsScriptScheduled())
716 SendSysMessage("DB scripts used currently, please attempt reload later.");
717 SetSentErrorMessage(true);
718 return false;
721 if(*arg!='a')
722 sLog.outString( "Re-Loading Scripts from `spell_scripts`...");
724 objmgr.LoadSpellScripts();
726 if(*arg!='a')
727 SendGlobalSysMessage("DB table `spell_scripts` reloaded.");
729 return true;
732 bool ChatHandler::HandleReloadDbScriptStringCommand(const char* /*arg*/)
734 sLog.outString( "Re-Loading Script strings from `db_script_string`...");
735 objmgr.LoadDbScriptStrings();
736 SendGlobalSysMessage("DB table `db_script_string` reloaded.");
737 return true;
740 bool ChatHandler::HandleReloadGameGraveyardZoneCommand(const char* /*arg*/)
742 sLog.outString( "Re-Loading Graveyard-zone links...");
744 objmgr.LoadGraveyardZones();
746 SendGlobalSysMessage("DB table `game_graveyard_zone` reloaded.");
748 return true;
751 bool ChatHandler::HandleReloadGameTeleCommand(const char* /*arg*/)
753 sLog.outString( "Re-Loading Game Tele coordinates...");
755 objmgr.LoadGameTele();
757 SendGlobalSysMessage("DB table `game_tele` reloaded.");
759 return true;
762 bool ChatHandler::HandleReloadLocalesAchievementRewardCommand(const char*)
764 sLog.outString( "Re-Loading Locales Achievement Reward Data..." );
765 achievementmgr.LoadRewardLocales();
766 SendGlobalSysMessage("DB table `locales_achievement_reward` reloaded.");
767 return true;
770 bool ChatHandler::HandleReloadLocalesCreatureCommand(const char* /*arg*/)
772 sLog.outString( "Re-Loading Locales Creature ...");
773 objmgr.LoadCreatureLocales();
774 SendGlobalSysMessage("DB table `locales_creature` reloaded.");
775 return true;
778 bool ChatHandler::HandleReloadLocalesGameobjectCommand(const char* /*arg*/)
780 sLog.outString( "Re-Loading Locales Gameobject ... ");
781 objmgr.LoadGameObjectLocales();
782 SendGlobalSysMessage("DB table `locales_gameobject` reloaded.");
783 return true;
786 bool ChatHandler::HandleReloadLocalesItemCommand(const char* /*arg*/)
788 sLog.outString( "Re-Loading Locales Item ... ");
789 objmgr.LoadItemLocales();
790 SendGlobalSysMessage("DB table `locales_item` reloaded.");
791 return true;
794 bool ChatHandler::HandleReloadLocalesNpcTextCommand(const char* /*arg*/)
796 sLog.outString( "Re-Loading Locales NPC Text ... ");
797 objmgr.LoadNpcTextLocales();
798 SendGlobalSysMessage("DB table `locales_npc_text` reloaded.");
799 return true;
802 bool ChatHandler::HandleReloadLocalesPageTextCommand(const char* /*arg*/)
804 sLog.outString( "Re-Loading Locales Page Text ... ");
805 objmgr.LoadPageTextLocales();
806 SendGlobalSysMessage("DB table `locales_page_text` reloaded.");
807 return true;
810 bool ChatHandler::HandleReloadLocalesPointsOfInterestCommand(const char* /*arg*/)
812 sLog.outString( "Re-Loading Locales Points Of Interest ... ");
813 objmgr.LoadPointOfInterestLocales();
814 SendGlobalSysMessage("DB table `locales_points_of_interest` reloaded.");
815 return true;
818 bool ChatHandler::HandleReloadLocalesQuestCommand(const char* /*arg*/)
820 sLog.outString( "Re-Loading Locales Quest ... ");
821 objmgr.LoadQuestLocales();
822 SendGlobalSysMessage("DB table `locales_quest` reloaded.");
823 return true;
826 bool ChatHandler::HandleReloadMailLevelRewardCommand(const char* /*arg*/)
828 sLog.outString( "Re-Loading Player level dependent mail rewards..." );
829 objmgr.LoadMailLevelRewards();
830 SendGlobalSysMessage("DB table `mail_level_reward` reloaded.");
831 return true;
834 bool ChatHandler::HandleLoadScriptsCommand(const char* args)
836 if(!LoadScriptingModule(args)) return true;
838 sWorld.SendWorldText(LANG_SCRIPTS_RELOADED);
839 return true;
842 bool ChatHandler::HandleAccountSetGmLevelCommand(const char* args)
844 char* arg1 = strtok((char*)args, " ");
845 if( !arg1 )
846 return false;
848 /// must be NULL if targeted syntax and must be not nULL if not targeted
849 char* arg2 = strtok(NULL, " ");
851 std::string targetAccountName;
852 uint32 targetAccountId = 0;
854 /// only target player different from self allowed (if targetPlayer!=NULL then not console)
855 Player* targetPlayer = getSelectedPlayer();
856 if(targetPlayer && m_session->GetPlayer()!=targetPlayer)
858 /// wrong command syntax or unexpected targeting
859 if(arg2)
860 return false;
862 /// security level expected in arg2 after this if.
863 arg2 = arg1;
865 targetAccountId = targetPlayer->GetSession()->GetAccountId();
866 accmgr.GetName(targetAccountId, targetAccountName);
868 else
870 /// wrong command syntax (second arg expected)
871 if(!arg2)
872 return false;
874 targetAccountName = arg1;
875 if (!AccountMgr::normalizeString(targetAccountName))
877 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,targetAccountName.c_str());
878 SetSentErrorMessage(true);
879 return false;
882 targetAccountId = accmgr.GetId(targetAccountName);
883 if(!targetAccountId)
885 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,targetAccountName.c_str());
886 SetSentErrorMessage(true);
887 return false;
891 int32 gm = (int32)atoi(arg2);
892 if ( gm < SEC_PLAYER || gm > SEC_ADMINISTRATOR )
894 SendSysMessage(LANG_BAD_VALUE);
895 SetSentErrorMessage(true);
896 return false;
899 /// can set security level only for target with less security and to less security that we have
900 /// This will reject self apply by specify account name
901 if(HasLowerSecurityAccount(NULL,targetAccountId,true))
902 return false;
904 /// account can't set security to same or grater level, need more power GM or console
905 AccountTypes plSecurity = m_session ? m_session->GetSecurity() : SEC_CONSOLE;
906 if (AccountTypes(gm) >= plSecurity )
908 SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
909 SetSentErrorMessage(true);
910 return false;
913 // This will prevent self apply by self target or no target
914 if(targetPlayer && m_session->GetPlayer()!=targetPlayer)
916 ChatHandler(targetPlayer).PSendSysMessage(LANG_YOURS_SECURITY_CHANGED,GetNameLink().c_str(), gm);
917 targetPlayer->GetSession()->SetSecurity(AccountTypes(gm));
920 PSendSysMessage(LANG_YOU_CHANGE_SECURITY, targetAccountName.c_str(), gm);
921 loginDatabase.PExecute("UPDATE account SET gmlevel = '%i' WHERE id = '%u'", gm, targetAccountId);
923 return true;
926 /// Set password for account
927 bool ChatHandler::HandleAccountSetPasswordCommand(const char* args)
929 if(!*args)
930 return false;
932 ///- Get the command line arguments
933 char *szAccount = strtok ((char*)args," ");
934 char *szPassword1 = strtok (NULL," ");
935 char *szPassword2 = strtok (NULL," ");
937 if (!szAccount||!szPassword1 || !szPassword2)
938 return false;
940 std::string account_name = szAccount;
941 if (!AccountMgr::normalizeString(account_name))
943 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
944 SetSentErrorMessage(true);
945 return false;
948 uint32 targetAccountId = accmgr.GetId(account_name);
949 if (!targetAccountId)
951 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
952 SetSentErrorMessage(true);
953 return false;
956 /// can set password only for target with less security
957 /// This is also reject self apply in fact
958 if(HasLowerSecurityAccount (NULL,targetAccountId,true))
959 return false;
961 if (strcmp(szPassword1,szPassword2))
963 SendSysMessage (LANG_NEW_PASSWORDS_NOT_MATCH);
964 SetSentErrorMessage (true);
965 return false;
968 AccountOpResult result = accmgr.ChangePassword(targetAccountId, szPassword1);
970 switch(result)
972 case AOR_OK:
973 SendSysMessage(LANG_COMMAND_PASSWORD);
974 break;
975 case AOR_NAME_NOT_EXIST:
976 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
977 SetSentErrorMessage(true);
978 return false;
979 case AOR_PASS_TOO_LONG:
980 SendSysMessage(LANG_PASSWORD_TOO_LONG);
981 SetSentErrorMessage(true);
982 return false;
983 default:
984 SendSysMessage(LANG_COMMAND_NOTCHANGEPASSWORD);
985 SetSentErrorMessage(true);
986 return false;
989 return true;
992 bool ChatHandler::HandleMaxSkillCommand(const char* /*args*/)
994 Player* SelectedPlayer = getSelectedPlayer();
995 if(!SelectedPlayer)
997 SendSysMessage(LANG_NO_CHAR_SELECTED);
998 SetSentErrorMessage(true);
999 return false;
1002 // each skills that have max skill value dependent from level seted to current level max skill value
1003 SelectedPlayer->UpdateSkillsToMaxSkillsForLevel();
1004 return true;
1007 bool ChatHandler::HandleSetSkillCommand(const char* args)
1009 // number or [name] Shift-click form |color|Hskill:skill_id|h[name]|h|r
1010 char* skill_p = extractKeyFromLink((char*)args,"Hskill");
1011 if(!skill_p)
1012 return false;
1014 char *level_p = strtok (NULL, " ");
1016 if( !level_p)
1017 return false;
1019 char *max_p = strtok (NULL, " ");
1021 int32 skill = atoi(skill_p);
1022 if (skill <= 0)
1024 PSendSysMessage(LANG_INVALID_SKILL_ID, skill);
1025 SetSentErrorMessage(true);
1026 return false;
1029 int32 level = atol (level_p);
1031 Player * target = getSelectedPlayer();
1032 if(!target)
1034 SendSysMessage(LANG_NO_CHAR_SELECTED);
1035 SetSentErrorMessage(true);
1036 return false;
1039 SkillLineEntry const* sl = sSkillLineStore.LookupEntry(skill);
1040 if(!sl)
1042 PSendSysMessage(LANG_INVALID_SKILL_ID, skill);
1043 SetSentErrorMessage(true);
1044 return false;
1047 std::string tNameLink = GetNameLink(target);
1049 if(!target->GetSkillValue(skill))
1051 PSendSysMessage(LANG_SET_SKILL_ERROR, tNameLink.c_str(), skill, sl->name[0]);
1052 SetSentErrorMessage(true);
1053 return false;
1056 int32 max = max_p ? atol (max_p) : target->GetPureMaxSkillValue(skill);
1058 if( level <= 0 || level > max || max <= 0 )
1059 return false;
1061 target->SetSkill(skill, level, max);
1062 PSendSysMessage(LANG_SET_SKILL, skill, sl->name[0], tNameLink.c_str(), level, max);
1064 return true;
1067 bool ChatHandler::HandleUnLearnCommand(const char* args)
1069 if (!*args)
1070 return false;
1072 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
1073 uint32 spell_id = extractSpellIdFromLink((char*)args);
1074 if(!spell_id)
1075 return false;
1077 char const* allStr = strtok(NULL," ");
1078 bool allRanks = allStr ? (strncmp(allStr, "all", strlen(allStr)) == 0) : false;
1080 Player* target = getSelectedPlayer();
1081 if(!target)
1083 SendSysMessage(LANG_NO_CHAR_SELECTED);
1084 SetSentErrorMessage(true);
1085 return false;
1088 if(allRanks)
1089 spell_id = spellmgr.GetFirstSpellInChain (spell_id);
1091 if (target->HasSpell(spell_id))
1092 target->removeSpell(spell_id,false,!allRanks);
1093 else
1094 SendSysMessage(LANG_FORGET_SPELL);
1096 if(GetTalentSpellCost(spell_id))
1097 target->SendTalentsInfoData(false);
1099 return true;
1102 bool ChatHandler::HandleCooldownCommand(const char* args)
1104 Player* target = getSelectedPlayer();
1105 if(!target)
1107 SendSysMessage(LANG_PLAYER_NOT_FOUND);
1108 SetSentErrorMessage(true);
1109 return false;
1112 std::string tNameLink = GetNameLink(target);
1114 if (!*args)
1116 target->RemoveAllSpellCooldown();
1117 PSendSysMessage(LANG_REMOVEALL_COOLDOWN, tNameLink.c_str());
1119 else
1121 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
1122 uint32 spell_id = extractSpellIdFromLink((char*)args);
1123 if(!spell_id)
1124 return false;
1126 if(!sSpellStore.LookupEntry(spell_id))
1128 PSendSysMessage(LANG_UNKNOWN_SPELL, target==m_session->GetPlayer() ? GetMangosString(LANG_YOU) : tNameLink.c_str());
1129 SetSentErrorMessage(true);
1130 return false;
1133 target->RemoveSpellCooldown(spell_id,true);
1134 PSendSysMessage(LANG_REMOVE_COOLDOWN, spell_id, target==m_session->GetPlayer() ? GetMangosString(LANG_YOU) : tNameLink.c_str());
1136 return true;
1139 bool ChatHandler::HandleLearnAllCommand(const char* /*args*/)
1141 static const char *allSpellList[] =
1143 "3365",
1144 "6233",
1145 "6247",
1146 "6246",
1147 "6477",
1148 "6478",
1149 "22810",
1150 "8386",
1151 "21651",
1152 "21652",
1153 "522",
1154 "7266",
1155 "8597",
1156 "2479",
1157 "22027",
1158 "6603",
1159 "5019",
1160 "133",
1161 "168",
1162 "227",
1163 "5009",
1164 "9078",
1165 "668",
1166 "203",
1167 "20599",
1168 "20600",
1169 "81",
1170 "20597",
1171 "20598",
1172 "20864",
1173 "1459",
1174 "5504",
1175 "587",
1176 "5143",
1177 "118",
1178 "5505",
1179 "597",
1180 "604",
1181 "1449",
1182 "1460",
1183 "2855",
1184 "1008",
1185 "475",
1186 "5506",
1187 "1463",
1188 "12824",
1189 "8437",
1190 "990",
1191 "5145",
1192 "8450",
1193 "1461",
1194 "759",
1195 "8494",
1196 "8455",
1197 "8438",
1198 "6127",
1199 "8416",
1200 "6129",
1201 "8451",
1202 "8495",
1203 "8439",
1204 "3552",
1205 "8417",
1206 "10138",
1207 "12825",
1208 "10169",
1209 "10156",
1210 "10144",
1211 "10191",
1212 "10201",
1213 "10211",
1214 "10053",
1215 "10173",
1216 "10139",
1217 "10145",
1218 "10192",
1219 "10170",
1220 "10202",
1221 "10054",
1222 "10174",
1223 "10193",
1224 "12826",
1225 "2136",
1226 "143",
1227 "145",
1228 "2137",
1229 "2120",
1230 "3140",
1231 "543",
1232 "2138",
1233 "2948",
1234 "8400",
1235 "2121",
1236 "8444",
1237 "8412",
1238 "8457",
1239 "8401",
1240 "8422",
1241 "8445",
1242 "8402",
1243 "8413",
1244 "8458",
1245 "8423",
1246 "8446",
1247 "10148",
1248 "10197",
1249 "10205",
1250 "10149",
1251 "10215",
1252 "10223",
1253 "10206",
1254 "10199",
1255 "10150",
1256 "10216",
1257 "10207",
1258 "10225",
1259 "10151",
1260 "116",
1261 "205",
1262 "7300",
1263 "122",
1264 "837",
1265 "10",
1266 "7301",
1267 "7322",
1268 "6143",
1269 "120",
1270 "865",
1271 "8406",
1272 "6141",
1273 "7302",
1274 "8461",
1275 "8407",
1276 "8492",
1277 "8427",
1278 "8408",
1279 "6131",
1280 "7320",
1281 "10159",
1282 "8462",
1283 "10185",
1284 "10179",
1285 "10160",
1286 "10180",
1287 "10219",
1288 "10186",
1289 "10177",
1290 "10230",
1291 "10181",
1292 "10161",
1293 "10187",
1294 "10220",
1295 "2018",
1296 "2663",
1297 "12260",
1298 "2660",
1299 "3115",
1300 "3326",
1301 "2665",
1302 "3116",
1303 "2738",
1304 "3293",
1305 "2661",
1306 "3319",
1307 "2662",
1308 "9983",
1309 "8880",
1310 "2737",
1311 "2739",
1312 "7408",
1313 "3320",
1314 "2666",
1315 "3323",
1316 "3324",
1317 "3294",
1318 "22723",
1319 "23219",
1320 "23220",
1321 "23221",
1322 "23228",
1323 "23338",
1324 "10788",
1325 "10790",
1326 "5611",
1327 "5016",
1328 "5609",
1329 "2060",
1330 "10963",
1331 "10964",
1332 "10965",
1333 "22593",
1334 "22594",
1335 "596",
1336 "996",
1337 "499",
1338 "768",
1339 "17002",
1340 "1448",
1341 "1082",
1342 "16979",
1343 "1079",
1344 "5215",
1345 "20484",
1346 "5221",
1347 "15590",
1348 "17007",
1349 "6795",
1350 "6807",
1351 "5487",
1352 "1446",
1353 "1066",
1354 "5421",
1355 "3139",
1356 "779",
1357 "6811",
1358 "6808",
1359 "1445",
1360 "5216",
1361 "1737",
1362 "5222",
1363 "5217",
1364 "1432",
1365 "6812",
1366 "9492",
1367 "5210",
1368 "3030",
1369 "1441",
1370 "783",
1371 "6801",
1372 "20739",
1373 "8944",
1374 "9491",
1375 "22569",
1376 "5226",
1377 "6786",
1378 "1433",
1379 "8973",
1380 "1828",
1381 "9495",
1382 "9006",
1383 "6794",
1384 "8993",
1385 "5203",
1386 "16914",
1387 "6784",
1388 "9635",
1389 "22830",
1390 "20722",
1391 "9748",
1392 "6790",
1393 "9753",
1394 "9493",
1395 "9752",
1396 "9831",
1397 "9825",
1398 "9822",
1399 "5204",
1400 "5401",
1401 "22831",
1402 "6793",
1403 "9845",
1404 "17401",
1405 "9882",
1406 "9868",
1407 "20749",
1408 "9893",
1409 "9899",
1410 "9895",
1411 "9832",
1412 "9902",
1413 "9909",
1414 "22832",
1415 "9828",
1416 "9851",
1417 "9883",
1418 "9869",
1419 "17406",
1420 "17402",
1421 "9914",
1422 "20750",
1423 "9897",
1424 "9848",
1425 "3127",
1426 "107",
1427 "204",
1428 "9116",
1429 "2457",
1430 "78",
1431 "18848",
1432 "331",
1433 "403",
1434 "2098",
1435 "1752",
1436 "11278",
1437 "11288",
1438 "11284",
1439 "6461",
1440 "2344",
1441 "2345",
1442 "6463",
1443 "2346",
1444 "2352",
1445 "775",
1446 "1434",
1447 "1612",
1448 "71",
1449 "2468",
1450 "2458",
1451 "2467",
1452 "7164",
1453 "7178",
1454 "7367",
1455 "7376",
1456 "7381",
1457 "21156",
1458 "5209",
1459 "3029",
1460 "5201",
1461 "9849",
1462 "9850",
1463 "20719",
1464 "22568",
1465 "22827",
1466 "22828",
1467 "22829",
1468 "6809",
1469 "8972",
1470 "9005",
1471 "9823",
1472 "9827",
1473 "6783",
1474 "9913",
1475 "6785",
1476 "6787",
1477 "9866",
1478 "9867",
1479 "9894",
1480 "9896",
1481 "6800",
1482 "8992",
1483 "9829",
1484 "9830",
1485 "780",
1486 "769",
1487 "6749",
1488 "6750",
1489 "9755",
1490 "9754",
1491 "9908",
1492 "20745",
1493 "20742",
1494 "20747",
1495 "20748",
1496 "9746",
1497 "9745",
1498 "9880",
1499 "9881",
1500 "5391",
1501 "842",
1502 "3025",
1503 "3031",
1504 "3287",
1505 "3329",
1506 "1945",
1507 "3559",
1508 "4933",
1509 "4934",
1510 "4935",
1511 "4936",
1512 "5142",
1513 "5390",
1514 "5392",
1515 "5404",
1516 "5420",
1517 "6405",
1518 "7293",
1519 "7965",
1520 "8041",
1521 "8153",
1522 "9033",
1523 "9034",
1524 //"9036", problems with ghost state
1525 "16421",
1526 "21653",
1527 "22660",
1528 "5225",
1529 "9846",
1530 "2426",
1531 "5916",
1532 "6634",
1533 //"6718", phasing stealth, annoying for learn all case.
1534 "6719",
1535 "8822",
1536 "9591",
1537 "9590",
1538 "10032",
1539 "17746",
1540 "17747",
1541 "8203",
1542 "11392",
1543 "12495",
1544 "16380",
1545 "23452",
1546 "4079",
1547 "4996",
1548 "4997",
1549 "4998",
1550 "4999",
1551 "5000",
1552 "6348",
1553 "6349",
1554 "6481",
1555 "6482",
1556 "6483",
1557 "6484",
1558 "11362",
1559 "11410",
1560 "11409",
1561 "12510",
1562 "12509",
1563 "12885",
1564 "13142",
1565 "21463",
1566 "23460",
1567 "11421",
1568 "11416",
1569 "11418",
1570 "1851",
1571 "10059",
1572 "11423",
1573 "11417",
1574 "11422",
1575 "11419",
1576 "11424",
1577 "11420",
1578 "27",
1579 "31",
1580 "33",
1581 "34",
1582 "35",
1583 "15125",
1584 "21127",
1585 "22950",
1586 "1180",
1587 "201",
1588 "12593",
1589 "12842",
1590 "16770",
1591 "6057",
1592 "12051",
1593 "18468",
1594 "12606",
1595 "12605",
1596 "18466",
1597 "12502",
1598 "12043",
1599 "15060",
1600 "12042",
1601 "12341",
1602 "12848",
1603 "12344",
1604 "12353",
1605 "18460",
1606 "11366",
1607 "12350",
1608 "12352",
1609 "13043",
1610 "11368",
1611 "11113",
1612 "12400",
1613 "11129",
1614 "16766",
1615 "12573",
1616 "15053",
1617 "12580",
1618 "12475",
1619 "12472",
1620 "12953",
1621 "12488",
1622 "11189",
1623 "12985",
1624 "12519",
1625 "16758",
1626 "11958",
1627 "12490",
1628 "11426",
1629 "3565",
1630 "3562",
1631 "18960",
1632 "3567",
1633 "3561",
1634 "3566",
1635 "3563",
1636 "1953",
1637 "2139",
1638 "12505",
1639 "13018",
1640 "12522",
1641 "12523",
1642 "5146",
1643 "5144",
1644 "5148",
1645 "8419",
1646 "8418",
1647 "10213",
1648 "10212",
1649 "10157",
1650 "12524",
1651 "13019",
1652 "12525",
1653 "13020",
1654 "12526",
1655 "13021",
1656 "18809",
1657 "13031",
1658 "13032",
1659 "13033",
1660 "4036",
1661 "3920",
1662 "3919",
1663 "3918",
1664 "7430",
1665 "3922",
1666 "3923",
1667 "7411",
1668 "7418",
1669 "7421",
1670 "13262",
1671 "7412",
1672 "7415",
1673 "7413",
1674 "7416",
1675 "13920",
1676 "13921",
1677 "7745",
1678 "7779",
1679 "7428",
1680 "7457",
1681 "7857",
1682 "7748",
1683 "7426",
1684 "13421",
1685 "7454",
1686 "13378",
1687 "7788",
1688 "14807",
1689 "14293",
1690 "7795",
1691 "6296",
1692 "20608",
1693 "755",
1694 "444",
1695 "427",
1696 "428",
1697 "442",
1698 "447",
1699 "3578",
1700 "3581",
1701 "19027",
1702 "3580",
1703 "665",
1704 "3579",
1705 "3577",
1706 "6755",
1707 "3576",
1708 "2575",
1709 "2577",
1710 "2578",
1711 "2579",
1712 "2580",
1713 "2656",
1714 "2657",
1715 "2576",
1716 "3564",
1717 "10248",
1718 "8388",
1719 "2659",
1720 "14891",
1721 "3308",
1722 "3307",
1723 "10097",
1724 "2658",
1725 "3569",
1726 "16153",
1727 "3304",
1728 "10098",
1729 "4037",
1730 "3929",
1731 "3931",
1732 "3926",
1733 "3924",
1734 "3930",
1735 "3977",
1736 "3925",
1737 "136",
1738 "228",
1739 "5487",
1740 "43",
1741 "202",
1745 int loop = 0;
1746 while(strcmp(allSpellList[loop], "0"))
1748 uint32 spell = atol((char*)allSpellList[loop++]);
1750 if (m_session->GetPlayer()->HasSpell(spell))
1751 continue;
1753 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
1754 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
1756 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
1757 continue;
1760 m_session->GetPlayer()->learnSpell(spell,false);
1763 SendSysMessage(LANG_COMMAND_LEARN_MANY_SPELLS);
1765 return true;
1768 bool ChatHandler::HandleLearnAllGMCommand(const char* /*args*/)
1770 static const char *gmSpellList[] =
1772 "24347", // Become A Fish, No Breath Bar
1773 "35132", // Visual Boom
1774 "38488", // Attack 4000-8000 AOE
1775 "38795", // Attack 2000 AOE + Slow Down 90%
1776 "15712", // Attack 200
1777 "1852", // GM Spell Silence
1778 "31899", // Kill
1779 "31924", // Kill
1780 "29878", // Kill My Self
1781 "26644", // More Kill
1783 "28550", //Invisible 24
1784 "23452", //Invisible + Target
1788 uint16 gmSpellIter = 0;
1789 while( strcmp(gmSpellList[gmSpellIter], "0") )
1791 uint32 spell = atol((char*)gmSpellList[gmSpellIter++]);
1793 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
1794 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
1796 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
1797 continue;
1800 m_session->GetPlayer()->learnSpell(spell,false);
1803 SendSysMessage(LANG_LEARNING_GM_SKILLS);
1804 return true;
1807 bool ChatHandler::HandleLearnAllMyClassCommand(const char* /*args*/)
1809 HandleLearnAllMySpellsCommand("");
1810 HandleLearnAllMyTalentsCommand("");
1811 return true;
1814 bool ChatHandler::HandleLearnAllMySpellsCommand(const char* /*args*/)
1816 ChrClassesEntry const* clsEntry = sChrClassesStore.LookupEntry(m_session->GetPlayer()->getClass());
1817 if(!clsEntry)
1818 return true;
1819 uint32 family = clsEntry->spellfamily;
1821 for (uint32 i = 0; i < sSpellStore.GetNumRows(); ++i)
1823 SpellEntry const *spellInfo = sSpellStore.LookupEntry(i);
1824 if(!spellInfo)
1825 continue;
1827 // skip server-side/triggered spells
1828 if(spellInfo->spellLevel==0)
1829 continue;
1831 // skip wrong class/race skills
1832 if(!m_session->GetPlayer()->IsSpellFitByClassAndRace(spellInfo->Id))
1833 continue;
1835 // skip other spell families
1836 if( spellInfo->SpellFamilyName != family)
1837 continue;
1839 // skip spells with first rank learned as talent (and all talents then also)
1840 uint32 first_rank = spellmgr.GetFirstSpellInChain(spellInfo->Id);
1841 if(GetTalentSpellCost(first_rank) > 0 )
1842 continue;
1844 // skip broken spells
1845 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
1846 continue;
1848 m_session->GetPlayer()->learnSpell(i,false);
1851 SendSysMessage(LANG_COMMAND_LEARN_CLASS_SPELLS);
1852 return true;
1855 bool ChatHandler::HandleLearnAllMyTalentsCommand(const char* /*args*/)
1857 Player* player = m_session->GetPlayer();
1858 uint32 classMask = player->getClassMask();
1860 for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
1862 TalentEntry const *talentInfo = sTalentStore.LookupEntry(i);
1863 if(!talentInfo)
1864 continue;
1866 TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab );
1867 if(!talentTabInfo)
1868 continue;
1870 if( (classMask & talentTabInfo->ClassMask) == 0 )
1871 continue;
1873 // search highest talent rank
1874 uint32 spellid = 0;
1876 for(int rank = MAX_TALENT_RANK-1; rank >= 0; --rank)
1878 if(talentInfo->RankID[rank]!=0)
1880 spellid = talentInfo->RankID[rank];
1881 break;
1885 if(!spellid) // ??? none spells in talent
1886 continue;
1888 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid);
1889 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
1890 continue;
1892 // learn highest rank of talent and learn all non-talent spell ranks (recursive by tree)
1893 player->learnSpellHighRank(spellid);
1896 SendSysMessage(LANG_COMMAND_LEARN_CLASS_TALENTS);
1897 return true;
1900 bool ChatHandler::HandleLearnAllMyPetTalentsCommand(const char* /*args*/)
1902 Player* player = m_session->GetPlayer();
1904 Pet* pet = player->GetPet();
1905 if(!pet)
1907 SendSysMessage(LANG_NO_PET_FOUND);
1908 SetSentErrorMessage(true);
1909 return false;
1912 CreatureInfo const *ci = pet->GetCreatureInfo();
1913 if(!ci)
1915 SendSysMessage(LANG_WRONG_PET_TYPE);
1916 SetSentErrorMessage(true);
1917 return false;
1920 CreatureFamilyEntry const *pet_family = sCreatureFamilyStore.LookupEntry(ci->family);
1921 if(!pet_family)
1923 SendSysMessage(LANG_WRONG_PET_TYPE);
1924 SetSentErrorMessage(true);
1925 return false;
1928 if(pet_family->petTalentType < 0) // not hunter pet
1930 SendSysMessage(LANG_WRONG_PET_TYPE);
1931 SetSentErrorMessage(true);
1932 return false;
1935 for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
1937 TalentEntry const *talentInfo = sTalentStore.LookupEntry(i);
1938 if(!talentInfo)
1939 continue;
1941 TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab );
1942 if(!talentTabInfo)
1943 continue;
1945 // prevent learn talent for different family (cheating)
1946 if(((1 << pet_family->petTalentType) & talentTabInfo->petTalentMask)==0)
1947 continue;
1949 // search highest talent rank
1950 uint32 spellid = 0;
1952 for(int rank = MAX_TALENT_RANK-1; rank >= 0; --rank)
1954 if(talentInfo->RankID[rank]!=0)
1956 spellid = talentInfo->RankID[rank];
1957 break;
1961 if(!spellid) // ??? none spells in talent
1962 continue;
1964 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid);
1965 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
1966 continue;
1968 // learn highest rank of talent and learn all non-talent spell ranks (recursive by tree)
1969 pet->learnSpellHighRank(spellid);
1972 SendSysMessage(LANG_COMMAND_LEARN_PET_TALENTS);
1973 return true;
1976 bool ChatHandler::HandleLearnAllLangCommand(const char* /*args*/)
1978 // skipping UNIVERSAL language (0)
1979 for(int i = 1; i < LANGUAGES_COUNT; ++i)
1980 m_session->GetPlayer()->learnSpell(lang_description[i].spell_id,false);
1982 SendSysMessage(LANG_COMMAND_LEARN_ALL_LANG);
1983 return true;
1986 bool ChatHandler::HandleLearnAllDefaultCommand(const char* args)
1988 Player* target;
1989 if(!extractPlayerTarget((char*)args,&target))
1990 return false;
1992 target->learnDefaultSpells();
1993 target->learnQuestRewardedSpells();
1995 PSendSysMessage(LANG_COMMAND_LEARN_ALL_DEFAULT_AND_QUEST,GetNameLink(target).c_str());
1996 return true;
1999 bool ChatHandler::HandleLearnCommand(const char* args)
2001 Player* targetPlayer = getSelectedPlayer();
2003 if(!targetPlayer)
2005 SendSysMessage(LANG_PLAYER_NOT_FOUND);
2006 SetSentErrorMessage(true);
2007 return false;
2010 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
2011 uint32 spell = extractSpellIdFromLink((char*)args);
2012 if(!spell || !sSpellStore.LookupEntry(spell))
2013 return false;
2015 char const* allStr = strtok(NULL," ");
2016 bool allRanks = allStr ? (strncmp(allStr, "all", strlen(allStr)) == 0) : false;
2018 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
2019 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
2021 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
2022 SetSentErrorMessage(true);
2023 return false;
2026 if (!allRanks && targetPlayer->HasSpell(spell))
2028 if(targetPlayer == m_session->GetPlayer())
2029 SendSysMessage(LANG_YOU_KNOWN_SPELL);
2030 else
2031 PSendSysMessage(LANG_TARGET_KNOWN_SPELL,GetNameLink(targetPlayer).c_str());
2032 SetSentErrorMessage(true);
2033 return false;
2036 if(allRanks)
2037 targetPlayer->learnSpellHighRank(spell);
2038 else
2039 targetPlayer->learnSpell(spell,false);
2041 uint32 first_spell = spellmgr.GetFirstSpellInChain(spell);
2042 if(GetTalentSpellCost(first_spell))
2043 targetPlayer->SendTalentsInfoData(false);
2045 return true;
2048 bool ChatHandler::HandleAddItemCommand(const char* args)
2050 if (!*args)
2051 return false;
2053 uint32 itemId = 0;
2055 if(args[0]=='[') // [name] manual form
2057 char* citemName = strtok((char*)args, "]");
2059 if(citemName && citemName[0])
2061 std::string itemName = citemName+1;
2062 WorldDatabase.escape_string(itemName);
2063 QueryResult *result = WorldDatabase.PQuery("SELECT entry FROM item_template WHERE name = '%s'", itemName.c_str());
2064 if (!result)
2066 PSendSysMessage(LANG_COMMAND_COULDNOTFIND, citemName+1);
2067 SetSentErrorMessage(true);
2068 return false;
2070 itemId = result->Fetch()->GetUInt16();
2071 delete result;
2073 else
2074 return false;
2076 else // item_id or [name] Shift-click form |color|Hitem:item_id:0:0:0|h[name]|h|r
2078 char* cId = extractKeyFromLink((char*)args,"Hitem");
2079 if(!cId)
2080 return false;
2081 itemId = atol(cId);
2084 char* ccount = strtok(NULL, " ");
2086 int32 count = 1;
2088 if (ccount)
2089 count = strtol(ccount, NULL, 10);
2091 if (count == 0)
2092 count = 1;
2094 Player* pl = m_session->GetPlayer();
2095 Player* plTarget = getSelectedPlayer();
2096 if(!plTarget)
2097 plTarget = pl;
2099 sLog.outDetail(GetMangosString(LANG_ADDITEM), itemId, count);
2101 ItemPrototype const *pProto = objmgr.GetItemPrototype(itemId);
2102 if(!pProto)
2104 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId);
2105 SetSentErrorMessage(true);
2106 return false;
2109 //Subtract
2110 if (count < 0)
2112 plTarget->DestroyItemCount(itemId, -count, true, false);
2113 PSendSysMessage(LANG_REMOVEITEM, itemId, -count, GetNameLink(plTarget).c_str());
2114 return true;
2117 //Adding items
2118 uint32 noSpaceForCount = 0;
2120 // check space and find places
2121 ItemPosCountVec dest;
2122 uint8 msg = plTarget->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, itemId, count, &noSpaceForCount );
2123 if( msg != EQUIP_ERR_OK ) // convert to possible store amount
2124 count -= noSpaceForCount;
2126 if( count == 0 || dest.empty()) // can't add any
2128 PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount );
2129 SetSentErrorMessage(true);
2130 return false;
2133 Item* item = plTarget->StoreNewItem( dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId));
2135 // remove binding (let GM give it to another player later)
2136 if(pl==plTarget)
2137 for(ItemPosCountVec::const_iterator itr = dest.begin(); itr != dest.end(); ++itr)
2138 if(Item* item1 = pl->GetItemByPos(itr->pos))
2139 item1->SetBinding( false );
2141 if(count > 0 && item)
2143 pl->SendNewItem(item,count,false,true);
2144 if(pl!=plTarget)
2145 plTarget->SendNewItem(item,count,true,false);
2148 if(noSpaceForCount > 0)
2149 PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount);
2151 return true;
2154 bool ChatHandler::HandleAddItemSetCommand(const char* args)
2156 if (!*args)
2157 return false;
2159 char* cId = extractKeyFromLink((char*)args,"Hitemset"); // number or [name] Shift-click form |color|Hitemset:itemset_id|h[name]|h|r
2160 if (!cId)
2161 return false;
2163 uint32 itemsetId = atol(cId);
2165 // prevent generation all items with itemset field value '0'
2166 if (itemsetId == 0)
2168 PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND,itemsetId);
2169 SetSentErrorMessage(true);
2170 return false;
2173 Player* pl = m_session->GetPlayer();
2174 Player* plTarget = getSelectedPlayer();
2175 if(!plTarget)
2176 plTarget = pl;
2178 sLog.outDetail(GetMangosString(LANG_ADDITEMSET), itemsetId);
2180 bool found = false;
2181 for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
2183 ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype>(id);
2184 if (!pProto)
2185 continue;
2187 if (pProto->ItemSet == itemsetId)
2189 found = true;
2190 ItemPosCountVec dest;
2191 uint8 msg = plTarget->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, pProto->ItemId, 1 );
2192 if (msg == EQUIP_ERR_OK)
2194 Item* item = plTarget->StoreNewItem( dest, pProto->ItemId, true);
2196 // remove binding (let GM give it to another player later)
2197 if (pl==plTarget)
2198 item->SetBinding( false );
2200 pl->SendNewItem(item,1,false,true);
2201 if (pl!=plTarget)
2202 plTarget->SendNewItem(item,1,true,false);
2204 else
2206 pl->SendEquipError( msg, NULL, NULL );
2207 PSendSysMessage(LANG_ITEM_CANNOT_CREATE, pProto->ItemId, 1);
2212 if (!found)
2214 PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND,itemsetId);
2216 SetSentErrorMessage(true);
2217 return false;
2220 return true;
2223 bool ChatHandler::HandleListItemCommand(const char* args)
2225 if(!*args)
2226 return false;
2228 char* cId = extractKeyFromLink((char*)args,"Hitem");
2229 if(!cId)
2230 return false;
2232 uint32 item_id = atol(cId);
2233 if(!item_id)
2235 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
2236 SetSentErrorMessage(true);
2237 return false;
2240 ItemPrototype const* itemProto = objmgr.GetItemPrototype(item_id);
2241 if(!itemProto)
2243 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
2244 SetSentErrorMessage(true);
2245 return false;
2248 char* c_count = strtok(NULL, " ");
2249 int count = c_count ? atol(c_count) : 10;
2251 if(count < 0)
2252 return false;
2254 QueryResult *result;
2256 // inventory case
2257 uint32 inv_count = 0;
2258 result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM character_inventory WHERE item_template='%u'",item_id);
2259 if(result)
2261 inv_count = (*result)[0].GetUInt32();
2262 delete result;
2265 result=CharacterDatabase.PQuery(
2266 // 0 1 2 3 4 5
2267 "SELECT ci.item, cibag.slot AS bag, ci.slot, ci.guid, characters.account,characters.name "
2268 "FROM character_inventory AS ci LEFT JOIN character_inventory AS cibag ON (cibag.item=ci.bag),characters "
2269 "WHERE ci.item_template='%u' AND ci.guid = characters.guid LIMIT %u ",
2270 item_id,uint32(count));
2272 if(result)
2276 Field *fields = result->Fetch();
2277 uint32 item_guid = fields[0].GetUInt32();
2278 uint32 item_bag = fields[1].GetUInt32();
2279 uint32 item_slot = fields[2].GetUInt32();
2280 uint32 owner_guid = fields[3].GetUInt32();
2281 uint32 owner_acc = fields[4].GetUInt32();
2282 std::string owner_name = fields[5].GetCppString();
2284 char const* item_pos = 0;
2285 if(Player::IsEquipmentPos(item_bag,item_slot))
2286 item_pos = "[equipped]";
2287 else if(Player::IsInventoryPos(item_bag,item_slot))
2288 item_pos = "[in inventory]";
2289 else if(Player::IsBankPos(item_bag,item_slot))
2290 item_pos = "[in bank]";
2291 else
2292 item_pos = "";
2294 PSendSysMessage(LANG_ITEMLIST_SLOT,
2295 item_guid,owner_name.c_str(),owner_guid,owner_acc,item_pos);
2296 } while (result->NextRow());
2298 int64 res_count = result->GetRowCount();
2300 delete result;
2302 if(count > res_count)
2303 count-=res_count;
2304 else if(count)
2305 count = 0;
2308 // mail case
2309 uint32 mail_count = 0;
2310 result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM mail_items WHERE item_template='%u'", item_id);
2311 if(result)
2313 mail_count = (*result)[0].GetUInt32();
2314 delete result;
2317 if(count > 0)
2319 result=CharacterDatabase.PQuery(
2320 // 0 1 2 3 4 5 6
2321 "SELECT mail_items.item_guid, mail.sender, mail.receiver, char_s.account, char_s.name, char_r.account, char_r.name "
2322 "FROM mail,mail_items,characters as char_s,characters as char_r "
2323 "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",
2324 item_id,uint32(count));
2326 else
2327 result = NULL;
2329 if(result)
2333 Field *fields = result->Fetch();
2334 uint32 item_guid = fields[0].GetUInt32();
2335 uint32 item_s = fields[1].GetUInt32();
2336 uint32 item_r = fields[2].GetUInt32();
2337 uint32 item_s_acc = fields[3].GetUInt32();
2338 std::string item_s_name = fields[4].GetCppString();
2339 uint32 item_r_acc = fields[5].GetUInt32();
2340 std::string item_r_name = fields[6].GetCppString();
2342 char const* item_pos = "[in mail]";
2344 PSendSysMessage(LANG_ITEMLIST_MAIL,
2345 item_guid,item_s_name.c_str(),item_s,item_s_acc,item_r_name.c_str(),item_r,item_r_acc,item_pos);
2346 } while (result->NextRow());
2348 int64 res_count = result->GetRowCount();
2350 delete result;
2352 if(count > res_count)
2353 count-=res_count;
2354 else if(count)
2355 count = 0;
2358 // auction case
2359 uint32 auc_count = 0;
2360 result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM auctionhouse WHERE item_template='%u'",item_id);
2361 if(result)
2363 auc_count = (*result)[0].GetUInt32();
2364 delete result;
2367 if(count > 0)
2369 result=CharacterDatabase.PQuery(
2370 // 0 1 2 3
2371 "SELECT auctionhouse.itemguid, auctionhouse.itemowner, characters.account, characters.name "
2372 "FROM auctionhouse,characters WHERE auctionhouse.item_template='%u' AND characters.guid = auctionhouse.itemowner LIMIT %u",
2373 item_id,uint32(count));
2375 else
2376 result = NULL;
2378 if(result)
2382 Field *fields = result->Fetch();
2383 uint32 item_guid = fields[0].GetUInt32();
2384 uint32 owner = fields[1].GetUInt32();
2385 uint32 owner_acc = fields[2].GetUInt32();
2386 std::string owner_name = fields[3].GetCppString();
2388 char const* item_pos = "[in auction]";
2390 PSendSysMessage(LANG_ITEMLIST_AUCTION, item_guid, owner_name.c_str(), owner, owner_acc,item_pos);
2391 } while (result->NextRow());
2393 delete result;
2396 // guild bank case
2397 uint32 guild_count = 0;
2398 result=CharacterDatabase.PQuery("SELECT COUNT(item_entry) FROM guild_bank_item WHERE item_entry='%u'",item_id);
2399 if(result)
2401 guild_count = (*result)[0].GetUInt32();
2402 delete result;
2405 result=CharacterDatabase.PQuery(
2406 // 0 1 2
2407 "SELECT gi.item_guid, gi.guildid, guild.name "
2408 "FROM guild_bank_item AS gi, guild WHERE gi.item_entry='%u' AND gi.guildid = guild.guildid LIMIT %u ",
2409 item_id,uint32(count));
2411 if(result)
2415 Field *fields = result->Fetch();
2416 uint32 item_guid = fields[0].GetUInt32();
2417 uint32 guild_guid = fields[1].GetUInt32();
2418 std::string guild_name = fields[2].GetCppString();
2420 char const* item_pos = "[in guild bank]";
2422 PSendSysMessage(LANG_ITEMLIST_GUILD,item_guid,guild_name.c_str(),guild_guid,item_pos);
2423 } while (result->NextRow());
2425 int64 res_count = result->GetRowCount();
2427 delete result;
2429 if(count > res_count)
2430 count-=res_count;
2431 else if(count)
2432 count = 0;
2435 if(inv_count+mail_count+auc_count+guild_count == 0)
2437 SendSysMessage(LANG_COMMAND_NOITEMFOUND);
2438 SetSentErrorMessage(true);
2439 return false;
2442 PSendSysMessage(LANG_COMMAND_LISTITEMMESSAGE,item_id,inv_count+mail_count+auc_count+guild_count,inv_count,mail_count,auc_count,guild_count);
2444 return true;
2447 bool ChatHandler::HandleListObjectCommand(const char* args)
2449 if(!*args)
2450 return false;
2452 // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r
2453 char* cId = extractKeyFromLink((char*)args,"Hgameobject_entry");
2454 if(!cId)
2455 return false;
2457 uint32 go_id = atol(cId);
2458 if(!go_id)
2460 PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id);
2461 SetSentErrorMessage(true);
2462 return false;
2465 GameObjectInfo const * gInfo = objmgr.GetGameObjectInfo(go_id);
2466 if(!gInfo)
2468 PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id);
2469 SetSentErrorMessage(true);
2470 return false;
2473 char* c_count = strtok(NULL, " ");
2474 int count = c_count ? atol(c_count) : 10;
2476 if(count < 0)
2477 return false;
2479 QueryResult *result;
2481 uint32 obj_count = 0;
2482 result=WorldDatabase.PQuery("SELECT COUNT(guid) FROM gameobject WHERE id='%u'",go_id);
2483 if(result)
2485 obj_count = (*result)[0].GetUInt32();
2486 delete result;
2489 if(m_session)
2491 Player* pl = m_session->GetPlayer();
2492 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",
2493 pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),go_id,uint32(count));
2495 else
2496 result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map FROM gameobject WHERE id = '%u' LIMIT %u",
2497 go_id,uint32(count));
2499 if (result)
2503 Field *fields = result->Fetch();
2504 uint32 guid = fields[0].GetUInt32();
2505 float x = fields[1].GetFloat();
2506 float y = fields[2].GetFloat();
2507 float z = fields[3].GetFloat();
2508 int mapid = fields[4].GetUInt16();
2510 if (m_session)
2511 PSendSysMessage(LANG_GO_LIST_CHAT, guid, guid, gInfo->name, x, y, z, mapid);
2512 else
2513 PSendSysMessage(LANG_GO_LIST_CONSOLE, guid, gInfo->name, x, y, z, mapid);
2514 } while (result->NextRow());
2516 delete result;
2519 PSendSysMessage(LANG_COMMAND_LISTOBJMESSAGE,go_id,obj_count);
2520 return true;
2523 bool ChatHandler::HandleListCreatureCommand(const char* args)
2525 if(!*args)
2526 return false;
2528 // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
2529 char* cId = extractKeyFromLink((char*)args,"Hcreature_entry");
2530 if(!cId)
2531 return false;
2533 uint32 cr_id = atol(cId);
2534 if(!cr_id)
2536 PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id);
2537 SetSentErrorMessage(true);
2538 return false;
2541 CreatureInfo const* cInfo = objmgr.GetCreatureTemplate(cr_id);
2542 if(!cInfo)
2544 PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id);
2545 SetSentErrorMessage(true);
2546 return false;
2549 char* c_count = strtok(NULL, " ");
2550 int count = c_count ? atol(c_count) : 10;
2552 if(count < 0)
2553 return false;
2555 QueryResult *result;
2557 uint32 cr_count = 0;
2558 result=WorldDatabase.PQuery("SELECT COUNT(guid) FROM creature WHERE id='%u'",cr_id);
2559 if(result)
2561 cr_count = (*result)[0].GetUInt32();
2562 delete result;
2565 if(m_session)
2567 Player* pl = m_session->GetPlayer();
2568 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",
2569 pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), cr_id,uint32(count));
2571 else
2572 result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map FROM creature WHERE id = '%u' LIMIT %u",
2573 cr_id,uint32(count));
2575 if (result)
2579 Field *fields = result->Fetch();
2580 uint32 guid = fields[0].GetUInt32();
2581 float x = fields[1].GetFloat();
2582 float y = fields[2].GetFloat();
2583 float z = fields[3].GetFloat();
2584 int mapid = fields[4].GetUInt16();
2586 if (m_session)
2587 PSendSysMessage(LANG_CREATURE_LIST_CHAT, guid, guid, cInfo->Name, x, y, z, mapid);
2588 else
2589 PSendSysMessage(LANG_CREATURE_LIST_CONSOLE, guid, cInfo->Name, x, y, z, mapid);
2590 } while (result->NextRow());
2592 delete result;
2595 PSendSysMessage(LANG_COMMAND_LISTCREATUREMESSAGE,cr_id,cr_count);
2596 return true;
2599 bool ChatHandler::HandleLookupItemCommand(const char* args)
2601 if(!*args)
2602 return false;
2604 std::string namepart = args;
2605 std::wstring wnamepart;
2607 // converting string that we try to find to lower case
2608 if(!Utf8toWStr(namepart,wnamepart))
2609 return false;
2611 wstrToLower(wnamepart);
2613 uint32 counter = 0;
2615 // Search in `item_template`
2616 for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
2618 ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype >(id);
2619 if(!pProto)
2620 continue;
2622 int loc_idx = GetSessionDbLocaleIndex();
2623 if ( loc_idx >= 0 )
2625 ItemLocale const *il = objmgr.GetItemLocale(pProto->ItemId);
2626 if (il)
2628 if (il->Name.size() > loc_idx && !il->Name[loc_idx].empty())
2630 std::string name = il->Name[loc_idx];
2632 if (Utf8FitTo(name, wnamepart))
2634 if (m_session)
2635 PSendSysMessage(LANG_ITEM_LIST_CHAT, id, id, name.c_str());
2636 else
2637 PSendSysMessage(LANG_ITEM_LIST_CONSOLE, id, name.c_str());
2638 ++counter;
2639 continue;
2645 std::string name = pProto->Name1;
2646 if(name.empty())
2647 continue;
2649 if (Utf8FitTo(name, wnamepart))
2651 if (m_session)
2652 PSendSysMessage(LANG_ITEM_LIST_CHAT, id, id, name.c_str());
2653 else
2654 PSendSysMessage(LANG_ITEM_LIST_CONSOLE, id, name.c_str());
2655 ++counter;
2659 if (counter==0)
2660 SendSysMessage(LANG_COMMAND_NOITEMFOUND);
2662 return true;
2665 bool ChatHandler::HandleLookupItemSetCommand(const char* args)
2667 if(!*args)
2668 return false;
2670 std::string namepart = args;
2671 std::wstring wnamepart;
2673 if(!Utf8toWStr(namepart,wnamepart))
2674 return false;
2676 // converting string that we try to find to lower case
2677 wstrToLower( wnamepart );
2679 uint32 counter = 0; // Counter for figure out that we found smth.
2681 // Search in ItemSet.dbc
2682 for (uint32 id = 0; id < sItemSetStore.GetNumRows(); id++)
2684 ItemSetEntry const *set = sItemSetStore.LookupEntry(id);
2685 if(set)
2687 int loc = GetSessionDbcLocale();
2688 std::string name = set->name[loc];
2689 if(name.empty())
2690 continue;
2692 if (!Utf8FitTo(name, wnamepart))
2694 loc = 0;
2695 for(; loc < MAX_LOCALE; ++loc)
2697 if(loc==GetSessionDbcLocale())
2698 continue;
2700 name = set->name[loc];
2701 if(name.empty())
2702 continue;
2704 if (Utf8FitTo(name, wnamepart))
2705 break;
2709 if(loc < MAX_LOCALE)
2711 // send item set in "id - [namedlink locale]" format
2712 if (m_session)
2713 PSendSysMessage(LANG_ITEMSET_LIST_CHAT,id,id,name.c_str(),localeNames[loc]);
2714 else
2715 PSendSysMessage(LANG_ITEMSET_LIST_CONSOLE,id,name.c_str(),localeNames[loc]);
2716 ++counter;
2720 if (counter == 0) // if counter == 0 then we found nth
2721 SendSysMessage(LANG_COMMAND_NOITEMSETFOUND);
2722 return true;
2725 bool ChatHandler::HandleLookupSkillCommand(const char* args)
2727 if(!*args)
2728 return false;
2730 // can be NULL in console call
2731 Player* target = getSelectedPlayer();
2733 std::string namepart = args;
2734 std::wstring wnamepart;
2736 if(!Utf8toWStr(namepart,wnamepart))
2737 return false;
2739 // converting string that we try to find to lower case
2740 wstrToLower( wnamepart );
2742 uint32 counter = 0; // Counter for figure out that we found smth.
2744 // Search in SkillLine.dbc
2745 for (uint32 id = 0; id < sSkillLineStore.GetNumRows(); id++)
2747 SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(id);
2748 if(skillInfo)
2750 int loc = GetSessionDbcLocale();
2751 std::string name = skillInfo->name[loc];
2752 if(name.empty())
2753 continue;
2755 if (!Utf8FitTo(name, wnamepart))
2757 loc = 0;
2758 for(; loc < MAX_LOCALE; ++loc)
2760 if(loc==GetSessionDbcLocale())
2761 continue;
2763 name = skillInfo->name[loc];
2764 if(name.empty())
2765 continue;
2767 if (Utf8FitTo(name, wnamepart))
2768 break;
2772 if(loc < MAX_LOCALE)
2774 char valStr[50] = "";
2775 char const* knownStr = "";
2776 if(target && target->HasSkill(id))
2778 knownStr = GetMangosString(LANG_KNOWN);
2779 uint32 curValue = target->GetPureSkillValue(id);
2780 uint32 maxValue = target->GetPureMaxSkillValue(id);
2781 uint32 permValue = target->GetSkillPermBonusValue(id);
2782 uint32 tempValue = target->GetSkillTempBonusValue(id);
2784 char const* valFormat = GetMangosString(LANG_SKILL_VALUES);
2785 snprintf(valStr,50,valFormat,curValue,maxValue,permValue,tempValue);
2788 // send skill in "id - [namedlink locale]" format
2789 if (m_session)
2790 PSendSysMessage(LANG_SKILL_LIST_CHAT,id,id,name.c_str(),localeNames[loc],knownStr,valStr);
2791 else
2792 PSendSysMessage(LANG_SKILL_LIST_CONSOLE,id,name.c_str(),localeNames[loc],knownStr,valStr);
2794 ++counter;
2798 if (counter == 0) // if counter == 0 then we found nth
2799 SendSysMessage(LANG_COMMAND_NOSKILLFOUND);
2800 return true;
2803 bool ChatHandler::HandleLookupSpellCommand(const char* args)
2805 if(!*args)
2806 return false;
2808 // can be NULL at console call
2809 Player* target = getSelectedPlayer();
2811 std::string namepart = args;
2812 std::wstring wnamepart;
2814 if(!Utf8toWStr(namepart,wnamepart))
2815 return false;
2817 // converting string that we try to find to lower case
2818 wstrToLower( wnamepart );
2820 uint32 counter = 0; // Counter for figure out that we found smth.
2822 // Search in Spell.dbc
2823 for (uint32 id = 0; id < sSpellStore.GetNumRows(); id++)
2825 SpellEntry const *spellInfo = sSpellStore.LookupEntry(id);
2826 if(spellInfo)
2828 int loc = GetSessionDbcLocale();
2829 std::string name = spellInfo->SpellName[loc];
2830 if(name.empty())
2831 continue;
2833 if (!Utf8FitTo(name, wnamepart))
2835 loc = 0;
2836 for(; loc < MAX_LOCALE; ++loc)
2838 if(loc==GetSessionDbcLocale())
2839 continue;
2841 name = spellInfo->SpellName[loc];
2842 if(name.empty())
2843 continue;
2845 if (Utf8FitTo(name, wnamepart))
2846 break;
2850 if(loc < MAX_LOCALE)
2852 bool known = target && target->HasSpell(id);
2853 bool learn = (spellInfo->Effect[0] == SPELL_EFFECT_LEARN_SPELL);
2855 uint32 talentCost = GetTalentSpellCost(id);
2857 bool talent = (talentCost > 0);
2858 bool passive = IsPassiveSpell(id);
2859 bool active = target && target->HasAura(id);
2861 // unit32 used to prevent interpreting uint8 as char at output
2862 // find rank of learned spell for learning spell, or talent rank
2863 uint32 rank = talentCost ? talentCost : spellmgr.GetSpellRank(learn ? spellInfo->EffectTriggerSpell[0] : id);
2865 // send spell in "id - [name, rank N] [talent] [passive] [learn] [known]" format
2866 std::ostringstream ss;
2867 if (m_session)
2868 ss << id << " - |cffffffff|Hspell:" << id << "|h[" << name;
2869 else
2870 ss << id << " - " << name;
2872 // include rank in link name
2873 if(rank)
2874 ss << GetMangosString(LANG_SPELL_RANK) << rank;
2876 if (m_session)
2877 ss << " " << localeNames[loc] << "]|h|r";
2878 else
2879 ss << " " << localeNames[loc];
2881 if(talent)
2882 ss << GetMangosString(LANG_TALENT);
2883 if(passive)
2884 ss << GetMangosString(LANG_PASSIVE);
2885 if(learn)
2886 ss << GetMangosString(LANG_LEARN);
2887 if(known)
2888 ss << GetMangosString(LANG_KNOWN);
2889 if(active)
2890 ss << GetMangosString(LANG_ACTIVE);
2892 SendSysMessage(ss.str().c_str());
2894 ++counter;
2898 if (counter == 0) // if counter == 0 then we found nth
2899 SendSysMessage(LANG_COMMAND_NOSPELLFOUND);
2900 return true;
2903 bool ChatHandler::HandleLookupQuestCommand(const char* args)
2905 if(!*args)
2906 return false;
2908 // can be NULL at console call
2909 Player* target = getSelectedPlayer();
2911 std::string namepart = args;
2912 std::wstring wnamepart;
2914 // converting string that we try to find to lower case
2915 if(!Utf8toWStr(namepart,wnamepart))
2916 return false;
2918 wstrToLower(wnamepart);
2920 uint32 counter = 0 ;
2922 ObjectMgr::QuestMap const& qTemplates = objmgr.GetQuestTemplates();
2923 for (ObjectMgr::QuestMap::const_iterator iter = qTemplates.begin(); iter != qTemplates.end(); ++iter)
2925 Quest * qinfo = iter->second;
2927 int loc_idx = GetSessionDbLocaleIndex();
2928 if ( loc_idx >= 0 )
2930 QuestLocale const *il = objmgr.GetQuestLocale(qinfo->GetQuestId());
2931 if (il)
2933 if (il->Title.size() > loc_idx && !il->Title[loc_idx].empty())
2935 std::string title = il->Title[loc_idx];
2937 if (Utf8FitTo(title, wnamepart))
2939 char const* statusStr = "";
2941 if(target)
2943 QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId());
2945 if(status == QUEST_STATUS_COMPLETE)
2947 if(target->GetQuestRewardStatus(qinfo->GetQuestId()))
2948 statusStr = GetMangosString(LANG_COMMAND_QUEST_REWARDED);
2949 else
2950 statusStr = GetMangosString(LANG_COMMAND_QUEST_COMPLETE);
2952 else if(status == QUEST_STATUS_INCOMPLETE)
2953 statusStr = GetMangosString(LANG_COMMAND_QUEST_ACTIVE);
2956 if (m_session)
2957 PSendSysMessage(LANG_QUEST_LIST_CHAT,qinfo->GetQuestId(),qinfo->GetQuestId(),qinfo->GetQuestLevel(),title.c_str(),statusStr);
2958 else
2959 PSendSysMessage(LANG_QUEST_LIST_CONSOLE,qinfo->GetQuestId(),title.c_str(),statusStr);
2960 ++counter;
2961 continue;
2967 std::string title = qinfo->GetTitle();
2968 if(title.empty())
2969 continue;
2971 if (Utf8FitTo(title, wnamepart))
2973 char const* statusStr = "";
2975 if(target)
2977 QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId());
2979 if(status == QUEST_STATUS_COMPLETE)
2981 if(target->GetQuestRewardStatus(qinfo->GetQuestId()))
2982 statusStr = GetMangosString(LANG_COMMAND_QUEST_REWARDED);
2983 else
2984 statusStr = GetMangosString(LANG_COMMAND_QUEST_COMPLETE);
2986 else if(status == QUEST_STATUS_INCOMPLETE)
2987 statusStr = GetMangosString(LANG_COMMAND_QUEST_ACTIVE);
2990 if (m_session)
2991 PSendSysMessage(LANG_QUEST_LIST_CHAT,qinfo->GetQuestId(),qinfo->GetQuestId(),qinfo->GetQuestLevel(),title.c_str(),statusStr);
2992 else
2993 PSendSysMessage(LANG_QUEST_LIST_CONSOLE,qinfo->GetQuestId(),title.c_str(),statusStr);
2995 ++counter;
2999 if (counter==0)
3000 SendSysMessage(LANG_COMMAND_NOQUESTFOUND);
3002 return true;
3005 bool ChatHandler::HandleLookupCreatureCommand(const char* args)
3007 if (!*args)
3008 return false;
3010 std::string namepart = args;
3011 std::wstring wnamepart;
3013 // converting string that we try to find to lower case
3014 if (!Utf8toWStr (namepart,wnamepart))
3015 return false;
3017 wstrToLower (wnamepart);
3019 uint32 counter = 0;
3021 for (uint32 id = 0; id< sCreatureStorage.MaxEntry; ++id)
3023 CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo> (id);
3024 if(!cInfo)
3025 continue;
3027 int loc_idx = GetSessionDbLocaleIndex();
3028 if (loc_idx >= 0)
3030 CreatureLocale const *cl = objmgr.GetCreatureLocale (id);
3031 if (cl)
3033 if (cl->Name.size() > loc_idx && !cl->Name[loc_idx].empty ())
3035 std::string name = cl->Name[loc_idx];
3037 if (Utf8FitTo (name, wnamepart))
3039 if (m_session)
3040 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CHAT, id, id, name.c_str ());
3041 else
3042 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CONSOLE, id, name.c_str ());
3043 ++counter;
3044 continue;
3050 std::string name = cInfo->Name;
3051 if (name.empty ())
3052 continue;
3054 if (Utf8FitTo(name, wnamepart))
3056 if (m_session)
3057 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CHAT, id, id, name.c_str ());
3058 else
3059 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CONSOLE, id, name.c_str ());
3060 ++counter;
3064 if (counter==0)
3065 SendSysMessage (LANG_COMMAND_NOCREATUREFOUND);
3067 return true;
3070 bool ChatHandler::HandleLookupObjectCommand(const char* args)
3072 if(!*args)
3073 return false;
3075 std::string namepart = args;
3076 std::wstring wnamepart;
3078 // converting string that we try to find to lower case
3079 if(!Utf8toWStr(namepart,wnamepart))
3080 return false;
3082 wstrToLower(wnamepart);
3084 uint32 counter = 0;
3086 for (uint32 id = 0; id< sGOStorage.MaxEntry; id++ )
3088 GameObjectInfo const* gInfo = sGOStorage.LookupEntry<GameObjectInfo>(id);
3089 if(!gInfo)
3090 continue;
3092 int loc_idx = GetSessionDbLocaleIndex();
3093 if ( loc_idx >= 0 )
3095 GameObjectLocale const *gl = objmgr.GetGameObjectLocale(id);
3096 if (gl)
3098 if (gl->Name.size() > loc_idx && !gl->Name[loc_idx].empty())
3100 std::string name = gl->Name[loc_idx];
3102 if (Utf8FitTo(name, wnamepart))
3104 if (m_session)
3105 PSendSysMessage(LANG_GO_ENTRY_LIST_CHAT, id, id, name.c_str());
3106 else
3107 PSendSysMessage(LANG_GO_ENTRY_LIST_CONSOLE, id, name.c_str());
3108 ++counter;
3109 continue;
3115 std::string name = gInfo->name;
3116 if(name.empty())
3117 continue;
3119 if(Utf8FitTo(name, wnamepart))
3121 if (m_session)
3122 PSendSysMessage(LANG_GO_ENTRY_LIST_CHAT, id, id, name.c_str());
3123 else
3124 PSendSysMessage(LANG_GO_ENTRY_LIST_CONSOLE, id, name.c_str());
3125 ++counter;
3129 if(counter==0)
3130 SendSysMessage(LANG_COMMAND_NOGAMEOBJECTFOUND);
3132 return true;
3135 bool ChatHandler::HandleLookupTaxiNodeCommand(const char * args)
3137 if(!*args)
3138 return false;
3140 std::string namepart = args;
3141 std::wstring wnamepart;
3143 if(!Utf8toWStr(namepart,wnamepart))
3144 return false;
3146 // converting string that we try to find to lower case
3147 wstrToLower( wnamepart );
3149 uint32 counter = 0; // Counter for figure out that we found smth.
3151 // Search in TaxiNodes.dbc
3152 for (uint32 id = 0; id < sTaxiNodesStore.GetNumRows(); id++)
3154 TaxiNodesEntry const *nodeEntry = sTaxiNodesStore.LookupEntry(id);
3155 if(nodeEntry)
3157 int loc = GetSessionDbcLocale();
3158 std::string name = nodeEntry->name[loc];
3159 if(name.empty())
3160 continue;
3162 if (!Utf8FitTo(name, wnamepart))
3164 loc = 0;
3165 for(; loc < MAX_LOCALE; ++loc)
3167 if(loc==GetSessionDbcLocale())
3168 continue;
3170 name = nodeEntry->name[loc];
3171 if(name.empty())
3172 continue;
3174 if (Utf8FitTo(name, wnamepart))
3175 break;
3179 if(loc < MAX_LOCALE)
3181 // send taxinode in "id - [name] (Map:m X:x Y:y Z:z)" format
3182 if (m_session)
3183 PSendSysMessage (LANG_TAXINODE_ENTRY_LIST_CHAT, id, id, name.c_str(),localeNames[loc],
3184 nodeEntry->map_id,nodeEntry->x,nodeEntry->y,nodeEntry->z);
3185 else
3186 PSendSysMessage (LANG_TAXINODE_ENTRY_LIST_CONSOLE, id, name.c_str(), localeNames[loc],
3187 nodeEntry->map_id,nodeEntry->x,nodeEntry->y,nodeEntry->z);
3188 ++counter;
3192 if (counter == 0) // if counter == 0 then we found nth
3193 SendSysMessage(LANG_COMMAND_NOTAXINODEFOUND);
3194 return true;
3197 /** \brief GM command level 3 - Create a guild.
3199 * This command allows a GM (level 3) to create a guild.
3201 * The "args" parameter contains the name of the guild leader
3202 * and then the name of the guild.
3205 bool ChatHandler::HandleGuildCreateCommand(const char* args)
3207 if(!*args)
3208 return false;
3210 // if not guild name only (in "") then player name
3211 Player* target;
3212 if(!extractPlayerTarget(*args!='"' ? (char*)args : NULL, &target))
3213 return false;
3215 char* tailStr = *args!='"' ? strtok(NULL, "") : (char*)args;
3216 if(!tailStr)
3217 return false;
3219 char* guildStr = extractQuotedArg(tailStr);
3220 if(!guildStr)
3221 return false;
3223 std::string guildname = guildStr;
3225 if (target->GetGuildId())
3227 SendSysMessage (LANG_PLAYER_IN_GUILD);
3228 return true;
3231 Guild *guild = new Guild;
3232 if (!guild->Create (target,guildname))
3234 delete guild;
3235 SendSysMessage (LANG_GUILD_NOT_CREATED);
3236 SetSentErrorMessage (true);
3237 return false;
3240 objmgr.AddGuild (guild);
3241 return true;
3244 bool ChatHandler::HandleGuildInviteCommand(const char *args)
3246 if(!*args)
3247 return false;
3249 // if not guild name only (in "") then player name
3250 uint64 target_guid;
3251 if(!extractPlayerTarget(*args!='"' ? (char*)args : NULL, NULL, &target_guid))
3252 return false;
3254 char* tailStr = *args!='"' ? strtok(NULL, "") : (char*)args;
3255 if(!tailStr)
3256 return false;
3258 char* guildStr = extractQuotedArg(tailStr);
3259 if(!guildStr)
3260 return false;
3262 std::string glName = guildStr;
3263 Guild* targetGuild = objmgr.GetGuildByName (glName);
3264 if (!targetGuild)
3265 return false;
3267 // player's guild membership checked in AddMember before add
3268 if (!targetGuild->AddMember (target_guid,targetGuild->GetLowestRank ()))
3269 return false;
3271 return true;
3274 bool ChatHandler::HandleGuildUninviteCommand(const char *args)
3276 Player* target;
3277 uint64 target_guid;
3278 if(!extractPlayerTarget((char*)args,&target,&target_guid))
3279 return false;
3281 uint32 glId = target ? target->GetGuildId () : Player::GetGuildIdFromDB (target_guid);
3282 if (!glId)
3283 return false;
3285 Guild* targetGuild = objmgr.GetGuildById (glId);
3286 if (!targetGuild)
3287 return false;
3289 targetGuild->DelMember (target_guid);
3290 return true;
3293 bool ChatHandler::HandleGuildRankCommand(const char *args)
3295 char* nameStr;
3296 char* rankStr;
3297 extractOptFirstArg((char*)args,&nameStr,&rankStr);
3298 if(!rankStr)
3299 return false;
3301 Player* target;
3302 uint64 target_guid;
3303 std::string target_name;
3304 if(!extractPlayerTarget(nameStr,&target,&target_guid,&target_name))
3305 return false;
3307 uint32 glId = target ? target->GetGuildId () : Player::GetGuildIdFromDB (target_guid);
3308 if (!glId)
3309 return false;
3311 Guild* targetGuild = objmgr.GetGuildById (glId);
3312 if (!targetGuild)
3313 return false;
3315 uint32 newrank = uint32 (atoi (rankStr));
3316 if (newrank > targetGuild->GetLowestRank ())
3317 return false;
3319 targetGuild->ChangeRank (target_guid,newrank);
3320 return true;
3323 bool ChatHandler::HandleGuildDeleteCommand(const char* args)
3325 if (!*args)
3326 return false;
3328 char* guildStr = extractQuotedArg((char*)args);
3329 if(!guildStr)
3330 return false;
3332 std::string gld = guildStr;
3334 Guild* targetGuild = objmgr.GetGuildByName (gld);
3335 if (!targetGuild)
3336 return false;
3338 targetGuild->Disband ();
3340 return true;
3343 bool ChatHandler::HandleGetDistanceCommand(const char* args)
3345 WorldObject* obj = NULL;
3347 if (*args)
3349 uint64 guid = extractGuidFromLink((char*)args);
3350 if(guid)
3351 obj = (WorldObject*)ObjectAccessor::GetObjectByTypeMask(*m_session->GetPlayer(),guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
3353 if(!obj)
3355 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3356 SetSentErrorMessage(true);
3357 return false;
3360 else
3362 obj = getSelectedUnit();
3364 if(!obj)
3366 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3367 SetSentErrorMessage(true);
3368 return false;
3372 PSendSysMessage(LANG_DISTANCE, m_session->GetPlayer()->GetDistance(obj),m_session->GetPlayer()->GetDistance2d(obj));
3374 return true;
3377 bool ChatHandler::HandleDieCommand(const char* /*args*/)
3379 Unit* target = getSelectedUnit();
3381 if(!target || !m_session->GetPlayer()->GetSelection())
3383 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3384 SetSentErrorMessage(true);
3385 return false;
3388 if(target->GetTypeId()==TYPEID_PLAYER)
3390 if(HasLowerSecurity((Player*)target,0,false))
3391 return false;
3394 if( target->isAlive() )
3396 m_session->GetPlayer()->DealDamage(target, target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
3399 return true;
3402 bool ChatHandler::HandleDamageCommand(const char * args)
3404 if (!*args)
3405 return false;
3407 Unit* target = getSelectedUnit();
3409 if (!target || !m_session->GetPlayer()->GetSelection())
3411 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3412 SetSentErrorMessage(true);
3413 return false;
3416 if (!target->isAlive())
3417 return true;
3419 char* damageStr = strtok((char*)args, " ");
3420 if (!damageStr)
3421 return false;
3423 int32 damage_int = atoi((char*)damageStr);
3424 if(damage_int <=0)
3425 return true;
3427 uint32 damage = damage_int;
3429 char* schoolStr = strtok((char*)NULL, " ");
3431 // flat melee damage without resistence/etc reduction
3432 if (!schoolStr)
3434 m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
3435 if (target != m_session->GetPlayer())
3436 m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, SPELL_SCHOOL_MASK_NORMAL, damage, 0, 0, VICTIMSTATE_NORMAL, 0);
3437 return true;
3440 uint32 school = schoolStr ? atoi((char*)schoolStr) : SPELL_SCHOOL_NORMAL;
3441 if(school >= MAX_SPELL_SCHOOL)
3442 return false;
3444 SpellSchoolMask schoolmask = SpellSchoolMask(1 << school);
3446 if ( schoolmask & SPELL_SCHOOL_MASK_NORMAL )
3447 damage = m_session->GetPlayer()->CalcArmorReducedDamage(target, damage);
3449 char* spellStr = strtok((char*)NULL, " ");
3451 // melee damage by specific school
3452 if (!spellStr)
3454 uint32 absorb = 0;
3455 uint32 resist = 0;
3457 m_session->GetPlayer()->CalcAbsorbResist(target,schoolmask, SPELL_DIRECT_DAMAGE, damage, &absorb, &resist);
3459 if (damage <= absorb + resist)
3460 return true;
3462 damage -= absorb + resist;
3464 m_session->GetPlayer()->DealDamageMods(target,damage,&absorb);
3465 m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, schoolmask, NULL, false);
3466 m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, schoolmask, damage, absorb, resist, VICTIMSTATE_NORMAL, 0);
3467 return true;
3470 // non-melee damage
3472 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
3473 uint32 spellid = extractSpellIdFromLink((char*)args);
3474 if (!spellid || !sSpellStore.LookupEntry(spellid))
3475 return false;
3477 m_session->GetPlayer()->SpellNonMeleeDamageLog(target, spellid, damage);
3478 return true;
3481 bool ChatHandler::HandleModifyArenaCommand(const char * args)
3483 if (!*args)
3484 return false;
3486 Player *target = getSelectedPlayer();
3487 if(!target)
3489 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3490 SetSentErrorMessage(true);
3491 return false;
3494 int32 amount = (uint32)atoi(args);
3496 target->ModifyArenaPoints(amount);
3498 PSendSysMessage(LANG_COMMAND_MODIFY_ARENA, GetNameLink(target).c_str(), target->GetArenaPoints());
3500 return true;
3503 bool ChatHandler::HandleReviveCommand(const char* args)
3505 Player* target;
3506 uint64 target_guid;
3507 if(!extractPlayerTarget((char*)args,&target,&target_guid))
3508 return false;
3510 if (target)
3512 target->ResurrectPlayer(0.5f);
3513 target->SpawnCorpseBones();
3514 target->SaveToDB();
3516 else
3517 // will resurrected at login without corpse
3518 ObjectAccessor::Instance().ConvertCorpseForPlayer(target_guid);
3520 return true;
3523 bool ChatHandler::HandleAuraCommand(const char* args)
3525 Unit *target = getSelectedUnit();
3526 if(!target)
3528 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3529 SetSentErrorMessage(true);
3530 return false;
3533 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
3534 uint32 spellID = extractSpellIdFromLink((char*)args);
3536 SpellEntry const *spellInfo = sSpellStore.LookupEntry( spellID );
3537 if(spellInfo)
3539 for(uint32 i = 0;i<3;++i)
3541 uint8 eff = spellInfo->Effect[i];
3542 if (eff>=TOTAL_SPELL_EFFECTS)
3543 continue;
3544 if( IsAreaAuraEffect(eff) ||
3545 eff == SPELL_EFFECT_APPLY_AURA ||
3546 eff == SPELL_EFFECT_PERSISTENT_AREA_AURA )
3548 Aura *Aur = CreateAura(spellInfo, i, NULL, target);
3549 target->AddAura(Aur);
3554 return true;
3557 bool ChatHandler::HandleUnAuraCommand(const char* args)
3559 Unit *target = getSelectedUnit();
3560 if(!target)
3562 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3563 SetSentErrorMessage(true);
3564 return false;
3567 std::string argstr = args;
3568 if (argstr == "all")
3570 target->RemoveAllAuras();
3571 return true;
3574 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
3575 uint32 spellID = extractSpellIdFromLink((char*)args);
3576 if(!spellID)
3577 return false;
3579 target->RemoveAurasDueToSpell(spellID);
3581 return true;
3584 bool ChatHandler::HandleLinkGraveCommand(const char* args)
3586 if(!*args)
3587 return false;
3589 char* px = strtok((char*)args, " ");
3590 if (!px)
3591 return false;
3593 uint32 g_id = (uint32)atoi(px);
3595 uint32 g_team;
3597 char* px2 = strtok(NULL, " ");
3599 if (!px2)
3600 g_team = 0;
3601 else if (strncmp(px2,"horde",6)==0)
3602 g_team = HORDE;
3603 else if (strncmp(px2,"alliance",9)==0)
3604 g_team = ALLIANCE;
3605 else
3606 return false;
3608 WorldSafeLocsEntry const* graveyard = sWorldSafeLocsStore.LookupEntry(g_id);
3610 if(!graveyard )
3612 PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST, g_id);
3613 SetSentErrorMessage(true);
3614 return false;
3617 Player* player = m_session->GetPlayer();
3619 uint32 zoneId = player->GetZoneId();
3621 AreaTableEntry const *areaEntry = GetAreaEntryByAreaID(zoneId);
3622 if(!areaEntry || areaEntry->zone !=0 )
3624 PSendSysMessage(LANG_COMMAND_GRAVEYARDWRONGZONE, g_id,zoneId);
3625 SetSentErrorMessage(true);
3626 return false;
3629 if(objmgr.AddGraveYardLink(g_id,zoneId,g_team))
3630 PSendSysMessage(LANG_COMMAND_GRAVEYARDLINKED, g_id,zoneId);
3631 else
3632 PSendSysMessage(LANG_COMMAND_GRAVEYARDALRLINKED, g_id,zoneId);
3634 return true;
3637 bool ChatHandler::HandleNearGraveCommand(const char* args)
3639 uint32 g_team;
3641 size_t argslen = strlen(args);
3643 if(!*args)
3644 g_team = 0;
3645 else if (strncmp((char*)args,"horde",argslen)==0)
3646 g_team = HORDE;
3647 else if (strncmp((char*)args,"alliance",argslen)==0)
3648 g_team = ALLIANCE;
3649 else
3650 return false;
3652 Player* player = m_session->GetPlayer();
3653 uint32 zone_id = player->GetZoneId();
3655 WorldSafeLocsEntry const* graveyard = objmgr.GetClosestGraveYard(
3656 player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(),player->GetMapId(),g_team);
3658 if(graveyard)
3660 uint32 g_id = graveyard->ID;
3662 GraveYardData const* data = objmgr.FindGraveYardData(g_id,zone_id);
3663 if (!data)
3665 PSendSysMessage(LANG_COMMAND_GRAVEYARDERROR,g_id);
3666 SetSentErrorMessage(true);
3667 return false;
3670 g_team = data->team;
3672 std::string team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_NOTEAM);
3674 if(g_team == 0)
3675 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ANY);
3676 else if(g_team == HORDE)
3677 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_HORDE);
3678 else if(g_team == ALLIANCE)
3679 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ALLIANCE);
3681 PSendSysMessage(LANG_COMMAND_GRAVEYARDNEAREST, g_id,team_name.c_str(),zone_id);
3683 else
3685 std::string team_name;
3687 if(g_team == 0)
3688 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ANY);
3689 else if(g_team == HORDE)
3690 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_HORDE);
3691 else if(g_team == ALLIANCE)
3692 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ALLIANCE);
3694 if(g_team == ~uint32(0))
3695 PSendSysMessage(LANG_COMMAND_ZONENOGRAVEYARDS, zone_id);
3696 else
3697 PSendSysMessage(LANG_COMMAND_ZONENOGRAFACTION, zone_id,team_name.c_str());
3700 return true;
3703 //-----------------------Npc Commands-----------------------
3704 bool ChatHandler::HandleNpcAllowMovementCommand(const char* /*args*/)
3706 if(sWorld.getAllowMovement())
3708 sWorld.SetAllowMovement(false);
3709 SendSysMessage(LANG_CREATURE_MOVE_DISABLED);
3711 else
3713 sWorld.SetAllowMovement(true);
3714 SendSysMessage(LANG_CREATURE_MOVE_ENABLED);
3716 return true;
3719 bool ChatHandler::HandleNpcChangeEntryCommand(const char *args)
3721 if (!*args)
3722 return false;
3724 uint32 newEntryNum = atoi(args);
3725 if(!newEntryNum)
3726 return false;
3728 Unit* unit = getSelectedUnit();
3729 if(!unit || unit->GetTypeId() != TYPEID_UNIT)
3731 SendSysMessage(LANG_SELECT_CREATURE);
3732 SetSentErrorMessage(true);
3733 return false;
3735 Creature* creature = (Creature*)unit;
3736 if(creature->UpdateEntry(newEntryNum))
3737 SendSysMessage(LANG_DONE);
3738 else
3739 SendSysMessage(LANG_ERROR);
3740 return true;
3743 bool ChatHandler::HandleNpcInfoCommand(const char* /*args*/)
3745 Creature* target = getSelectedCreature();
3747 if(!target)
3749 SendSysMessage(LANG_SELECT_CREATURE);
3750 SetSentErrorMessage(true);
3751 return false;
3754 uint32 faction = target->getFaction();
3755 uint32 npcflags = target->GetUInt32Value(UNIT_NPC_FLAGS);
3756 uint32 displayid = target->GetDisplayId();
3757 uint32 nativeid = target->GetNativeDisplayId();
3758 uint32 Entry = target->GetEntry();
3759 CreatureInfo const* cInfo = target->GetCreatureInfo();
3761 int32 curRespawnDelay = target->GetRespawnTimeEx()-time(NULL);
3762 if(curRespawnDelay < 0)
3763 curRespawnDelay = 0;
3764 std::string curRespawnDelayStr = secsToTimeString(curRespawnDelay,true);
3765 std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(),true);
3767 PSendSysMessage(LANG_NPCINFO_CHAR, target->GetDBTableGUIDLow(), faction, npcflags, Entry, displayid, nativeid);
3768 PSendSysMessage(LANG_NPCINFO_LEVEL, target->getLevel());
3769 PSendSysMessage(LANG_NPCINFO_HEALTH,target->GetCreateHealth(), target->GetMaxHealth(), target->GetHealth());
3770 PSendSysMessage(LANG_NPCINFO_FLAGS, target->GetUInt32Value(UNIT_FIELD_FLAGS), target->GetUInt32Value(UNIT_DYNAMIC_FLAGS), target->getFaction());
3771 PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES, defRespawnDelayStr.c_str(),curRespawnDelayStr.c_str());
3772 PSendSysMessage(LANG_NPCINFO_LOOT, cInfo->lootid,cInfo->pickpocketLootId,cInfo->SkinLootId);
3773 PSendSysMessage(LANG_NPCINFO_DUNGEON_ID, target->GetInstanceId());
3774 PSendSysMessage(LANG_NPCINFO_POSITION,float(target->GetPositionX()), float(target->GetPositionY()), float(target->GetPositionZ()));
3776 if ((npcflags & UNIT_NPC_FLAG_VENDOR) )
3778 SendSysMessage(LANG_NPCINFO_VENDOR);
3780 if ((npcflags & UNIT_NPC_FLAG_TRAINER) )
3782 SendSysMessage(LANG_NPCINFO_TRAINER);
3785 return true;
3788 //play npc emote
3789 bool ChatHandler::HandleNpcPlayEmoteCommand(const char* args)
3791 uint32 emote = atoi((char*)args);
3793 Creature* target = getSelectedCreature();
3794 if(!target)
3796 SendSysMessage(LANG_SELECT_CREATURE);
3797 SetSentErrorMessage(true);
3798 return false;
3801 target->SetUInt32Value(UNIT_NPC_EMOTESTATE,emote);
3803 return true;
3806 //TODO: NpcCommands that needs to be fixed :
3808 bool ChatHandler::HandleNpcAddWeaponCommand(const char* /*args*/)
3810 /*if (!*args)
3811 return false;
3813 uint64 guid = m_session->GetPlayer()->GetSelection();
3814 if (guid == 0)
3816 SendSysMessage(LANG_NO_SELECTION);
3817 return true;
3820 Creature *pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
3822 if(!pCreature)
3824 SendSysMessage(LANG_SELECT_CREATURE);
3825 return true;
3828 char* pSlotID = strtok((char*)args, " ");
3829 if (!pSlotID)
3830 return false;
3832 char* pItemID = strtok(NULL, " ");
3833 if (!pItemID)
3834 return false;
3836 uint32 ItemID = atoi(pItemID);
3837 uint32 SlotID = atoi(pSlotID);
3839 ItemPrototype* tmpItem = objmgr.GetItemPrototype(ItemID);
3841 bool added = false;
3842 if(tmpItem)
3844 switch(SlotID)
3846 case 1:
3847 pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, ItemID);
3848 added = true;
3849 break;
3850 case 2:
3851 pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_01, ItemID);
3852 added = true;
3853 break;
3854 case 3:
3855 pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_02, ItemID);
3856 added = true;
3857 break;
3858 default:
3859 PSendSysMessage(LANG_ITEM_SLOT_NOT_EXIST,SlotID);
3860 added = false;
3861 break;
3864 if(added)
3865 PSendSysMessage(LANG_ITEM_ADDED_TO_SLOT,ItemID,tmpItem->Name1,SlotID);
3867 else
3869 PSendSysMessage(LANG_ITEM_NOT_FOUND,ItemID);
3870 return true;
3873 return true;
3875 //----------------------------------------------------------
3877 bool ChatHandler::HandleExploreCheatCommand(const char* args)
3879 if (!*args)
3880 return false;
3882 int flag = atoi((char*)args);
3884 Player *chr = getSelectedPlayer();
3885 if (chr == NULL)
3887 SendSysMessage(LANG_NO_CHAR_SELECTED);
3888 SetSentErrorMessage(true);
3889 return false;
3892 if (flag != 0)
3894 PSendSysMessage(LANG_YOU_SET_EXPLORE_ALL, GetNameLink(chr).c_str());
3895 if (needReportToTarget(chr))
3896 ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_ALL,GetNameLink().c_str());
3898 else
3900 PSendSysMessage(LANG_YOU_SET_EXPLORE_NOTHING, GetNameLink(chr).c_str());
3901 if (needReportToTarget(chr))
3902 ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_NOTHING,GetNameLink().c_str());
3905 for (uint8 i=0; i<128; ++i)
3907 if (flag != 0)
3909 m_session->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i,0xFFFFFFFF);
3911 else
3913 m_session->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i,0);
3917 return true;
3920 bool ChatHandler::HandleHoverCommand(const char* args)
3922 char* px = strtok((char*)args, " ");
3923 uint32 flag;
3924 if (!px)
3925 flag = 1;
3926 else
3927 flag = atoi(px);
3929 m_session->GetPlayer()->SetHover(flag);
3931 if (flag)
3932 SendSysMessage(LANG_HOVER_ENABLED);
3933 else
3934 SendSysMessage(LANG_HOVER_DISABLED);
3936 return true;
3939 void ChatHandler::HandleCharacterLevel(Player* player, uint64 player_guid, uint32 oldlevel, uint32 newlevel)
3941 if(player)
3943 player->GiveLevel(newlevel);
3944 player->InitTalentForLevel();
3945 player->SetUInt32Value(PLAYER_XP,0);
3947 if(needReportToTarget(player))
3949 if(oldlevel == newlevel)
3950 ChatHandler(player).PSendSysMessage(LANG_YOURS_LEVEL_PROGRESS_RESET,GetNameLink().c_str());
3951 else if(oldlevel < newlevel)
3952 ChatHandler(player).PSendSysMessage(LANG_YOURS_LEVEL_UP,GetNameLink().c_str(),newlevel);
3953 else // if(oldlevel > newlevel)
3954 ChatHandler(player).PSendSysMessage(LANG_YOURS_LEVEL_DOWN,GetNameLink().c_str(),newlevel);
3957 else
3959 // update level and XP at level, all other will be updated at loading
3960 CharacterDatabase.PExecute("UPDATE characters SET level = '%u', xp = 0 WHERE guid = '%u'", newlevel, GUID_LOPART(player_guid));
3964 bool ChatHandler::HandleCharacterLevelCommand(const char* args)
3966 char* nameStr;
3967 char* levelStr;
3968 extractOptFirstArg((char*)args,&nameStr,&levelStr);
3969 if(!levelStr)
3970 return false;
3972 // exception opt second arg: .character level $name
3973 if(isalpha(levelStr[0]))
3975 nameStr = levelStr;
3976 levelStr = NULL; // current level will used
3979 Player* target;
3980 uint64 target_guid;
3981 std::string target_name;
3982 if(!extractPlayerTarget(nameStr,&target,&target_guid,&target_name))
3983 return false;
3985 int32 oldlevel = target ? target->getLevel() : Player::GetLevelFromDB(target_guid);
3986 int32 newlevel = levelStr ? atoi(levelStr) : oldlevel;
3988 if(newlevel < 1)
3989 return false; // invalid level
3991 if(newlevel > STRONG_MAX_LEVEL) // hardcoded maximum level
3992 newlevel = STRONG_MAX_LEVEL;
3994 HandleCharacterLevel(target,target_guid,oldlevel,newlevel);
3996 if(!m_session || m_session->GetPlayer() != target) // including player==NULL
3998 std::string nameLink = playerLink(target_name);
3999 PSendSysMessage(LANG_YOU_CHANGE_LVL,nameLink.c_str(),newlevel);
4002 return true;
4005 bool ChatHandler::HandleLevelUpCommand(const char* args)
4007 char* nameStr;
4008 char* levelStr;
4009 extractOptFirstArg((char*)args,&nameStr,&levelStr);
4011 // exception opt second arg: .character level $name
4012 if(levelStr && isalpha(levelStr[0]))
4014 nameStr = levelStr;
4015 levelStr = NULL; // current level will used
4018 Player* target;
4019 uint64 target_guid;
4020 std::string target_name;
4021 if(!extractPlayerTarget(nameStr,&target,&target_guid,&target_name))
4022 return false;
4024 int32 oldlevel = target ? target->getLevel() : Player::GetLevelFromDB(target_guid);
4025 int32 addlevel = levelStr ? atoi(levelStr) : 1;
4026 int32 newlevel = oldlevel + addlevel;
4028 if(newlevel < 1)
4029 newlevel = 1;
4031 if(newlevel > STRONG_MAX_LEVEL) // hardcoded maximum level
4032 newlevel = STRONG_MAX_LEVEL;
4034 HandleCharacterLevel(target,target_guid,oldlevel,newlevel);
4036 if(!m_session || m_session->GetPlayer() != target) // including chr==NULL
4038 std::string nameLink = playerLink(target_name);
4039 PSendSysMessage(LANG_YOU_CHANGE_LVL,nameLink.c_str(),newlevel);
4042 return true;
4045 bool ChatHandler::HandleShowAreaCommand(const char* args)
4047 if (!*args)
4048 return false;
4050 Player *chr = getSelectedPlayer();
4051 if (chr == NULL)
4053 SendSysMessage(LANG_NO_CHAR_SELECTED);
4054 SetSentErrorMessage(true);
4055 return false;
4058 int area = GetAreaFlagByAreaID(atoi((char*)args));
4059 int offset = area / 32;
4060 uint32 val = (uint32)(1 << (area % 32));
4062 if(area<0 || offset >= 128)
4064 SendSysMessage(LANG_BAD_VALUE);
4065 SetSentErrorMessage(true);
4066 return false;
4069 uint32 currFields = chr->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset);
4070 chr->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields | val));
4072 SendSysMessage(LANG_EXPLORE_AREA);
4073 return true;
4076 bool ChatHandler::HandleHideAreaCommand(const char* args)
4078 if (!*args)
4079 return false;
4081 Player *chr = getSelectedPlayer();
4082 if (chr == NULL)
4084 SendSysMessage(LANG_NO_CHAR_SELECTED);
4085 SetSentErrorMessage(true);
4086 return false;
4089 int area = GetAreaFlagByAreaID(atoi((char*)args));
4090 int offset = area / 32;
4091 uint32 val = (uint32)(1 << (area % 32));
4093 if(area<0 || offset >= 128)
4095 SendSysMessage(LANG_BAD_VALUE);
4096 SetSentErrorMessage(true);
4097 return false;
4100 uint32 currFields = chr->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset);
4101 chr->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields ^ val));
4103 SendSysMessage(LANG_UNEXPLORE_AREA);
4104 return true;
4107 bool ChatHandler::HandleBankCommand(const char* /*args*/)
4109 m_session->SendShowBank( m_session->GetPlayer()->GetGUID() );
4111 return true;
4114 bool ChatHandler::HandleChangeWeather(const char* args)
4116 if(!*args)
4117 return false;
4119 //Weather is OFF
4120 if (!sWorld.getConfig(CONFIG_WEATHER))
4122 SendSysMessage(LANG_WEATHER_DISABLED);
4123 SetSentErrorMessage(true);
4124 return false;
4127 //*Change the weather of a cell
4128 char* px = strtok((char*)args, " ");
4129 char* py = strtok(NULL, " ");
4131 if (!px || !py)
4132 return false;
4134 uint32 type = (uint32)atoi(px); //0 to 3, 0: fine, 1: rain, 2: snow, 3: sand
4135 float grade = (float)atof(py); //0 to 1, sending -1 is instand good weather
4137 Player *player = m_session->GetPlayer();
4138 uint32 zoneid = player->GetZoneId();
4140 Weather* wth = sWorld.FindWeather(zoneid);
4142 if(!wth)
4143 wth = sWorld.AddWeather(zoneid);
4144 if(!wth)
4146 SendSysMessage(LANG_NO_WEATHER);
4147 SetSentErrorMessage(true);
4148 return false;
4151 wth->SetWeather(WeatherType(type), grade);
4153 return true;
4156 bool ChatHandler::HandleTeleAddCommand(const char * args)
4158 if(!*args)
4159 return false;
4161 Player *player=m_session->GetPlayer();
4162 if (!player)
4163 return false;
4165 std::string name = args;
4167 if(objmgr.GetGameTele(name))
4169 SendSysMessage(LANG_COMMAND_TP_ALREADYEXIST);
4170 SetSentErrorMessage(true);
4171 return false;
4174 GameTele tele;
4175 tele.position_x = player->GetPositionX();
4176 tele.position_y = player->GetPositionY();
4177 tele.position_z = player->GetPositionZ();
4178 tele.orientation = player->GetOrientation();
4179 tele.mapId = player->GetMapId();
4180 tele.name = name;
4182 if(objmgr.AddGameTele(tele))
4184 SendSysMessage(LANG_COMMAND_TP_ADDED);
4186 else
4188 SendSysMessage(LANG_COMMAND_TP_ADDEDERR);
4189 SetSentErrorMessage(true);
4190 return false;
4193 return true;
4196 bool ChatHandler::HandleTeleDelCommand(const char * args)
4198 if(!*args)
4199 return false;
4201 std::string name = args;
4203 if(!objmgr.DeleteGameTele(name))
4205 SendSysMessage(LANG_COMMAND_TELE_NOTFOUND);
4206 SetSentErrorMessage(true);
4207 return false;
4210 SendSysMessage(LANG_COMMAND_TP_DELETED);
4211 return true;
4214 bool ChatHandler::HandleListAurasCommand (const char * /*args*/)
4216 Unit *unit = getSelectedUnit();
4217 if(!unit)
4219 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
4220 SetSentErrorMessage(true);
4221 return false;
4224 char const* talentStr = GetMangosString(LANG_TALENT);
4225 char const* passiveStr = GetMangosString(LANG_PASSIVE);
4227 Unit::AuraMap const& uAuras = unit->GetAuras();
4228 PSendSysMessage(LANG_COMMAND_TARGET_LISTAURAS, uAuras.size());
4229 for (Unit::AuraMap::const_iterator itr = uAuras.begin(); itr != uAuras.end(); ++itr)
4231 bool talent = GetTalentSpellCost(itr->second->GetId()) > 0;
4233 char const* name = itr->second->GetSpellProto()->SpellName[GetSessionDbcLocale()];
4235 if (m_session)
4237 std::ostringstream ss_name;
4238 ss_name << "|cffffffff|Hspell:" << itr->second->GetId() << "|h[" << name << "]|h|r";
4240 PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffIndex(),
4241 itr->second->GetModifier()->m_auraname, itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(),
4242 ss_name.str().c_str(),
4243 (itr->second->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
4244 IS_PLAYER_GUID(itr->second->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(itr->second->GetCasterGUID()));
4246 else
4248 PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffIndex(),
4249 itr->second->GetModifier()->m_auraname, itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(),
4250 name,
4251 (itr->second->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
4252 IS_PLAYER_GUID(itr->second->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(itr->second->GetCasterGUID()));
4255 for (int i = 0; i < TOTAL_AURAS; ++i)
4257 Unit::AuraList const& uAuraList = unit->GetAurasByType(AuraType(i));
4258 if (uAuraList.empty()) continue;
4259 PSendSysMessage(LANG_COMMAND_TARGET_LISTAURATYPE, uAuraList.size(), i);
4260 for (Unit::AuraList::const_iterator itr = uAuraList.begin(); itr != uAuraList.end(); ++itr)
4262 bool talent = GetTalentSpellCost((*itr)->GetId()) > 0;
4264 char const* name = (*itr)->GetSpellProto()->SpellName[GetSessionDbcLocale()];
4266 if (m_session)
4268 std::ostringstream ss_name;
4269 ss_name << "|cffffffff|Hspell:" << (*itr)->GetId() << "|h[" << name << "]|h|r";
4271 PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(),
4272 ss_name.str().c_str(),((*itr)->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
4273 IS_PLAYER_GUID((*itr)->GetCasterGUID()) ? "player" : "creature",GUID_LOPART((*itr)->GetCasterGUID()));
4275 else
4277 PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(),
4278 name,((*itr)->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
4279 IS_PLAYER_GUID((*itr)->GetCasterGUID()) ? "player" : "creature",GUID_LOPART((*itr)->GetCasterGUID()));
4283 return true;
4286 bool ChatHandler::HandleResetAchievementsCommand (const char * args)
4288 Player* target;
4289 uint64 target_guid;
4290 if (!extractPlayerTarget((char*)args,&target,&target_guid))
4291 return false;
4293 if(target)
4294 target->GetAchievementMgr().Reset();
4295 else
4296 AchievementMgr::DeleteFromDB(GUID_LOPART(target_guid));
4298 return true;
4301 bool ChatHandler::HandleResetHonorCommand (const char * args)
4303 Player* target;
4304 if (!extractPlayerTarget((char*)args,&target))
4305 return false;
4307 target->SetUInt32Value(PLAYER_FIELD_KILLS, 0);
4308 target->SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORBALE_KILLS, 0);
4309 target->SetUInt32Value(PLAYER_FIELD_HONOR_CURRENCY, 0);
4310 target->SetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, 0);
4311 target->SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, 0);
4312 target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL);
4314 return true;
4317 static bool HandleResetStatsOrLevelHelper(Player* player)
4319 ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(player->getClass());
4320 if(!cEntry)
4322 sLog.outError("Class %u not found in DBC (Wrong DBC files?)",player->getClass());
4323 return false;
4326 uint8 powertype = cEntry->powerType;
4328 // reset m_form if no aura
4329 if(!player->HasAuraType(SPELL_AURA_MOD_SHAPESHIFT))
4330 player->m_form = FORM_NONE;
4332 player->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE );
4333 player->SetFloatValue(UNIT_FIELD_COMBATREACH, 1.5f );
4335 player->setFactionForRace(player->getRace());
4337 player->SetUInt32Value(UNIT_FIELD_BYTES_0, ( ( player->getRace() ) | ( player->getClass() << 8 ) | ( player->getGender() << 16 ) | ( powertype << 24 ) ) );
4339 // reset only if player not in some form;
4340 if(player->m_form==FORM_NONE)
4341 player->InitDisplayIds();
4343 player->SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP );
4344 player->SetByteValue(UNIT_FIELD_BYTES_2, 3, player->m_form);
4346 player->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
4348 //-1 is default value
4349 player->SetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, uint32(-1));
4351 //player->SetUInt32Value(PLAYER_FIELD_BYTES, 0xEEE00000 );
4352 return true;
4355 bool ChatHandler::HandleResetLevelCommand(const char * args)
4357 Player* target;
4358 if(!extractPlayerTarget((char*)args,&target))
4359 return false;
4361 if(!HandleResetStatsOrLevelHelper(target))
4362 return false;
4364 // set starting level
4365 uint32 start_level = target->getClass() != CLASS_DEATH_KNIGHT
4366 ? sWorld.getConfig(CONFIG_START_PLAYER_LEVEL)
4367 : sWorld.getConfig(CONFIG_START_HEROIC_PLAYER_LEVEL);
4369 target->_ApplyAllLevelScaleItemMods(false);
4371 target->SetLevel(start_level);
4372 target->InitRunes();
4373 target->InitStatsForLevel(true);
4374 target->InitTaxiNodesForLevel();
4375 target->InitGlyphsForLevel();
4376 target->InitTalentForLevel();
4377 target->SetUInt32Value(PLAYER_XP,0);
4379 target->_ApplyAllLevelScaleItemMods(true);
4381 // reset level for pet
4382 if(Pet* pet = target->GetPet())
4383 pet->SynchronizeLevelWithOwner();
4385 return true;
4388 bool ChatHandler::HandleResetStatsCommand(const char * args)
4390 Player* target;
4391 if (!extractPlayerTarget((char*)args,&target))
4392 return false;
4394 if (!HandleResetStatsOrLevelHelper(target))
4395 return false;
4397 target->InitRunes();
4398 target->InitStatsForLevel(true);
4399 target->InitTaxiNodesForLevel();
4400 target->InitGlyphsForLevel();
4401 target->InitTalentForLevel();
4403 return true;
4406 bool ChatHandler::HandleResetSpellsCommand(const char * args)
4408 Player* target;
4409 uint64 target_guid;
4410 std::string target_name;
4411 if(!extractPlayerTarget((char*)args,&target,&target_guid,&target_name))
4412 return false;
4414 if(target)
4416 target->resetSpells();
4418 ChatHandler(target).SendSysMessage(LANG_RESET_SPELLS);
4419 if(!m_session || m_session->GetPlayer()!=target)
4420 PSendSysMessage(LANG_RESET_SPELLS_ONLINE,GetNameLink(target).c_str());
4422 else
4424 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",uint32(AT_LOGIN_RESET_SPELLS), GUID_LOPART(target_guid));
4425 PSendSysMessage(LANG_RESET_SPELLS_OFFLINE,target_name.c_str());
4428 return true;
4431 bool ChatHandler::HandleResetTalentsCommand(const char * args)
4433 Player* target;
4434 uint64 target_guid;
4435 std::string target_name;
4436 if (!extractPlayerTarget((char*)args,&target,&target_guid,&target_name))
4438 // Try reset talents as Hunter Pet
4439 Creature* creature = getSelectedCreature();
4440 if (!*args && creature && creature->isPet())
4442 Unit *owner = creature->GetOwner();
4443 if(owner && owner->GetTypeId() == TYPEID_PLAYER && ((Pet *)creature)->IsPermanentPetFor((Player*)owner))
4445 ((Pet *)creature)->resetTalents(true);
4446 ((Player*)owner)->SendTalentsInfoData(true);
4448 ChatHandler((Player*)owner).SendSysMessage(LANG_RESET_PET_TALENTS);
4449 if(!m_session || m_session->GetPlayer()!=((Player*)owner))
4450 PSendSysMessage(LANG_RESET_PET_TALENTS_ONLINE,GetNameLink((Player*)owner).c_str());
4452 return true;
4455 SendSysMessage(LANG_NO_CHAR_SELECTED);
4456 SetSentErrorMessage(true);
4457 return false;
4460 if (target)
4462 target->resetTalents(true);
4463 target->SendTalentsInfoData(false);
4464 ChatHandler(target).SendSysMessage(LANG_RESET_TALENTS);
4465 if (!m_session || m_session->GetPlayer()!=target)
4466 PSendSysMessage(LANG_RESET_TALENTS_ONLINE,GetNameLink(target).c_str());
4468 Pet* pet = target->GetPet();
4469 Pet::resetTalentsForAllPetsOf(target,pet);
4470 if(pet)
4471 target->SendTalentsInfoData(true);
4472 return true;
4474 else if (target_guid)
4476 uint32 at_flags = AT_LOGIN_NONE | AT_LOGIN_RESET_PET_TALENTS;
4477 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",at_flags, GUID_LOPART(target_guid) );
4478 std::string nameLink = playerLink(target_name);
4479 PSendSysMessage(LANG_RESET_TALENTS_OFFLINE,nameLink.c_str());
4480 return true;
4483 SendSysMessage(LANG_NO_CHAR_SELECTED);
4484 SetSentErrorMessage(true);
4485 return false;
4488 bool ChatHandler::HandleResetAllCommand(const char * args)
4490 if(!*args)
4491 return false;
4493 std::string casename = args;
4495 AtLoginFlags atLogin;
4497 // Command specially created as single command to prevent using short case names
4498 if(casename=="spells")
4500 atLogin = AT_LOGIN_RESET_SPELLS;
4501 sWorld.SendWorldText(LANG_RESETALL_SPELLS);
4502 if(!m_session)
4503 SendSysMessage(LANG_RESETALL_SPELLS);
4505 else if(casename=="talents")
4507 atLogin = AtLoginFlags(AT_LOGIN_RESET_TALENTS | AT_LOGIN_RESET_PET_TALENTS);
4508 sWorld.SendWorldText(LANG_RESETALL_TALENTS);
4509 if(!m_session)
4510 SendSysMessage(LANG_RESETALL_TALENTS);
4512 else
4514 PSendSysMessage(LANG_RESETALL_UNKNOWN_CASE,args);
4515 SetSentErrorMessage(true);
4516 return false;
4519 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE (at_login & '%u') = '0'",atLogin,atLogin);
4520 HashMapHolder<Player>::MapType const& plist = ObjectAccessor::Instance().GetPlayers();
4521 for(HashMapHolder<Player>::MapType::const_iterator itr = plist.begin(); itr != plist.end(); ++itr)
4522 itr->second->SetAtLoginFlag(atLogin);
4524 return true;
4527 bool ChatHandler::HandleServerShutDownCancelCommand(const char* /*args*/)
4529 sWorld.ShutdownCancel();
4530 return true;
4533 bool ChatHandler::HandleServerShutDownCommand(const char* args)
4535 if(!*args)
4536 return false;
4538 char* time_str = strtok ((char*) args, " ");
4539 char* exitcode_str = strtok (NULL, "");
4541 int32 time = atoi (time_str);
4543 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4544 if ((time == 0 && (time_str[0]!='0' || time_str[1]!='\0')) || time < 0)
4545 return false;
4547 if (exitcode_str)
4549 int32 exitcode = atoi (exitcode_str);
4551 // Handle atoi() errors
4552 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4553 return false;
4555 // Exit code should be in range of 0-125, 126-255 is used
4556 // in many shells for their own return codes and code > 255
4557 // is not supported in many others
4558 if (exitcode < 0 || exitcode > 125)
4559 return false;
4561 sWorld.ShutdownServ (time, 0, exitcode);
4563 else
4564 sWorld.ShutdownServ(time,0,SHUTDOWN_EXIT_CODE);
4565 return true;
4568 bool ChatHandler::HandleServerRestartCommand(const char* args)
4570 if(!*args)
4571 return false;
4573 char* time_str = strtok ((char*) args, " ");
4574 char* exitcode_str = strtok (NULL, "");
4576 int32 time = atoi (time_str);
4578 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4579 if ((time == 0 && (time_str[0]!='0' || time_str[1]!='\0')) || time < 0)
4580 return false;
4582 if (exitcode_str)
4584 int32 exitcode = atoi (exitcode_str);
4586 // Handle atoi() errors
4587 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4588 return false;
4590 // Exit code should be in range of 0-125, 126-255 is used
4591 // in many shells for their own return codes and code > 255
4592 // is not supported in many others
4593 if (exitcode < 0 || exitcode > 125)
4594 return false;
4596 sWorld.ShutdownServ (time, SHUTDOWN_MASK_RESTART, exitcode);
4598 else
4599 sWorld.ShutdownServ(time, SHUTDOWN_MASK_RESTART, RESTART_EXIT_CODE);
4600 return true;
4603 bool ChatHandler::HandleServerIdleRestartCommand(const char* args)
4605 if(!*args)
4606 return false;
4608 char* time_str = strtok ((char*) args, " ");
4609 char* exitcode_str = strtok (NULL, "");
4611 int32 time = atoi (time_str);
4613 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4614 if ((time == 0 && (time_str[0]!='0' || time_str[1]!='\0')) || time < 0)
4615 return false;
4617 if (exitcode_str)
4619 int32 exitcode = atoi (exitcode_str);
4621 // Handle atoi() errors
4622 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4623 return false;
4625 // Exit code should be in range of 0-125, 126-255 is used
4626 // in many shells for their own return codes and code > 255
4627 // is not supported in many others
4628 if (exitcode < 0 || exitcode > 125)
4629 return false;
4631 sWorld.ShutdownServ (time, SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE, exitcode);
4633 else
4634 sWorld.ShutdownServ(time,SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE,RESTART_EXIT_CODE);
4635 return true;
4638 bool ChatHandler::HandleServerIdleShutDownCommand(const char* args)
4640 if(!*args)
4641 return false;
4643 char* time_str = strtok ((char*) args, " ");
4644 char* exitcode_str = strtok (NULL, "");
4646 int32 time = atoi (time_str);
4648 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4649 if ((time == 0 && (time_str[0]!='0' || time_str[1]!='\0')) || time < 0)
4650 return false;
4652 if (exitcode_str)
4654 int32 exitcode = atoi (exitcode_str);
4656 // Handle atoi() errors
4657 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4658 return false;
4660 // Exit code should be in range of 0-125, 126-255 is used
4661 // in many shells for their own return codes and code > 255
4662 // is not supported in many others
4663 if (exitcode < 0 || exitcode > 125)
4664 return false;
4666 sWorld.ShutdownServ (time, SHUTDOWN_MASK_IDLE, exitcode);
4668 else
4669 sWorld.ShutdownServ(time,SHUTDOWN_MASK_IDLE,SHUTDOWN_EXIT_CODE);
4670 return true;
4673 bool ChatHandler::HandleQuestAdd(const char* args)
4675 Player* player = getSelectedPlayer();
4676 if(!player)
4678 SendSysMessage(LANG_NO_CHAR_SELECTED);
4679 SetSentErrorMessage(true);
4680 return false;
4683 // .addquest #entry'
4684 // number or [name] Shift-click form |color|Hquest:quest_id:quest_level|h[name]|h|r
4685 char* cId = extractKeyFromLink((char*)args,"Hquest");
4686 if(!cId)
4687 return false;
4689 uint32 entry = atol(cId);
4691 Quest const* pQuest = objmgr.GetQuestTemplate(entry);
4693 if(!pQuest)
4695 PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND,entry);
4696 SetSentErrorMessage(true);
4697 return false;
4700 // check item starting quest (it can work incorrectly if added without item in inventory)
4701 for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
4703 ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype>(id);
4704 if (!pProto)
4705 continue;
4707 if (pProto->StartQuest == entry)
4709 PSendSysMessage(LANG_COMMAND_QUEST_STARTFROMITEM, entry, pProto->ItemId);
4710 SetSentErrorMessage(true);
4711 return false;
4715 // ok, normal (creature/GO starting) quest
4716 if( player->CanAddQuest( pQuest, true ) )
4718 player->AddQuest( pQuest, NULL );
4720 if ( player->CanCompleteQuest( entry ) )
4721 player->CompleteQuest( entry );
4724 return true;
4727 bool ChatHandler::HandleQuestRemove(const char* args)
4729 Player* player = getSelectedPlayer();
4730 if(!player)
4732 SendSysMessage(LANG_NO_CHAR_SELECTED);
4733 SetSentErrorMessage(true);
4734 return false;
4737 // .removequest #entry'
4738 // number or [name] Shift-click form |color|Hquest:quest_id:quest_level|h[name]|h|r
4739 char* cId = extractKeyFromLink((char*)args,"Hquest");
4740 if(!cId)
4741 return false;
4743 uint32 entry = atol(cId);
4745 Quest const* pQuest = objmgr.GetQuestTemplate(entry);
4747 if(!pQuest)
4749 PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry);
4750 SetSentErrorMessage(true);
4751 return false;
4754 // remove all quest entries for 'entry' from quest log
4755 for(uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot )
4757 uint32 quest = player->GetQuestSlotQuestId(slot);
4758 if(quest==entry)
4760 player->SetQuestSlot(slot,0);
4762 // we ignore unequippable quest items in this case, its' still be equipped
4763 player->TakeQuestSourceItem( quest, false );
4767 // set quest status to not started (will updated in DB at next save)
4768 player->SetQuestStatus( entry, QUEST_STATUS_NONE);
4770 // reset rewarded for restart repeatable quest
4771 player->getQuestStatusMap()[entry].m_rewarded = false;
4773 SendSysMessage(LANG_COMMAND_QUEST_REMOVED);
4774 return true;
4777 bool ChatHandler::HandleQuestComplete(const char* args)
4779 Player* player = getSelectedPlayer();
4780 if(!player)
4782 SendSysMessage(LANG_NO_CHAR_SELECTED);
4783 SetSentErrorMessage(true);
4784 return false;
4787 // .quest complete #entry
4788 // number or [name] Shift-click form |color|Hquest:quest_id:quest_level|h[name]|h|r
4789 char* cId = extractKeyFromLink((char*)args,"Hquest");
4790 if(!cId)
4791 return false;
4793 uint32 entry = atol(cId);
4795 Quest const* pQuest = objmgr.GetQuestTemplate(entry);
4797 // If player doesn't have the quest
4798 if(!pQuest || player->GetQuestStatus(entry) == QUEST_STATUS_NONE)
4800 PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry);
4801 SetSentErrorMessage(true);
4802 return false;
4805 // Add quest items for quests that require items
4806 for(uint8 x = 0; x < QUEST_ITEM_OBJECTIVES_COUNT; ++x)
4808 uint32 id = pQuest->ReqItemId[x];
4809 uint32 count = pQuest->ReqItemCount[x];
4810 if(!id || !count)
4811 continue;
4813 uint32 curItemCount = player->GetItemCount(id,true);
4815 ItemPosCountVec dest;
4816 uint8 msg = player->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, id, count - curItemCount );
4817 if( msg == EQUIP_ERR_OK )
4819 Item* item = player->StoreNewItem( dest, id, true);
4820 player->SendNewItem(item,count-curItemCount, true, false);
4824 // All creature/GO slain/casted (not required, but otherwise it will display "Creature slain 0/10")
4825 for(uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
4827 uint32 creature = pQuest->ReqCreatureOrGOId[i];
4828 uint32 creaturecount = pQuest->ReqCreatureOrGOCount[i];
4830 if(uint32 spell_id = pQuest->ReqSpell[i])
4832 for(uint16 z = 0; z < creaturecount; ++z)
4833 player->CastedCreatureOrGO(creature,0,spell_id);
4835 else if(creature > 0)
4837 if(CreatureInfo const* cInfo = objmgr.GetCreatureTemplate(creature))
4838 for(uint16 z = 0; z < creaturecount; ++z)
4839 player->KilledMonster(cInfo,0);
4841 else if(creature < 0)
4843 for(uint16 z = 0; z < creaturecount; ++z)
4844 player->CastedCreatureOrGO(creature,0,0);
4848 // If the quest requires reputation to complete
4849 if(uint32 repFaction = pQuest->GetRepObjectiveFaction())
4851 uint32 repValue = pQuest->GetRepObjectiveValue();
4852 uint32 curRep = player->GetReputationMgr().GetReputation(repFaction);
4853 if(curRep < repValue)
4854 if(FactionEntry const *factionEntry = sFactionStore.LookupEntry(repFaction))
4855 player->GetReputationMgr().SetReputation(factionEntry,repValue);
4858 // If the quest requires money
4859 int32 ReqOrRewMoney = pQuest->GetRewOrReqMoney();
4860 if(ReqOrRewMoney < 0)
4861 player->ModifyMoney(-ReqOrRewMoney);
4863 player->CompleteQuest(entry);
4864 return true;
4867 bool ChatHandler::HandleBanAccountCommand(const char* args)
4869 return HandleBanHelper(BAN_ACCOUNT,args);
4872 bool ChatHandler::HandleBanCharacterCommand(const char* args)
4874 return HandleBanHelper(BAN_CHARACTER,args);
4877 bool ChatHandler::HandleBanIPCommand(const char* args)
4879 return HandleBanHelper(BAN_IP,args);
4882 bool ChatHandler::HandleBanHelper(BanMode mode, const char* args)
4884 if (!*args)
4885 return false;
4887 char* cnameOrIP = strtok ((char*)args, " ");
4888 if (!cnameOrIP)
4889 return false;
4891 std::string nameOrIP = cnameOrIP;
4893 char* duration = strtok (NULL," ");
4894 if(!duration || !atoi(duration))
4895 return false;
4897 char* reason = strtok (NULL,"");
4898 if(!reason)
4899 return false;
4901 switch(mode)
4903 case BAN_ACCOUNT:
4904 if (!AccountMgr::normalizeString(nameOrIP))
4906 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,nameOrIP.c_str());
4907 SetSentErrorMessage(true);
4908 return false;
4910 break;
4911 case BAN_CHARACTER:
4912 if(!normalizePlayerName(nameOrIP))
4914 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4915 SetSentErrorMessage(true);
4916 return false;
4918 break;
4919 case BAN_IP:
4920 if(!IsIPAddress(nameOrIP.c_str()))
4921 return false;
4922 break;
4925 switch(sWorld.BanAccount(mode, nameOrIP, duration, reason,m_session ? m_session->GetPlayerName() : ""))
4927 case BAN_SUCCESS:
4928 if(atoi(duration)>0)
4929 PSendSysMessage(LANG_BAN_YOUBANNED,nameOrIP.c_str(),secsToTimeString(TimeStringToSecs(duration),true).c_str(),reason);
4930 else
4931 PSendSysMessage(LANG_BAN_YOUPERMBANNED,nameOrIP.c_str(),reason);
4932 break;
4933 case BAN_SYNTAX_ERROR:
4934 return false;
4935 case BAN_NOTFOUND:
4936 switch(mode)
4938 default:
4939 PSendSysMessage(LANG_BAN_NOTFOUND,"account",nameOrIP.c_str());
4940 break;
4941 case BAN_CHARACTER:
4942 PSendSysMessage(LANG_BAN_NOTFOUND,"character",nameOrIP.c_str());
4943 break;
4944 case BAN_IP:
4945 PSendSysMessage(LANG_BAN_NOTFOUND,"ip",nameOrIP.c_str());
4946 break;
4948 SetSentErrorMessage(true);
4949 return false;
4952 return true;
4955 bool ChatHandler::HandleUnBanAccountCommand(const char* args)
4957 return HandleUnBanHelper(BAN_ACCOUNT,args);
4960 bool ChatHandler::HandleUnBanCharacterCommand(const char* args)
4962 return HandleUnBanHelper(BAN_CHARACTER,args);
4965 bool ChatHandler::HandleUnBanIPCommand(const char* args)
4967 return HandleUnBanHelper(BAN_IP,args);
4970 bool ChatHandler::HandleUnBanHelper(BanMode mode, const char* args)
4972 if (!*args)
4973 return false;
4975 char* cnameOrIP = strtok ((char*)args, " ");
4976 if(!cnameOrIP)
4977 return false;
4979 std::string nameOrIP = cnameOrIP;
4981 switch(mode)
4983 case BAN_ACCOUNT:
4984 if (!AccountMgr::normalizeString(nameOrIP))
4986 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,nameOrIP.c_str());
4987 SetSentErrorMessage(true);
4988 return false;
4990 break;
4991 case BAN_CHARACTER:
4992 if(!normalizePlayerName(nameOrIP))
4994 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4995 SetSentErrorMessage(true);
4996 return false;
4998 break;
4999 case BAN_IP:
5000 if(!IsIPAddress(nameOrIP.c_str()))
5001 return false;
5002 break;
5005 if(sWorld.RemoveBanAccount(mode,nameOrIP))
5006 PSendSysMessage(LANG_UNBAN_UNBANNED,nameOrIP.c_str());
5007 else
5008 PSendSysMessage(LANG_UNBAN_ERROR,nameOrIP.c_str());
5010 return true;
5013 bool ChatHandler::HandleBanInfoAccountCommand(const char* args)
5015 if (!*args)
5016 return false;
5018 char* cname = strtok((char*)args, "");
5019 if (!cname)
5020 return false;
5022 std::string account_name = cname;
5023 if (!AccountMgr::normalizeString(account_name))
5025 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5026 SetSentErrorMessage(true);
5027 return false;
5030 uint32 accountid = accmgr.GetId(account_name);
5031 if (!accountid)
5033 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5034 return true;
5037 return HandleBanInfoHelper(accountid,account_name.c_str());
5040 bool ChatHandler::HandleBanInfoCharacterCommand(const char* args)
5042 Player* target;
5043 uint64 target_guid;
5044 if (!extractPlayerTarget((char*)args,&target,&target_guid))
5045 return false;
5047 uint32 accountid = target ? target->GetSession()->GetAccountId() : objmgr.GetPlayerAccountIdByGUID(target_guid);
5049 std::string accountname;
5050 if (!accmgr.GetName(accountid,accountname))
5052 PSendSysMessage(LANG_BANINFO_NOCHARACTER);
5053 return true;
5056 return HandleBanInfoHelper(accountid,accountname.c_str());
5059 bool ChatHandler::HandleBanInfoHelper(uint32 accountid, char const* accountname)
5061 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);
5062 if(!result)
5064 PSendSysMessage(LANG_BANINFO_NOACCOUNTBAN, accountname);
5065 return true;
5068 PSendSysMessage(LANG_BANINFO_BANHISTORY,accountname);
5071 Field* fields = result->Fetch();
5073 time_t unbandate = time_t(fields[3].GetUInt64());
5074 bool active = false;
5075 if(fields[2].GetBool() && (fields[1].GetUInt64() == (uint64)0 ||unbandate >= time(NULL)) )
5076 active = true;
5077 bool permanent = (fields[1].GetUInt64() == (uint64)0);
5078 std::string bantime = permanent?GetMangosString(LANG_BANINFO_INFINITE):secsToTimeString(fields[1].GetUInt64(), true);
5079 PSendSysMessage(LANG_BANINFO_HISTORYENTRY,
5080 fields[0].GetString(), bantime.c_str(), active ? GetMangosString(LANG_BANINFO_YES):GetMangosString(LANG_BANINFO_NO), fields[4].GetString(), fields[5].GetString());
5081 }while (result->NextRow());
5083 delete result;
5084 return true;
5087 bool ChatHandler::HandleBanInfoIPCommand(const char* args)
5089 if (!*args)
5090 return false;
5092 char* cIP = strtok ((char*)args, "");
5093 if(!cIP)
5094 return false;
5096 if (!IsIPAddress(cIP))
5097 return false;
5099 std::string IP = cIP;
5101 loginDatabase.escape_string(IP);
5102 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());
5103 if(!result)
5105 PSendSysMessage(LANG_BANINFO_NOIP);
5106 return true;
5109 Field *fields = result->Fetch();
5110 bool permanent = !fields[6].GetUInt64();
5111 PSendSysMessage(LANG_BANINFO_IPENTRY,
5112 fields[0].GetString(), fields[1].GetString(), permanent ? GetMangosString(LANG_BANINFO_NEVER):fields[2].GetString(),
5113 permanent ? GetMangosString(LANG_BANINFO_INFINITE):secsToTimeString(fields[3].GetUInt64(), true).c_str(), fields[4].GetString(), fields[5].GetString());
5114 delete result;
5115 return true;
5118 bool ChatHandler::HandleBanListCharacterCommand(const char* args)
5120 loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
5122 char* cFilter = strtok ((char*)args, " ");
5123 if(!cFilter)
5124 return false;
5126 std::string filter = cFilter;
5127 loginDatabase.escape_string(filter);
5128 QueryResult* result = CharacterDatabase.PQuery("SELECT account FROM characters WHERE name "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'"),filter.c_str());
5129 if (!result)
5131 PSendSysMessage(LANG_BANLIST_NOCHARACTER);
5132 return true;
5135 return HandleBanListHelper(result);
5138 bool ChatHandler::HandleBanListAccountCommand(const char* args)
5140 loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
5142 char* cFilter = strtok((char*)args, " ");
5143 std::string filter = cFilter ? cFilter : "";
5144 loginDatabase.escape_string(filter);
5146 QueryResult* result;
5148 if(filter.empty())
5150 result = loginDatabase.Query("SELECT account.id, username FROM account, account_banned"
5151 " WHERE account.id = account_banned.id AND active = 1 GROUP BY account.id");
5153 else
5155 result = loginDatabase.PQuery("SELECT account.id, username FROM account, account_banned"
5156 " WHERE account.id = account_banned.id AND active = 1 AND username "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")" GROUP BY account.id",
5157 filter.c_str());
5160 if (!result)
5162 PSendSysMessage(LANG_BANLIST_NOACCOUNT);
5163 return true;
5166 return HandleBanListHelper(result);
5169 bool ChatHandler::HandleBanListHelper(QueryResult* result)
5171 PSendSysMessage(LANG_BANLIST_MATCHINGACCOUNT);
5173 // Chat short output
5174 if(m_session)
5178 Field* fields = result->Fetch();
5179 uint32 accountid = fields[0].GetUInt32();
5181 QueryResult* banresult = loginDatabase.PQuery("SELECT account.username FROM account,account_banned WHERE account_banned.id='%u' AND account_banned.id=account.id",accountid);
5182 if(banresult)
5184 Field* fields2 = banresult->Fetch();
5185 PSendSysMessage("%s",fields2[0].GetString());
5186 delete banresult;
5188 } while (result->NextRow());
5190 // Console wide output
5191 else
5193 SendSysMessage(LANG_BANLIST_ACCOUNTS);
5194 SendSysMessage("===============================================================================");
5195 SendSysMessage(LANG_BANLIST_ACCOUNTS_HEADER);
5198 SendSysMessage("-------------------------------------------------------------------------------");
5199 Field *fields = result->Fetch();
5200 uint32 account_id = fields[0].GetUInt32 ();
5202 std::string account_name;
5204 // "account" case, name can be get in same query
5205 if(result->GetFieldCount() > 1)
5206 account_name = fields[1].GetCppString();
5207 // "character" case, name need extract from another DB
5208 else
5209 accmgr.GetName (account_id,account_name);
5211 // No SQL injection. id is uint32.
5212 QueryResult *banInfo = loginDatabase.PQuery("SELECT bandate,unbandate,bannedby,banreason FROM account_banned WHERE id = %u ORDER BY unbandate", account_id);
5213 if (banInfo)
5215 Field *fields2 = banInfo->Fetch();
5218 time_t t_ban = fields2[0].GetUInt64();
5219 tm* aTm_ban = localtime(&t_ban);
5221 if (fields2[0].GetUInt64() == fields2[1].GetUInt64())
5223 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|",
5224 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,
5225 fields2[2].GetString(),fields2[3].GetString());
5227 else
5229 time_t t_unban = fields2[1].GetUInt64();
5230 tm* aTm_unban = localtime(&t_unban);
5231 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|",
5232 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,
5233 aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min,
5234 fields2[2].GetString(),fields2[3].GetString());
5236 }while ( banInfo->NextRow() );
5237 delete banInfo;
5239 }while( result->NextRow() );
5240 SendSysMessage("===============================================================================");
5243 delete result;
5244 return true;
5247 bool ChatHandler::HandleBanListIPCommand(const char* args)
5249 loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
5251 char* cFilter = strtok((char*)args, " ");
5252 std::string filter = cFilter ? cFilter : "";
5253 loginDatabase.escape_string(filter);
5255 QueryResult* result;
5257 if(filter.empty())
5259 result = loginDatabase.Query ("SELECT ip,bandate,unbandate,bannedby,banreason FROM ip_banned"
5260 " WHERE (bandate=unbandate OR unbandate>UNIX_TIMESTAMP())"
5261 " ORDER BY unbandate" );
5263 else
5265 result = loginDatabase.PQuery( "SELECT ip,bandate,unbandate,bannedby,banreason FROM ip_banned"
5266 " WHERE (bandate=unbandate OR unbandate>UNIX_TIMESTAMP()) AND ip "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")
5267 " ORDER BY unbandate",filter.c_str() );
5270 if(!result)
5272 PSendSysMessage(LANG_BANLIST_NOIP);
5273 return true;
5276 PSendSysMessage(LANG_BANLIST_MATCHINGIP);
5277 // Chat short output
5278 if(m_session)
5282 Field* fields = result->Fetch();
5283 PSendSysMessage("%s",fields[0].GetString());
5284 } while (result->NextRow());
5286 // Console wide output
5287 else
5289 SendSysMessage(LANG_BANLIST_IPS);
5290 SendSysMessage("===============================================================================");
5291 SendSysMessage(LANG_BANLIST_IPS_HEADER);
5294 SendSysMessage("-------------------------------------------------------------------------------");
5295 Field *fields = result->Fetch();
5296 time_t t_ban = fields[1].GetUInt64();
5297 tm* aTm_ban = localtime(&t_ban);
5298 if ( fields[1].GetUInt64() == fields[2].GetUInt64() )
5300 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|",
5301 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,
5302 fields[3].GetString(), fields[4].GetString());
5304 else
5306 time_t t_unban = fields[2].GetUInt64();
5307 tm* aTm_unban = localtime(&t_unban);
5308 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|",
5309 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,
5310 aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min,
5311 fields[3].GetString(), fields[4].GetString());
5313 }while( result->NextRow() );
5314 SendSysMessage("===============================================================================");
5317 delete result;
5318 return true;
5321 bool ChatHandler::HandleRespawnCommand(const char* /*args*/)
5323 Player* pl = m_session->GetPlayer();
5325 // accept only explicitly selected target (not implicitly self targeting case)
5326 Unit* target = getSelectedUnit();
5327 if(pl->GetSelection() && target)
5329 if(target->GetTypeId()!=TYPEID_UNIT)
5331 SendSysMessage(LANG_SELECT_CREATURE);
5332 SetSentErrorMessage(true);
5333 return false;
5336 if(target->isDead())
5337 ((Creature*)target)->Respawn();
5338 return true;
5341 CellPair p(MaNGOS::ComputeCellPair(pl->GetPositionX(), pl->GetPositionY()));
5342 Cell cell(p);
5343 cell.data.Part.reserved = ALL_DISTRICT;
5344 cell.SetNoCreate();
5346 MaNGOS::RespawnDo u_do;
5347 MaNGOS::WorldObjectWorker<MaNGOS::RespawnDo> worker(pl,u_do);
5349 TypeContainerVisitor<MaNGOS::WorldObjectWorker<MaNGOS::RespawnDo>, GridTypeMapContainer > obj_worker(worker);
5350 CellLock<GridReadGuard> cell_lock(cell, p);
5351 cell_lock->Visit(cell_lock, obj_worker, *pl->GetMap());
5353 return true;
5356 bool ChatHandler::HandleGMFlyCommand(const char* args)
5358 if (!*args)
5359 return false;
5361 Player *target = getSelectedPlayer();
5362 if (!target)
5363 target = m_session->GetPlayer();
5365 WorldPacket data(12);
5366 if (strncmp(args, "on", 3) == 0)
5367 data.SetOpcode(SMSG_MOVE_SET_CAN_FLY);
5368 else if (strncmp(args, "off", 4) == 0)
5369 data.SetOpcode(SMSG_MOVE_UNSET_CAN_FLY);
5370 else
5372 SendSysMessage(LANG_USE_BOL);
5373 return false;
5375 data.append(target->GetPackGUID());
5376 data << uint32(0); // unknown
5377 target->SendMessageToSet(&data, true);
5378 PSendSysMessage(LANG_COMMAND_FLYMODE_STATUS, GetNameLink(target).c_str(), args);
5379 return true;
5382 bool ChatHandler::HandlePDumpLoadCommand(const char *args)
5384 if (!*args)
5385 return false;
5387 char * file = strtok((char*)args, " ");
5388 if (!file)
5389 return false;
5391 char * account = strtok(NULL, " ");
5392 if (!account)
5393 return false;
5395 std::string account_name = account;
5396 if (!AccountMgr::normalizeString(account_name))
5398 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5399 SetSentErrorMessage(true);
5400 return false;
5403 uint32 account_id = accmgr.GetId(account_name);
5404 if (!account_id)
5406 account_id = atoi(account); // use original string
5407 if (!account_id)
5409 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5410 SetSentErrorMessage(true);
5411 return false;
5415 if (!accmgr.GetName(account_id,account_name))
5417 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5418 SetSentErrorMessage(true);
5419 return false;
5422 char* guid_str = NULL;
5423 char* name_str = strtok(NULL, " ");
5425 std::string name;
5426 if (name_str)
5428 name = name_str;
5429 // normalize the name if specified and check if it exists
5430 if (!normalizePlayerName(name))
5432 PSendSysMessage(LANG_INVALID_CHARACTER_NAME);
5433 SetSentErrorMessage(true);
5434 return false;
5437 if (ObjectMgr::CheckPlayerName(name,true) != CHAR_NAME_SUCCESS)
5439 PSendSysMessage(LANG_INVALID_CHARACTER_NAME);
5440 SetSentErrorMessage(true);
5441 return false;
5444 guid_str = strtok(NULL, " ");
5447 uint32 guid = 0;
5449 if (guid_str)
5451 guid = atoi(guid_str);
5452 if (!guid)
5454 PSendSysMessage(LANG_INVALID_CHARACTER_GUID);
5455 SetSentErrorMessage(true);
5456 return false;
5459 if (objmgr.GetPlayerAccountIdByGUID(guid))
5461 PSendSysMessage(LANG_CHARACTER_GUID_IN_USE,guid);
5462 SetSentErrorMessage(true);
5463 return false;
5467 switch(PlayerDumpReader().LoadDump(file, account_id, name, guid))
5469 case DUMP_SUCCESS:
5470 PSendSysMessage(LANG_COMMAND_IMPORT_SUCCESS);
5471 break;
5472 case DUMP_FILE_OPEN_ERROR:
5473 PSendSysMessage(LANG_FILE_OPEN_FAIL,file);
5474 SetSentErrorMessage(true);
5475 return false;
5476 case DUMP_FILE_BROKEN:
5477 PSendSysMessage(LANG_DUMP_BROKEN,file);
5478 SetSentErrorMessage(true);
5479 return false;
5480 case DUMP_TOO_MANY_CHARS:
5481 PSendSysMessage(LANG_ACCOUNT_CHARACTER_LIST_FULL,account_name.c_str(),account_id);
5482 SetSentErrorMessage(true);
5483 return false;
5484 default:
5485 PSendSysMessage(LANG_COMMAND_IMPORT_FAILED);
5486 SetSentErrorMessage(true);
5487 return false;
5490 return true;
5493 bool ChatHandler::HandlePDumpWriteCommand(const char *args)
5495 if (!*args)
5496 return false;
5498 char* file = strtok((char*)args, " ");
5499 char* p2 = strtok(NULL, " ");
5501 if(!file || !p2)
5502 return false;
5504 uint32 guid;
5505 // character name can't start from number
5506 if (isNumeric(p2[0]))
5507 guid = atoi(p2);
5508 else
5510 std::string name = extractPlayerNameFromLink(p2);
5511 if(name.empty())
5513 SendSysMessage(LANG_PLAYER_NOT_FOUND);
5514 SetSentErrorMessage(true);
5515 return false;
5518 guid = objmgr.GetPlayerGUIDByName(name);
5521 if(!objmgr.GetPlayerAccountIdByGUID(guid))
5523 PSendSysMessage(LANG_PLAYER_NOT_FOUND);
5524 SetSentErrorMessage(true);
5525 return false;
5528 switch(PlayerDumpWriter().WriteDump(file, guid))
5530 case DUMP_SUCCESS:
5531 PSendSysMessage(LANG_COMMAND_EXPORT_SUCCESS);
5532 break;
5533 case DUMP_FILE_OPEN_ERROR:
5534 PSendSysMessage(LANG_FILE_OPEN_FAIL,file);
5535 SetSentErrorMessage(true);
5536 return false;
5537 default:
5538 PSendSysMessage(LANG_COMMAND_EXPORT_FAILED);
5539 SetSentErrorMessage(true);
5540 return false;
5543 return true;
5546 bool ChatHandler::HandleMovegensCommand(const char* /*args*/)
5548 Unit* unit = getSelectedUnit();
5549 if(!unit)
5551 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5552 SetSentErrorMessage(true);
5553 return false;
5556 PSendSysMessage(LANG_MOVEGENS_LIST,(unit->GetTypeId()==TYPEID_PLAYER ? "Player" : "Creature" ),unit->GetGUIDLow());
5558 MotionMaster* mm = unit->GetMotionMaster();
5559 for(MotionMaster::const_iterator itr = mm->begin(); itr != mm->end(); ++itr)
5561 switch((*itr)->GetMovementGeneratorType())
5563 case IDLE_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_IDLE); break;
5564 case RANDOM_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_RANDOM); break;
5565 case WAYPOINT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_WAYPOINT); break;
5566 case ANIMAL_RANDOM_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_ANIMAL_RANDOM); break;
5567 case CONFUSED_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_CONFUSED); break;
5568 case TARGETED_MOTION_TYPE:
5570 if(unit->GetTypeId()==TYPEID_PLAYER)
5572 TargetedMovementGenerator<Player> const* mgen = static_cast<TargetedMovementGenerator<Player> const*>(*itr);
5573 Unit* target = mgen->GetTarget();
5574 if(target)
5575 PSendSysMessage(LANG_MOVEGENS_TARGETED_PLAYER,target->GetName(),target->GetGUIDLow());
5576 else
5577 SendSysMessage(LANG_MOVEGENS_TARGETED_NULL);
5579 else
5581 TargetedMovementGenerator<Creature> const* mgen = static_cast<TargetedMovementGenerator<Creature> const*>(*itr);
5582 Unit* target = mgen->GetTarget();
5583 if(target)
5584 PSendSysMessage(LANG_MOVEGENS_TARGETED_CREATURE,target->GetName(),target->GetGUIDLow());
5585 else
5586 SendSysMessage(LANG_MOVEGENS_TARGETED_NULL);
5588 break;
5590 case HOME_MOTION_TYPE:
5591 if(unit->GetTypeId()==TYPEID_UNIT)
5593 float x,y,z;
5594 (*itr)->GetDestination(x,y,z);
5595 PSendSysMessage(LANG_MOVEGENS_HOME_CREATURE,x,y,z);
5597 else
5598 SendSysMessage(LANG_MOVEGENS_HOME_PLAYER);
5599 break;
5600 case FLIGHT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_FLIGHT); break;
5601 case POINT_MOTION_TYPE:
5603 float x,y,z;
5604 (*itr)->GetDestination(x,y,z);
5605 PSendSysMessage(LANG_MOVEGENS_POINT,x,y,z);
5606 break;
5608 case FLEEING_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_FEAR); break;
5609 case DISTRACT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_DISTRACT); break;
5610 default:
5611 PSendSysMessage(LANG_MOVEGENS_UNKNOWN,(*itr)->GetMovementGeneratorType());
5612 break;
5615 return true;
5618 bool ChatHandler::HandleServerPLimitCommand(const char *args)
5620 if(*args)
5622 char* param = strtok((char*)args, " ");
5623 if(!param)
5624 return false;
5626 int l = strlen(param);
5628 if( strncmp(param,"player",l) == 0 )
5629 sWorld.SetPlayerLimit(-SEC_PLAYER);
5630 else if(strncmp(param,"moderator",l) == 0 )
5631 sWorld.SetPlayerLimit(-SEC_MODERATOR);
5632 else if(strncmp(param,"gamemaster",l) == 0 )
5633 sWorld.SetPlayerLimit(-SEC_GAMEMASTER);
5634 else if(strncmp(param,"administrator",l) == 0 )
5635 sWorld.SetPlayerLimit(-SEC_ADMINISTRATOR);
5636 else if(strncmp(param,"reset",l) == 0 )
5637 sWorld.SetPlayerLimit( sConfig.GetIntDefault("PlayerLimit", DEFAULT_PLAYER_LIMIT) );
5638 else
5640 int val = atoi(param);
5641 if(val < -SEC_ADMINISTRATOR) val = -SEC_ADMINISTRATOR;
5643 sWorld.SetPlayerLimit(val);
5646 // kick all low security level players
5647 if(sWorld.GetPlayerAmountLimit() > SEC_PLAYER)
5648 sWorld.KickAllLess(sWorld.GetPlayerSecurityLimit());
5651 uint32 pLimit = sWorld.GetPlayerAmountLimit();
5652 AccountTypes allowedAccountType = sWorld.GetPlayerSecurityLimit();
5653 char const* secName = "";
5654 switch(allowedAccountType)
5656 case SEC_PLAYER: secName = "Player"; break;
5657 case SEC_MODERATOR: secName = "Moderator"; break;
5658 case SEC_GAMEMASTER: secName = "Gamemaster"; break;
5659 case SEC_ADMINISTRATOR: secName = "Administrator"; break;
5660 default: secName = "<unknown>"; break;
5663 PSendSysMessage("Player limits: amount %u, min. security level %s.",pLimit,secName);
5665 return true;
5668 bool ChatHandler::HandleCastCommand(const char* args)
5670 if(!*args)
5671 return false;
5673 Unit* target = getSelectedUnit();
5675 if(!target)
5677 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5678 SetSentErrorMessage(true);
5679 return false;
5682 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5683 uint32 spell = extractSpellIdFromLink((char*)args);
5684 if(!spell)
5685 return false;
5687 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
5688 if(!spellInfo)
5689 return false;
5691 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
5693 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
5694 SetSentErrorMessage(true);
5695 return false;
5698 char* trig_str = strtok(NULL, " ");
5699 if(trig_str)
5701 int l = strlen(trig_str);
5702 if(strncmp(trig_str,"triggered",l) != 0 )
5703 return false;
5706 bool triggered = (trig_str != NULL);
5708 m_session->GetPlayer()->CastSpell(target,spell,triggered);
5710 return true;
5713 bool ChatHandler::HandleCastBackCommand(const char* args)
5715 Creature* caster = getSelectedCreature();
5717 if(!caster)
5719 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5720 SetSentErrorMessage(true);
5721 return false;
5724 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
5725 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5726 uint32 spell = extractSpellIdFromLink((char*)args);
5727 if(!spell || !sSpellStore.LookupEntry(spell))
5728 return false;
5730 char* trig_str = strtok(NULL, " ");
5731 if(trig_str)
5733 int l = strlen(trig_str);
5734 if(strncmp(trig_str,"triggered",l) != 0 )
5735 return false;
5738 bool triggered = (trig_str != NULL);
5740 caster->SetFacingToObject(m_session->GetPlayer());
5742 caster->CastSpell(m_session->GetPlayer(),spell,triggered);
5744 return true;
5747 bool ChatHandler::HandleCastDistCommand(const char* args)
5749 if(!*args)
5750 return false;
5752 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5753 uint32 spell = extractSpellIdFromLink((char*)args);
5754 if(!spell)
5755 return false;
5757 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
5758 if(!spellInfo)
5759 return false;
5761 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
5763 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
5764 SetSentErrorMessage(true);
5765 return false;
5768 char *distStr = strtok(NULL, " ");
5770 float dist = 0;
5772 if(distStr)
5773 sscanf(distStr, "%f", &dist);
5775 char* trig_str = strtok(NULL, " ");
5776 if(trig_str)
5778 int l = strlen(trig_str);
5779 if(strncmp(trig_str,"triggered",l) != 0 )
5780 return false;
5783 bool triggered = (trig_str != NULL);
5785 float x,y,z;
5786 m_session->GetPlayer()->GetClosePoint(x,y,z,dist);
5788 m_session->GetPlayer()->CastSpell(x,y,z,spell,triggered);
5789 return true;
5792 bool ChatHandler::HandleCastTargetCommand(const char* args)
5794 Creature* caster = getSelectedCreature();
5796 if(!caster)
5798 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5799 SetSentErrorMessage(true);
5800 return false;
5803 if(!caster->getVictim())
5805 SendSysMessage(LANG_SELECTED_TARGET_NOT_HAVE_VICTIM);
5806 SetSentErrorMessage(true);
5807 return false;
5810 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5811 uint32 spell = extractSpellIdFromLink((char*)args);
5812 if(!spell || !sSpellStore.LookupEntry(spell))
5813 return false;
5815 char* trig_str = strtok(NULL, " ");
5816 if(trig_str)
5818 int l = strlen(trig_str);
5819 if(strncmp(trig_str,"triggered",l) != 0 )
5820 return false;
5823 bool triggered = (trig_str != NULL);
5825 caster->SetFacingToObject(m_session->GetPlayer());
5827 caster->CastSpell(caster->getVictim(),spell,triggered);
5829 return true;
5833 ComeToMe command REQUIRED for 3rd party scripting library to have access to PointMovementGenerator
5834 Without this function 3rd party scripting library will get linking errors (unresolved external)
5835 when attempting to use the PointMovementGenerator
5837 bool ChatHandler::HandleComeToMeCommand(const char *args)
5839 Creature* caster = getSelectedCreature();
5841 if(!caster)
5843 SendSysMessage(LANG_SELECT_CREATURE);
5844 SetSentErrorMessage(true);
5845 return false;
5848 char* newFlagStr = strtok((char*)args, " ");
5850 if(!newFlagStr)
5851 return false;
5853 uint32 newFlags = atoi(newFlagStr);
5855 caster->SetMonsterMoveFlags(MonsterMovementFlags(newFlags));
5857 Player* pl = m_session->GetPlayer();
5859 caster->GetMotionMaster()->MovePoint(0, pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ());
5860 return true;
5863 bool ChatHandler::HandleCastSelfCommand(const char* args)
5865 if(!*args)
5866 return false;
5868 Unit* target = getSelectedUnit();
5870 if(!target)
5872 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5873 SetSentErrorMessage(true);
5874 return false;
5877 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5878 uint32 spell = extractSpellIdFromLink((char*)args);
5879 if(!spell)
5880 return false;
5882 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
5883 if(!spellInfo)
5884 return false;
5886 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
5888 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
5889 SetSentErrorMessage(true);
5890 return false;
5893 target->CastSpell(target,spell,false);
5895 return true;
5898 std::string GetTimeString(uint32 time)
5900 uint16 days = time / DAY, hours = (time % DAY) / HOUR, minute = (time % HOUR) / MINUTE;
5901 std::ostringstream ss;
5902 if(days) ss << days << "d ";
5903 if(hours) ss << hours << "h ";
5904 ss << minute << "m";
5905 return ss.str();
5908 bool ChatHandler::HandleInstanceListBindsCommand(const char* /*args*/)
5910 Player* player = getSelectedPlayer();
5911 if (!player) player = m_session->GetPlayer();
5912 uint32 counter = 0;
5913 for(uint8 i = 0; i < MAX_DIFFICULTY; ++i)
5915 Player::BoundInstancesMap &binds = player->GetBoundInstances(Difficulty(i));
5916 for(Player::BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end(); ++itr)
5918 InstanceSave *save = itr->second.save;
5919 std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
5920 if (const MapEntry* entry = sMapStore.LookupEntry(itr->first))
5922 PSendSysMessage("map: %d (%s) inst: %d perm: %s diff: %d canReset: %s TTR: %s",
5923 itr->first, entry->name[m_session->GetSessionDbcLocale()], save->GetInstanceId(), itr->second.perm ? "yes" : "no",
5924 save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str());
5926 else
5927 PSendSysMessage("bound for a nonexistant map %u", itr->first);
5928 counter++;
5931 PSendSysMessage("player binds: %d", counter);
5932 counter = 0;
5933 Group *group = player->GetGroup();
5934 if(group)
5936 for(uint8 i = 0; i < MAX_DIFFICULTY; ++i)
5938 Group::BoundInstancesMap &binds = group->GetBoundInstances(Difficulty(i));
5939 for(Group::BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end(); ++itr)
5941 InstanceSave *save = itr->second.save;
5942 std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
5943 if (const MapEntry* entry = sMapStore.LookupEntry(itr->first))
5945 PSendSysMessage("map: %d (%s) inst: %d perm: %s diff: %d canReset: %s TTR: %s",
5946 itr->first, entry->name[m_session->GetSessionDbcLocale()], save->GetInstanceId(), itr->second.perm ? "yes" : "no",
5947 save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str());
5949 else
5950 PSendSysMessage("bound for a nonexistant map %u", itr->first);
5951 counter++;
5955 PSendSysMessage("group binds: %d", counter);
5957 return true;
5960 bool ChatHandler::HandleInstanceUnbindCommand(const char* args)
5962 if(!*args)
5963 return false;
5965 Player* player = getSelectedPlayer();
5966 if (!player)
5967 player = m_session->GetPlayer();
5968 uint32 counter = 0;
5969 uint32 mapid = 0;
5970 bool got_map = false;
5972 if (strncmp(args,"all",strlen(args)) != 0)
5974 if(!isNumeric(args[0]))
5975 return false;
5977 got_map = true;
5978 mapid = atoi(args);
5981 for(uint8 i = 0; i < MAX_DIFFICULTY; ++i)
5983 Player::BoundInstancesMap &binds = player->GetBoundInstances(Difficulty(i));
5984 for(Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end();)
5986 if (got_map && mapid != itr->first)
5988 ++itr;
5989 continue;
5991 if(itr->first != player->GetMapId())
5993 InstanceSave *save = itr->second.save;
5994 std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
5996 if (const MapEntry* entry = sMapStore.LookupEntry(itr->first))
5998 PSendSysMessage("unbinding map: %d (%s) inst: %d perm: %s diff: %d canReset: %s TTR: %s",
5999 itr->first, entry->name[m_session->GetSessionDbcLocale()], save->GetInstanceId(), itr->second.perm ? "yes" : "no",
6000 save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str());
6002 else
6003 PSendSysMessage("bound for a nonexistant map %u", itr->first);
6004 player->UnbindInstance(itr, Difficulty(i));
6005 counter++;
6007 else
6008 ++itr;
6011 PSendSysMessage("instances unbound: %d", counter);
6012 return true;
6015 bool ChatHandler::HandleInstanceStatsCommand(const char* /*args*/)
6017 PSendSysMessage("instances loaded: %d", MapManager::Instance().GetNumInstances());
6018 PSendSysMessage("players in instances: %d", MapManager::Instance().GetNumPlayersInInstances());
6019 PSendSysMessage("instance saves: %d", sInstanceSaveManager.GetNumInstanceSaves());
6020 PSendSysMessage("players bound: %d", sInstanceSaveManager.GetNumBoundPlayersTotal());
6021 PSendSysMessage("groups bound: %d", sInstanceSaveManager.GetNumBoundGroupsTotal());
6022 return true;
6025 bool ChatHandler::HandleInstanceSaveDataCommand(const char * /*args*/)
6027 Player* pl = m_session->GetPlayer();
6029 Map* map = pl->GetMap();
6030 if (!map->IsDungeon())
6032 PSendSysMessage("Map is not a dungeon.");
6033 SetSentErrorMessage(true);
6034 return false;
6037 if (!((InstanceMap*)map)->GetInstanceData())
6039 PSendSysMessage("Map has no instance data.");
6040 SetSentErrorMessage(true);
6041 return false;
6044 ((InstanceMap*)map)->GetInstanceData()->SaveToDB();
6045 return true;
6048 /// Display the list of GMs
6049 bool ChatHandler::HandleGMListFullCommand(const char* /*args*/)
6051 ///- Get the accounts with GM Level >0
6052 QueryResult *result = loginDatabase.Query( "SELECT username,gmlevel FROM account WHERE gmlevel > 0" );
6053 if(result)
6055 SendSysMessage(LANG_GMLIST);
6056 SendSysMessage("========================");
6057 SendSysMessage(LANG_GMLIST_HEADER);
6058 SendSysMessage("========================");
6060 ///- Circle through them. Display username and GM level
6063 Field *fields = result->Fetch();
6064 PSendSysMessage("|%15s|%6s|", fields[0].GetString(),fields[1].GetString());
6065 }while( result->NextRow() );
6067 PSendSysMessage("========================");
6068 delete result;
6070 else
6071 PSendSysMessage(LANG_GMLIST_EMPTY);
6072 return true;
6075 /// Define the 'Message of the day' for the realm
6076 bool ChatHandler::HandleServerSetMotdCommand(const char* args)
6078 sWorld.SetMotd(args);
6079 PSendSysMessage(LANG_MOTD_NEW, args);
6080 return true;
6083 /// Set/Unset the expansion level for an account
6084 bool ChatHandler::HandleAccountSetAddonCommand(const char* args)
6086 ///- Get the command line arguments
6087 char *szAcc = strtok((char*)args," ");
6088 char *szExp = strtok(NULL," ");
6090 if(!szAcc)
6091 return false;
6093 std::string account_name;
6094 uint32 account_id;
6096 if (!szExp)
6098 Player* player = getSelectedPlayer();
6099 if (!player)
6100 return false;
6102 account_id = player->GetSession()->GetAccountId();
6103 accmgr.GetName(account_id,account_name);
6104 szExp = szAcc;
6106 else
6108 ///- Convert Account name to Upper Format
6109 account_name = szAcc;
6110 if (!AccountMgr::normalizeString(account_name))
6112 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
6113 SetSentErrorMessage(true);
6114 return false;
6117 account_id = accmgr.GetId(account_name);
6118 if (!account_id)
6120 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
6121 SetSentErrorMessage(true);
6122 return false;
6127 // Let set addon state only for lesser (strong) security level
6128 // or to self account
6129 if (m_session && m_session->GetAccountId () != account_id &&
6130 HasLowerSecurityAccount (NULL,account_id,true))
6131 return false;
6133 int lev=atoi(szExp); //get int anyway (0 if error)
6134 if(lev < 0)
6135 return false;
6137 // No SQL injection
6138 loginDatabase.PExecute("UPDATE account SET expansion = '%d' WHERE id = '%u'",lev,account_id);
6139 PSendSysMessage(LANG_ACCOUNT_SETADDON,account_name.c_str(),account_id,lev);
6140 return true;
6143 //Send items by mail
6144 bool ChatHandler::HandleSendItemsCommand(const char* args)
6146 // format: name "subject text" "mail text" item1[:count1] item2[:count2] ... item12[:count12]
6147 Player* receiver;
6148 uint64 receiver_guid;
6149 std::string receiver_name;
6150 if(!extractPlayerTarget((char*)args,&receiver,&receiver_guid,&receiver_name))
6151 return false;
6153 char* tail1 = strtok(NULL, "");
6154 if(!tail1)
6155 return false;
6157 char* msgSubject = extractQuotedArg(tail1);
6158 if (!msgSubject)
6159 return false;
6161 char* tail2 = strtok(NULL, "");
6162 if(!tail2)
6163 return false;
6165 char* msgText = extractQuotedArg(tail2);
6166 if (!msgText)
6167 return false;
6169 // msgSubject, msgText isn't NUL after prev. check
6170 std::string subject = msgSubject;
6171 std::string text = msgText;
6173 // extract items
6174 typedef std::pair<uint32,uint32> ItemPair;
6175 typedef std::list< ItemPair > ItemPairs;
6176 ItemPairs items;
6178 // get all tail string
6179 char* tail = strtok(NULL, "");
6181 // get from tail next item str
6182 while(char* itemStr = strtok(tail, " "))
6184 // and get new tail
6185 tail = strtok(NULL, "");
6187 // parse item str
6188 char* itemIdStr = strtok(itemStr, ":");
6189 char* itemCountStr = strtok(NULL, " ");
6191 uint32 item_id = atoi(itemIdStr);
6192 if(!item_id)
6193 return false;
6195 ItemPrototype const* item_proto = objmgr.GetItemPrototype(item_id);
6196 if(!item_proto)
6198 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
6199 SetSentErrorMessage(true);
6200 return false;
6203 uint32 item_count = itemCountStr ? atoi(itemCountStr) : 1;
6204 if (item_count < 1 || (item_proto->MaxCount > 0 && item_count > uint32(item_proto->MaxCount)))
6206 PSendSysMessage(LANG_COMMAND_INVALID_ITEM_COUNT, item_count,item_id);
6207 SetSentErrorMessage(true);
6208 return false;
6211 while(item_count > item_proto->GetMaxStackSize())
6213 items.push_back(ItemPair(item_id,item_proto->GetMaxStackSize()));
6214 item_count -= item_proto->GetMaxStackSize();
6217 items.push_back(ItemPair(item_id,item_count));
6219 if(items.size() > MAX_MAIL_ITEMS)
6221 PSendSysMessage(LANG_COMMAND_MAIL_ITEMS_LIMIT, MAX_MAIL_ITEMS);
6222 SetSentErrorMessage(true);
6223 return false;
6227 // from console show not existed sender
6228 MailSender sender(MAIL_NORMAL,m_session ? m_session->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM);
6230 uint32 itemTextId = !text.empty() ? objmgr.CreateItemText( text ) : 0;
6232 // fill mail
6233 MailDraft draft(subject, itemTextId);
6235 for(ItemPairs::const_iterator itr = items.begin(); itr != items.end(); ++itr)
6237 if(Item* item = Item::CreateItem(itr->first,itr->second,m_session ? m_session->GetPlayer() : 0))
6239 item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted
6240 draft.AddItem(item);
6244 draft.SendMailTo(MailReceiver(receiver,GUID_LOPART(receiver_guid)), sender);
6246 std::string nameLink = playerLink(receiver_name);
6247 PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
6248 return true;
6251 ///Send money by mail
6252 bool ChatHandler::HandleSendMoneyCommand(const char* args)
6254 /// format: name "subject text" "mail text" money
6256 Player* receiver;
6257 uint64 receiver_guid;
6258 std::string receiver_name;
6259 if(!extractPlayerTarget((char*)args,&receiver,&receiver_guid,&receiver_name))
6260 return false;
6262 char* tail1 = strtok(NULL, "");
6263 if (!tail1)
6264 return false;
6266 char* msgSubject = extractQuotedArg(tail1);
6267 if (!msgSubject)
6268 return false;
6270 char* tail2 = strtok(NULL, "");
6271 if (!tail2)
6272 return false;
6274 char* msgText = extractQuotedArg(tail2);
6275 if (!msgText)
6276 return false;
6278 char* money_str = strtok(NULL, "");
6279 int32 money = money_str ? atoi(money_str) : 0;
6280 if (money <= 0)
6281 return false;
6283 // msgSubject, msgText isn't NUL after prev. check
6284 std::string subject = msgSubject;
6285 std::string text = msgText;
6287 // from console show not existed sender
6288 MailSender sender(MAIL_NORMAL,m_session ? m_session->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM);
6290 uint32 itemTextId = !text.empty() ? objmgr.CreateItemText( text ) : 0;
6292 MailDraft(subject, itemTextId)
6293 .AddMoney(money)
6294 .SendMailTo(MailReceiver(receiver,GUID_LOPART(receiver_guid)),sender);
6296 std::string nameLink = playerLink(receiver_name);
6297 PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
6298 return true;
6301 /// Send a message to a player in game
6302 bool ChatHandler::HandleSendMessageCommand(const char* args)
6304 ///- Find the player
6305 Player *rPlayer;
6306 if(!extractPlayerTarget((char*)args,&rPlayer))
6307 return false;
6309 char* msg_str = strtok(NULL, "");
6310 if(!msg_str)
6311 return false;
6313 ///- Check that he is not logging out.
6314 if(rPlayer->GetSession()->isLogingOut())
6316 SendSysMessage(LANG_PLAYER_NOT_FOUND);
6317 SetSentErrorMessage(true);
6318 return false;
6321 ///- Send the message
6322 //Use SendAreaTriggerMessage for fastest delivery.
6323 rPlayer->GetSession()->SendAreaTriggerMessage("%s", msg_str);
6324 rPlayer->GetSession()->SendAreaTriggerMessage("|cffff0000[Message from administrator]:|r");
6326 //Confirmation message
6327 std::string nameLink = GetNameLink(rPlayer);
6328 PSendSysMessage(LANG_SENDMESSAGE,nameLink.c_str(),msg_str);
6329 return true;
6332 bool ChatHandler::HandleFlushArenaPointsCommand(const char * /*args*/)
6334 sBattleGroundMgr.DistributeArenaPoints();
6335 return true;
6338 bool ChatHandler::HandleModifyGenderCommand(const char *args)
6340 if(!*args)
6341 return false;
6343 Player *player = getSelectedPlayer();
6345 if(!player)
6347 PSendSysMessage(LANG_PLAYER_NOT_FOUND);
6348 SetSentErrorMessage(true);
6349 return false;
6352 PlayerInfo const* info = objmgr.GetPlayerInfo(player->getRace(), player->getClass());
6353 if(!info)
6354 return false;
6356 char const* gender_str = (char*)args;
6357 int gender_len = strlen(gender_str);
6359 Gender gender;
6361 if(!strncmp(gender_str, "male", gender_len)) // MALE
6363 if(player->getGender() == GENDER_MALE)
6364 return true;
6366 gender = GENDER_MALE;
6368 else if (!strncmp(gender_str, "female", gender_len)) // FEMALE
6370 if(player->getGender() == GENDER_FEMALE)
6371 return true;
6373 gender = GENDER_FEMALE;
6375 else
6377 SendSysMessage(LANG_MUST_MALE_OR_FEMALE);
6378 SetSentErrorMessage(true);
6379 return false;
6382 // Set gender
6383 player->SetByteValue(UNIT_FIELD_BYTES_0, 2, gender);
6384 player->SetByteValue(PLAYER_BYTES_3, 0, gender);
6386 // Change display ID
6387 player->InitDisplayIds();
6389 char const* gender_full = gender ? "female" : "male";
6391 PSendSysMessage(LANG_YOU_CHANGE_GENDER, GetNameLink(player).c_str(), gender_full);
6393 if (needReportToTarget(player))
6394 ChatHandler(player).PSendSysMessage(LANG_YOUR_GENDER_CHANGED, gender_full, GetNameLink().c_str());
6396 return true;