[9184] Fixed unread packet tail spam for CMSG_LEAVE_BATTLEFIELD
[getmangos.git] / src / game / Level3.cpp
blob2f20e405d3922f6be7db4a53ec71e01c35b5cb3e
1 /*
2 * Copyright (C) 2005-2010 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 HandleReloadNpcTrainerCommand("a");
106 HandleReloadNpcVendorCommand("a");
107 HandleReloadPointsOfInterestCommand("a");
108 HandleReloadSpellClickSpellsCommand("a");
109 return true;
112 bool ChatHandler::HandleReloadAllQuestCommand(const char* /*args*/)
114 HandleReloadQuestAreaTriggersCommand("a");
115 HandleReloadQuestTemplateCommand("a");
117 sLog.outString( "Re-Loading Quests Relations..." );
118 sObjectMgr.LoadQuestRelations();
119 SendGlobalSysMessage("DB tables `*_questrelation` and `*_involvedrelation` reloaded.");
120 return true;
123 bool ChatHandler::HandleReloadAllScriptsCommand(const char*)
125 if(sWorld.IsScriptScheduled())
127 PSendSysMessage("DB scripts used currently, please attempt reload later.");
128 SetSentErrorMessage(true);
129 return false;
132 sLog.outString( "Re-Loading Scripts..." );
133 HandleReloadGameObjectScriptsCommand("a");
134 HandleReloadEventScriptsCommand("a");
135 HandleReloadQuestEndScriptsCommand("a");
136 HandleReloadQuestStartScriptsCommand("a");
137 HandleReloadSpellScriptsCommand("a");
138 SendGlobalSysMessage("DB tables `*_scripts` reloaded.");
139 HandleReloadDbScriptStringCommand("a");
140 return true;
143 bool ChatHandler::HandleReloadAllEventAICommand(const char*)
145 HandleReloadEventAITextsCommand("a");
146 HandleReloadEventAISummonsCommand("a");
147 HandleReloadEventAIScriptsCommand("a");
148 return true;
151 bool ChatHandler::HandleReloadAllSpellCommand(const char*)
153 HandleReloadSkillDiscoveryTemplateCommand("a");
154 HandleReloadSkillExtraItemTemplateCommand("a");
155 HandleReloadSpellAreaCommand("a");
156 HandleReloadSpellChainCommand("a");
157 HandleReloadSpellElixirCommand("a");
158 HandleReloadSpellLearnSpellCommand("a");
159 HandleReloadSpellProcEventCommand("a");
160 HandleReloadSpellBonusesCommand("a");
161 HandleReloadSpellProcItemEnchantCommand("a");
162 HandleReloadSpellScriptTargetCommand("a");
163 HandleReloadSpellTargetPositionCommand("a");
164 HandleReloadSpellThreatsCommand("a");
165 HandleReloadSpellPetAurasCommand("a");
166 return true;
169 bool ChatHandler::HandleReloadAllItemCommand(const char*)
171 HandleReloadPageTextsCommand("a");
172 HandleReloadItemEnchantementsCommand("a");
173 HandleReloadItemRequiredTragetCommand("a");
174 return true;
177 bool ChatHandler::HandleReloadAllLocalesCommand(const char* /*args*/)
179 HandleReloadLocalesAchievementRewardCommand("a");
180 HandleReloadLocalesCreatureCommand("a");
181 HandleReloadLocalesGameobjectCommand("a");
182 HandleReloadLocalesItemCommand("a");
183 HandleReloadLocalesNpcTextCommand("a");
184 HandleReloadLocalesPageTextCommand("a");
185 HandleReloadLocalesPointsOfInterestCommand("a");
186 HandleReloadLocalesQuestCommand("a");
187 return true;
190 bool ChatHandler::HandleReloadConfigCommand(const char* /*args*/)
192 sLog.outString( "Re-Loading config settings..." );
193 sWorld.LoadConfigSettings(true);
194 sMapMgr.InitializeVisibilityDistanceInfo();
195 SendGlobalSysMessage("World config settings reloaded.");
196 return true;
199 bool ChatHandler::HandleReloadAchievementCriteriaRequirementCommand(const char*)
201 sLog.outString( "Re-Loading Additional Achievement Criteria Requirements Data..." );
202 sAchievementMgr.LoadAchievementCriteriaRequirements();
203 SendGlobalSysMessage("DB table `achievement_criteria_requirement` reloaded.");
204 return true;
207 bool ChatHandler::HandleReloadAchievementRewardCommand(const char*)
209 sLog.outString( "Re-Loading Achievement Reward Data..." );
210 sAchievementMgr.LoadRewards();
211 SendGlobalSysMessage("DB table `achievement_reward` reloaded.");
212 return true;
215 bool ChatHandler::HandleReloadAreaTriggerTavernCommand(const char*)
217 sLog.outString( "Re-Loading Tavern Area Triggers..." );
218 sObjectMgr.LoadTavernAreaTriggers();
219 SendGlobalSysMessage("DB table `areatrigger_tavern` reloaded.");
220 return true;
223 bool ChatHandler::HandleReloadAreaTriggerTeleportCommand(const char*)
225 sLog.outString( "Re-Loading AreaTrigger teleport definitions..." );
226 sObjectMgr.LoadAreaTriggerTeleports();
227 SendGlobalSysMessage("DB table `areatrigger_teleport` reloaded.");
228 return true;
231 bool ChatHandler::HandleReloadCommandCommand(const char*)
233 load_command_table = true;
234 SendGlobalSysMessage("DB table `command` will be reloaded at next chat command use.");
235 return true;
238 bool ChatHandler::HandleReloadCreatureQuestRelationsCommand(const char*)
240 sLog.outString( "Loading Quests Relations... (`creature_questrelation`)" );
241 sObjectMgr.LoadCreatureQuestRelations();
242 SendGlobalSysMessage("DB table `creature_questrelation` (creature quest givers) reloaded.");
243 return true;
246 bool ChatHandler::HandleReloadCreatureQuestInvRelationsCommand(const char*)
248 sLog.outString( "Loading Quests Relations... (`creature_involvedrelation`)" );
249 sObjectMgr.LoadCreatureInvolvedRelations();
250 SendGlobalSysMessage("DB table `creature_involvedrelation` (creature quest takers) reloaded.");
251 return true;
254 bool ChatHandler::HandleReloadGossipMenuCommand(const char*)
256 sLog.outString( "Re-Loading `gossip_menu` Table!" );
257 sObjectMgr.LoadGossipMenu();
258 SendGlobalSysMessage("DB table `gossip_menu` reloaded.");
259 return true;
262 bool ChatHandler::HandleReloadGossipMenuOptionCommand(const char*)
264 sLog.outString( "Re-Loading `gossip_menu_option` Table!" );
265 sObjectMgr.LoadGossipMenuItems();
266 SendGlobalSysMessage("DB table `gossip_menu_option` reloaded.");
267 return true;
270 bool ChatHandler::HandleReloadGOQuestRelationsCommand(const char*)
272 sLog.outString( "Loading Quests Relations... (`gameobject_questrelation`)" );
273 sObjectMgr.LoadGameobjectQuestRelations();
274 SendGlobalSysMessage("DB table `gameobject_questrelation` (gameobject quest givers) reloaded.");
275 return true;
278 bool ChatHandler::HandleReloadGOQuestInvRelationsCommand(const char*)
280 sLog.outString( "Loading Quests Relations... (`gameobject_involvedrelation`)" );
281 sObjectMgr.LoadGameobjectInvolvedRelations();
282 SendGlobalSysMessage("DB table `gameobject_involvedrelation` (gameobject quest takers) reloaded.");
283 return true;
286 bool ChatHandler::HandleReloadQuestAreaTriggersCommand(const char*)
288 sLog.outString( "Re-Loading Quest Area Triggers..." );
289 sObjectMgr.LoadQuestAreaTriggers();
290 SendGlobalSysMessage("DB table `areatrigger_involvedrelation` (quest area triggers) reloaded.");
291 return true;
294 bool ChatHandler::HandleReloadQuestTemplateCommand(const char*)
296 sLog.outString( "Re-Loading Quest Templates..." );
297 sObjectMgr.LoadQuests();
298 SendGlobalSysMessage("DB table `quest_template` (quest definitions) reloaded.");
300 /// dependent also from `gameobject` but this table not reloaded anyway
301 sLog.outString( "Re-Loading GameObjects for quests..." );
302 sObjectMgr.LoadGameObjectForQuests();
303 SendGlobalSysMessage("Data GameObjects for quests reloaded.");
304 return true;
307 bool ChatHandler::HandleReloadLootTemplatesCreatureCommand(const char*)
309 sLog.outString( "Re-Loading Loot Tables... (`creature_loot_template`)" );
310 LoadLootTemplates_Creature();
311 LootTemplates_Creature.CheckLootRefs();
312 SendGlobalSysMessage("DB table `creature_loot_template` reloaded.");
313 return true;
316 bool ChatHandler::HandleReloadLootTemplatesDisenchantCommand(const char*)
318 sLog.outString( "Re-Loading Loot Tables... (`disenchant_loot_template`)" );
319 LoadLootTemplates_Disenchant();
320 LootTemplates_Disenchant.CheckLootRefs();
321 SendGlobalSysMessage("DB table `disenchant_loot_template` reloaded.");
322 return true;
325 bool ChatHandler::HandleReloadLootTemplatesFishingCommand(const char*)
327 sLog.outString( "Re-Loading Loot Tables... (`fishing_loot_template`)" );
328 LoadLootTemplates_Fishing();
329 LootTemplates_Fishing.CheckLootRefs();
330 SendGlobalSysMessage("DB table `fishing_loot_template` reloaded.");
331 return true;
334 bool ChatHandler::HandleReloadLootTemplatesGameobjectCommand(const char*)
336 sLog.outString( "Re-Loading Loot Tables... (`gameobject_loot_template`)" );
337 LoadLootTemplates_Gameobject();
338 LootTemplates_Gameobject.CheckLootRefs();
339 SendGlobalSysMessage("DB table `gameobject_loot_template` reloaded.");
340 return true;
343 bool ChatHandler::HandleReloadLootTemplatesItemCommand(const char*)
345 sLog.outString( "Re-Loading Loot Tables... (`item_loot_template`)" );
346 LoadLootTemplates_Item();
347 LootTemplates_Item.CheckLootRefs();
348 SendGlobalSysMessage("DB table `item_loot_template` reloaded.");
349 return true;
352 bool ChatHandler::HandleReloadLootTemplatesMillingCommand(const char*)
354 sLog.outString( "Re-Loading Loot Tables... (`milling_loot_template`)" );
355 LoadLootTemplates_Milling();
356 LootTemplates_Milling.CheckLootRefs();
357 SendGlobalSysMessage("DB table `milling_loot_template` reloaded.");
358 return true;
361 bool ChatHandler::HandleReloadLootTemplatesPickpocketingCommand(const char*)
363 sLog.outString( "Re-Loading Loot Tables... (`pickpocketing_loot_template`)" );
364 LoadLootTemplates_Pickpocketing();
365 LootTemplates_Pickpocketing.CheckLootRefs();
366 SendGlobalSysMessage("DB table `pickpocketing_loot_template` reloaded.");
367 return true;
370 bool ChatHandler::HandleReloadLootTemplatesProspectingCommand(const char*)
372 sLog.outString( "Re-Loading Loot Tables... (`prospecting_loot_template`)" );
373 LoadLootTemplates_Prospecting();
374 LootTemplates_Prospecting.CheckLootRefs();
375 SendGlobalSysMessage("DB table `prospecting_loot_template` reloaded.");
376 return true;
379 bool ChatHandler::HandleReloadLootTemplatesMailCommand(const char*)
381 sLog.outString( "Re-Loading Loot Tables... (`mail_loot_template`)" );
382 LoadLootTemplates_Mail();
383 LootTemplates_Mail.CheckLootRefs();
384 SendGlobalSysMessage("DB table `mail_loot_template` reloaded.");
385 return true;
388 bool ChatHandler::HandleReloadLootTemplatesReferenceCommand(const char*)
390 sLog.outString( "Re-Loading Loot Tables... (`reference_loot_template`)" );
391 LoadLootTemplates_Reference();
392 SendGlobalSysMessage("DB table `reference_loot_template` reloaded.");
393 return true;
396 bool ChatHandler::HandleReloadLootTemplatesSkinningCommand(const char*)
398 sLog.outString( "Re-Loading Loot Tables... (`skinning_loot_template`)" );
399 LoadLootTemplates_Skinning();
400 LootTemplates_Skinning.CheckLootRefs();
401 SendGlobalSysMessage("DB table `skinning_loot_template` reloaded.");
402 return true;
405 bool ChatHandler::HandleReloadLootTemplatesSpellCommand(const char*)
407 sLog.outString( "Re-Loading Loot Tables... (`spell_loot_template`)" );
408 LoadLootTemplates_Spell();
409 LootTemplates_Spell.CheckLootRefs();
410 SendGlobalSysMessage("DB table `spell_loot_template` reloaded.");
411 return true;
414 bool ChatHandler::HandleReloadMangosStringCommand(const char*)
416 sLog.outString( "Re-Loading mangos_string Table!" );
417 sObjectMgr.LoadMangosStrings();
418 SendGlobalSysMessage("DB table `mangos_string` reloaded.");
419 return true;
422 bool ChatHandler::HandleReloadNpcGossipCommand(const char*)
424 sLog.outString( "Re-Loading `npc_gossip` Table!" );
425 sObjectMgr.LoadNpcTextId();
426 SendGlobalSysMessage("DB table `npc_gossip` reloaded.");
427 return true;
430 bool ChatHandler::HandleReloadNpcTrainerCommand(const char*)
432 sLog.outString( "Re-Loading `npc_trainer` Table!" );
433 sObjectMgr.LoadTrainerSpell();
434 SendGlobalSysMessage("DB table `npc_trainer` reloaded.");
435 return true;
438 bool ChatHandler::HandleReloadNpcVendorCommand(const char*)
440 sLog.outString( "Re-Loading `npc_vendor` Table!" );
441 sObjectMgr.LoadVendors();
442 SendGlobalSysMessage("DB table `npc_vendor` reloaded.");
443 return true;
446 bool ChatHandler::HandleReloadPointsOfInterestCommand(const char*)
448 sLog.outString( "Re-Loading `points_of_interest` Table!" );
449 sObjectMgr.LoadPointsOfInterest();
450 SendGlobalSysMessage("DB table `points_of_interest` reloaded.");
451 return true;
454 bool ChatHandler::HandleReloadSpellClickSpellsCommand(const char*)
456 sLog.outString( "Re-Loading `npc_spellclick_spells` Table!" );
457 sObjectMgr.LoadNPCSpellClickSpells();
458 SendGlobalSysMessage("DB table `npc_spellclick_spells` reloaded.");
459 return true;
462 bool ChatHandler::HandleReloadReservedNameCommand(const char*)
464 sLog.outString( "Loading ReservedNames... (`reserved_name`)" );
465 sObjectMgr.LoadReservedPlayersNames();
466 SendGlobalSysMessage("DB table `reserved_name` (player reserved names) reloaded.");
467 return true;
470 bool ChatHandler::HandleReloadSkillDiscoveryTemplateCommand(const char* /*args*/)
472 sLog.outString( "Re-Loading Skill Discovery Table..." );
473 LoadSkillDiscoveryTable();
474 SendGlobalSysMessage("DB table `skill_discovery_template` (recipes discovered at crafting) reloaded.");
475 return true;
478 bool ChatHandler::HandleReloadSkillExtraItemTemplateCommand(const char* /*args*/)
480 sLog.outString( "Re-Loading Skill Extra Item Table..." );
481 LoadSkillExtraItemTable();
482 SendGlobalSysMessage("DB table `skill_extra_item_template` (extra item creation when crafting) reloaded.");
483 return true;
486 bool ChatHandler::HandleReloadSkillFishingBaseLevelCommand(const char* /*args*/)
488 sLog.outString( "Re-Loading Skill Fishing base level requirements..." );
489 sObjectMgr.LoadFishingBaseSkillLevel();
490 SendGlobalSysMessage("DB table `skill_fishing_base_level` (fishing base level for zone/subzone) reloaded.");
491 return true;
494 bool ChatHandler::HandleReloadSpellAreaCommand(const char*)
496 sLog.outString( "Re-Loading SpellArea Data..." );
497 sSpellMgr.LoadSpellAreas();
498 SendGlobalSysMessage("DB table `spell_area` (spell dependences from area/quest/auras state) reloaded.");
499 return true;
502 bool ChatHandler::HandleReloadSpellChainCommand(const char*)
504 sLog.outString( "Re-Loading Spell Chain Data... " );
505 sSpellMgr.LoadSpellChains();
506 SendGlobalSysMessage("DB table `spell_chain` (spell ranks) reloaded.");
507 return true;
510 bool ChatHandler::HandleReloadSpellElixirCommand(const char*)
512 sLog.outString( "Re-Loading Spell Elixir types..." );
513 sSpellMgr.LoadSpellElixirs();
514 SendGlobalSysMessage("DB table `spell_elixir` (spell elixir types) reloaded.");
515 return true;
518 bool ChatHandler::HandleReloadSpellLearnSpellCommand(const char*)
520 sLog.outString( "Re-Loading Spell Learn Spells..." );
521 sSpellMgr.LoadSpellLearnSpells();
522 SendGlobalSysMessage("DB table `spell_learn_spell` reloaded.");
523 return true;
526 bool ChatHandler::HandleReloadSpellProcEventCommand(const char*)
528 sLog.outString( "Re-Loading Spell Proc Event conditions..." );
529 sSpellMgr.LoadSpellProcEvents();
530 SendGlobalSysMessage("DB table `spell_proc_event` (spell proc trigger requirements) reloaded.");
531 return true;
534 bool ChatHandler::HandleReloadSpellBonusesCommand(const char*)
536 sLog.outString( "Re-Loading Spell Bonus Data..." );
537 sSpellMgr.LoadSpellBonusess();
538 SendGlobalSysMessage("DB table `spell_bonus_data` (spell damage/healing coefficients) reloaded.");
539 return true;
542 bool ChatHandler::HandleReloadSpellProcItemEnchantCommand(const char*)
544 sLog.outString( "Re-Loading Spell Proc Item Enchant..." );
545 sSpellMgr.LoadSpellProcItemEnchant();
546 SendGlobalSysMessage("DB table `spell_proc_item_enchant` (item enchantment ppm) reloaded.");
547 return true;
550 bool ChatHandler::HandleReloadSpellScriptTargetCommand(const char*)
552 sLog.outString( "Re-Loading SpellsScriptTarget..." );
553 sSpellMgr.LoadSpellScriptTarget();
554 SendGlobalSysMessage("DB table `spell_script_target` (spell targets selection in case specific creature/GO requirements) reloaded.");
555 return true;
558 bool ChatHandler::HandleReloadSpellTargetPositionCommand(const char*)
560 sLog.outString( "Re-Loading Spell target coordinates..." );
561 sSpellMgr.LoadSpellTargetPositions();
562 SendGlobalSysMessage("DB table `spell_target_position` (destination coordinates for spell targets) reloaded.");
563 return true;
566 bool ChatHandler::HandleReloadSpellThreatsCommand(const char*)
568 sLog.outString( "Re-Loading Aggro Spells Definitions...");
569 sSpellMgr.LoadSpellThreats();
570 SendGlobalSysMessage("DB table `spell_threat` (spell aggro definitions) reloaded.");
571 return true;
574 bool ChatHandler::HandleReloadSpellPetAurasCommand(const char*)
576 sLog.outString( "Re-Loading Spell pet auras...");
577 sSpellMgr.LoadSpellPetAuras();
578 SendGlobalSysMessage("DB table `spell_pet_auras` reloaded.");
579 return true;
582 bool ChatHandler::HandleReloadPageTextsCommand(const char*)
584 sLog.outString( "Re-Loading Page Texts..." );
585 sObjectMgr.LoadPageTexts();
586 SendGlobalSysMessage("DB table `page_texts` reloaded.");
587 return true;
590 bool ChatHandler::HandleReloadItemEnchantementsCommand(const char*)
592 sLog.outString( "Re-Loading Item Random Enchantments Table..." );
593 LoadRandomEnchantmentsTable();
594 SendGlobalSysMessage("DB table `item_enchantment_template` reloaded.");
595 return true;
598 bool ChatHandler::HandleReloadItemRequiredTragetCommand(const char*)
600 sLog.outString( "Re-Loading Item Required Targets Table..." );
601 sObjectMgr.LoadItemRequiredTarget();
602 SendGlobalSysMessage("DB table `item_required_target` reloaded.");
603 return true;
606 bool ChatHandler::HandleReloadBattleEventCommand(const char*)
608 sLog.outString( "Re-Loading BattleGround Eventindexes..." );
609 sBattleGroundMgr.LoadBattleEventIndexes();
610 SendGlobalSysMessage("DB table `gameobject_battleground` and `creature_battleground` reloaded.");
611 return true;
614 bool ChatHandler::HandleReloadGameObjectScriptsCommand(const char* arg)
616 if(sWorld.IsScriptScheduled())
618 SendSysMessage("DB scripts used currently, please attempt reload later.");
619 SetSentErrorMessage(true);
620 return false;
623 if(*arg!='a')
624 sLog.outString( "Re-Loading Scripts from `gameobject_scripts`...");
626 sObjectMgr.LoadGameObjectScripts();
628 if(*arg!='a')
629 SendGlobalSysMessage("DB table `gameobject_scripts` reloaded.");
631 return true;
634 bool ChatHandler::HandleReloadEventScriptsCommand(const char* arg)
636 if(sWorld.IsScriptScheduled())
638 SendSysMessage("DB scripts used currently, please attempt reload later.");
639 SetSentErrorMessage(true);
640 return false;
643 if(*arg!='a')
644 sLog.outString( "Re-Loading Scripts from `event_scripts`...");
646 sObjectMgr.LoadEventScripts();
648 if(*arg!='a')
649 SendGlobalSysMessage("DB table `event_scripts` reloaded.");
651 return true;
654 bool ChatHandler::HandleReloadEventAITextsCommand(const char* arg)
657 sLog.outString( "Re-Loading Texts from `creature_ai_texts`...");
658 sEventAIMgr.LoadCreatureEventAI_Texts(true);
659 SendGlobalSysMessage("DB table `creature_ai_texts` reloaded.");
660 return true;
663 bool ChatHandler::HandleReloadEventAISummonsCommand(const char* arg)
665 sLog.outString( "Re-Loading Summons from `creature_ai_summons`...");
666 sEventAIMgr.LoadCreatureEventAI_Summons(true);
667 SendGlobalSysMessage("DB table `creature_ai_summons` reloaded.");
668 return true;
671 bool ChatHandler::HandleReloadEventAIScriptsCommand(const char* arg)
673 sLog.outString( "Re-Loading Scripts from `creature_ai_scripts`...");
674 sEventAIMgr.LoadCreatureEventAI_Scripts();
675 SendGlobalSysMessage("DB table `creature_ai_scripts` reloaded.");
676 return true;
679 bool ChatHandler::HandleReloadQuestEndScriptsCommand(const char* arg)
681 if(sWorld.IsScriptScheduled())
683 SendSysMessage("DB scripts used currently, please attempt reload later.");
684 SetSentErrorMessage(true);
685 return false;
688 if(*arg!='a')
689 sLog.outString( "Re-Loading Scripts from `quest_end_scripts`...");
691 sObjectMgr.LoadQuestEndScripts();
693 if(*arg!='a')
694 SendGlobalSysMessage("DB table `quest_end_scripts` reloaded.");
696 return true;
699 bool ChatHandler::HandleReloadQuestStartScriptsCommand(const char* arg)
701 if(sWorld.IsScriptScheduled())
703 SendSysMessage("DB scripts used currently, please attempt reload later.");
704 SetSentErrorMessage(true);
705 return false;
708 if(*arg!='a')
709 sLog.outString( "Re-Loading Scripts from `quest_start_scripts`...");
711 sObjectMgr.LoadQuestStartScripts();
713 if(*arg!='a')
714 SendGlobalSysMessage("DB table `quest_start_scripts` reloaded.");
716 return true;
719 bool ChatHandler::HandleReloadSpellScriptsCommand(const char* arg)
721 if(sWorld.IsScriptScheduled())
723 SendSysMessage("DB scripts used currently, please attempt reload later.");
724 SetSentErrorMessage(true);
725 return false;
728 if(*arg!='a')
729 sLog.outString( "Re-Loading Scripts from `spell_scripts`...");
731 sObjectMgr.LoadSpellScripts();
733 if(*arg!='a')
734 SendGlobalSysMessage("DB table `spell_scripts` reloaded.");
736 return true;
739 bool ChatHandler::HandleReloadDbScriptStringCommand(const char* /*arg*/)
741 sLog.outString( "Re-Loading Script strings from `db_script_string`...");
742 sObjectMgr.LoadDbScriptStrings();
743 SendGlobalSysMessage("DB table `db_script_string` reloaded.");
744 return true;
747 bool ChatHandler::HandleReloadGameGraveyardZoneCommand(const char* /*arg*/)
749 sLog.outString( "Re-Loading Graveyard-zone links...");
751 sObjectMgr.LoadGraveyardZones();
753 SendGlobalSysMessage("DB table `game_graveyard_zone` reloaded.");
755 return true;
758 bool ChatHandler::HandleReloadGameTeleCommand(const char* /*arg*/)
760 sLog.outString( "Re-Loading Game Tele coordinates...");
762 sObjectMgr.LoadGameTele();
764 SendGlobalSysMessage("DB table `game_tele` reloaded.");
766 return true;
769 bool ChatHandler::HandleReloadLocalesAchievementRewardCommand(const char*)
771 sLog.outString( "Re-Loading Locales Achievement Reward Data..." );
772 sAchievementMgr.LoadRewardLocales();
773 SendGlobalSysMessage("DB table `locales_achievement_reward` reloaded.");
774 return true;
777 bool ChatHandler::HandleReloadLocalesCreatureCommand(const char* /*arg*/)
779 sLog.outString( "Re-Loading Locales Creature ...");
780 sObjectMgr.LoadCreatureLocales();
781 SendGlobalSysMessage("DB table `locales_creature` reloaded.");
782 return true;
785 bool ChatHandler::HandleReloadLocalesGameobjectCommand(const char* /*arg*/)
787 sLog.outString( "Re-Loading Locales Gameobject ... ");
788 sObjectMgr.LoadGameObjectLocales();
789 SendGlobalSysMessage("DB table `locales_gameobject` reloaded.");
790 return true;
793 bool ChatHandler::HandleReloadLocalesItemCommand(const char* /*arg*/)
795 sLog.outString( "Re-Loading Locales Item ... ");
796 sObjectMgr.LoadItemLocales();
797 SendGlobalSysMessage("DB table `locales_item` reloaded.");
798 return true;
801 bool ChatHandler::HandleReloadLocalesNpcTextCommand(const char* /*arg*/)
803 sLog.outString( "Re-Loading Locales NPC Text ... ");
804 sObjectMgr.LoadNpcTextLocales();
805 SendGlobalSysMessage("DB table `locales_npc_text` reloaded.");
806 return true;
809 bool ChatHandler::HandleReloadLocalesPageTextCommand(const char* /*arg*/)
811 sLog.outString( "Re-Loading Locales Page Text ... ");
812 sObjectMgr.LoadPageTextLocales();
813 SendGlobalSysMessage("DB table `locales_page_text` reloaded.");
814 return true;
817 bool ChatHandler::HandleReloadLocalesPointsOfInterestCommand(const char* /*arg*/)
819 sLog.outString( "Re-Loading Locales Points Of Interest ... ");
820 sObjectMgr.LoadPointOfInterestLocales();
821 SendGlobalSysMessage("DB table `locales_points_of_interest` reloaded.");
822 return true;
825 bool ChatHandler::HandleReloadLocalesQuestCommand(const char* /*arg*/)
827 sLog.outString( "Re-Loading Locales Quest ... ");
828 sObjectMgr.LoadQuestLocales();
829 SendGlobalSysMessage("DB table `locales_quest` reloaded.");
830 return true;
833 bool ChatHandler::HandleReloadMailLevelRewardCommand(const char* /*arg*/)
835 sLog.outString( "Re-Loading Player level dependent mail rewards..." );
836 sObjectMgr.LoadMailLevelRewards();
837 SendGlobalSysMessage("DB table `mail_level_reward` reloaded.");
838 return true;
841 bool ChatHandler::HandleLoadScriptsCommand(const char* args)
843 if(!LoadScriptingModule(args)) return true;
845 sWorld.SendWorldText(LANG_SCRIPTS_RELOADED);
846 return true;
849 bool ChatHandler::HandleAccountSetGmLevelCommand(const char* args)
851 char* arg1 = strtok((char*)args, " ");
852 if( !arg1 )
853 return false;
855 /// must be NULL if targeted syntax and must be not nULL if not targeted
856 char* arg2 = strtok(NULL, " ");
858 std::string targetAccountName;
859 uint32 targetAccountId = 0;
861 /// only target player different from self allowed (if targetPlayer!=NULL then not console)
862 Player* targetPlayer = getSelectedPlayer();
863 if(targetPlayer && m_session->GetPlayer()!=targetPlayer)
865 /// wrong command syntax or unexpected targeting
866 if(arg2)
867 return false;
869 /// security level expected in arg2 after this if.
870 arg2 = arg1;
872 targetAccountId = targetPlayer->GetSession()->GetAccountId();
873 sAccountMgr.GetName(targetAccountId, targetAccountName);
875 else
877 /// wrong command syntax (second arg expected)
878 if(!arg2)
879 return false;
881 targetAccountName = arg1;
882 if (!AccountMgr::normalizeString(targetAccountName))
884 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,targetAccountName.c_str());
885 SetSentErrorMessage(true);
886 return false;
889 targetAccountId = sAccountMgr.GetId(targetAccountName);
890 if(!targetAccountId)
892 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,targetAccountName.c_str());
893 SetSentErrorMessage(true);
894 return false;
898 int32 gm = (int32)atoi(arg2);
899 if ( gm < SEC_PLAYER || gm > SEC_ADMINISTRATOR )
901 SendSysMessage(LANG_BAD_VALUE);
902 SetSentErrorMessage(true);
903 return false;
906 /// can set security level only for target with less security and to less security that we have
907 /// This will reject self apply by specify account name
908 if(HasLowerSecurityAccount(NULL,targetAccountId,true))
909 return false;
911 /// account can't set security to same or grater level, need more power GM or console
912 AccountTypes plSecurity = m_session ? m_session->GetSecurity() : SEC_CONSOLE;
913 if (AccountTypes(gm) >= plSecurity )
915 SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
916 SetSentErrorMessage(true);
917 return false;
920 // This will prevent self apply by self target or no target
921 if(targetPlayer && m_session->GetPlayer()!=targetPlayer)
923 ChatHandler(targetPlayer).PSendSysMessage(LANG_YOURS_SECURITY_CHANGED,GetNameLink().c_str(), gm);
924 targetPlayer->GetSession()->SetSecurity(AccountTypes(gm));
927 PSendSysMessage(LANG_YOU_CHANGE_SECURITY, targetAccountName.c_str(), gm);
928 loginDatabase.PExecute("UPDATE account SET gmlevel = '%i' WHERE id = '%u'", gm, targetAccountId);
930 return true;
933 /// Set password for account
934 bool ChatHandler::HandleAccountSetPasswordCommand(const char* args)
936 if(!*args)
937 return false;
939 ///- Get the command line arguments
940 char *szAccount = strtok ((char*)args," ");
941 char *szPassword1 = strtok (NULL," ");
942 char *szPassword2 = strtok (NULL," ");
944 if (!szAccount||!szPassword1 || !szPassword2)
945 return false;
947 std::string account_name = szAccount;
948 if (!AccountMgr::normalizeString(account_name))
950 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
951 SetSentErrorMessage(true);
952 return false;
955 uint32 targetAccountId = sAccountMgr.GetId(account_name);
956 if (!targetAccountId)
958 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
959 SetSentErrorMessage(true);
960 return false;
963 /// can set password only for target with less security
964 /// This is also reject self apply in fact
965 if(HasLowerSecurityAccount (NULL,targetAccountId,true))
966 return false;
968 if (strcmp(szPassword1,szPassword2))
970 SendSysMessage (LANG_NEW_PASSWORDS_NOT_MATCH);
971 SetSentErrorMessage (true);
972 return false;
975 AccountOpResult result = sAccountMgr.ChangePassword(targetAccountId, szPassword1);
977 switch(result)
979 case AOR_OK:
980 SendSysMessage(LANG_COMMAND_PASSWORD);
981 break;
982 case AOR_NAME_NOT_EXIST:
983 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
984 SetSentErrorMessage(true);
985 return false;
986 case AOR_PASS_TOO_LONG:
987 SendSysMessage(LANG_PASSWORD_TOO_LONG);
988 SetSentErrorMessage(true);
989 return false;
990 default:
991 SendSysMessage(LANG_COMMAND_NOTCHANGEPASSWORD);
992 SetSentErrorMessage(true);
993 return false;
996 return true;
999 bool ChatHandler::HandleMaxSkillCommand(const char* /*args*/)
1001 Player* SelectedPlayer = getSelectedPlayer();
1002 if(!SelectedPlayer)
1004 SendSysMessage(LANG_NO_CHAR_SELECTED);
1005 SetSentErrorMessage(true);
1006 return false;
1009 // each skills that have max skill value dependent from level seted to current level max skill value
1010 SelectedPlayer->UpdateSkillsToMaxSkillsForLevel();
1011 return true;
1014 bool ChatHandler::HandleSetSkillCommand(const char* args)
1016 // number or [name] Shift-click form |color|Hskill:skill_id|h[name]|h|r
1017 char* skill_p = extractKeyFromLink((char*)args,"Hskill");
1018 if(!skill_p)
1019 return false;
1021 char *level_p = strtok (NULL, " ");
1023 if( !level_p)
1024 return false;
1026 char *max_p = strtok (NULL, " ");
1028 int32 skill = atoi(skill_p);
1029 if (skill <= 0)
1031 PSendSysMessage(LANG_INVALID_SKILL_ID, skill);
1032 SetSentErrorMessage(true);
1033 return false;
1036 int32 level = atol (level_p);
1038 Player * target = getSelectedPlayer();
1039 if(!target)
1041 SendSysMessage(LANG_NO_CHAR_SELECTED);
1042 SetSentErrorMessage(true);
1043 return false;
1046 SkillLineEntry const* sl = sSkillLineStore.LookupEntry(skill);
1047 if(!sl)
1049 PSendSysMessage(LANG_INVALID_SKILL_ID, skill);
1050 SetSentErrorMessage(true);
1051 return false;
1054 std::string tNameLink = GetNameLink(target);
1056 if(!target->GetSkillValue(skill))
1058 PSendSysMessage(LANG_SET_SKILL_ERROR, tNameLink.c_str(), skill, sl->name[GetSessionDbcLocale()]);
1059 SetSentErrorMessage(true);
1060 return false;
1063 int32 max = max_p ? atol (max_p) : target->GetPureMaxSkillValue(skill);
1065 if( level <= 0 || level > max || max <= 0 )
1066 return false;
1068 target->SetSkill(skill, level, max);
1069 PSendSysMessage(LANG_SET_SKILL, skill, sl->name[GetSessionDbcLocale()], tNameLink.c_str(), level, max);
1071 return true;
1074 bool ChatHandler::HandleUnLearnCommand(const char* args)
1076 if (!*args)
1077 return false;
1079 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
1080 uint32 spell_id = extractSpellIdFromLink((char*)args);
1081 if(!spell_id)
1082 return false;
1084 char const* allStr = strtok(NULL," ");
1085 bool allRanks = allStr ? (strncmp(allStr, "all", strlen(allStr)) == 0) : false;
1087 Player* target = getSelectedPlayer();
1088 if(!target)
1090 SendSysMessage(LANG_NO_CHAR_SELECTED);
1091 SetSentErrorMessage(true);
1092 return false;
1095 if(allRanks)
1096 spell_id = sSpellMgr.GetFirstSpellInChain (spell_id);
1098 if (target->HasSpell(spell_id))
1099 target->removeSpell(spell_id,false,!allRanks);
1100 else
1101 SendSysMessage(LANG_FORGET_SPELL);
1103 if(GetTalentSpellCost(spell_id))
1104 target->SendTalentsInfoData(false);
1106 return true;
1109 bool ChatHandler::HandleCooldownCommand(const char* args)
1111 Player* target = getSelectedPlayer();
1112 if(!target)
1114 SendSysMessage(LANG_PLAYER_NOT_FOUND);
1115 SetSentErrorMessage(true);
1116 return false;
1119 std::string tNameLink = GetNameLink(target);
1121 if (!*args)
1123 target->RemoveAllSpellCooldown();
1124 PSendSysMessage(LANG_REMOVEALL_COOLDOWN, tNameLink.c_str());
1126 else
1128 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
1129 uint32 spell_id = extractSpellIdFromLink((char*)args);
1130 if(!spell_id)
1131 return false;
1133 if(!sSpellStore.LookupEntry(spell_id))
1135 PSendSysMessage(LANG_UNKNOWN_SPELL, target==m_session->GetPlayer() ? GetMangosString(LANG_YOU) : tNameLink.c_str());
1136 SetSentErrorMessage(true);
1137 return false;
1140 target->RemoveSpellCooldown(spell_id,true);
1141 PSendSysMessage(LANG_REMOVE_COOLDOWN, spell_id, target==m_session->GetPlayer() ? GetMangosString(LANG_YOU) : tNameLink.c_str());
1143 return true;
1146 bool ChatHandler::HandleLearnAllCommand(const char* /*args*/)
1148 static const char *allSpellList[] =
1150 "3365",
1151 "6233",
1152 "6247",
1153 "6246",
1154 "6477",
1155 "6478",
1156 "22810",
1157 "8386",
1158 "21651",
1159 "21652",
1160 "522",
1161 "7266",
1162 "8597",
1163 "2479",
1164 "22027",
1165 "6603",
1166 "5019",
1167 "133",
1168 "168",
1169 "227",
1170 "5009",
1171 "9078",
1172 "668",
1173 "203",
1174 "20599",
1175 "20600",
1176 "81",
1177 "20597",
1178 "20598",
1179 "20864",
1180 "1459",
1181 "5504",
1182 "587",
1183 "5143",
1184 "118",
1185 "5505",
1186 "597",
1187 "604",
1188 "1449",
1189 "1460",
1190 "2855",
1191 "1008",
1192 "475",
1193 "5506",
1194 "1463",
1195 "12824",
1196 "8437",
1197 "990",
1198 "5145",
1199 "8450",
1200 "1461",
1201 "759",
1202 "8494",
1203 "8455",
1204 "8438",
1205 "6127",
1206 "8416",
1207 "6129",
1208 "8451",
1209 "8495",
1210 "8439",
1211 "3552",
1212 "8417",
1213 "10138",
1214 "12825",
1215 "10169",
1216 "10156",
1217 "10144",
1218 "10191",
1219 "10201",
1220 "10211",
1221 "10053",
1222 "10173",
1223 "10139",
1224 "10145",
1225 "10192",
1226 "10170",
1227 "10202",
1228 "10054",
1229 "10174",
1230 "10193",
1231 "12826",
1232 "2136",
1233 "143",
1234 "145",
1235 "2137",
1236 "2120",
1237 "3140",
1238 "543",
1239 "2138",
1240 "2948",
1241 "8400",
1242 "2121",
1243 "8444",
1244 "8412",
1245 "8457",
1246 "8401",
1247 "8422",
1248 "8445",
1249 "8402",
1250 "8413",
1251 "8458",
1252 "8423",
1253 "8446",
1254 "10148",
1255 "10197",
1256 "10205",
1257 "10149",
1258 "10215",
1259 "10223",
1260 "10206",
1261 "10199",
1262 "10150",
1263 "10216",
1264 "10207",
1265 "10225",
1266 "10151",
1267 "116",
1268 "205",
1269 "7300",
1270 "122",
1271 "837",
1272 "10",
1273 "7301",
1274 "7322",
1275 "6143",
1276 "120",
1277 "865",
1278 "8406",
1279 "6141",
1280 "7302",
1281 "8461",
1282 "8407",
1283 "8492",
1284 "8427",
1285 "8408",
1286 "6131",
1287 "7320",
1288 "10159",
1289 "8462",
1290 "10185",
1291 "10179",
1292 "10160",
1293 "10180",
1294 "10219",
1295 "10186",
1296 "10177",
1297 "10230",
1298 "10181",
1299 "10161",
1300 "10187",
1301 "10220",
1302 "2018",
1303 "2663",
1304 "12260",
1305 "2660",
1306 "3115",
1307 "3326",
1308 "2665",
1309 "3116",
1310 "2738",
1311 "3293",
1312 "2661",
1313 "3319",
1314 "2662",
1315 "9983",
1316 "8880",
1317 "2737",
1318 "2739",
1319 "7408",
1320 "3320",
1321 "2666",
1322 "3323",
1323 "3324",
1324 "3294",
1325 "22723",
1326 "23219",
1327 "23220",
1328 "23221",
1329 "23228",
1330 "23338",
1331 "10788",
1332 "10790",
1333 "5611",
1334 "5016",
1335 "5609",
1336 "2060",
1337 "10963",
1338 "10964",
1339 "10965",
1340 "22593",
1341 "22594",
1342 "596",
1343 "996",
1344 "499",
1345 "768",
1346 "17002",
1347 "1448",
1348 "1082",
1349 "16979",
1350 "1079",
1351 "5215",
1352 "20484",
1353 "5221",
1354 "15590",
1355 "17007",
1356 "6795",
1357 "6807",
1358 "5487",
1359 "1446",
1360 "1066",
1361 "5421",
1362 "3139",
1363 "779",
1364 "6811",
1365 "6808",
1366 "1445",
1367 "5216",
1368 "1737",
1369 "5222",
1370 "5217",
1371 "1432",
1372 "6812",
1373 "9492",
1374 "5210",
1375 "3030",
1376 "1441",
1377 "783",
1378 "6801",
1379 "20739",
1380 "8944",
1381 "9491",
1382 "22569",
1383 "5226",
1384 "6786",
1385 "1433",
1386 "8973",
1387 "1828",
1388 "9495",
1389 "9006",
1390 "6794",
1391 "8993",
1392 "5203",
1393 "16914",
1394 "6784",
1395 "9635",
1396 "22830",
1397 "20722",
1398 "9748",
1399 "6790",
1400 "9753",
1401 "9493",
1402 "9752",
1403 "9831",
1404 "9825",
1405 "9822",
1406 "5204",
1407 "5401",
1408 "22831",
1409 "6793",
1410 "9845",
1411 "17401",
1412 "9882",
1413 "9868",
1414 "20749",
1415 "9893",
1416 "9899",
1417 "9895",
1418 "9832",
1419 "9902",
1420 "9909",
1421 "22832",
1422 "9828",
1423 "9851",
1424 "9883",
1425 "9869",
1426 "17406",
1427 "17402",
1428 "9914",
1429 "20750",
1430 "9897",
1431 "9848",
1432 "3127",
1433 "107",
1434 "204",
1435 "9116",
1436 "2457",
1437 "78",
1438 "18848",
1439 "331",
1440 "403",
1441 "2098",
1442 "1752",
1443 "11278",
1444 "11288",
1445 "11284",
1446 "6461",
1447 "2344",
1448 "2345",
1449 "6463",
1450 "2346",
1451 "2352",
1452 "775",
1453 "1434",
1454 "1612",
1455 "71",
1456 "2468",
1457 "2458",
1458 "2467",
1459 "7164",
1460 "7178",
1461 "7367",
1462 "7376",
1463 "7381",
1464 "21156",
1465 "5209",
1466 "3029",
1467 "5201",
1468 "9849",
1469 "9850",
1470 "20719",
1471 "22568",
1472 "22827",
1473 "22828",
1474 "22829",
1475 "6809",
1476 "8972",
1477 "9005",
1478 "9823",
1479 "9827",
1480 "6783",
1481 "9913",
1482 "6785",
1483 "6787",
1484 "9866",
1485 "9867",
1486 "9894",
1487 "9896",
1488 "6800",
1489 "8992",
1490 "9829",
1491 "9830",
1492 "780",
1493 "769",
1494 "6749",
1495 "6750",
1496 "9755",
1497 "9754",
1498 "9908",
1499 "20745",
1500 "20742",
1501 "20747",
1502 "20748",
1503 "9746",
1504 "9745",
1505 "9880",
1506 "9881",
1507 "5391",
1508 "842",
1509 "3025",
1510 "3031",
1511 "3287",
1512 "3329",
1513 "1945",
1514 "3559",
1515 "4933",
1516 "4934",
1517 "4935",
1518 "4936",
1519 "5142",
1520 "5390",
1521 "5392",
1522 "5404",
1523 "5420",
1524 "6405",
1525 "7293",
1526 "7965",
1527 "8041",
1528 "8153",
1529 "9033",
1530 "9034",
1531 //"9036", problems with ghost state
1532 "16421",
1533 "21653",
1534 "22660",
1535 "5225",
1536 "9846",
1537 "2426",
1538 "5916",
1539 "6634",
1540 //"6718", phasing stealth, annoying for learn all case.
1541 "6719",
1542 "8822",
1543 "9591",
1544 "9590",
1545 "10032",
1546 "17746",
1547 "17747",
1548 "8203",
1549 "11392",
1550 "12495",
1551 "16380",
1552 "23452",
1553 "4079",
1554 "4996",
1555 "4997",
1556 "4998",
1557 "4999",
1558 "5000",
1559 "6348",
1560 "6349",
1561 "6481",
1562 "6482",
1563 "6483",
1564 "6484",
1565 "11362",
1566 "11410",
1567 "11409",
1568 "12510",
1569 "12509",
1570 "12885",
1571 "13142",
1572 "21463",
1573 "23460",
1574 "11421",
1575 "11416",
1576 "11418",
1577 "1851",
1578 "10059",
1579 "11423",
1580 "11417",
1581 "11422",
1582 "11419",
1583 "11424",
1584 "11420",
1585 "27",
1586 "31",
1587 "33",
1588 "34",
1589 "35",
1590 "15125",
1591 "21127",
1592 "22950",
1593 "1180",
1594 "201",
1595 "12593",
1596 "12842",
1597 "16770",
1598 "6057",
1599 "12051",
1600 "18468",
1601 "12606",
1602 "12605",
1603 "18466",
1604 "12502",
1605 "12043",
1606 "15060",
1607 "12042",
1608 "12341",
1609 "12848",
1610 "12344",
1611 "12353",
1612 "18460",
1613 "11366",
1614 "12350",
1615 "12352",
1616 "13043",
1617 "11368",
1618 "11113",
1619 "12400",
1620 "11129",
1621 "16766",
1622 "12573",
1623 "15053",
1624 "12580",
1625 "12475",
1626 "12472",
1627 "12953",
1628 "12488",
1629 "11189",
1630 "12985",
1631 "12519",
1632 "16758",
1633 "11958",
1634 "12490",
1635 "11426",
1636 "3565",
1637 "3562",
1638 "18960",
1639 "3567",
1640 "3561",
1641 "3566",
1642 "3563",
1643 "1953",
1644 "2139",
1645 "12505",
1646 "13018",
1647 "12522",
1648 "12523",
1649 "5146",
1650 "5144",
1651 "5148",
1652 "8419",
1653 "8418",
1654 "10213",
1655 "10212",
1656 "10157",
1657 "12524",
1658 "13019",
1659 "12525",
1660 "13020",
1661 "12526",
1662 "13021",
1663 "18809",
1664 "13031",
1665 "13032",
1666 "13033",
1667 "4036",
1668 "3920",
1669 "3919",
1670 "3918",
1671 "7430",
1672 "3922",
1673 "3923",
1674 "7411",
1675 "7418",
1676 "7421",
1677 "13262",
1678 "7412",
1679 "7415",
1680 "7413",
1681 "7416",
1682 "13920",
1683 "13921",
1684 "7745",
1685 "7779",
1686 "7428",
1687 "7457",
1688 "7857",
1689 "7748",
1690 "7426",
1691 "13421",
1692 "7454",
1693 "13378",
1694 "7788",
1695 "14807",
1696 "14293",
1697 "7795",
1698 "6296",
1699 "20608",
1700 "755",
1701 "444",
1702 "427",
1703 "428",
1704 "442",
1705 "447",
1706 "3578",
1707 "3581",
1708 "19027",
1709 "3580",
1710 "665",
1711 "3579",
1712 "3577",
1713 "6755",
1714 "3576",
1715 "2575",
1716 "2577",
1717 "2578",
1718 "2579",
1719 "2580",
1720 "2656",
1721 "2657",
1722 "2576",
1723 "3564",
1724 "10248",
1725 "8388",
1726 "2659",
1727 "14891",
1728 "3308",
1729 "3307",
1730 "10097",
1731 "2658",
1732 "3569",
1733 "16153",
1734 "3304",
1735 "10098",
1736 "4037",
1737 "3929",
1738 "3931",
1739 "3926",
1740 "3924",
1741 "3930",
1742 "3977",
1743 "3925",
1744 "136",
1745 "228",
1746 "5487",
1747 "43",
1748 "202",
1752 int loop = 0;
1753 while(strcmp(allSpellList[loop], "0"))
1755 uint32 spell = atol((char*)allSpellList[loop++]);
1757 if (m_session->GetPlayer()->HasSpell(spell))
1758 continue;
1760 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
1761 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
1763 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
1764 continue;
1767 m_session->GetPlayer()->learnSpell(spell,false);
1770 SendSysMessage(LANG_COMMAND_LEARN_MANY_SPELLS);
1772 return true;
1775 bool ChatHandler::HandleLearnAllGMCommand(const char* /*args*/)
1777 static const char *gmSpellList[] =
1779 "24347", // Become A Fish, No Breath Bar
1780 "35132", // Visual Boom
1781 "38488", // Attack 4000-8000 AOE
1782 "38795", // Attack 2000 AOE + Slow Down 90%
1783 "15712", // Attack 200
1784 "1852", // GM Spell Silence
1785 "31899", // Kill
1786 "31924", // Kill
1787 "29878", // Kill My Self
1788 "26644", // More Kill
1790 "28550", //Invisible 24
1791 "23452", //Invisible + Target
1795 uint16 gmSpellIter = 0;
1796 while( strcmp(gmSpellList[gmSpellIter], "0") )
1798 uint32 spell = atol((char*)gmSpellList[gmSpellIter++]);
1800 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
1801 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
1803 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
1804 continue;
1807 m_session->GetPlayer()->learnSpell(spell,false);
1810 SendSysMessage(LANG_LEARNING_GM_SKILLS);
1811 return true;
1814 bool ChatHandler::HandleLearnAllMyClassCommand(const char* /*args*/)
1816 HandleLearnAllMySpellsCommand("");
1817 HandleLearnAllMyTalentsCommand("");
1818 return true;
1821 bool ChatHandler::HandleLearnAllMySpellsCommand(const char* /*args*/)
1823 ChrClassesEntry const* clsEntry = sChrClassesStore.LookupEntry(m_session->GetPlayer()->getClass());
1824 if(!clsEntry)
1825 return true;
1826 uint32 family = clsEntry->spellfamily;
1828 for (uint32 i = 0; i < sSpellStore.GetNumRows(); ++i)
1830 SpellEntry const *spellInfo = sSpellStore.LookupEntry(i);
1831 if(!spellInfo)
1832 continue;
1834 // skip server-side/triggered spells
1835 if(spellInfo->spellLevel==0)
1836 continue;
1838 // skip wrong class/race skills
1839 if(!m_session->GetPlayer()->IsSpellFitByClassAndRace(spellInfo->Id))
1840 continue;
1842 // skip other spell families
1843 if( spellInfo->SpellFamilyName != family)
1844 continue;
1846 // skip spells with first rank learned as talent (and all talents then also)
1847 uint32 first_rank = sSpellMgr.GetFirstSpellInChain(spellInfo->Id);
1848 if(GetTalentSpellCost(first_rank) > 0 )
1849 continue;
1851 // skip broken spells
1852 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
1853 continue;
1855 m_session->GetPlayer()->learnSpell(i,false);
1858 SendSysMessage(LANG_COMMAND_LEARN_CLASS_SPELLS);
1859 return true;
1862 bool ChatHandler::HandleLearnAllMyTalentsCommand(const char* /*args*/)
1864 Player* player = m_session->GetPlayer();
1865 uint32 classMask = player->getClassMask();
1867 for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
1869 TalentEntry const *talentInfo = sTalentStore.LookupEntry(i);
1870 if(!talentInfo)
1871 continue;
1873 TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab );
1874 if(!talentTabInfo)
1875 continue;
1877 if( (classMask & talentTabInfo->ClassMask) == 0 )
1878 continue;
1880 // search highest talent rank
1881 uint32 spellid = 0;
1883 for(int rank = MAX_TALENT_RANK-1; rank >= 0; --rank)
1885 if(talentInfo->RankID[rank]!=0)
1887 spellid = talentInfo->RankID[rank];
1888 break;
1892 if(!spellid) // ??? none spells in talent
1893 continue;
1895 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid);
1896 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
1897 continue;
1899 // learn highest rank of talent and learn all non-talent spell ranks (recursive by tree)
1900 player->learnSpellHighRank(spellid);
1903 SendSysMessage(LANG_COMMAND_LEARN_CLASS_TALENTS);
1904 return true;
1907 bool ChatHandler::HandleLearnAllMyPetTalentsCommand(const char* /*args*/)
1909 Player* player = m_session->GetPlayer();
1911 Pet* pet = player->GetPet();
1912 if(!pet)
1914 SendSysMessage(LANG_NO_PET_FOUND);
1915 SetSentErrorMessage(true);
1916 return false;
1919 CreatureInfo const *ci = pet->GetCreatureInfo();
1920 if(!ci)
1922 SendSysMessage(LANG_WRONG_PET_TYPE);
1923 SetSentErrorMessage(true);
1924 return false;
1927 CreatureFamilyEntry const *pet_family = sCreatureFamilyStore.LookupEntry(ci->family);
1928 if(!pet_family)
1930 SendSysMessage(LANG_WRONG_PET_TYPE);
1931 SetSentErrorMessage(true);
1932 return false;
1935 if(pet_family->petTalentType < 0) // not hunter pet
1937 SendSysMessage(LANG_WRONG_PET_TYPE);
1938 SetSentErrorMessage(true);
1939 return false;
1942 for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
1944 TalentEntry const *talentInfo = sTalentStore.LookupEntry(i);
1945 if(!talentInfo)
1946 continue;
1948 TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab );
1949 if(!talentTabInfo)
1950 continue;
1952 // prevent learn talent for different family (cheating)
1953 if(((1 << pet_family->petTalentType) & talentTabInfo->petTalentMask)==0)
1954 continue;
1956 // search highest talent rank
1957 uint32 spellid = 0;
1959 for(int rank = MAX_TALENT_RANK-1; rank >= 0; --rank)
1961 if(talentInfo->RankID[rank]!=0)
1963 spellid = talentInfo->RankID[rank];
1964 break;
1968 if(!spellid) // ??? none spells in talent
1969 continue;
1971 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid);
1972 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
1973 continue;
1975 // learn highest rank of talent and learn all non-talent spell ranks (recursive by tree)
1976 pet->learnSpellHighRank(spellid);
1979 SendSysMessage(LANG_COMMAND_LEARN_PET_TALENTS);
1980 return true;
1983 bool ChatHandler::HandleLearnAllLangCommand(const char* /*args*/)
1985 // skipping UNIVERSAL language (0)
1986 for(int i = 1; i < LANGUAGES_COUNT; ++i)
1987 m_session->GetPlayer()->learnSpell(lang_description[i].spell_id,false);
1989 SendSysMessage(LANG_COMMAND_LEARN_ALL_LANG);
1990 return true;
1993 bool ChatHandler::HandleLearnAllDefaultCommand(const char* args)
1995 Player* target;
1996 if(!extractPlayerTarget((char*)args,&target))
1997 return false;
1999 target->learnDefaultSpells();
2000 target->learnQuestRewardedSpells();
2002 PSendSysMessage(LANG_COMMAND_LEARN_ALL_DEFAULT_AND_QUEST,GetNameLink(target).c_str());
2003 return true;
2006 bool ChatHandler::HandleLearnCommand(const char* args)
2008 Player* targetPlayer = getSelectedPlayer();
2010 if(!targetPlayer)
2012 SendSysMessage(LANG_PLAYER_NOT_FOUND);
2013 SetSentErrorMessage(true);
2014 return false;
2017 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
2018 uint32 spell = extractSpellIdFromLink((char*)args);
2019 if(!spell || !sSpellStore.LookupEntry(spell))
2020 return false;
2022 char const* allStr = strtok(NULL," ");
2023 bool allRanks = allStr ? (strncmp(allStr, "all", strlen(allStr)) == 0) : false;
2025 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
2026 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
2028 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
2029 SetSentErrorMessage(true);
2030 return false;
2033 if (!allRanks && targetPlayer->HasSpell(spell))
2035 if(targetPlayer == m_session->GetPlayer())
2036 SendSysMessage(LANG_YOU_KNOWN_SPELL);
2037 else
2038 PSendSysMessage(LANG_TARGET_KNOWN_SPELL,GetNameLink(targetPlayer).c_str());
2039 SetSentErrorMessage(true);
2040 return false;
2043 if(allRanks)
2044 targetPlayer->learnSpellHighRank(spell);
2045 else
2046 targetPlayer->learnSpell(spell,false);
2048 uint32 first_spell = sSpellMgr.GetFirstSpellInChain(spell);
2049 if(GetTalentSpellCost(first_spell))
2050 targetPlayer->SendTalentsInfoData(false);
2052 return true;
2055 bool ChatHandler::HandleAddItemCommand(const char* args)
2057 if (!*args)
2058 return false;
2060 uint32 itemId = 0;
2062 if(args[0]=='[') // [name] manual form
2064 char* citemName = strtok((char*)args, "]");
2066 if(citemName && citemName[0])
2068 std::string itemName = citemName+1;
2069 WorldDatabase.escape_string(itemName);
2070 QueryResult *result = WorldDatabase.PQuery("SELECT entry FROM item_template WHERE name = '%s'", itemName.c_str());
2071 if (!result)
2073 PSendSysMessage(LANG_COMMAND_COULDNOTFIND, citemName+1);
2074 SetSentErrorMessage(true);
2075 return false;
2077 itemId = result->Fetch()->GetUInt16();
2078 delete result;
2080 else
2081 return false;
2083 else // item_id or [name] Shift-click form |color|Hitem:item_id:0:0:0|h[name]|h|r
2085 char* cId = extractKeyFromLink((char*)args,"Hitem");
2086 if(!cId)
2087 return false;
2088 itemId = atol(cId);
2091 char* ccount = strtok(NULL, " ");
2093 int32 count = 1;
2095 if (ccount)
2096 count = strtol(ccount, NULL, 10);
2098 if (count == 0)
2099 count = 1;
2101 Player* pl = m_session->GetPlayer();
2102 Player* plTarget = getSelectedPlayer();
2103 if(!plTarget)
2104 plTarget = pl;
2106 sLog.outDetail(GetMangosString(LANG_ADDITEM), itemId, count);
2108 ItemPrototype const *pProto = ObjectMgr::GetItemPrototype(itemId);
2109 if(!pProto)
2111 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId);
2112 SetSentErrorMessage(true);
2113 return false;
2116 //Subtract
2117 if (count < 0)
2119 plTarget->DestroyItemCount(itemId, -count, true, false);
2120 PSendSysMessage(LANG_REMOVEITEM, itemId, -count, GetNameLink(plTarget).c_str());
2121 return true;
2124 //Adding items
2125 uint32 noSpaceForCount = 0;
2127 // check space and find places
2128 ItemPosCountVec dest;
2129 uint8 msg = plTarget->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, itemId, count, &noSpaceForCount );
2130 if( msg != EQUIP_ERR_OK ) // convert to possible store amount
2131 count -= noSpaceForCount;
2133 if( count == 0 || dest.empty()) // can't add any
2135 PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount );
2136 SetSentErrorMessage(true);
2137 return false;
2140 Item* item = plTarget->StoreNewItem( dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId));
2142 // remove binding (let GM give it to another player later)
2143 if(pl==plTarget)
2144 for(ItemPosCountVec::const_iterator itr = dest.begin(); itr != dest.end(); ++itr)
2145 if(Item* item1 = pl->GetItemByPos(itr->pos))
2146 item1->SetBinding( false );
2148 if(count > 0 && item)
2150 pl->SendNewItem(item,count,false,true);
2151 if(pl!=plTarget)
2152 plTarget->SendNewItem(item,count,true,false);
2155 if(noSpaceForCount > 0)
2156 PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount);
2158 return true;
2161 bool ChatHandler::HandleAddItemSetCommand(const char* args)
2163 if (!*args)
2164 return false;
2166 char* cId = extractKeyFromLink((char*)args,"Hitemset"); // number or [name] Shift-click form |color|Hitemset:itemset_id|h[name]|h|r
2167 if (!cId)
2168 return false;
2170 uint32 itemsetId = atol(cId);
2172 // prevent generation all items with itemset field value '0'
2173 if (itemsetId == 0)
2175 PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND,itemsetId);
2176 SetSentErrorMessage(true);
2177 return false;
2180 Player* pl = m_session->GetPlayer();
2181 Player* plTarget = getSelectedPlayer();
2182 if(!plTarget)
2183 plTarget = pl;
2185 sLog.outDetail(GetMangosString(LANG_ADDITEMSET), itemsetId);
2187 bool found = false;
2188 for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
2190 ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype>(id);
2191 if (!pProto)
2192 continue;
2194 if (pProto->ItemSet == itemsetId)
2196 found = true;
2197 ItemPosCountVec dest;
2198 uint8 msg = plTarget->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, pProto->ItemId, 1 );
2199 if (msg == EQUIP_ERR_OK)
2201 Item* item = plTarget->StoreNewItem( dest, pProto->ItemId, true);
2203 // remove binding (let GM give it to another player later)
2204 if (pl==plTarget)
2205 item->SetBinding( false );
2207 pl->SendNewItem(item,1,false,true);
2208 if (pl!=plTarget)
2209 plTarget->SendNewItem(item,1,true,false);
2211 else
2213 pl->SendEquipError( msg, NULL, NULL );
2214 PSendSysMessage(LANG_ITEM_CANNOT_CREATE, pProto->ItemId, 1);
2219 if (!found)
2221 PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND,itemsetId);
2223 SetSentErrorMessage(true);
2224 return false;
2227 return true;
2230 bool ChatHandler::HandleListItemCommand(const char* args)
2232 if(!*args)
2233 return false;
2235 char* cId = extractKeyFromLink((char*)args,"Hitem");
2236 if(!cId)
2237 return false;
2239 uint32 item_id = atol(cId);
2240 if(!item_id)
2242 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
2243 SetSentErrorMessage(true);
2244 return false;
2247 ItemPrototype const* itemProto = ObjectMgr::GetItemPrototype(item_id);
2248 if(!itemProto)
2250 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
2251 SetSentErrorMessage(true);
2252 return false;
2255 char* c_count = strtok(NULL, " ");
2256 int count = c_count ? atol(c_count) : 10;
2258 if(count < 0)
2259 return false;
2261 QueryResult *result;
2263 // inventory case
2264 uint32 inv_count = 0;
2265 result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM character_inventory WHERE item_template='%u'",item_id);
2266 if(result)
2268 inv_count = (*result)[0].GetUInt32();
2269 delete result;
2272 result=CharacterDatabase.PQuery(
2273 // 0 1 2 3 4 5
2274 "SELECT ci.item, cibag.slot AS bag, ci.slot, ci.guid, characters.account,characters.name "
2275 "FROM character_inventory AS ci LEFT JOIN character_inventory AS cibag ON (cibag.item=ci.bag),characters "
2276 "WHERE ci.item_template='%u' AND ci.guid = characters.guid LIMIT %u ",
2277 item_id,uint32(count));
2279 if(result)
2283 Field *fields = result->Fetch();
2284 uint32 item_guid = fields[0].GetUInt32();
2285 uint32 item_bag = fields[1].GetUInt32();
2286 uint32 item_slot = fields[2].GetUInt32();
2287 uint32 owner_guid = fields[3].GetUInt32();
2288 uint32 owner_acc = fields[4].GetUInt32();
2289 std::string owner_name = fields[5].GetCppString();
2291 char const* item_pos = 0;
2292 if(Player::IsEquipmentPos(item_bag,item_slot))
2293 item_pos = "[equipped]";
2294 else if(Player::IsInventoryPos(item_bag,item_slot))
2295 item_pos = "[in inventory]";
2296 else if(Player::IsBankPos(item_bag,item_slot))
2297 item_pos = "[in bank]";
2298 else
2299 item_pos = "";
2301 PSendSysMessage(LANG_ITEMLIST_SLOT,
2302 item_guid,owner_name.c_str(),owner_guid,owner_acc,item_pos);
2303 } while (result->NextRow());
2305 int64 res_count = result->GetRowCount();
2307 delete result;
2309 if(count > res_count)
2310 count-=res_count;
2311 else if(count)
2312 count = 0;
2315 // mail case
2316 uint32 mail_count = 0;
2317 result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM mail_items WHERE item_template='%u'", item_id);
2318 if(result)
2320 mail_count = (*result)[0].GetUInt32();
2321 delete result;
2324 if(count > 0)
2326 result=CharacterDatabase.PQuery(
2327 // 0 1 2 3 4 5 6
2328 "SELECT mail_items.item_guid, mail.sender, mail.receiver, char_s.account, char_s.name, char_r.account, char_r.name "
2329 "FROM mail,mail_items,characters as char_s,characters as char_r "
2330 "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",
2331 item_id,uint32(count));
2333 else
2334 result = NULL;
2336 if(result)
2340 Field *fields = result->Fetch();
2341 uint32 item_guid = fields[0].GetUInt32();
2342 uint32 item_s = fields[1].GetUInt32();
2343 uint32 item_r = fields[2].GetUInt32();
2344 uint32 item_s_acc = fields[3].GetUInt32();
2345 std::string item_s_name = fields[4].GetCppString();
2346 uint32 item_r_acc = fields[5].GetUInt32();
2347 std::string item_r_name = fields[6].GetCppString();
2349 char const* item_pos = "[in mail]";
2351 PSendSysMessage(LANG_ITEMLIST_MAIL,
2352 item_guid,item_s_name.c_str(),item_s,item_s_acc,item_r_name.c_str(),item_r,item_r_acc,item_pos);
2353 } while (result->NextRow());
2355 int64 res_count = result->GetRowCount();
2357 delete result;
2359 if(count > res_count)
2360 count-=res_count;
2361 else if(count)
2362 count = 0;
2365 // auction case
2366 uint32 auc_count = 0;
2367 result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM auctionhouse WHERE item_template='%u'",item_id);
2368 if(result)
2370 auc_count = (*result)[0].GetUInt32();
2371 delete result;
2374 if(count > 0)
2376 result=CharacterDatabase.PQuery(
2377 // 0 1 2 3
2378 "SELECT auctionhouse.itemguid, auctionhouse.itemowner, characters.account, characters.name "
2379 "FROM auctionhouse,characters WHERE auctionhouse.item_template='%u' AND characters.guid = auctionhouse.itemowner LIMIT %u",
2380 item_id,uint32(count));
2382 else
2383 result = NULL;
2385 if(result)
2389 Field *fields = result->Fetch();
2390 uint32 item_guid = fields[0].GetUInt32();
2391 uint32 owner = fields[1].GetUInt32();
2392 uint32 owner_acc = fields[2].GetUInt32();
2393 std::string owner_name = fields[3].GetCppString();
2395 char const* item_pos = "[in auction]";
2397 PSendSysMessage(LANG_ITEMLIST_AUCTION, item_guid, owner_name.c_str(), owner, owner_acc,item_pos);
2398 } while (result->NextRow());
2400 delete result;
2403 // guild bank case
2404 uint32 guild_count = 0;
2405 result=CharacterDatabase.PQuery("SELECT COUNT(item_entry) FROM guild_bank_item WHERE item_entry='%u'",item_id);
2406 if(result)
2408 guild_count = (*result)[0].GetUInt32();
2409 delete result;
2412 result=CharacterDatabase.PQuery(
2413 // 0 1 2
2414 "SELECT gi.item_guid, gi.guildid, guild.name "
2415 "FROM guild_bank_item AS gi, guild WHERE gi.item_entry='%u' AND gi.guildid = guild.guildid LIMIT %u ",
2416 item_id,uint32(count));
2418 if(result)
2422 Field *fields = result->Fetch();
2423 uint32 item_guid = fields[0].GetUInt32();
2424 uint32 guild_guid = fields[1].GetUInt32();
2425 std::string guild_name = fields[2].GetCppString();
2427 char const* item_pos = "[in guild bank]";
2429 PSendSysMessage(LANG_ITEMLIST_GUILD,item_guid,guild_name.c_str(),guild_guid,item_pos);
2430 } while (result->NextRow());
2432 int64 res_count = result->GetRowCount();
2434 delete result;
2436 if(count > res_count)
2437 count-=res_count;
2438 else if(count)
2439 count = 0;
2442 if(inv_count+mail_count+auc_count+guild_count == 0)
2444 SendSysMessage(LANG_COMMAND_NOITEMFOUND);
2445 SetSentErrorMessage(true);
2446 return false;
2449 PSendSysMessage(LANG_COMMAND_LISTITEMMESSAGE,item_id,inv_count+mail_count+auc_count+guild_count,inv_count,mail_count,auc_count,guild_count);
2451 return true;
2454 bool ChatHandler::HandleListObjectCommand(const char* args)
2456 if(!*args)
2457 return false;
2459 // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r
2460 char* cId = extractKeyFromLink((char*)args,"Hgameobject_entry");
2461 if(!cId)
2462 return false;
2464 uint32 go_id = atol(cId);
2465 if(!go_id)
2467 PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id);
2468 SetSentErrorMessage(true);
2469 return false;
2472 GameObjectInfo const * gInfo = ObjectMgr::GetGameObjectInfo(go_id);
2473 if(!gInfo)
2475 PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id);
2476 SetSentErrorMessage(true);
2477 return false;
2480 char* c_count = strtok(NULL, " ");
2481 int count = c_count ? atol(c_count) : 10;
2483 if(count < 0)
2484 return false;
2486 QueryResult *result;
2488 uint32 obj_count = 0;
2489 result=WorldDatabase.PQuery("SELECT COUNT(guid) FROM gameobject WHERE id='%u'",go_id);
2490 if(result)
2492 obj_count = (*result)[0].GetUInt32();
2493 delete result;
2496 if(m_session)
2498 Player* pl = m_session->GetPlayer();
2499 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",
2500 pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),go_id,uint32(count));
2502 else
2503 result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map FROM gameobject WHERE id = '%u' LIMIT %u",
2504 go_id,uint32(count));
2506 if (result)
2510 Field *fields = result->Fetch();
2511 uint32 guid = fields[0].GetUInt32();
2512 float x = fields[1].GetFloat();
2513 float y = fields[2].GetFloat();
2514 float z = fields[3].GetFloat();
2515 int mapid = fields[4].GetUInt16();
2517 if (m_session)
2518 PSendSysMessage(LANG_GO_LIST_CHAT, guid, guid, gInfo->name, x, y, z, mapid);
2519 else
2520 PSendSysMessage(LANG_GO_LIST_CONSOLE, guid, gInfo->name, x, y, z, mapid);
2521 } while (result->NextRow());
2523 delete result;
2526 PSendSysMessage(LANG_COMMAND_LISTOBJMESSAGE,go_id,obj_count);
2527 return true;
2530 bool ChatHandler::HandleListCreatureCommand(const char* args)
2532 if(!*args)
2533 return false;
2535 // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
2536 char* cId = extractKeyFromLink((char*)args,"Hcreature_entry");
2537 if(!cId)
2538 return false;
2540 uint32 cr_id = atol(cId);
2541 if(!cr_id)
2543 PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id);
2544 SetSentErrorMessage(true);
2545 return false;
2548 CreatureInfo const* cInfo = ObjectMgr::GetCreatureTemplate(cr_id);
2549 if(!cInfo)
2551 PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id);
2552 SetSentErrorMessage(true);
2553 return false;
2556 char* c_count = strtok(NULL, " ");
2557 int count = c_count ? atol(c_count) : 10;
2559 if(count < 0)
2560 return false;
2562 QueryResult *result;
2564 uint32 cr_count = 0;
2565 result=WorldDatabase.PQuery("SELECT COUNT(guid) FROM creature WHERE id='%u'",cr_id);
2566 if(result)
2568 cr_count = (*result)[0].GetUInt32();
2569 delete result;
2572 if(m_session)
2574 Player* pl = m_session->GetPlayer();
2575 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",
2576 pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), cr_id,uint32(count));
2578 else
2579 result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map FROM creature WHERE id = '%u' LIMIT %u",
2580 cr_id,uint32(count));
2582 if (result)
2586 Field *fields = result->Fetch();
2587 uint32 guid = fields[0].GetUInt32();
2588 float x = fields[1].GetFloat();
2589 float y = fields[2].GetFloat();
2590 float z = fields[3].GetFloat();
2591 int mapid = fields[4].GetUInt16();
2593 if (m_session)
2594 PSendSysMessage(LANG_CREATURE_LIST_CHAT, guid, guid, cInfo->Name, x, y, z, mapid);
2595 else
2596 PSendSysMessage(LANG_CREATURE_LIST_CONSOLE, guid, cInfo->Name, x, y, z, mapid);
2597 } while (result->NextRow());
2599 delete result;
2602 PSendSysMessage(LANG_COMMAND_LISTCREATUREMESSAGE,cr_id,cr_count);
2603 return true;
2606 bool ChatHandler::HandleLookupItemCommand(const char* args)
2608 if(!*args)
2609 return false;
2611 std::string namepart = args;
2612 std::wstring wnamepart;
2614 // converting string that we try to find to lower case
2615 if(!Utf8toWStr(namepart,wnamepart))
2616 return false;
2618 wstrToLower(wnamepart);
2620 uint32 counter = 0;
2622 // Search in `item_template`
2623 for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
2625 ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype >(id);
2626 if(!pProto)
2627 continue;
2629 int loc_idx = GetSessionDbLocaleIndex();
2630 if ( loc_idx >= 0 )
2632 ItemLocale const *il = sObjectMgr.GetItemLocale(pProto->ItemId);
2633 if (il)
2635 if (il->Name.size() > loc_idx && !il->Name[loc_idx].empty())
2637 std::string name = il->Name[loc_idx];
2639 if (Utf8FitTo(name, wnamepart))
2641 if (m_session)
2642 PSendSysMessage(LANG_ITEM_LIST_CHAT, id, id, name.c_str());
2643 else
2644 PSendSysMessage(LANG_ITEM_LIST_CONSOLE, id, name.c_str());
2645 ++counter;
2646 continue;
2652 std::string name = pProto->Name1;
2653 if(name.empty())
2654 continue;
2656 if (Utf8FitTo(name, wnamepart))
2658 if (m_session)
2659 PSendSysMessage(LANG_ITEM_LIST_CHAT, id, id, name.c_str());
2660 else
2661 PSendSysMessage(LANG_ITEM_LIST_CONSOLE, id, name.c_str());
2662 ++counter;
2666 if (counter==0)
2667 SendSysMessage(LANG_COMMAND_NOITEMFOUND);
2669 return true;
2672 bool ChatHandler::HandleLookupItemSetCommand(const char* args)
2674 if(!*args)
2675 return false;
2677 std::string namepart = args;
2678 std::wstring wnamepart;
2680 if(!Utf8toWStr(namepart,wnamepart))
2681 return false;
2683 // converting string that we try to find to lower case
2684 wstrToLower( wnamepart );
2686 uint32 counter = 0; // Counter for figure out that we found smth.
2688 // Search in ItemSet.dbc
2689 for (uint32 id = 0; id < sItemSetStore.GetNumRows(); id++)
2691 ItemSetEntry const *set = sItemSetStore.LookupEntry(id);
2692 if(set)
2694 int loc = GetSessionDbcLocale();
2695 std::string name = set->name[loc];
2696 if(name.empty())
2697 continue;
2699 if (!Utf8FitTo(name, wnamepart))
2701 loc = 0;
2702 for(; loc < MAX_LOCALE; ++loc)
2704 if(loc==GetSessionDbcLocale())
2705 continue;
2707 name = set->name[loc];
2708 if(name.empty())
2709 continue;
2711 if (Utf8FitTo(name, wnamepart))
2712 break;
2716 if(loc < MAX_LOCALE)
2718 // send item set in "id - [namedlink locale]" format
2719 if (m_session)
2720 PSendSysMessage(LANG_ITEMSET_LIST_CHAT,id,id,name.c_str(),localeNames[loc]);
2721 else
2722 PSendSysMessage(LANG_ITEMSET_LIST_CONSOLE,id,name.c_str(),localeNames[loc]);
2723 ++counter;
2727 if (counter == 0) // if counter == 0 then we found nth
2728 SendSysMessage(LANG_COMMAND_NOITEMSETFOUND);
2729 return true;
2732 bool ChatHandler::HandleLookupSkillCommand(const char* args)
2734 if(!*args)
2735 return false;
2737 // can be NULL in console call
2738 Player* target = getSelectedPlayer();
2740 std::string namepart = args;
2741 std::wstring wnamepart;
2743 if(!Utf8toWStr(namepart,wnamepart))
2744 return false;
2746 // converting string that we try to find to lower case
2747 wstrToLower( wnamepart );
2749 uint32 counter = 0; // Counter for figure out that we found smth.
2751 // Search in SkillLine.dbc
2752 for (uint32 id = 0; id < sSkillLineStore.GetNumRows(); id++)
2754 SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(id);
2755 if(skillInfo)
2757 int loc = GetSessionDbcLocale();
2758 std::string name = skillInfo->name[loc];
2759 if(name.empty())
2760 continue;
2762 if (!Utf8FitTo(name, wnamepart))
2764 loc = 0;
2765 for(; loc < MAX_LOCALE; ++loc)
2767 if(loc==GetSessionDbcLocale())
2768 continue;
2770 name = skillInfo->name[loc];
2771 if(name.empty())
2772 continue;
2774 if (Utf8FitTo(name, wnamepart))
2775 break;
2779 if(loc < MAX_LOCALE)
2781 char valStr[50] = "";
2782 char const* knownStr = "";
2783 if(target && target->HasSkill(id))
2785 knownStr = GetMangosString(LANG_KNOWN);
2786 uint32 curValue = target->GetPureSkillValue(id);
2787 uint32 maxValue = target->GetPureMaxSkillValue(id);
2788 uint32 permValue = target->GetSkillPermBonusValue(id);
2789 uint32 tempValue = target->GetSkillTempBonusValue(id);
2791 char const* valFormat = GetMangosString(LANG_SKILL_VALUES);
2792 snprintf(valStr,50,valFormat,curValue,maxValue,permValue,tempValue);
2795 // send skill in "id - [namedlink locale]" format
2796 if (m_session)
2797 PSendSysMessage(LANG_SKILL_LIST_CHAT,id,id,name.c_str(),localeNames[loc],knownStr,valStr);
2798 else
2799 PSendSysMessage(LANG_SKILL_LIST_CONSOLE,id,name.c_str(),localeNames[loc],knownStr,valStr);
2801 ++counter;
2805 if (counter == 0) // if counter == 0 then we found nth
2806 SendSysMessage(LANG_COMMAND_NOSKILLFOUND);
2807 return true;
2810 bool ChatHandler::HandleLookupSpellCommand(const char* args)
2812 if(!*args)
2813 return false;
2815 // can be NULL at console call
2816 Player* target = getSelectedPlayer();
2818 std::string namepart = args;
2819 std::wstring wnamepart;
2821 if(!Utf8toWStr(namepart,wnamepart))
2822 return false;
2824 // converting string that we try to find to lower case
2825 wstrToLower( wnamepart );
2827 uint32 counter = 0; // Counter for figure out that we found smth.
2829 // Search in Spell.dbc
2830 for (uint32 id = 0; id < sSpellStore.GetNumRows(); id++)
2832 SpellEntry const *spellInfo = sSpellStore.LookupEntry(id);
2833 if(spellInfo)
2835 int loc = GetSessionDbcLocale();
2836 std::string name = spellInfo->SpellName[loc];
2837 if(name.empty())
2838 continue;
2840 if (!Utf8FitTo(name, wnamepart))
2842 loc = 0;
2843 for(; loc < MAX_LOCALE; ++loc)
2845 if(loc==GetSessionDbcLocale())
2846 continue;
2848 name = spellInfo->SpellName[loc];
2849 if(name.empty())
2850 continue;
2852 if (Utf8FitTo(name, wnamepart))
2853 break;
2857 if(loc < MAX_LOCALE)
2859 bool known = target && target->HasSpell(id);
2860 bool learn = (spellInfo->Effect[0] == SPELL_EFFECT_LEARN_SPELL);
2862 uint32 talentCost = GetTalentSpellCost(id);
2864 bool talent = (talentCost > 0);
2865 bool passive = IsPassiveSpell(id);
2866 bool active = target && target->HasAura(id);
2868 // unit32 used to prevent interpreting uint8 as char at output
2869 // find rank of learned spell for learning spell, or talent rank
2870 uint32 rank = talentCost ? talentCost : sSpellMgr.GetSpellRank(learn ? spellInfo->EffectTriggerSpell[0] : id);
2872 // send spell in "id - [name, rank N] [talent] [passive] [learn] [known]" format
2873 std::ostringstream ss;
2874 if (m_session)
2875 ss << id << " - |cffffffff|Hspell:" << id << "|h[" << name;
2876 else
2877 ss << id << " - " << name;
2879 // include rank in link name
2880 if(rank)
2881 ss << GetMangosString(LANG_SPELL_RANK) << rank;
2883 if (m_session)
2884 ss << " " << localeNames[loc] << "]|h|r";
2885 else
2886 ss << " " << localeNames[loc];
2888 if(talent)
2889 ss << GetMangosString(LANG_TALENT);
2890 if(passive)
2891 ss << GetMangosString(LANG_PASSIVE);
2892 if(learn)
2893 ss << GetMangosString(LANG_LEARN);
2894 if(known)
2895 ss << GetMangosString(LANG_KNOWN);
2896 if(active)
2897 ss << GetMangosString(LANG_ACTIVE);
2899 SendSysMessage(ss.str().c_str());
2901 ++counter;
2905 if (counter == 0) // if counter == 0 then we found nth
2906 SendSysMessage(LANG_COMMAND_NOSPELLFOUND);
2907 return true;
2910 bool ChatHandler::HandleLookupQuestCommand(const char* args)
2912 if(!*args)
2913 return false;
2915 // can be NULL at console call
2916 Player* target = getSelectedPlayer();
2918 std::string namepart = args;
2919 std::wstring wnamepart;
2921 // converting string that we try to find to lower case
2922 if(!Utf8toWStr(namepart,wnamepart))
2923 return false;
2925 wstrToLower(wnamepart);
2927 uint32 counter = 0 ;
2929 ObjectMgr::QuestMap const& qTemplates = sObjectMgr.GetQuestTemplates();
2930 for (ObjectMgr::QuestMap::const_iterator iter = qTemplates.begin(); iter != qTemplates.end(); ++iter)
2932 Quest * qinfo = iter->second;
2934 int loc_idx = GetSessionDbLocaleIndex();
2935 if ( loc_idx >= 0 )
2937 QuestLocale const *il = sObjectMgr.GetQuestLocale(qinfo->GetQuestId());
2938 if (il)
2940 if (il->Title.size() > loc_idx && !il->Title[loc_idx].empty())
2942 std::string title = il->Title[loc_idx];
2944 if (Utf8FitTo(title, wnamepart))
2946 char const* statusStr = "";
2948 if(target)
2950 QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId());
2952 if(status == QUEST_STATUS_COMPLETE)
2954 if(target->GetQuestRewardStatus(qinfo->GetQuestId()))
2955 statusStr = GetMangosString(LANG_COMMAND_QUEST_REWARDED);
2956 else
2957 statusStr = GetMangosString(LANG_COMMAND_QUEST_COMPLETE);
2959 else if(status == QUEST_STATUS_INCOMPLETE)
2960 statusStr = GetMangosString(LANG_COMMAND_QUEST_ACTIVE);
2963 if (m_session)
2964 PSendSysMessage(LANG_QUEST_LIST_CHAT,qinfo->GetQuestId(),qinfo->GetQuestId(),qinfo->GetQuestLevel(),title.c_str(),statusStr);
2965 else
2966 PSendSysMessage(LANG_QUEST_LIST_CONSOLE,qinfo->GetQuestId(),title.c_str(),statusStr);
2967 ++counter;
2968 continue;
2974 std::string title = qinfo->GetTitle();
2975 if(title.empty())
2976 continue;
2978 if (Utf8FitTo(title, wnamepart))
2980 char const* statusStr = "";
2982 if(target)
2984 QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId());
2986 if(status == QUEST_STATUS_COMPLETE)
2988 if(target->GetQuestRewardStatus(qinfo->GetQuestId()))
2989 statusStr = GetMangosString(LANG_COMMAND_QUEST_REWARDED);
2990 else
2991 statusStr = GetMangosString(LANG_COMMAND_QUEST_COMPLETE);
2993 else if(status == QUEST_STATUS_INCOMPLETE)
2994 statusStr = GetMangosString(LANG_COMMAND_QUEST_ACTIVE);
2997 if (m_session)
2998 PSendSysMessage(LANG_QUEST_LIST_CHAT,qinfo->GetQuestId(),qinfo->GetQuestId(),qinfo->GetQuestLevel(),title.c_str(),statusStr);
2999 else
3000 PSendSysMessage(LANG_QUEST_LIST_CONSOLE,qinfo->GetQuestId(),title.c_str(),statusStr);
3002 ++counter;
3006 if (counter==0)
3007 SendSysMessage(LANG_COMMAND_NOQUESTFOUND);
3009 return true;
3012 bool ChatHandler::HandleLookupCreatureCommand(const char* args)
3014 if (!*args)
3015 return false;
3017 std::string namepart = args;
3018 std::wstring wnamepart;
3020 // converting string that we try to find to lower case
3021 if (!Utf8toWStr (namepart,wnamepart))
3022 return false;
3024 wstrToLower (wnamepart);
3026 uint32 counter = 0;
3028 for (uint32 id = 0; id< sCreatureStorage.MaxEntry; ++id)
3030 CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo> (id);
3031 if(!cInfo)
3032 continue;
3034 int loc_idx = GetSessionDbLocaleIndex();
3035 if (loc_idx >= 0)
3037 CreatureLocale const *cl = sObjectMgr.GetCreatureLocale (id);
3038 if (cl)
3040 if (cl->Name.size() > loc_idx && !cl->Name[loc_idx].empty ())
3042 std::string name = cl->Name[loc_idx];
3044 if (Utf8FitTo (name, wnamepart))
3046 if (m_session)
3047 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CHAT, id, id, name.c_str ());
3048 else
3049 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CONSOLE, id, name.c_str ());
3050 ++counter;
3051 continue;
3057 std::string name = cInfo->Name;
3058 if (name.empty ())
3059 continue;
3061 if (Utf8FitTo(name, wnamepart))
3063 if (m_session)
3064 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CHAT, id, id, name.c_str ());
3065 else
3066 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CONSOLE, id, name.c_str ());
3067 ++counter;
3071 if (counter==0)
3072 SendSysMessage (LANG_COMMAND_NOCREATUREFOUND);
3074 return true;
3077 bool ChatHandler::HandleLookupObjectCommand(const char* args)
3079 if(!*args)
3080 return false;
3082 std::string namepart = args;
3083 std::wstring wnamepart;
3085 // converting string that we try to find to lower case
3086 if(!Utf8toWStr(namepart,wnamepart))
3087 return false;
3089 wstrToLower(wnamepart);
3091 uint32 counter = 0;
3093 for (uint32 id = 0; id< sGOStorage.MaxEntry; id++ )
3095 GameObjectInfo const* gInfo = sGOStorage.LookupEntry<GameObjectInfo>(id);
3096 if(!gInfo)
3097 continue;
3099 int loc_idx = GetSessionDbLocaleIndex();
3100 if ( loc_idx >= 0 )
3102 GameObjectLocale const *gl = sObjectMgr.GetGameObjectLocale(id);
3103 if (gl)
3105 if (gl->Name.size() > loc_idx && !gl->Name[loc_idx].empty())
3107 std::string name = gl->Name[loc_idx];
3109 if (Utf8FitTo(name, wnamepart))
3111 if (m_session)
3112 PSendSysMessage(LANG_GO_ENTRY_LIST_CHAT, id, id, name.c_str());
3113 else
3114 PSendSysMessage(LANG_GO_ENTRY_LIST_CONSOLE, id, name.c_str());
3115 ++counter;
3116 continue;
3122 std::string name = gInfo->name;
3123 if(name.empty())
3124 continue;
3126 if(Utf8FitTo(name, wnamepart))
3128 if (m_session)
3129 PSendSysMessage(LANG_GO_ENTRY_LIST_CHAT, id, id, name.c_str());
3130 else
3131 PSendSysMessage(LANG_GO_ENTRY_LIST_CONSOLE, id, name.c_str());
3132 ++counter;
3136 if(counter==0)
3137 SendSysMessage(LANG_COMMAND_NOGAMEOBJECTFOUND);
3139 return true;
3142 bool ChatHandler::HandleLookupTaxiNodeCommand(const char * args)
3144 if(!*args)
3145 return false;
3147 std::string namepart = args;
3148 std::wstring wnamepart;
3150 if(!Utf8toWStr(namepart,wnamepart))
3151 return false;
3153 // converting string that we try to find to lower case
3154 wstrToLower( wnamepart );
3156 uint32 counter = 0; // Counter for figure out that we found smth.
3158 // Search in TaxiNodes.dbc
3159 for (uint32 id = 0; id < sTaxiNodesStore.GetNumRows(); id++)
3161 TaxiNodesEntry const *nodeEntry = sTaxiNodesStore.LookupEntry(id);
3162 if(nodeEntry)
3164 int loc = GetSessionDbcLocale();
3165 std::string name = nodeEntry->name[loc];
3166 if(name.empty())
3167 continue;
3169 if (!Utf8FitTo(name, wnamepart))
3171 loc = 0;
3172 for(; loc < MAX_LOCALE; ++loc)
3174 if(loc==GetSessionDbcLocale())
3175 continue;
3177 name = nodeEntry->name[loc];
3178 if(name.empty())
3179 continue;
3181 if (Utf8FitTo(name, wnamepart))
3182 break;
3186 if(loc < MAX_LOCALE)
3188 // send taxinode in "id - [name] (Map:m X:x Y:y Z:z)" format
3189 if (m_session)
3190 PSendSysMessage (LANG_TAXINODE_ENTRY_LIST_CHAT, id, id, name.c_str(),localeNames[loc],
3191 nodeEntry->map_id,nodeEntry->x,nodeEntry->y,nodeEntry->z);
3192 else
3193 PSendSysMessage (LANG_TAXINODE_ENTRY_LIST_CONSOLE, id, name.c_str(), localeNames[loc],
3194 nodeEntry->map_id,nodeEntry->x,nodeEntry->y,nodeEntry->z);
3195 ++counter;
3199 if (counter == 0) // if counter == 0 then we found nth
3200 SendSysMessage(LANG_COMMAND_NOTAXINODEFOUND);
3201 return true;
3204 /** \brief GM command level 3 - Create a guild.
3206 * This command allows a GM (level 3) to create a guild.
3208 * The "args" parameter contains the name of the guild leader
3209 * and then the name of the guild.
3212 bool ChatHandler::HandleGuildCreateCommand(const char* args)
3214 if(!*args)
3215 return false;
3217 // if not guild name only (in "") then player name
3218 Player* target;
3219 if(!extractPlayerTarget(*args!='"' ? (char*)args : NULL, &target))
3220 return false;
3222 char* tailStr = *args!='"' ? strtok(NULL, "") : (char*)args;
3223 if(!tailStr)
3224 return false;
3226 char* guildStr = extractQuotedArg(tailStr);
3227 if(!guildStr)
3228 return false;
3230 std::string guildname = guildStr;
3232 if (target->GetGuildId())
3234 SendSysMessage (LANG_PLAYER_IN_GUILD);
3235 return true;
3238 Guild *guild = new Guild;
3239 if (!guild->Create (target,guildname))
3241 delete guild;
3242 SendSysMessage (LANG_GUILD_NOT_CREATED);
3243 SetSentErrorMessage (true);
3244 return false;
3247 sObjectMgr.AddGuild (guild);
3248 return true;
3251 bool ChatHandler::HandleGuildInviteCommand(const char *args)
3253 if(!*args)
3254 return false;
3256 // if not guild name only (in "") then player name
3257 uint64 target_guid;
3258 if(!extractPlayerTarget(*args!='"' ? (char*)args : NULL, NULL, &target_guid))
3259 return false;
3261 char* tailStr = *args!='"' ? strtok(NULL, "") : (char*)args;
3262 if(!tailStr)
3263 return false;
3265 char* guildStr = extractQuotedArg(tailStr);
3266 if(!guildStr)
3267 return false;
3269 std::string glName = guildStr;
3270 Guild* targetGuild = sObjectMgr.GetGuildByName (glName);
3271 if (!targetGuild)
3272 return false;
3274 // player's guild membership checked in AddMember before add
3275 if (!targetGuild->AddMember (target_guid,targetGuild->GetLowestRank ()))
3276 return false;
3278 return true;
3281 bool ChatHandler::HandleGuildUninviteCommand(const char *args)
3283 Player* target;
3284 uint64 target_guid;
3285 if(!extractPlayerTarget((char*)args,&target,&target_guid))
3286 return false;
3288 uint32 glId = target ? target->GetGuildId () : Player::GetGuildIdFromDB (target_guid);
3289 if (!glId)
3290 return false;
3292 Guild* targetGuild = sObjectMgr.GetGuildById (glId);
3293 if (!targetGuild)
3294 return false;
3296 targetGuild->DelMember (target_guid);
3297 return true;
3300 bool ChatHandler::HandleGuildRankCommand(const char *args)
3302 char* nameStr;
3303 char* rankStr;
3304 extractOptFirstArg((char*)args,&nameStr,&rankStr);
3305 if(!rankStr)
3306 return false;
3308 Player* target;
3309 uint64 target_guid;
3310 std::string target_name;
3311 if(!extractPlayerTarget(nameStr,&target,&target_guid,&target_name))
3312 return false;
3314 uint32 glId = target ? target->GetGuildId () : Player::GetGuildIdFromDB (target_guid);
3315 if (!glId)
3316 return false;
3318 Guild* targetGuild = sObjectMgr.GetGuildById (glId);
3319 if (!targetGuild)
3320 return false;
3322 uint32 newrank = uint32 (atoi (rankStr));
3323 if (newrank > targetGuild->GetLowestRank ())
3324 return false;
3326 targetGuild->ChangeRank (target_guid,newrank);
3327 return true;
3330 bool ChatHandler::HandleGuildDeleteCommand(const char* args)
3332 if (!*args)
3333 return false;
3335 char* guildStr = extractQuotedArg((char*)args);
3336 if(!guildStr)
3337 return false;
3339 std::string gld = guildStr;
3341 Guild* targetGuild = sObjectMgr.GetGuildByName (gld);
3342 if (!targetGuild)
3343 return false;
3345 targetGuild->Disband ();
3347 return true;
3350 bool ChatHandler::HandleGetDistanceCommand(const char* args)
3352 WorldObject* obj = NULL;
3354 if (*args)
3356 uint64 guid = extractGuidFromLink((char*)args);
3357 if(guid)
3358 obj = (WorldObject*)ObjectAccessor::GetObjectByTypeMask(*m_session->GetPlayer(),guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
3360 if(!obj)
3362 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3363 SetSentErrorMessage(true);
3364 return false;
3367 else
3369 obj = getSelectedUnit();
3371 if(!obj)
3373 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3374 SetSentErrorMessage(true);
3375 return false;
3379 PSendSysMessage(LANG_DISTANCE, m_session->GetPlayer()->GetDistance(obj),m_session->GetPlayer()->GetDistance2d(obj));
3381 return true;
3384 bool ChatHandler::HandleDieCommand(const char* /*args*/)
3386 Unit* target = getSelectedUnit();
3388 if(!target || !m_session->GetPlayer()->GetSelection())
3390 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3391 SetSentErrorMessage(true);
3392 return false;
3395 if(target->GetTypeId()==TYPEID_PLAYER)
3397 if(HasLowerSecurity((Player*)target,0,false))
3398 return false;
3401 if( target->isAlive() )
3403 m_session->GetPlayer()->DealDamage(target, target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
3406 return true;
3409 bool ChatHandler::HandleDamageCommand(const char * args)
3411 if (!*args)
3412 return false;
3414 Unit* target = getSelectedUnit();
3416 if (!target || !m_session->GetPlayer()->GetSelection())
3418 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3419 SetSentErrorMessage(true);
3420 return false;
3423 if (!target->isAlive())
3424 return true;
3426 char* damageStr = strtok((char*)args, " ");
3427 if (!damageStr)
3428 return false;
3430 int32 damage_int = atoi((char*)damageStr);
3431 if(damage_int <=0)
3432 return true;
3434 uint32 damage = damage_int;
3436 char* schoolStr = strtok((char*)NULL, " ");
3438 // flat melee damage without resistence/etc reduction
3439 if (!schoolStr)
3441 m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
3442 if (target != m_session->GetPlayer())
3443 m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, SPELL_SCHOOL_MASK_NORMAL, damage, 0, 0, VICTIMSTATE_NORMAL, 0);
3444 return true;
3447 uint32 school = schoolStr ? atoi((char*)schoolStr) : SPELL_SCHOOL_NORMAL;
3448 if(school >= MAX_SPELL_SCHOOL)
3449 return false;
3451 SpellSchoolMask schoolmask = SpellSchoolMask(1 << school);
3453 if ( schoolmask & SPELL_SCHOOL_MASK_NORMAL )
3454 damage = m_session->GetPlayer()->CalcArmorReducedDamage(target, damage);
3456 char* spellStr = strtok((char*)NULL, " ");
3458 // melee damage by specific school
3459 if (!spellStr)
3461 uint32 absorb = 0;
3462 uint32 resist = 0;
3464 m_session->GetPlayer()->CalcAbsorbResist(target,schoolmask, SPELL_DIRECT_DAMAGE, damage, &absorb, &resist);
3466 if (damage <= absorb + resist)
3467 return true;
3469 damage -= absorb + resist;
3471 m_session->GetPlayer()->DealDamageMods(target,damage,&absorb);
3472 m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, schoolmask, NULL, false);
3473 m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, schoolmask, damage, absorb, resist, VICTIMSTATE_NORMAL, 0);
3474 return true;
3477 // non-melee damage
3479 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
3480 uint32 spellid = extractSpellIdFromLink((char*)args);
3481 if (!spellid || !sSpellStore.LookupEntry(spellid))
3482 return false;
3484 m_session->GetPlayer()->SpellNonMeleeDamageLog(target, spellid, damage);
3485 return true;
3488 bool ChatHandler::HandleModifyArenaCommand(const char * args)
3490 if (!*args)
3491 return false;
3493 Player *target = getSelectedPlayer();
3494 if(!target)
3496 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3497 SetSentErrorMessage(true);
3498 return false;
3501 int32 amount = (uint32)atoi(args);
3503 target->ModifyArenaPoints(amount);
3505 PSendSysMessage(LANG_COMMAND_MODIFY_ARENA, GetNameLink(target).c_str(), target->GetArenaPoints());
3507 return true;
3510 bool ChatHandler::HandleReviveCommand(const char* args)
3512 Player* target;
3513 uint64 target_guid;
3514 if(!extractPlayerTarget((char*)args,&target,&target_guid))
3515 return false;
3517 if (target)
3519 target->ResurrectPlayer(0.5f);
3520 target->SpawnCorpseBones();
3522 else
3523 // will resurrected at login without corpse
3524 sObjectAccessor.ConvertCorpseForPlayer(target_guid);
3526 return true;
3529 bool ChatHandler::HandleAuraCommand(const char* args)
3531 Unit *target = getSelectedUnit();
3532 if(!target)
3534 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3535 SetSentErrorMessage(true);
3536 return false;
3539 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
3540 uint32 spellID = extractSpellIdFromLink((char*)args);
3542 SpellEntry const *spellInfo = sSpellStore.LookupEntry( spellID );
3543 if(spellInfo)
3545 for(uint32 i = 0;i<3;++i)
3547 uint8 eff = spellInfo->Effect[i];
3548 if (eff>=TOTAL_SPELL_EFFECTS)
3549 continue;
3550 if( IsAreaAuraEffect(eff) ||
3551 eff == SPELL_EFFECT_APPLY_AURA ||
3552 eff == SPELL_EFFECT_PERSISTENT_AREA_AURA )
3554 Aura *Aur = CreateAura(spellInfo, i, NULL, target);
3555 target->AddAura(Aur);
3560 return true;
3563 bool ChatHandler::HandleUnAuraCommand(const char* args)
3565 Unit *target = getSelectedUnit();
3566 if(!target)
3568 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3569 SetSentErrorMessage(true);
3570 return false;
3573 std::string argstr = args;
3574 if (argstr == "all")
3576 target->RemoveAllAuras();
3577 return true;
3580 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
3581 uint32 spellID = extractSpellIdFromLink((char*)args);
3582 if(!spellID)
3583 return false;
3585 target->RemoveAurasDueToSpell(spellID);
3587 return true;
3590 bool ChatHandler::HandleLinkGraveCommand(const char* args)
3592 if(!*args)
3593 return false;
3595 char* px = strtok((char*)args, " ");
3596 if (!px)
3597 return false;
3599 uint32 g_id = (uint32)atoi(px);
3601 uint32 g_team;
3603 char* px2 = strtok(NULL, " ");
3605 if (!px2)
3606 g_team = 0;
3607 else if (strncmp(px2,"horde",6)==0)
3608 g_team = HORDE;
3609 else if (strncmp(px2,"alliance",9)==0)
3610 g_team = ALLIANCE;
3611 else
3612 return false;
3614 WorldSafeLocsEntry const* graveyard = sWorldSafeLocsStore.LookupEntry(g_id);
3616 if(!graveyard )
3618 PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST, g_id);
3619 SetSentErrorMessage(true);
3620 return false;
3623 Player* player = m_session->GetPlayer();
3625 uint32 zoneId = player->GetZoneId();
3627 AreaTableEntry const *areaEntry = GetAreaEntryByAreaID(zoneId);
3628 if(!areaEntry || areaEntry->zone !=0 )
3630 PSendSysMessage(LANG_COMMAND_GRAVEYARDWRONGZONE, g_id,zoneId);
3631 SetSentErrorMessage(true);
3632 return false;
3635 if(sObjectMgr.AddGraveYardLink(g_id,zoneId,g_team))
3636 PSendSysMessage(LANG_COMMAND_GRAVEYARDLINKED, g_id,zoneId);
3637 else
3638 PSendSysMessage(LANG_COMMAND_GRAVEYARDALRLINKED, g_id,zoneId);
3640 return true;
3643 bool ChatHandler::HandleNearGraveCommand(const char* args)
3645 uint32 g_team;
3647 size_t argslen = strlen(args);
3649 if(!*args)
3650 g_team = 0;
3651 else if (strncmp((char*)args,"horde",argslen)==0)
3652 g_team = HORDE;
3653 else if (strncmp((char*)args,"alliance",argslen)==0)
3654 g_team = ALLIANCE;
3655 else
3656 return false;
3658 Player* player = m_session->GetPlayer();
3659 uint32 zone_id = player->GetZoneId();
3661 WorldSafeLocsEntry const* graveyard = sObjectMgr.GetClosestGraveYard(
3662 player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(),player->GetMapId(),g_team);
3664 if(graveyard)
3666 uint32 g_id = graveyard->ID;
3668 GraveYardData const* data = sObjectMgr.FindGraveYardData(g_id,zone_id);
3669 if (!data)
3671 PSendSysMessage(LANG_COMMAND_GRAVEYARDERROR,g_id);
3672 SetSentErrorMessage(true);
3673 return false;
3676 g_team = data->team;
3678 std::string team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_NOTEAM);
3680 if(g_team == 0)
3681 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ANY);
3682 else if(g_team == HORDE)
3683 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_HORDE);
3684 else if(g_team == ALLIANCE)
3685 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ALLIANCE);
3687 PSendSysMessage(LANG_COMMAND_GRAVEYARDNEAREST, g_id,team_name.c_str(),zone_id);
3689 else
3691 std::string team_name;
3693 if(g_team == 0)
3694 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ANY);
3695 else if(g_team == HORDE)
3696 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_HORDE);
3697 else if(g_team == ALLIANCE)
3698 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ALLIANCE);
3700 if(g_team == ~uint32(0))
3701 PSendSysMessage(LANG_COMMAND_ZONENOGRAVEYARDS, zone_id);
3702 else
3703 PSendSysMessage(LANG_COMMAND_ZONENOGRAFACTION, zone_id,team_name.c_str());
3706 return true;
3709 //-----------------------Npc Commands-----------------------
3710 bool ChatHandler::HandleNpcAllowMovementCommand(const char* /*args*/)
3712 if(sWorld.getAllowMovement())
3714 sWorld.SetAllowMovement(false);
3715 SendSysMessage(LANG_CREATURE_MOVE_DISABLED);
3717 else
3719 sWorld.SetAllowMovement(true);
3720 SendSysMessage(LANG_CREATURE_MOVE_ENABLED);
3722 return true;
3725 bool ChatHandler::HandleNpcChangeEntryCommand(const char *args)
3727 if (!*args)
3728 return false;
3730 uint32 newEntryNum = atoi(args);
3731 if(!newEntryNum)
3732 return false;
3734 Unit* unit = getSelectedUnit();
3735 if(!unit || unit->GetTypeId() != TYPEID_UNIT)
3737 SendSysMessage(LANG_SELECT_CREATURE);
3738 SetSentErrorMessage(true);
3739 return false;
3741 Creature* creature = (Creature*)unit;
3742 if(creature->UpdateEntry(newEntryNum))
3743 SendSysMessage(LANG_DONE);
3744 else
3745 SendSysMessage(LANG_ERROR);
3746 return true;
3749 bool ChatHandler::HandleNpcInfoCommand(const char* /*args*/)
3751 Creature* target = getSelectedCreature();
3753 if(!target)
3755 SendSysMessage(LANG_SELECT_CREATURE);
3756 SetSentErrorMessage(true);
3757 return false;
3760 uint32 faction = target->getFaction();
3761 uint32 npcflags = target->GetUInt32Value(UNIT_NPC_FLAGS);
3762 uint32 displayid = target->GetDisplayId();
3763 uint32 nativeid = target->GetNativeDisplayId();
3764 uint32 Entry = target->GetEntry();
3765 CreatureInfo const* cInfo = target->GetCreatureInfo();
3767 int32 curRespawnDelay = target->GetRespawnTimeEx()-time(NULL);
3768 if(curRespawnDelay < 0)
3769 curRespawnDelay = 0;
3770 std::string curRespawnDelayStr = secsToTimeString(curRespawnDelay,true);
3771 std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(),true);
3773 PSendSysMessage(LANG_NPCINFO_CHAR, target->GetDBTableGUIDLow(), faction, npcflags, Entry, displayid, nativeid);
3774 PSendSysMessage(LANG_NPCINFO_LEVEL, target->getLevel());
3775 PSendSysMessage(LANG_NPCINFO_HEALTH,target->GetCreateHealth(), target->GetMaxHealth(), target->GetHealth());
3776 PSendSysMessage(LANG_NPCINFO_FLAGS, target->GetUInt32Value(UNIT_FIELD_FLAGS), target->GetUInt32Value(UNIT_DYNAMIC_FLAGS), target->getFaction());
3777 PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES, defRespawnDelayStr.c_str(),curRespawnDelayStr.c_str());
3778 PSendSysMessage(LANG_NPCINFO_LOOT, cInfo->lootid,cInfo->pickpocketLootId,cInfo->SkinLootId);
3779 PSendSysMessage(LANG_NPCINFO_DUNGEON_ID, target->GetInstanceId());
3780 PSendSysMessage(LANG_NPCINFO_POSITION,float(target->GetPositionX()), float(target->GetPositionY()), float(target->GetPositionZ()));
3782 if ((npcflags & UNIT_NPC_FLAG_VENDOR) )
3784 SendSysMessage(LANG_NPCINFO_VENDOR);
3786 if ((npcflags & UNIT_NPC_FLAG_TRAINER) )
3788 SendSysMessage(LANG_NPCINFO_TRAINER);
3791 return true;
3794 //play npc emote
3795 bool ChatHandler::HandleNpcPlayEmoteCommand(const char* args)
3797 uint32 emote = atoi((char*)args);
3799 Creature* target = getSelectedCreature();
3800 if(!target)
3802 SendSysMessage(LANG_SELECT_CREATURE);
3803 SetSentErrorMessage(true);
3804 return false;
3807 target->SetUInt32Value(UNIT_NPC_EMOTESTATE,emote);
3809 return true;
3812 //TODO: NpcCommands that needs to be fixed :
3814 bool ChatHandler::HandleNpcAddWeaponCommand(const char* /*args*/)
3816 /*if (!*args)
3817 return false;
3819 uint64 guid = m_session->GetPlayer()->GetSelection();
3820 if (guid == 0)
3822 SendSysMessage(LANG_NO_SELECTION);
3823 return true;
3826 Creature *pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
3828 if(!pCreature)
3830 SendSysMessage(LANG_SELECT_CREATURE);
3831 return true;
3834 char* pSlotID = strtok((char*)args, " ");
3835 if (!pSlotID)
3836 return false;
3838 char* pItemID = strtok(NULL, " ");
3839 if (!pItemID)
3840 return false;
3842 uint32 ItemID = atoi(pItemID);
3843 uint32 SlotID = atoi(pSlotID);
3845 ItemPrototype* tmpItem = ObjectMgr::GetItemPrototype(ItemID);
3847 bool added = false;
3848 if(tmpItem)
3850 switch(SlotID)
3852 case 1:
3853 pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, ItemID);
3854 added = true;
3855 break;
3856 case 2:
3857 pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_01, ItemID);
3858 added = true;
3859 break;
3860 case 3:
3861 pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_02, ItemID);
3862 added = true;
3863 break;
3864 default:
3865 PSendSysMessage(LANG_ITEM_SLOT_NOT_EXIST,SlotID);
3866 added = false;
3867 break;
3870 if(added)
3871 PSendSysMessage(LANG_ITEM_ADDED_TO_SLOT,ItemID,tmpItem->Name1,SlotID);
3873 else
3875 PSendSysMessage(LANG_ITEM_NOT_FOUND,ItemID);
3876 return true;
3879 return true;
3881 //----------------------------------------------------------
3883 bool ChatHandler::HandleExploreCheatCommand(const char* args)
3885 if (!*args)
3886 return false;
3888 int flag = atoi((char*)args);
3890 Player *chr = getSelectedPlayer();
3891 if (chr == NULL)
3893 SendSysMessage(LANG_NO_CHAR_SELECTED);
3894 SetSentErrorMessage(true);
3895 return false;
3898 if (flag != 0)
3900 PSendSysMessage(LANG_YOU_SET_EXPLORE_ALL, GetNameLink(chr).c_str());
3901 if (needReportToTarget(chr))
3902 ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_ALL,GetNameLink().c_str());
3904 else
3906 PSendSysMessage(LANG_YOU_SET_EXPLORE_NOTHING, GetNameLink(chr).c_str());
3907 if (needReportToTarget(chr))
3908 ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_NOTHING,GetNameLink().c_str());
3911 for (uint8 i=0; i<128; ++i)
3913 if (flag != 0)
3915 m_session->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i,0xFFFFFFFF);
3917 else
3919 m_session->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i,0);
3923 return true;
3926 bool ChatHandler::HandleHoverCommand(const char* args)
3928 char* px = strtok((char*)args, " ");
3929 uint32 flag;
3930 if (!px)
3931 flag = 1;
3932 else
3933 flag = atoi(px);
3935 m_session->GetPlayer()->SetHover(flag);
3937 if (flag)
3938 SendSysMessage(LANG_HOVER_ENABLED);
3939 else
3940 SendSysMessage(LANG_HOVER_DISABLED);
3942 return true;
3945 void ChatHandler::HandleCharacterLevel(Player* player, uint64 player_guid, uint32 oldlevel, uint32 newlevel)
3947 if(player)
3949 player->GiveLevel(newlevel);
3950 player->InitTalentForLevel();
3951 player->SetUInt32Value(PLAYER_XP,0);
3953 if(needReportToTarget(player))
3955 if(oldlevel == newlevel)
3956 ChatHandler(player).PSendSysMessage(LANG_YOURS_LEVEL_PROGRESS_RESET,GetNameLink().c_str());
3957 else if(oldlevel < newlevel)
3958 ChatHandler(player).PSendSysMessage(LANG_YOURS_LEVEL_UP,GetNameLink().c_str(),newlevel);
3959 else // if(oldlevel > newlevel)
3960 ChatHandler(player).PSendSysMessage(LANG_YOURS_LEVEL_DOWN,GetNameLink().c_str(),newlevel);
3963 else
3965 // update level and XP at level, all other will be updated at loading
3966 CharacterDatabase.PExecute("UPDATE characters SET level = '%u', xp = 0 WHERE guid = '%u'", newlevel, GUID_LOPART(player_guid));
3970 bool ChatHandler::HandleCharacterLevelCommand(const char* args)
3972 char* nameStr;
3973 char* levelStr;
3974 extractOptFirstArg((char*)args,&nameStr,&levelStr);
3975 if(!levelStr)
3976 return false;
3978 // exception opt second arg: .character level $name
3979 if(isalpha(levelStr[0]))
3981 nameStr = levelStr;
3982 levelStr = NULL; // current level will used
3985 Player* target;
3986 uint64 target_guid;
3987 std::string target_name;
3988 if(!extractPlayerTarget(nameStr,&target,&target_guid,&target_name))
3989 return false;
3991 int32 oldlevel = target ? target->getLevel() : Player::GetLevelFromDB(target_guid);
3992 int32 newlevel = levelStr ? atoi(levelStr) : oldlevel;
3994 if(newlevel < 1)
3995 return false; // invalid level
3997 if(newlevel > STRONG_MAX_LEVEL) // hardcoded maximum level
3998 newlevel = STRONG_MAX_LEVEL;
4000 HandleCharacterLevel(target,target_guid,oldlevel,newlevel);
4002 if(!m_session || m_session->GetPlayer() != target) // including player==NULL
4004 std::string nameLink = playerLink(target_name);
4005 PSendSysMessage(LANG_YOU_CHANGE_LVL,nameLink.c_str(),newlevel);
4008 return true;
4011 bool ChatHandler::HandleLevelUpCommand(const char* args)
4013 char* nameStr;
4014 char* levelStr;
4015 extractOptFirstArg((char*)args,&nameStr,&levelStr);
4017 // exception opt second arg: .character level $name
4018 if(levelStr && isalpha(levelStr[0]))
4020 nameStr = levelStr;
4021 levelStr = NULL; // current level will used
4024 Player* target;
4025 uint64 target_guid;
4026 std::string target_name;
4027 if(!extractPlayerTarget(nameStr,&target,&target_guid,&target_name))
4028 return false;
4030 int32 oldlevel = target ? target->getLevel() : Player::GetLevelFromDB(target_guid);
4031 int32 addlevel = levelStr ? atoi(levelStr) : 1;
4032 int32 newlevel = oldlevel + addlevel;
4034 if(newlevel < 1)
4035 newlevel = 1;
4037 if(newlevel > STRONG_MAX_LEVEL) // hardcoded maximum level
4038 newlevel = STRONG_MAX_LEVEL;
4040 HandleCharacterLevel(target,target_guid,oldlevel,newlevel);
4042 if(!m_session || m_session->GetPlayer() != target) // including chr==NULL
4044 std::string nameLink = playerLink(target_name);
4045 PSendSysMessage(LANG_YOU_CHANGE_LVL,nameLink.c_str(),newlevel);
4048 return true;
4051 bool ChatHandler::HandleShowAreaCommand(const char* args)
4053 if (!*args)
4054 return false;
4056 Player *chr = getSelectedPlayer();
4057 if (chr == NULL)
4059 SendSysMessage(LANG_NO_CHAR_SELECTED);
4060 SetSentErrorMessage(true);
4061 return false;
4064 int area = GetAreaFlagByAreaID(atoi((char*)args));
4065 int offset = area / 32;
4066 uint32 val = (uint32)(1 << (area % 32));
4068 if(area<0 || offset >= 128)
4070 SendSysMessage(LANG_BAD_VALUE);
4071 SetSentErrorMessage(true);
4072 return false;
4075 uint32 currFields = chr->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset);
4076 chr->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields | val));
4078 SendSysMessage(LANG_EXPLORE_AREA);
4079 return true;
4082 bool ChatHandler::HandleHideAreaCommand(const char* args)
4084 if (!*args)
4085 return false;
4087 Player *chr = getSelectedPlayer();
4088 if (chr == NULL)
4090 SendSysMessage(LANG_NO_CHAR_SELECTED);
4091 SetSentErrorMessage(true);
4092 return false;
4095 int area = GetAreaFlagByAreaID(atoi((char*)args));
4096 int offset = area / 32;
4097 uint32 val = (uint32)(1 << (area % 32));
4099 if(area<0 || offset >= 128)
4101 SendSysMessage(LANG_BAD_VALUE);
4102 SetSentErrorMessage(true);
4103 return false;
4106 uint32 currFields = chr->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset);
4107 chr->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields ^ val));
4109 SendSysMessage(LANG_UNEXPLORE_AREA);
4110 return true;
4113 bool ChatHandler::HandleBankCommand(const char* /*args*/)
4115 m_session->SendShowBank( m_session->GetPlayer()->GetGUID() );
4117 return true;
4120 bool ChatHandler::HandleChangeWeather(const char* args)
4122 if(!*args)
4123 return false;
4125 //Weather is OFF
4126 if (!sWorld.getConfig(CONFIG_WEATHER))
4128 SendSysMessage(LANG_WEATHER_DISABLED);
4129 SetSentErrorMessage(true);
4130 return false;
4133 //*Change the weather of a cell
4134 char* px = strtok((char*)args, " ");
4135 char* py = strtok(NULL, " ");
4137 if (!px || !py)
4138 return false;
4140 uint32 type = (uint32)atoi(px); //0 to 3, 0: fine, 1: rain, 2: snow, 3: sand
4141 float grade = (float)atof(py); //0 to 1, sending -1 is instand good weather
4143 Player *player = m_session->GetPlayer();
4144 uint32 zoneid = player->GetZoneId();
4146 Weather* wth = sWorld.FindWeather(zoneid);
4148 if(!wth)
4149 wth = sWorld.AddWeather(zoneid);
4150 if(!wth)
4152 SendSysMessage(LANG_NO_WEATHER);
4153 SetSentErrorMessage(true);
4154 return false;
4157 wth->SetWeather(WeatherType(type), grade);
4159 return true;
4162 bool ChatHandler::HandleTeleAddCommand(const char * args)
4164 if(!*args)
4165 return false;
4167 Player *player=m_session->GetPlayer();
4168 if (!player)
4169 return false;
4171 std::string name = args;
4173 if(sObjectMgr.GetGameTele(name))
4175 SendSysMessage(LANG_COMMAND_TP_ALREADYEXIST);
4176 SetSentErrorMessage(true);
4177 return false;
4180 GameTele tele;
4181 tele.position_x = player->GetPositionX();
4182 tele.position_y = player->GetPositionY();
4183 tele.position_z = player->GetPositionZ();
4184 tele.orientation = player->GetOrientation();
4185 tele.mapId = player->GetMapId();
4186 tele.name = name;
4188 if(sObjectMgr.AddGameTele(tele))
4190 SendSysMessage(LANG_COMMAND_TP_ADDED);
4192 else
4194 SendSysMessage(LANG_COMMAND_TP_ADDEDERR);
4195 SetSentErrorMessage(true);
4196 return false;
4199 return true;
4202 bool ChatHandler::HandleTeleDelCommand(const char * args)
4204 if(!*args)
4205 return false;
4207 std::string name = args;
4209 if(!sObjectMgr.DeleteGameTele(name))
4211 SendSysMessage(LANG_COMMAND_TELE_NOTFOUND);
4212 SetSentErrorMessage(true);
4213 return false;
4216 SendSysMessage(LANG_COMMAND_TP_DELETED);
4217 return true;
4220 bool ChatHandler::HandleListAurasCommand (const char * /*args*/)
4222 Unit *unit = getSelectedUnit();
4223 if(!unit)
4225 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
4226 SetSentErrorMessage(true);
4227 return false;
4230 char const* talentStr = GetMangosString(LANG_TALENT);
4231 char const* passiveStr = GetMangosString(LANG_PASSIVE);
4233 Unit::AuraMap const& uAuras = unit->GetAuras();
4234 PSendSysMessage(LANG_COMMAND_TARGET_LISTAURAS, uAuras.size());
4235 for (Unit::AuraMap::const_iterator itr = uAuras.begin(); itr != uAuras.end(); ++itr)
4237 bool talent = GetTalentSpellCost(itr->second->GetId()) > 0;
4239 char const* name = itr->second->GetSpellProto()->SpellName[GetSessionDbcLocale()];
4241 if (m_session)
4243 std::ostringstream ss_name;
4244 ss_name << "|cffffffff|Hspell:" << itr->second->GetId() << "|h[" << name << "]|h|r";
4246 PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffIndex(),
4247 itr->second->GetModifier()->m_auraname, itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(),
4248 ss_name.str().c_str(),
4249 (itr->second->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
4250 IS_PLAYER_GUID(itr->second->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(itr->second->GetCasterGUID()));
4252 else
4254 PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffIndex(),
4255 itr->second->GetModifier()->m_auraname, itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(),
4256 name,
4257 (itr->second->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
4258 IS_PLAYER_GUID(itr->second->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(itr->second->GetCasterGUID()));
4261 for (int i = 0; i < TOTAL_AURAS; ++i)
4263 Unit::AuraList const& uAuraList = unit->GetAurasByType(AuraType(i));
4264 if (uAuraList.empty()) continue;
4265 PSendSysMessage(LANG_COMMAND_TARGET_LISTAURATYPE, uAuraList.size(), i);
4266 for (Unit::AuraList::const_iterator itr = uAuraList.begin(); itr != uAuraList.end(); ++itr)
4268 bool talent = GetTalentSpellCost((*itr)->GetId()) > 0;
4270 char const* name = (*itr)->GetSpellProto()->SpellName[GetSessionDbcLocale()];
4272 if (m_session)
4274 std::ostringstream ss_name;
4275 ss_name << "|cffffffff|Hspell:" << (*itr)->GetId() << "|h[" << name << "]|h|r";
4277 PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(),
4278 ss_name.str().c_str(),((*itr)->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
4279 IS_PLAYER_GUID((*itr)->GetCasterGUID()) ? "player" : "creature",GUID_LOPART((*itr)->GetCasterGUID()));
4281 else
4283 PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(),
4284 name,((*itr)->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
4285 IS_PLAYER_GUID((*itr)->GetCasterGUID()) ? "player" : "creature",GUID_LOPART((*itr)->GetCasterGUID()));
4289 return true;
4292 bool ChatHandler::HandleResetAchievementsCommand (const char * args)
4294 Player* target;
4295 uint64 target_guid;
4296 if (!extractPlayerTarget((char*)args,&target,&target_guid))
4297 return false;
4299 if(target)
4300 target->GetAchievementMgr().Reset();
4301 else
4302 AchievementMgr::DeleteFromDB(GUID_LOPART(target_guid));
4304 return true;
4307 bool ChatHandler::HandleResetHonorCommand (const char * args)
4309 Player* target;
4310 if (!extractPlayerTarget((char*)args,&target))
4311 return false;
4313 target->SetUInt32Value(PLAYER_FIELD_KILLS, 0);
4314 target->SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORBALE_KILLS, 0);
4315 target->SetUInt32Value(PLAYER_FIELD_HONOR_CURRENCY, 0);
4316 target->SetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, 0);
4317 target->SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, 0);
4318 target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL);
4320 return true;
4323 static bool HandleResetStatsOrLevelHelper(Player* player)
4325 ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(player->getClass());
4326 if(!cEntry)
4328 sLog.outError("Class %u not found in DBC (Wrong DBC files?)",player->getClass());
4329 return false;
4332 uint8 powertype = cEntry->powerType;
4334 // reset m_form if no aura
4335 if(!player->HasAuraType(SPELL_AURA_MOD_SHAPESHIFT))
4336 player->m_form = FORM_NONE;
4338 player->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE );
4339 player->SetFloatValue(UNIT_FIELD_COMBATREACH, 1.5f );
4341 player->setFactionForRace(player->getRace());
4343 player->SetUInt32Value(UNIT_FIELD_BYTES_0, ( ( player->getRace() ) | ( player->getClass() << 8 ) | ( player->getGender() << 16 ) | ( powertype << 24 ) ) );
4345 // reset only if player not in some form;
4346 if(player->m_form==FORM_NONE)
4347 player->InitDisplayIds();
4349 player->SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP );
4350 player->SetByteValue(UNIT_FIELD_BYTES_2, 3, player->m_form);
4352 player->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
4354 //-1 is default value
4355 player->SetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, uint32(-1));
4357 //player->SetUInt32Value(PLAYER_FIELD_BYTES, 0xEEE00000 );
4358 return true;
4361 bool ChatHandler::HandleResetLevelCommand(const char * args)
4363 Player* target;
4364 if(!extractPlayerTarget((char*)args,&target))
4365 return false;
4367 if(!HandleResetStatsOrLevelHelper(target))
4368 return false;
4370 // set starting level
4371 uint32 start_level = target->getClass() != CLASS_DEATH_KNIGHT
4372 ? sWorld.getConfig(CONFIG_START_PLAYER_LEVEL)
4373 : sWorld.getConfig(CONFIG_START_HEROIC_PLAYER_LEVEL);
4375 target->_ApplyAllLevelScaleItemMods(false);
4377 target->SetLevel(start_level);
4378 target->InitRunes();
4379 target->InitStatsForLevel(true);
4380 target->InitTaxiNodesForLevel();
4381 target->InitGlyphsForLevel();
4382 target->InitTalentForLevel();
4383 target->SetUInt32Value(PLAYER_XP,0);
4385 target->_ApplyAllLevelScaleItemMods(true);
4387 // reset level for pet
4388 if(Pet* pet = target->GetPet())
4389 pet->SynchronizeLevelWithOwner();
4391 return true;
4394 bool ChatHandler::HandleResetStatsCommand(const char * args)
4396 Player* target;
4397 if (!extractPlayerTarget((char*)args,&target))
4398 return false;
4400 if (!HandleResetStatsOrLevelHelper(target))
4401 return false;
4403 target->InitRunes();
4404 target->InitStatsForLevel(true);
4405 target->InitTaxiNodesForLevel();
4406 target->InitGlyphsForLevel();
4407 target->InitTalentForLevel();
4409 return true;
4412 bool ChatHandler::HandleResetSpellsCommand(const char * args)
4414 Player* target;
4415 uint64 target_guid;
4416 std::string target_name;
4417 if(!extractPlayerTarget((char*)args,&target,&target_guid,&target_name))
4418 return false;
4420 if(target)
4422 target->resetSpells();
4424 ChatHandler(target).SendSysMessage(LANG_RESET_SPELLS);
4425 if(!m_session || m_session->GetPlayer()!=target)
4426 PSendSysMessage(LANG_RESET_SPELLS_ONLINE,GetNameLink(target).c_str());
4428 else
4430 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",uint32(AT_LOGIN_RESET_SPELLS), GUID_LOPART(target_guid));
4431 PSendSysMessage(LANG_RESET_SPELLS_OFFLINE,target_name.c_str());
4434 return true;
4437 bool ChatHandler::HandleResetTalentsCommand(const char * args)
4439 Player* target;
4440 uint64 target_guid;
4441 std::string target_name;
4442 if (!extractPlayerTarget((char*)args,&target,&target_guid,&target_name))
4444 // Try reset talents as Hunter Pet
4445 Creature* creature = getSelectedCreature();
4446 if (!*args && creature && creature->isPet())
4448 Unit *owner = creature->GetOwner();
4449 if(owner && owner->GetTypeId() == TYPEID_PLAYER && ((Pet *)creature)->IsPermanentPetFor((Player*)owner))
4451 ((Pet *)creature)->resetTalents(true);
4452 ((Player*)owner)->SendTalentsInfoData(true);
4454 ChatHandler((Player*)owner).SendSysMessage(LANG_RESET_PET_TALENTS);
4455 if(!m_session || m_session->GetPlayer()!=((Player*)owner))
4456 PSendSysMessage(LANG_RESET_PET_TALENTS_ONLINE,GetNameLink((Player*)owner).c_str());
4458 return true;
4461 SendSysMessage(LANG_NO_CHAR_SELECTED);
4462 SetSentErrorMessage(true);
4463 return false;
4466 if (target)
4468 target->resetTalents(true);
4469 target->SendTalentsInfoData(false);
4470 ChatHandler(target).SendSysMessage(LANG_RESET_TALENTS);
4471 if (!m_session || m_session->GetPlayer()!=target)
4472 PSendSysMessage(LANG_RESET_TALENTS_ONLINE,GetNameLink(target).c_str());
4474 Pet* pet = target->GetPet();
4475 Pet::resetTalentsForAllPetsOf(target,pet);
4476 if(pet)
4477 target->SendTalentsInfoData(true);
4478 return true;
4480 else if (target_guid)
4482 uint32 at_flags = AT_LOGIN_NONE | AT_LOGIN_RESET_PET_TALENTS;
4483 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",at_flags, GUID_LOPART(target_guid) );
4484 std::string nameLink = playerLink(target_name);
4485 PSendSysMessage(LANG_RESET_TALENTS_OFFLINE,nameLink.c_str());
4486 return true;
4489 SendSysMessage(LANG_NO_CHAR_SELECTED);
4490 SetSentErrorMessage(true);
4491 return false;
4494 bool ChatHandler::HandleResetAllCommand(const char * args)
4496 if(!*args)
4497 return false;
4499 std::string casename = args;
4501 AtLoginFlags atLogin;
4503 // Command specially created as single command to prevent using short case names
4504 if(casename=="spells")
4506 atLogin = AT_LOGIN_RESET_SPELLS;
4507 sWorld.SendWorldText(LANG_RESETALL_SPELLS);
4508 if(!m_session)
4509 SendSysMessage(LANG_RESETALL_SPELLS);
4511 else if(casename=="talents")
4513 atLogin = AtLoginFlags(AT_LOGIN_RESET_TALENTS | AT_LOGIN_RESET_PET_TALENTS);
4514 sWorld.SendWorldText(LANG_RESETALL_TALENTS);
4515 if(!m_session)
4516 SendSysMessage(LANG_RESETALL_TALENTS);
4518 else
4520 PSendSysMessage(LANG_RESETALL_UNKNOWN_CASE,args);
4521 SetSentErrorMessage(true);
4522 return false;
4525 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE (at_login & '%u') = '0'",atLogin,atLogin);
4526 HashMapHolder<Player>::MapType const& plist = sObjectAccessor.GetPlayers();
4527 for(HashMapHolder<Player>::MapType::const_iterator itr = plist.begin(); itr != plist.end(); ++itr)
4528 itr->second->SetAtLoginFlag(atLogin);
4530 return true;
4533 bool ChatHandler::HandleServerShutDownCancelCommand(const char* /*args*/)
4535 sWorld.ShutdownCancel();
4536 return true;
4539 bool ChatHandler::HandleServerShutDownCommand(const char* args)
4541 if(!*args)
4542 return false;
4544 char* time_str = strtok ((char*) args, " ");
4545 char* exitcode_str = strtok (NULL, "");
4547 int32 time = atoi (time_str);
4549 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4550 if ((time == 0 && (time_str[0]!='0' || time_str[1]!='\0')) || time < 0)
4551 return false;
4553 if (exitcode_str)
4555 int32 exitcode = atoi (exitcode_str);
4557 // Handle atoi() errors
4558 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4559 return false;
4561 // Exit code should be in range of 0-125, 126-255 is used
4562 // in many shells for their own return codes and code > 255
4563 // is not supported in many others
4564 if (exitcode < 0 || exitcode > 125)
4565 return false;
4567 sWorld.ShutdownServ (time, 0, exitcode);
4569 else
4570 sWorld.ShutdownServ(time,0,SHUTDOWN_EXIT_CODE);
4571 return true;
4574 bool ChatHandler::HandleServerRestartCommand(const char* args)
4576 if(!*args)
4577 return false;
4579 char* time_str = strtok ((char*) args, " ");
4580 char* exitcode_str = strtok (NULL, "");
4582 int32 time = atoi (time_str);
4584 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4585 if ((time == 0 && (time_str[0]!='0' || time_str[1]!='\0')) || time < 0)
4586 return false;
4588 if (exitcode_str)
4590 int32 exitcode = atoi (exitcode_str);
4592 // Handle atoi() errors
4593 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4594 return false;
4596 // Exit code should be in range of 0-125, 126-255 is used
4597 // in many shells for their own return codes and code > 255
4598 // is not supported in many others
4599 if (exitcode < 0 || exitcode > 125)
4600 return false;
4602 sWorld.ShutdownServ (time, SHUTDOWN_MASK_RESTART, exitcode);
4604 else
4605 sWorld.ShutdownServ(time, SHUTDOWN_MASK_RESTART, RESTART_EXIT_CODE);
4606 return true;
4609 bool ChatHandler::HandleServerIdleRestartCommand(const char* args)
4611 if(!*args)
4612 return false;
4614 char* time_str = strtok ((char*) args, " ");
4615 char* exitcode_str = strtok (NULL, "");
4617 int32 time = atoi (time_str);
4619 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4620 if ((time == 0 && (time_str[0]!='0' || time_str[1]!='\0')) || time < 0)
4621 return false;
4623 if (exitcode_str)
4625 int32 exitcode = atoi (exitcode_str);
4627 // Handle atoi() errors
4628 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4629 return false;
4631 // Exit code should be in range of 0-125, 126-255 is used
4632 // in many shells for their own return codes and code > 255
4633 // is not supported in many others
4634 if (exitcode < 0 || exitcode > 125)
4635 return false;
4637 sWorld.ShutdownServ (time, SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE, exitcode);
4639 else
4640 sWorld.ShutdownServ(time,SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE,RESTART_EXIT_CODE);
4641 return true;
4644 bool ChatHandler::HandleServerIdleShutDownCommand(const char* args)
4646 if(!*args)
4647 return false;
4649 char* time_str = strtok ((char*) args, " ");
4650 char* exitcode_str = strtok (NULL, "");
4652 int32 time = atoi (time_str);
4654 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4655 if ((time == 0 && (time_str[0]!='0' || time_str[1]!='\0')) || time < 0)
4656 return false;
4658 if (exitcode_str)
4660 int32 exitcode = atoi (exitcode_str);
4662 // Handle atoi() errors
4663 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4664 return false;
4666 // Exit code should be in range of 0-125, 126-255 is used
4667 // in many shells for their own return codes and code > 255
4668 // is not supported in many others
4669 if (exitcode < 0 || exitcode > 125)
4670 return false;
4672 sWorld.ShutdownServ (time, SHUTDOWN_MASK_IDLE, exitcode);
4674 else
4675 sWorld.ShutdownServ(time,SHUTDOWN_MASK_IDLE,SHUTDOWN_EXIT_CODE);
4676 return true;
4679 bool ChatHandler::HandleQuestAdd(const char* args)
4681 Player* player = getSelectedPlayer();
4682 if(!player)
4684 SendSysMessage(LANG_NO_CHAR_SELECTED);
4685 SetSentErrorMessage(true);
4686 return false;
4689 // .addquest #entry'
4690 // number or [name] Shift-click form |color|Hquest:quest_id:quest_level|h[name]|h|r
4691 char* cId = extractKeyFromLink((char*)args,"Hquest");
4692 if(!cId)
4693 return false;
4695 uint32 entry = atol(cId);
4697 Quest const* pQuest = sObjectMgr.GetQuestTemplate(entry);
4699 if(!pQuest)
4701 PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND,entry);
4702 SetSentErrorMessage(true);
4703 return false;
4706 // check item starting quest (it can work incorrectly if added without item in inventory)
4707 for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
4709 ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype>(id);
4710 if (!pProto)
4711 continue;
4713 if (pProto->StartQuest == entry)
4715 PSendSysMessage(LANG_COMMAND_QUEST_STARTFROMITEM, entry, pProto->ItemId);
4716 SetSentErrorMessage(true);
4717 return false;
4721 // ok, normal (creature/GO starting) quest
4722 if( player->CanAddQuest( pQuest, true ) )
4724 player->AddQuest( pQuest, NULL );
4726 if ( player->CanCompleteQuest( entry ) )
4727 player->CompleteQuest( entry );
4730 return true;
4733 bool ChatHandler::HandleQuestRemove(const char* args)
4735 Player* player = getSelectedPlayer();
4736 if(!player)
4738 SendSysMessage(LANG_NO_CHAR_SELECTED);
4739 SetSentErrorMessage(true);
4740 return false;
4743 // .removequest #entry'
4744 // number or [name] Shift-click form |color|Hquest:quest_id:quest_level|h[name]|h|r
4745 char* cId = extractKeyFromLink((char*)args,"Hquest");
4746 if(!cId)
4747 return false;
4749 uint32 entry = atol(cId);
4751 Quest const* pQuest = sObjectMgr.GetQuestTemplate(entry);
4753 if(!pQuest)
4755 PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry);
4756 SetSentErrorMessage(true);
4757 return false;
4760 // remove all quest entries for 'entry' from quest log
4761 for(uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot )
4763 uint32 quest = player->GetQuestSlotQuestId(slot);
4764 if(quest==entry)
4766 player->SetQuestSlot(slot,0);
4768 // we ignore unequippable quest items in this case, its' still be equipped
4769 player->TakeQuestSourceItem( quest, false );
4773 // set quest status to not started (will updated in DB at next save)
4774 player->SetQuestStatus( entry, QUEST_STATUS_NONE);
4776 // reset rewarded for restart repeatable quest
4777 player->getQuestStatusMap()[entry].m_rewarded = false;
4779 SendSysMessage(LANG_COMMAND_QUEST_REMOVED);
4780 return true;
4783 bool ChatHandler::HandleQuestComplete(const char* args)
4785 Player* player = getSelectedPlayer();
4786 if(!player)
4788 SendSysMessage(LANG_NO_CHAR_SELECTED);
4789 SetSentErrorMessage(true);
4790 return false;
4793 // .quest complete #entry
4794 // number or [name] Shift-click form |color|Hquest:quest_id:quest_level|h[name]|h|r
4795 char* cId = extractKeyFromLink((char*)args,"Hquest");
4796 if(!cId)
4797 return false;
4799 uint32 entry = atol(cId);
4801 Quest const* pQuest = sObjectMgr.GetQuestTemplate(entry);
4803 // If player doesn't have the quest
4804 if(!pQuest || player->GetQuestStatus(entry) == QUEST_STATUS_NONE)
4806 PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry);
4807 SetSentErrorMessage(true);
4808 return false;
4811 // Add quest items for quests that require items
4812 for(uint8 x = 0; x < QUEST_ITEM_OBJECTIVES_COUNT; ++x)
4814 uint32 id = pQuest->ReqItemId[x];
4815 uint32 count = pQuest->ReqItemCount[x];
4816 if(!id || !count)
4817 continue;
4819 uint32 curItemCount = player->GetItemCount(id,true);
4821 ItemPosCountVec dest;
4822 uint8 msg = player->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, id, count - curItemCount );
4823 if( msg == EQUIP_ERR_OK )
4825 Item* item = player->StoreNewItem( dest, id, true);
4826 player->SendNewItem(item,count-curItemCount, true, false);
4830 // All creature/GO slain/casted (not required, but otherwise it will display "Creature slain 0/10")
4831 for(uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
4833 uint32 creature = pQuest->ReqCreatureOrGOId[i];
4834 uint32 creaturecount = pQuest->ReqCreatureOrGOCount[i];
4836 if(uint32 spell_id = pQuest->ReqSpell[i])
4838 for(uint16 z = 0; z < creaturecount; ++z)
4839 player->CastedCreatureOrGO(creature,0,spell_id);
4841 else if(creature > 0)
4843 if(CreatureInfo const* cInfo = ObjectMgr::GetCreatureTemplate(creature))
4844 for(uint16 z = 0; z < creaturecount; ++z)
4845 player->KilledMonster(cInfo,0);
4847 else if(creature < 0)
4849 for(uint16 z = 0; z < creaturecount; ++z)
4850 player->CastedCreatureOrGO(creature,0,0);
4854 // If the quest requires reputation to complete
4855 if(uint32 repFaction = pQuest->GetRepObjectiveFaction())
4857 uint32 repValue = pQuest->GetRepObjectiveValue();
4858 uint32 curRep = player->GetReputationMgr().GetReputation(repFaction);
4859 if(curRep < repValue)
4860 if(FactionEntry const *factionEntry = sFactionStore.LookupEntry(repFaction))
4861 player->GetReputationMgr().SetReputation(factionEntry,repValue);
4864 // If the quest requires money
4865 int32 ReqOrRewMoney = pQuest->GetRewOrReqMoney();
4866 if(ReqOrRewMoney < 0)
4867 player->ModifyMoney(-ReqOrRewMoney);
4869 player->CompleteQuest(entry);
4870 return true;
4873 bool ChatHandler::HandleBanAccountCommand(const char* args)
4875 return HandleBanHelper(BAN_ACCOUNT,args);
4878 bool ChatHandler::HandleBanCharacterCommand(const char* args)
4880 return HandleBanHelper(BAN_CHARACTER,args);
4883 bool ChatHandler::HandleBanIPCommand(const char* args)
4885 return HandleBanHelper(BAN_IP,args);
4888 bool ChatHandler::HandleBanHelper(BanMode mode, const char* args)
4890 if (!*args)
4891 return false;
4893 char* cnameOrIP = strtok ((char*)args, " ");
4894 if (!cnameOrIP)
4895 return false;
4897 std::string nameOrIP = cnameOrIP;
4899 char* duration = strtok (NULL," ");
4900 if(!duration || !atoi(duration))
4901 return false;
4903 char* reason = strtok (NULL,"");
4904 if(!reason)
4905 return false;
4907 switch(mode)
4909 case BAN_ACCOUNT:
4910 if (!AccountMgr::normalizeString(nameOrIP))
4912 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,nameOrIP.c_str());
4913 SetSentErrorMessage(true);
4914 return false;
4916 break;
4917 case BAN_CHARACTER:
4918 if(!normalizePlayerName(nameOrIP))
4920 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4921 SetSentErrorMessage(true);
4922 return false;
4924 break;
4925 case BAN_IP:
4926 if(!IsIPAddress(nameOrIP.c_str()))
4927 return false;
4928 break;
4931 switch(sWorld.BanAccount(mode, nameOrIP, duration, reason,m_session ? m_session->GetPlayerName() : ""))
4933 case BAN_SUCCESS:
4934 if(atoi(duration)>0)
4935 PSendSysMessage(LANG_BAN_YOUBANNED,nameOrIP.c_str(),secsToTimeString(TimeStringToSecs(duration),true).c_str(),reason);
4936 else
4937 PSendSysMessage(LANG_BAN_YOUPERMBANNED,nameOrIP.c_str(),reason);
4938 break;
4939 case BAN_SYNTAX_ERROR:
4940 return false;
4941 case BAN_NOTFOUND:
4942 switch(mode)
4944 default:
4945 PSendSysMessage(LANG_BAN_NOTFOUND,"account",nameOrIP.c_str());
4946 break;
4947 case BAN_CHARACTER:
4948 PSendSysMessage(LANG_BAN_NOTFOUND,"character",nameOrIP.c_str());
4949 break;
4950 case BAN_IP:
4951 PSendSysMessage(LANG_BAN_NOTFOUND,"ip",nameOrIP.c_str());
4952 break;
4954 SetSentErrorMessage(true);
4955 return false;
4958 return true;
4961 bool ChatHandler::HandleUnBanAccountCommand(const char* args)
4963 return HandleUnBanHelper(BAN_ACCOUNT,args);
4966 bool ChatHandler::HandleUnBanCharacterCommand(const char* args)
4968 return HandleUnBanHelper(BAN_CHARACTER,args);
4971 bool ChatHandler::HandleUnBanIPCommand(const char* args)
4973 return HandleUnBanHelper(BAN_IP,args);
4976 bool ChatHandler::HandleUnBanHelper(BanMode mode, const char* args)
4978 if (!*args)
4979 return false;
4981 char* cnameOrIP = strtok ((char*)args, " ");
4982 if(!cnameOrIP)
4983 return false;
4985 std::string nameOrIP = cnameOrIP;
4987 switch(mode)
4989 case BAN_ACCOUNT:
4990 if (!AccountMgr::normalizeString(nameOrIP))
4992 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,nameOrIP.c_str());
4993 SetSentErrorMessage(true);
4994 return false;
4996 break;
4997 case BAN_CHARACTER:
4998 if(!normalizePlayerName(nameOrIP))
5000 SendSysMessage(LANG_PLAYER_NOT_FOUND);
5001 SetSentErrorMessage(true);
5002 return false;
5004 break;
5005 case BAN_IP:
5006 if(!IsIPAddress(nameOrIP.c_str()))
5007 return false;
5008 break;
5011 if(sWorld.RemoveBanAccount(mode,nameOrIP))
5012 PSendSysMessage(LANG_UNBAN_UNBANNED,nameOrIP.c_str());
5013 else
5014 PSendSysMessage(LANG_UNBAN_ERROR,nameOrIP.c_str());
5016 return true;
5019 bool ChatHandler::HandleBanInfoAccountCommand(const char* args)
5021 if (!*args)
5022 return false;
5024 char* cname = strtok((char*)args, "");
5025 if (!cname)
5026 return false;
5028 std::string account_name = cname;
5029 if (!AccountMgr::normalizeString(account_name))
5031 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5032 SetSentErrorMessage(true);
5033 return false;
5036 uint32 accountid = sAccountMgr.GetId(account_name);
5037 if (!accountid)
5039 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5040 return true;
5043 return HandleBanInfoHelper(accountid,account_name.c_str());
5046 bool ChatHandler::HandleBanInfoCharacterCommand(const char* args)
5048 Player* target;
5049 uint64 target_guid;
5050 if (!extractPlayerTarget((char*)args,&target,&target_guid))
5051 return false;
5053 uint32 accountid = target ? target->GetSession()->GetAccountId() : sObjectMgr.GetPlayerAccountIdByGUID(target_guid);
5055 std::string accountname;
5056 if (!sAccountMgr.GetName(accountid,accountname))
5058 PSendSysMessage(LANG_BANINFO_NOCHARACTER);
5059 return true;
5062 return HandleBanInfoHelper(accountid,accountname.c_str());
5065 bool ChatHandler::HandleBanInfoHelper(uint32 accountid, char const* accountname)
5067 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);
5068 if(!result)
5070 PSendSysMessage(LANG_BANINFO_NOACCOUNTBAN, accountname);
5071 return true;
5074 PSendSysMessage(LANG_BANINFO_BANHISTORY,accountname);
5077 Field* fields = result->Fetch();
5079 time_t unbandate = time_t(fields[3].GetUInt64());
5080 bool active = false;
5081 if(fields[2].GetBool() && (fields[1].GetUInt64() == (uint64)0 ||unbandate >= time(NULL)) )
5082 active = true;
5083 bool permanent = (fields[1].GetUInt64() == (uint64)0);
5084 std::string bantime = permanent?GetMangosString(LANG_BANINFO_INFINITE):secsToTimeString(fields[1].GetUInt64(), true);
5085 PSendSysMessage(LANG_BANINFO_HISTORYENTRY,
5086 fields[0].GetString(), bantime.c_str(), active ? GetMangosString(LANG_BANINFO_YES):GetMangosString(LANG_BANINFO_NO), fields[4].GetString(), fields[5].GetString());
5087 }while (result->NextRow());
5089 delete result;
5090 return true;
5093 bool ChatHandler::HandleBanInfoIPCommand(const char* args)
5095 if (!*args)
5096 return false;
5098 char* cIP = strtok ((char*)args, "");
5099 if(!cIP)
5100 return false;
5102 if (!IsIPAddress(cIP))
5103 return false;
5105 std::string IP = cIP;
5107 loginDatabase.escape_string(IP);
5108 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());
5109 if(!result)
5111 PSendSysMessage(LANG_BANINFO_NOIP);
5112 return true;
5115 Field *fields = result->Fetch();
5116 bool permanent = !fields[6].GetUInt64();
5117 PSendSysMessage(LANG_BANINFO_IPENTRY,
5118 fields[0].GetString(), fields[1].GetString(), permanent ? GetMangosString(LANG_BANINFO_NEVER):fields[2].GetString(),
5119 permanent ? GetMangosString(LANG_BANINFO_INFINITE):secsToTimeString(fields[3].GetUInt64(), true).c_str(), fields[4].GetString(), fields[5].GetString());
5120 delete result;
5121 return true;
5124 bool ChatHandler::HandleBanListCharacterCommand(const char* args)
5126 loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
5128 char* cFilter = strtok ((char*)args, " ");
5129 if(!cFilter)
5130 return false;
5132 std::string filter = cFilter;
5133 loginDatabase.escape_string(filter);
5134 QueryResult* result = CharacterDatabase.PQuery("SELECT account FROM characters WHERE name "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'"),filter.c_str());
5135 if (!result)
5137 PSendSysMessage(LANG_BANLIST_NOCHARACTER);
5138 return true;
5141 return HandleBanListHelper(result);
5144 bool ChatHandler::HandleBanListAccountCommand(const char* args)
5146 loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
5148 char* cFilter = strtok((char*)args, " ");
5149 std::string filter = cFilter ? cFilter : "";
5150 loginDatabase.escape_string(filter);
5152 QueryResult* result;
5154 if(filter.empty())
5156 result = loginDatabase.Query("SELECT account.id, username FROM account, account_banned"
5157 " WHERE account.id = account_banned.id AND active = 1 GROUP BY account.id");
5159 else
5161 result = loginDatabase.PQuery("SELECT account.id, username FROM account, account_banned"
5162 " WHERE account.id = account_banned.id AND active = 1 AND username "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")" GROUP BY account.id",
5163 filter.c_str());
5166 if (!result)
5168 PSendSysMessage(LANG_BANLIST_NOACCOUNT);
5169 return true;
5172 return HandleBanListHelper(result);
5175 bool ChatHandler::HandleBanListHelper(QueryResult* result)
5177 PSendSysMessage(LANG_BANLIST_MATCHINGACCOUNT);
5179 // Chat short output
5180 if(m_session)
5184 Field* fields = result->Fetch();
5185 uint32 accountid = fields[0].GetUInt32();
5187 QueryResult* banresult = loginDatabase.PQuery("SELECT account.username FROM account,account_banned WHERE account_banned.id='%u' AND account_banned.id=account.id",accountid);
5188 if(banresult)
5190 Field* fields2 = banresult->Fetch();
5191 PSendSysMessage("%s",fields2[0].GetString());
5192 delete banresult;
5194 } while (result->NextRow());
5196 // Console wide output
5197 else
5199 SendSysMessage(LANG_BANLIST_ACCOUNTS);
5200 SendSysMessage("===============================================================================");
5201 SendSysMessage(LANG_BANLIST_ACCOUNTS_HEADER);
5204 SendSysMessage("-------------------------------------------------------------------------------");
5205 Field *fields = result->Fetch();
5206 uint32 account_id = fields[0].GetUInt32 ();
5208 std::string account_name;
5210 // "account" case, name can be get in same query
5211 if(result->GetFieldCount() > 1)
5212 account_name = fields[1].GetCppString();
5213 // "character" case, name need extract from another DB
5214 else
5215 sAccountMgr.GetName (account_id,account_name);
5217 // No SQL injection. id is uint32.
5218 QueryResult *banInfo = loginDatabase.PQuery("SELECT bandate,unbandate,bannedby,banreason FROM account_banned WHERE id = %u ORDER BY unbandate", account_id);
5219 if (banInfo)
5221 Field *fields2 = banInfo->Fetch();
5224 time_t t_ban = fields2[0].GetUInt64();
5225 tm* aTm_ban = localtime(&t_ban);
5227 if (fields2[0].GetUInt64() == fields2[1].GetUInt64())
5229 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|",
5230 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,
5231 fields2[2].GetString(),fields2[3].GetString());
5233 else
5235 time_t t_unban = fields2[1].GetUInt64();
5236 tm* aTm_unban = localtime(&t_unban);
5237 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|",
5238 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,
5239 aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min,
5240 fields2[2].GetString(),fields2[3].GetString());
5242 }while ( banInfo->NextRow() );
5243 delete banInfo;
5245 }while( result->NextRow() );
5246 SendSysMessage("===============================================================================");
5249 delete result;
5250 return true;
5253 bool ChatHandler::HandleBanListIPCommand(const char* args)
5255 loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
5257 char* cFilter = strtok((char*)args, " ");
5258 std::string filter = cFilter ? cFilter : "";
5259 loginDatabase.escape_string(filter);
5261 QueryResult* result;
5263 if(filter.empty())
5265 result = loginDatabase.Query ("SELECT ip,bandate,unbandate,bannedby,banreason FROM ip_banned"
5266 " WHERE (bandate=unbandate OR unbandate>UNIX_TIMESTAMP())"
5267 " ORDER BY unbandate" );
5269 else
5271 result = loginDatabase.PQuery( "SELECT ip,bandate,unbandate,bannedby,banreason FROM ip_banned"
5272 " WHERE (bandate=unbandate OR unbandate>UNIX_TIMESTAMP()) AND ip "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")
5273 " ORDER BY unbandate",filter.c_str() );
5276 if(!result)
5278 PSendSysMessage(LANG_BANLIST_NOIP);
5279 return true;
5282 PSendSysMessage(LANG_BANLIST_MATCHINGIP);
5283 // Chat short output
5284 if(m_session)
5288 Field* fields = result->Fetch();
5289 PSendSysMessage("%s",fields[0].GetString());
5290 } while (result->NextRow());
5292 // Console wide output
5293 else
5295 SendSysMessage(LANG_BANLIST_IPS);
5296 SendSysMessage("===============================================================================");
5297 SendSysMessage(LANG_BANLIST_IPS_HEADER);
5300 SendSysMessage("-------------------------------------------------------------------------------");
5301 Field *fields = result->Fetch();
5302 time_t t_ban = fields[1].GetUInt64();
5303 tm* aTm_ban = localtime(&t_ban);
5304 if ( fields[1].GetUInt64() == fields[2].GetUInt64() )
5306 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|",
5307 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,
5308 fields[3].GetString(), fields[4].GetString());
5310 else
5312 time_t t_unban = fields[2].GetUInt64();
5313 tm* aTm_unban = localtime(&t_unban);
5314 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|",
5315 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,
5316 aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min,
5317 fields[3].GetString(), fields[4].GetString());
5319 }while( result->NextRow() );
5320 SendSysMessage("===============================================================================");
5323 delete result;
5324 return true;
5327 bool ChatHandler::HandleRespawnCommand(const char* /*args*/)
5329 Player* pl = m_session->GetPlayer();
5331 // accept only explicitly selected target (not implicitly self targeting case)
5332 Unit* target = getSelectedUnit();
5333 if(pl->GetSelection() && target)
5335 if(target->GetTypeId()!=TYPEID_UNIT)
5337 SendSysMessage(LANG_SELECT_CREATURE);
5338 SetSentErrorMessage(true);
5339 return false;
5342 if(target->isDead())
5343 ((Creature*)target)->Respawn();
5344 return true;
5347 CellPair p(MaNGOS::ComputeCellPair(pl->GetPositionX(), pl->GetPositionY()));
5348 Cell cell(p);
5349 cell.data.Part.reserved = ALL_DISTRICT;
5350 cell.SetNoCreate();
5352 MaNGOS::RespawnDo u_do;
5353 MaNGOS::WorldObjectWorker<MaNGOS::RespawnDo> worker(pl,u_do);
5355 TypeContainerVisitor<MaNGOS::WorldObjectWorker<MaNGOS::RespawnDo>, GridTypeMapContainer > obj_worker(worker);
5356 CellLock<GridReadGuard> cell_lock(cell, p);
5357 cell_lock->Visit(cell_lock, obj_worker, *pl->GetMap());
5359 return true;
5362 bool ChatHandler::HandleGMFlyCommand(const char* args)
5364 if (!*args)
5365 return false;
5367 Player *target = getSelectedPlayer();
5368 if (!target)
5369 target = m_session->GetPlayer();
5371 WorldPacket data(12);
5372 if (strncmp(args, "on", 3) == 0)
5373 data.SetOpcode(SMSG_MOVE_SET_CAN_FLY);
5374 else if (strncmp(args, "off", 4) == 0)
5375 data.SetOpcode(SMSG_MOVE_UNSET_CAN_FLY);
5376 else
5378 SendSysMessage(LANG_USE_BOL);
5379 return false;
5381 data.append(target->GetPackGUID());
5382 data << uint32(0); // unknown
5383 target->SendMessageToSet(&data, true);
5384 PSendSysMessage(LANG_COMMAND_FLYMODE_STATUS, GetNameLink(target).c_str(), args);
5385 return true;
5388 bool ChatHandler::HandlePDumpLoadCommand(const char *args)
5390 if (!*args)
5391 return false;
5393 char * file = strtok((char*)args, " ");
5394 if (!file)
5395 return false;
5397 char * account = strtok(NULL, " ");
5398 if (!account)
5399 return false;
5401 std::string account_name = account;
5402 if (!AccountMgr::normalizeString(account_name))
5404 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5405 SetSentErrorMessage(true);
5406 return false;
5409 uint32 account_id = sAccountMgr.GetId(account_name);
5410 if (!account_id)
5412 account_id = atoi(account); // use original string
5413 if (!account_id)
5415 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5416 SetSentErrorMessage(true);
5417 return false;
5421 if (!sAccountMgr.GetName(account_id,account_name))
5423 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5424 SetSentErrorMessage(true);
5425 return false;
5428 char* guid_str = NULL;
5429 char* name_str = strtok(NULL, " ");
5431 std::string name;
5432 if (name_str)
5434 name = name_str;
5435 // normalize the name if specified and check if it exists
5436 if (!normalizePlayerName(name))
5438 PSendSysMessage(LANG_INVALID_CHARACTER_NAME);
5439 SetSentErrorMessage(true);
5440 return false;
5443 if (ObjectMgr::CheckPlayerName(name,true) != CHAR_NAME_SUCCESS)
5445 PSendSysMessage(LANG_INVALID_CHARACTER_NAME);
5446 SetSentErrorMessage(true);
5447 return false;
5450 guid_str = strtok(NULL, " ");
5453 uint32 guid = 0;
5455 if (guid_str)
5457 guid = atoi(guid_str);
5458 if (!guid)
5460 PSendSysMessage(LANG_INVALID_CHARACTER_GUID);
5461 SetSentErrorMessage(true);
5462 return false;
5465 if (sObjectMgr.GetPlayerAccountIdByGUID(guid))
5467 PSendSysMessage(LANG_CHARACTER_GUID_IN_USE,guid);
5468 SetSentErrorMessage(true);
5469 return false;
5473 switch(PlayerDumpReader().LoadDump(file, account_id, name, guid))
5475 case DUMP_SUCCESS:
5476 PSendSysMessage(LANG_COMMAND_IMPORT_SUCCESS);
5477 break;
5478 case DUMP_FILE_OPEN_ERROR:
5479 PSendSysMessage(LANG_FILE_OPEN_FAIL,file);
5480 SetSentErrorMessage(true);
5481 return false;
5482 case DUMP_FILE_BROKEN:
5483 PSendSysMessage(LANG_DUMP_BROKEN,file);
5484 SetSentErrorMessage(true);
5485 return false;
5486 case DUMP_TOO_MANY_CHARS:
5487 PSendSysMessage(LANG_ACCOUNT_CHARACTER_LIST_FULL,account_name.c_str(),account_id);
5488 SetSentErrorMessage(true);
5489 return false;
5490 default:
5491 PSendSysMessage(LANG_COMMAND_IMPORT_FAILED);
5492 SetSentErrorMessage(true);
5493 return false;
5496 return true;
5499 bool ChatHandler::HandlePDumpWriteCommand(const char *args)
5501 if (!*args)
5502 return false;
5504 char* file = strtok((char*)args, " ");
5505 char* p2 = strtok(NULL, " ");
5507 if(!file || !p2)
5508 return false;
5510 uint32 guid;
5511 // character name can't start from number
5512 if (isNumeric(p2[0]))
5513 guid = atoi(p2);
5514 else
5516 std::string name = extractPlayerNameFromLink(p2);
5517 if(name.empty())
5519 SendSysMessage(LANG_PLAYER_NOT_FOUND);
5520 SetSentErrorMessage(true);
5521 return false;
5524 guid = sObjectMgr.GetPlayerGUIDByName(name);
5527 if(!sObjectMgr.GetPlayerAccountIdByGUID(guid))
5529 PSendSysMessage(LANG_PLAYER_NOT_FOUND);
5530 SetSentErrorMessage(true);
5531 return false;
5534 switch(PlayerDumpWriter().WriteDump(file, guid))
5536 case DUMP_SUCCESS:
5537 PSendSysMessage(LANG_COMMAND_EXPORT_SUCCESS);
5538 break;
5539 case DUMP_FILE_OPEN_ERROR:
5540 PSendSysMessage(LANG_FILE_OPEN_FAIL,file);
5541 SetSentErrorMessage(true);
5542 return false;
5543 default:
5544 PSendSysMessage(LANG_COMMAND_EXPORT_FAILED);
5545 SetSentErrorMessage(true);
5546 return false;
5549 return true;
5552 bool ChatHandler::HandleMovegensCommand(const char* /*args*/)
5554 Unit* unit = getSelectedUnit();
5555 if(!unit)
5557 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5558 SetSentErrorMessage(true);
5559 return false;
5562 PSendSysMessage(LANG_MOVEGENS_LIST,(unit->GetTypeId()==TYPEID_PLAYER ? "Player" : "Creature" ),unit->GetGUIDLow());
5564 MotionMaster* mm = unit->GetMotionMaster();
5565 for(MotionMaster::const_iterator itr = mm->begin(); itr != mm->end(); ++itr)
5567 switch((*itr)->GetMovementGeneratorType())
5569 case IDLE_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_IDLE); break;
5570 case RANDOM_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_RANDOM); break;
5571 case WAYPOINT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_WAYPOINT); break;
5572 case ANIMAL_RANDOM_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_ANIMAL_RANDOM); break;
5573 case CONFUSED_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_CONFUSED); break;
5574 case TARGETED_MOTION_TYPE:
5576 if(unit->GetTypeId()==TYPEID_PLAYER)
5578 TargetedMovementGenerator<Player> const* mgen = static_cast<TargetedMovementGenerator<Player> const*>(*itr);
5579 Unit* target = mgen->GetTarget();
5580 if(target)
5581 PSendSysMessage(LANG_MOVEGENS_TARGETED_PLAYER,target->GetName(),target->GetGUIDLow());
5582 else
5583 SendSysMessage(LANG_MOVEGENS_TARGETED_NULL);
5585 else
5587 TargetedMovementGenerator<Creature> const* mgen = static_cast<TargetedMovementGenerator<Creature> const*>(*itr);
5588 Unit* target = mgen->GetTarget();
5589 if(target)
5590 PSendSysMessage(LANG_MOVEGENS_TARGETED_CREATURE,target->GetName(),target->GetGUIDLow());
5591 else
5592 SendSysMessage(LANG_MOVEGENS_TARGETED_NULL);
5594 break;
5596 case HOME_MOTION_TYPE:
5597 if(unit->GetTypeId()==TYPEID_UNIT)
5599 float x,y,z;
5600 (*itr)->GetDestination(x,y,z);
5601 PSendSysMessage(LANG_MOVEGENS_HOME_CREATURE,x,y,z);
5603 else
5604 SendSysMessage(LANG_MOVEGENS_HOME_PLAYER);
5605 break;
5606 case FLIGHT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_FLIGHT); break;
5607 case POINT_MOTION_TYPE:
5609 float x,y,z;
5610 (*itr)->GetDestination(x,y,z);
5611 PSendSysMessage(LANG_MOVEGENS_POINT,x,y,z);
5612 break;
5614 case FLEEING_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_FEAR); break;
5615 case DISTRACT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_DISTRACT); break;
5616 default:
5617 PSendSysMessage(LANG_MOVEGENS_UNKNOWN,(*itr)->GetMovementGeneratorType());
5618 break;
5621 return true;
5624 bool ChatHandler::HandleServerPLimitCommand(const char *args)
5626 if(*args)
5628 char* param = strtok((char*)args, " ");
5629 if(!param)
5630 return false;
5632 int l = strlen(param);
5634 if( strncmp(param,"player",l) == 0 )
5635 sWorld.SetPlayerLimit(-SEC_PLAYER);
5636 else if(strncmp(param,"moderator",l) == 0 )
5637 sWorld.SetPlayerLimit(-SEC_MODERATOR);
5638 else if(strncmp(param,"gamemaster",l) == 0 )
5639 sWorld.SetPlayerLimit(-SEC_GAMEMASTER);
5640 else if(strncmp(param,"administrator",l) == 0 )
5641 sWorld.SetPlayerLimit(-SEC_ADMINISTRATOR);
5642 else if(strncmp(param,"reset",l) == 0 )
5643 sWorld.SetPlayerLimit( sConfig.GetIntDefault("PlayerLimit", DEFAULT_PLAYER_LIMIT) );
5644 else
5646 int val = atoi(param);
5647 if(val < -SEC_ADMINISTRATOR) val = -SEC_ADMINISTRATOR;
5649 sWorld.SetPlayerLimit(val);
5652 // kick all low security level players
5653 if(sWorld.GetPlayerAmountLimit() > SEC_PLAYER)
5654 sWorld.KickAllLess(sWorld.GetPlayerSecurityLimit());
5657 uint32 pLimit = sWorld.GetPlayerAmountLimit();
5658 AccountTypes allowedAccountType = sWorld.GetPlayerSecurityLimit();
5659 char const* secName = "";
5660 switch(allowedAccountType)
5662 case SEC_PLAYER: secName = "Player"; break;
5663 case SEC_MODERATOR: secName = "Moderator"; break;
5664 case SEC_GAMEMASTER: secName = "Gamemaster"; break;
5665 case SEC_ADMINISTRATOR: secName = "Administrator"; break;
5666 default: secName = "<unknown>"; break;
5669 PSendSysMessage("Player limits: amount %u, min. security level %s.",pLimit,secName);
5671 return true;
5674 bool ChatHandler::HandleCastCommand(const char* args)
5676 if(!*args)
5677 return false;
5679 Unit* target = getSelectedUnit();
5681 if(!target)
5683 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5684 SetSentErrorMessage(true);
5685 return false;
5688 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5689 uint32 spell = extractSpellIdFromLink((char*)args);
5690 if(!spell)
5691 return false;
5693 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
5694 if(!spellInfo)
5695 return false;
5697 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
5699 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
5700 SetSentErrorMessage(true);
5701 return false;
5704 char* trig_str = strtok(NULL, " ");
5705 if(trig_str)
5707 int l = strlen(trig_str);
5708 if(strncmp(trig_str,"triggered",l) != 0 )
5709 return false;
5712 bool triggered = (trig_str != NULL);
5714 m_session->GetPlayer()->CastSpell(target,spell,triggered);
5716 return true;
5719 bool ChatHandler::HandleCastBackCommand(const char* args)
5721 Creature* caster = getSelectedCreature();
5723 if(!caster)
5725 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5726 SetSentErrorMessage(true);
5727 return false;
5730 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
5731 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5732 uint32 spell = extractSpellIdFromLink((char*)args);
5733 if(!spell || !sSpellStore.LookupEntry(spell))
5734 return false;
5736 char* trig_str = strtok(NULL, " ");
5737 if(trig_str)
5739 int l = strlen(trig_str);
5740 if(strncmp(trig_str,"triggered",l) != 0 )
5741 return false;
5744 bool triggered = (trig_str != NULL);
5746 caster->SetFacingToObject(m_session->GetPlayer());
5748 caster->CastSpell(m_session->GetPlayer(),spell,triggered);
5750 return true;
5753 bool ChatHandler::HandleCastDistCommand(const char* args)
5755 if(!*args)
5756 return false;
5758 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5759 uint32 spell = extractSpellIdFromLink((char*)args);
5760 if(!spell)
5761 return false;
5763 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
5764 if(!spellInfo)
5765 return false;
5767 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
5769 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
5770 SetSentErrorMessage(true);
5771 return false;
5774 char *distStr = strtok(NULL, " ");
5776 float dist = 0;
5778 if(distStr)
5779 sscanf(distStr, "%f", &dist);
5781 char* trig_str = strtok(NULL, " ");
5782 if(trig_str)
5784 int l = strlen(trig_str);
5785 if(strncmp(trig_str,"triggered",l) != 0 )
5786 return false;
5789 bool triggered = (trig_str != NULL);
5791 float x,y,z;
5792 m_session->GetPlayer()->GetClosePoint(x,y,z,dist);
5794 m_session->GetPlayer()->CastSpell(x,y,z,spell,triggered);
5795 return true;
5798 bool ChatHandler::HandleCastTargetCommand(const char* args)
5800 Creature* caster = getSelectedCreature();
5802 if(!caster)
5804 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5805 SetSentErrorMessage(true);
5806 return false;
5809 if(!caster->getVictim())
5811 SendSysMessage(LANG_SELECTED_TARGET_NOT_HAVE_VICTIM);
5812 SetSentErrorMessage(true);
5813 return false;
5816 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5817 uint32 spell = extractSpellIdFromLink((char*)args);
5818 if(!spell || !sSpellStore.LookupEntry(spell))
5819 return false;
5821 char* trig_str = strtok(NULL, " ");
5822 if(trig_str)
5824 int l = strlen(trig_str);
5825 if(strncmp(trig_str,"triggered",l) != 0 )
5826 return false;
5829 bool triggered = (trig_str != NULL);
5831 caster->SetFacingToObject(m_session->GetPlayer());
5833 caster->CastSpell(caster->getVictim(),spell,triggered);
5835 return true;
5839 ComeToMe command REQUIRED for 3rd party scripting library to have access to PointMovementGenerator
5840 Without this function 3rd party scripting library will get linking errors (unresolved external)
5841 when attempting to use the PointMovementGenerator
5843 bool ChatHandler::HandleComeToMeCommand(const char *args)
5845 Creature* caster = getSelectedCreature();
5847 if(!caster)
5849 SendSysMessage(LANG_SELECT_CREATURE);
5850 SetSentErrorMessage(true);
5851 return false;
5854 char* newFlagStr = strtok((char*)args, " ");
5856 if(!newFlagStr)
5857 return false;
5859 uint32 newFlags = atoi(newFlagStr);
5861 caster->SetMonsterMoveFlags(MonsterMovementFlags(newFlags));
5863 Player* pl = m_session->GetPlayer();
5865 caster->GetMotionMaster()->MovePoint(0, pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ());
5866 return true;
5869 bool ChatHandler::HandleCastSelfCommand(const char* args)
5871 if(!*args)
5872 return false;
5874 Unit* target = getSelectedUnit();
5876 if(!target)
5878 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5879 SetSentErrorMessage(true);
5880 return false;
5883 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5884 uint32 spell = extractSpellIdFromLink((char*)args);
5885 if(!spell)
5886 return false;
5888 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
5889 if(!spellInfo)
5890 return false;
5892 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
5894 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
5895 SetSentErrorMessage(true);
5896 return false;
5899 target->CastSpell(target,spell,false);
5901 return true;
5904 std::string GetTimeString(uint32 time)
5906 uint16 days = time / DAY, hours = (time % DAY) / HOUR, minute = (time % HOUR) / MINUTE;
5907 std::ostringstream ss;
5908 if(days) ss << days << "d ";
5909 if(hours) ss << hours << "h ";
5910 ss << minute << "m";
5911 return ss.str();
5914 bool ChatHandler::HandleInstanceListBindsCommand(const char* /*args*/)
5916 Player* player = getSelectedPlayer();
5917 if (!player) player = m_session->GetPlayer();
5918 uint32 counter = 0;
5919 for(uint8 i = 0; i < MAX_DIFFICULTY; ++i)
5921 Player::BoundInstancesMap &binds = player->GetBoundInstances(Difficulty(i));
5922 for(Player::BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end(); ++itr)
5924 InstanceSave *save = itr->second.save;
5925 std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
5926 if (const MapEntry* entry = sMapStore.LookupEntry(itr->first))
5928 PSendSysMessage("map: %d (%s) inst: %d perm: %s diff: %d canReset: %s TTR: %s",
5929 itr->first, entry->name[m_session->GetSessionDbcLocale()], save->GetInstanceId(), itr->second.perm ? "yes" : "no",
5930 save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str());
5932 else
5933 PSendSysMessage("bound for a nonexistant map %u", itr->first);
5934 counter++;
5937 PSendSysMessage("player binds: %d", counter);
5938 counter = 0;
5939 Group *group = player->GetGroup();
5940 if(group)
5942 for(uint8 i = 0; i < MAX_DIFFICULTY; ++i)
5944 Group::BoundInstancesMap &binds = group->GetBoundInstances(Difficulty(i));
5945 for(Group::BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end(); ++itr)
5947 InstanceSave *save = itr->second.save;
5948 std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
5949 if (const MapEntry* entry = sMapStore.LookupEntry(itr->first))
5951 PSendSysMessage("map: %d (%s) inst: %d perm: %s diff: %d canReset: %s TTR: %s",
5952 itr->first, entry->name[m_session->GetSessionDbcLocale()], save->GetInstanceId(), itr->second.perm ? "yes" : "no",
5953 save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str());
5955 else
5956 PSendSysMessage("bound for a nonexistant map %u", itr->first);
5957 counter++;
5961 PSendSysMessage("group binds: %d", counter);
5963 return true;
5966 bool ChatHandler::HandleInstanceUnbindCommand(const char* args)
5968 if(!*args)
5969 return false;
5971 Player* player = getSelectedPlayer();
5972 if (!player)
5973 player = m_session->GetPlayer();
5974 uint32 counter = 0;
5975 uint32 mapid = 0;
5976 bool got_map = false;
5978 if (strncmp(args,"all",strlen(args)) != 0)
5980 if(!isNumeric(args[0]))
5981 return false;
5983 got_map = true;
5984 mapid = atoi(args);
5987 for(uint8 i = 0; i < MAX_DIFFICULTY; ++i)
5989 Player::BoundInstancesMap &binds = player->GetBoundInstances(Difficulty(i));
5990 for(Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end();)
5992 if (got_map && mapid != itr->first)
5994 ++itr;
5995 continue;
5997 if(itr->first != player->GetMapId())
5999 InstanceSave *save = itr->second.save;
6000 std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
6002 if (const MapEntry* entry = sMapStore.LookupEntry(itr->first))
6004 PSendSysMessage("unbinding map: %d (%s) inst: %d perm: %s diff: %d canReset: %s TTR: %s",
6005 itr->first, entry->name[m_session->GetSessionDbcLocale()], save->GetInstanceId(), itr->second.perm ? "yes" : "no",
6006 save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str());
6008 else
6009 PSendSysMessage("bound for a nonexistant map %u", itr->first);
6010 player->UnbindInstance(itr, Difficulty(i));
6011 counter++;
6013 else
6014 ++itr;
6017 PSendSysMessage("instances unbound: %d", counter);
6018 return true;
6021 bool ChatHandler::HandleInstanceStatsCommand(const char* /*args*/)
6023 PSendSysMessage("instances loaded: %d", sMapMgr.GetNumInstances());
6024 PSendSysMessage("players in instances: %d", sMapMgr.GetNumPlayersInInstances());
6025 PSendSysMessage("instance saves: %d", sInstanceSaveMgr.GetNumInstanceSaves());
6026 PSendSysMessage("players bound: %d", sInstanceSaveMgr.GetNumBoundPlayersTotal());
6027 PSendSysMessage("groups bound: %d", sInstanceSaveMgr.GetNumBoundGroupsTotal());
6028 return true;
6031 bool ChatHandler::HandleInstanceSaveDataCommand(const char * /*args*/)
6033 Player* pl = m_session->GetPlayer();
6035 Map* map = pl->GetMap();
6036 if (!map->IsDungeon())
6038 PSendSysMessage("Map is not a dungeon.");
6039 SetSentErrorMessage(true);
6040 return false;
6043 if (!((InstanceMap*)map)->GetInstanceData())
6045 PSendSysMessage("Map has no instance data.");
6046 SetSentErrorMessage(true);
6047 return false;
6050 ((InstanceMap*)map)->GetInstanceData()->SaveToDB();
6051 return true;
6054 /// Display the list of GMs
6055 bool ChatHandler::HandleGMListFullCommand(const char* /*args*/)
6057 ///- Get the accounts with GM Level >0
6058 QueryResult *result = loginDatabase.Query( "SELECT username,gmlevel FROM account WHERE gmlevel > 0" );
6059 if(result)
6061 SendSysMessage(LANG_GMLIST);
6062 SendSysMessage("========================");
6063 SendSysMessage(LANG_GMLIST_HEADER);
6064 SendSysMessage("========================");
6066 ///- Circle through them. Display username and GM level
6069 Field *fields = result->Fetch();
6070 PSendSysMessage("|%15s|%6s|", fields[0].GetString(),fields[1].GetString());
6071 }while( result->NextRow() );
6073 PSendSysMessage("========================");
6074 delete result;
6076 else
6077 PSendSysMessage(LANG_GMLIST_EMPTY);
6078 return true;
6081 /// Define the 'Message of the day' for the realm
6082 bool ChatHandler::HandleServerSetMotdCommand(const char* args)
6084 sWorld.SetMotd(args);
6085 PSendSysMessage(LANG_MOTD_NEW, args);
6086 return true;
6089 /// Set/Unset the expansion level for an account
6090 bool ChatHandler::HandleAccountSetAddonCommand(const char* args)
6092 ///- Get the command line arguments
6093 char *szAcc = strtok((char*)args," ");
6094 char *szExp = strtok(NULL," ");
6096 if(!szAcc)
6097 return false;
6099 std::string account_name;
6100 uint32 account_id;
6102 if (!szExp)
6104 Player* player = getSelectedPlayer();
6105 if (!player)
6106 return false;
6108 account_id = player->GetSession()->GetAccountId();
6109 sAccountMgr.GetName(account_id,account_name);
6110 szExp = szAcc;
6112 else
6114 ///- Convert Account name to Upper Format
6115 account_name = szAcc;
6116 if (!AccountMgr::normalizeString(account_name))
6118 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
6119 SetSentErrorMessage(true);
6120 return false;
6123 account_id = sAccountMgr.GetId(account_name);
6124 if (!account_id)
6126 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
6127 SetSentErrorMessage(true);
6128 return false;
6133 // Let set addon state only for lesser (strong) security level
6134 // or to self account
6135 if (m_session && m_session->GetAccountId () != account_id &&
6136 HasLowerSecurityAccount (NULL,account_id,true))
6137 return false;
6139 int lev=atoi(szExp); //get int anyway (0 if error)
6140 if(lev < 0)
6141 return false;
6143 // No SQL injection
6144 loginDatabase.PExecute("UPDATE account SET expansion = '%d' WHERE id = '%u'",lev,account_id);
6145 PSendSysMessage(LANG_ACCOUNT_SETADDON,account_name.c_str(),account_id,lev);
6146 return true;
6149 //Send items by mail
6150 bool ChatHandler::HandleSendItemsCommand(const char* args)
6152 // format: name "subject text" "mail text" item1[:count1] item2[:count2] ... item12[:count12]
6153 Player* receiver;
6154 uint64 receiver_guid;
6155 std::string receiver_name;
6156 if(!extractPlayerTarget((char*)args,&receiver,&receiver_guid,&receiver_name))
6157 return false;
6159 char* tail1 = strtok(NULL, "");
6160 if(!tail1)
6161 return false;
6163 char* msgSubject = extractQuotedArg(tail1);
6164 if (!msgSubject)
6165 return false;
6167 char* tail2 = strtok(NULL, "");
6168 if(!tail2)
6169 return false;
6171 char* msgText = extractQuotedArg(tail2);
6172 if (!msgText)
6173 return false;
6175 // msgSubject, msgText isn't NUL after prev. check
6176 std::string subject = msgSubject;
6177 std::string text = msgText;
6179 // extract items
6180 typedef std::pair<uint32,uint32> ItemPair;
6181 typedef std::list< ItemPair > ItemPairs;
6182 ItemPairs items;
6184 // get all tail string
6185 char* tail = strtok(NULL, "");
6187 // get from tail next item str
6188 while(char* itemStr = strtok(tail, " "))
6190 // and get new tail
6191 tail = strtok(NULL, "");
6193 // parse item str
6194 char* itemIdStr = strtok(itemStr, ":");
6195 char* itemCountStr = strtok(NULL, " ");
6197 uint32 item_id = atoi(itemIdStr);
6198 if(!item_id)
6199 return false;
6201 ItemPrototype const* item_proto = ObjectMgr::GetItemPrototype(item_id);
6202 if(!item_proto)
6204 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
6205 SetSentErrorMessage(true);
6206 return false;
6209 uint32 item_count = itemCountStr ? atoi(itemCountStr) : 1;
6210 if (item_count < 1 || (item_proto->MaxCount > 0 && item_count > uint32(item_proto->MaxCount)))
6212 PSendSysMessage(LANG_COMMAND_INVALID_ITEM_COUNT, item_count,item_id);
6213 SetSentErrorMessage(true);
6214 return false;
6217 while(item_count > item_proto->GetMaxStackSize())
6219 items.push_back(ItemPair(item_id,item_proto->GetMaxStackSize()));
6220 item_count -= item_proto->GetMaxStackSize();
6223 items.push_back(ItemPair(item_id,item_count));
6225 if(items.size() > MAX_MAIL_ITEMS)
6227 PSendSysMessage(LANG_COMMAND_MAIL_ITEMS_LIMIT, MAX_MAIL_ITEMS);
6228 SetSentErrorMessage(true);
6229 return false;
6233 // from console show not existed sender
6234 MailSender sender(MAIL_NORMAL,m_session ? m_session->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM);
6236 uint32 itemTextId = !text.empty() ? sObjectMgr.CreateItemText( text ) : 0;
6238 // fill mail
6239 MailDraft draft(subject, itemTextId);
6241 for(ItemPairs::const_iterator itr = items.begin(); itr != items.end(); ++itr)
6243 if(Item* item = Item::CreateItem(itr->first,itr->second,m_session ? m_session->GetPlayer() : 0))
6245 item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted
6246 draft.AddItem(item);
6250 draft.SendMailTo(MailReceiver(receiver,GUID_LOPART(receiver_guid)), sender);
6252 std::string nameLink = playerLink(receiver_name);
6253 PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
6254 return true;
6257 ///Send money by mail
6258 bool ChatHandler::HandleSendMoneyCommand(const char* args)
6260 /// format: name "subject text" "mail text" money
6262 Player* receiver;
6263 uint64 receiver_guid;
6264 std::string receiver_name;
6265 if(!extractPlayerTarget((char*)args,&receiver,&receiver_guid,&receiver_name))
6266 return false;
6268 char* tail1 = strtok(NULL, "");
6269 if (!tail1)
6270 return false;
6272 char* msgSubject = extractQuotedArg(tail1);
6273 if (!msgSubject)
6274 return false;
6276 char* tail2 = strtok(NULL, "");
6277 if (!tail2)
6278 return false;
6280 char* msgText = extractQuotedArg(tail2);
6281 if (!msgText)
6282 return false;
6284 char* money_str = strtok(NULL, "");
6285 int32 money = money_str ? atoi(money_str) : 0;
6286 if (money <= 0)
6287 return false;
6289 // msgSubject, msgText isn't NUL after prev. check
6290 std::string subject = msgSubject;
6291 std::string text = msgText;
6293 // from console show not existed sender
6294 MailSender sender(MAIL_NORMAL,m_session ? m_session->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM);
6296 uint32 itemTextId = !text.empty() ? sObjectMgr.CreateItemText( text ) : 0;
6298 MailDraft(subject, itemTextId)
6299 .AddMoney(money)
6300 .SendMailTo(MailReceiver(receiver,GUID_LOPART(receiver_guid)),sender);
6302 std::string nameLink = playerLink(receiver_name);
6303 PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
6304 return true;
6307 /// Send a message to a player in game
6308 bool ChatHandler::HandleSendMessageCommand(const char* args)
6310 ///- Find the player
6311 Player *rPlayer;
6312 if(!extractPlayerTarget((char*)args,&rPlayer))
6313 return false;
6315 char* msg_str = strtok(NULL, "");
6316 if(!msg_str)
6317 return false;
6319 ///- Check that he is not logging out.
6320 if(rPlayer->GetSession()->isLogingOut())
6322 SendSysMessage(LANG_PLAYER_NOT_FOUND);
6323 SetSentErrorMessage(true);
6324 return false;
6327 ///- Send the message
6328 //Use SendAreaTriggerMessage for fastest delivery.
6329 rPlayer->GetSession()->SendAreaTriggerMessage("%s", msg_str);
6330 rPlayer->GetSession()->SendAreaTriggerMessage("|cffff0000[Message from administrator]:|r");
6332 //Confirmation message
6333 std::string nameLink = GetNameLink(rPlayer);
6334 PSendSysMessage(LANG_SENDMESSAGE,nameLink.c_str(),msg_str);
6335 return true;
6338 bool ChatHandler::HandleFlushArenaPointsCommand(const char * /*args*/)
6340 sBattleGroundMgr.DistributeArenaPoints();
6341 return true;
6344 bool ChatHandler::HandleModifyGenderCommand(const char *args)
6346 if(!*args)
6347 return false;
6349 Player *player = getSelectedPlayer();
6351 if(!player)
6353 PSendSysMessage(LANG_PLAYER_NOT_FOUND);
6354 SetSentErrorMessage(true);
6355 return false;
6358 PlayerInfo const* info = sObjectMgr.GetPlayerInfo(player->getRace(), player->getClass());
6359 if(!info)
6360 return false;
6362 char const* gender_str = (char*)args;
6363 int gender_len = strlen(gender_str);
6365 Gender gender;
6367 if(!strncmp(gender_str, "male", gender_len)) // MALE
6369 if(player->getGender() == GENDER_MALE)
6370 return true;
6372 gender = GENDER_MALE;
6374 else if (!strncmp(gender_str, "female", gender_len)) // FEMALE
6376 if(player->getGender() == GENDER_FEMALE)
6377 return true;
6379 gender = GENDER_FEMALE;
6381 else
6383 SendSysMessage(LANG_MUST_MALE_OR_FEMALE);
6384 SetSentErrorMessage(true);
6385 return false;
6388 // Set gender
6389 player->SetByteValue(UNIT_FIELD_BYTES_0, 2, gender);
6390 player->SetByteValue(PLAYER_BYTES_3, 0, gender);
6392 // Change display ID
6393 player->InitDisplayIds();
6395 char const* gender_full = gender ? "female" : "male";
6397 PSendSysMessage(LANG_YOU_CHANGE_GENDER, GetNameLink(player).c_str(), gender_full);
6399 if (needReportToTarget(player))
6400 ChatHandler(player).PSendSysMessage(LANG_YOUR_GENDER_CHANGED, gender_full, GetNameLink().c_str());
6402 return true;