[9411] More SpellEffectIndex using in apropriate cases
[getmangos.git] / src / game / Level3.cpp
blob73918b927c1a1630db2456b7c9681d67f5aad325
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 HandleReloadAllGossipsCommand("");
69 HandleReloadAllLocalesCommand("");
71 HandleReloadMailLevelRewardCommand("");
72 HandleReloadCommandCommand("");
73 HandleReloadReservedNameCommand("");
74 HandleReloadMangosStringCommand("");
75 HandleReloadGameTeleCommand("");
76 return true;
79 bool ChatHandler::HandleReloadAllAchievementCommand(const char*)
81 HandleReloadAchievementCriteriaRequirementCommand("");
82 HandleReloadAchievementRewardCommand("");
83 return true;
86 bool ChatHandler::HandleReloadAllAreaCommand(const char*)
88 //HandleReloadQuestAreaTriggersCommand(""); -- reloaded in HandleReloadAllQuestCommand
89 HandleReloadAreaTriggerTeleportCommand("");
90 HandleReloadAreaTriggerTavernCommand("");
91 HandleReloadGameGraveyardZoneCommand("");
92 return true;
95 bool ChatHandler::HandleReloadAllLootCommand(const char*)
97 sLog.outString( "Re-Loading Loot Tables..." );
98 LoadLootTables();
99 SendGlobalSysMessage("DB tables `*_loot_template` reloaded.");
100 return true;
103 bool ChatHandler::HandleReloadAllNpcCommand(const char* args)
105 if(*args!='a') // will be reloaded from all_gossips
106 HandleReloadNpcGossipCommand("a");
107 HandleReloadNpcTrainerCommand("a");
108 HandleReloadNpcVendorCommand("a");
109 HandleReloadPointsOfInterestCommand("a");
110 HandleReloadSpellClickSpellsCommand("a");
111 return true;
114 bool ChatHandler::HandleReloadAllQuestCommand(const char* /*args*/)
116 HandleReloadQuestAreaTriggersCommand("a");
117 HandleReloadQuestPOICommand("a");
118 HandleReloadQuestTemplateCommand("a");
120 sLog.outString( "Re-Loading Quests Relations..." );
121 sObjectMgr.LoadQuestRelations();
122 SendGlobalSysMessage("DB tables `*_questrelation` and `*_involvedrelation` reloaded.");
123 return true;
126 bool ChatHandler::HandleReloadAllScriptsCommand(const char*)
128 if(sWorld.IsScriptScheduled())
130 PSendSysMessage("DB scripts used currently, please attempt reload later.");
131 SetSentErrorMessage(true);
132 return false;
135 sLog.outString( "Re-Loading Scripts..." );
136 HandleReloadGameObjectScriptsCommand("a");
137 HandleReloadGossipScriptsCommand("a");
138 HandleReloadEventScriptsCommand("a");
139 HandleReloadQuestEndScriptsCommand("a");
140 HandleReloadQuestStartScriptsCommand("a");
141 HandleReloadSpellScriptsCommand("a");
142 SendGlobalSysMessage("DB tables `*_scripts` reloaded.");
143 HandleReloadDbScriptStringCommand("a");
144 return true;
147 bool ChatHandler::HandleReloadAllEventAICommand(const char*)
149 HandleReloadEventAITextsCommand("a");
150 HandleReloadEventAISummonsCommand("a");
151 HandleReloadEventAIScriptsCommand("a");
152 return true;
155 bool ChatHandler::HandleReloadAllSpellCommand(const char*)
157 HandleReloadSkillDiscoveryTemplateCommand("a");
158 HandleReloadSkillExtraItemTemplateCommand("a");
159 HandleReloadSpellAreaCommand("a");
160 HandleReloadSpellChainCommand("a");
161 HandleReloadSpellElixirCommand("a");
162 HandleReloadSpellLearnSpellCommand("a");
163 HandleReloadSpellProcEventCommand("a");
164 HandleReloadSpellBonusesCommand("a");
165 HandleReloadSpellProcItemEnchantCommand("a");
166 HandleReloadSpellScriptTargetCommand("a");
167 HandleReloadSpellTargetPositionCommand("a");
168 HandleReloadSpellThreatsCommand("a");
169 HandleReloadSpellPetAurasCommand("a");
170 return true;
173 bool ChatHandler::HandleReloadAllGossipsCommand(const char* args)
175 HandleReloadGossipMenuCommand("a");
176 HandleReloadGossipMenuOptionCommand("a");
177 if(*args!='a') // already reload from all_scripts
178 HandleReloadGossipScriptsCommand("a");
179 HandleReloadNpcGossipCommand("a");
180 HandleReloadPointsOfInterestCommand("a");
181 return true;
184 bool ChatHandler::HandleReloadAllItemCommand(const char*)
186 HandleReloadPageTextsCommand("a");
187 HandleReloadItemEnchantementsCommand("a");
188 HandleReloadItemRequiredTragetCommand("a");
189 return true;
192 bool ChatHandler::HandleReloadAllLocalesCommand(const char* /*args*/)
194 HandleReloadLocalesAchievementRewardCommand("a");
195 HandleReloadLocalesCreatureCommand("a");
196 HandleReloadLocalesGameobjectCommand("a");
197 HandleReloadLocalesGossipMenuOptionCommand("a");
198 HandleReloadLocalesItemCommand("a");
199 HandleReloadLocalesNpcTextCommand("a");
200 HandleReloadLocalesPageTextCommand("a");
201 HandleReloadLocalesPointsOfInterestCommand("a");
202 HandleReloadLocalesQuestCommand("a");
203 return true;
206 bool ChatHandler::HandleReloadConfigCommand(const char* /*args*/)
208 sLog.outString( "Re-Loading config settings..." );
209 sWorld.LoadConfigSettings(true);
210 sMapMgr.InitializeVisibilityDistanceInfo();
211 SendGlobalSysMessage("World config settings reloaded.");
212 return true;
215 bool ChatHandler::HandleReloadAchievementCriteriaRequirementCommand(const char*)
217 sLog.outString( "Re-Loading Additional Achievement Criteria Requirements Data..." );
218 sAchievementMgr.LoadAchievementCriteriaRequirements();
219 SendGlobalSysMessage("DB table `achievement_criteria_requirement` reloaded.");
220 return true;
223 bool ChatHandler::HandleReloadAchievementRewardCommand(const char*)
225 sLog.outString( "Re-Loading Achievement Reward Data..." );
226 sAchievementMgr.LoadRewards();
227 SendGlobalSysMessage("DB table `achievement_reward` reloaded.");
228 return true;
231 bool ChatHandler::HandleReloadAreaTriggerTavernCommand(const char*)
233 sLog.outString( "Re-Loading Tavern Area Triggers..." );
234 sObjectMgr.LoadTavernAreaTriggers();
235 SendGlobalSysMessage("DB table `areatrigger_tavern` reloaded.");
236 return true;
239 bool ChatHandler::HandleReloadAreaTriggerTeleportCommand(const char*)
241 sLog.outString( "Re-Loading AreaTrigger teleport definitions..." );
242 sObjectMgr.LoadAreaTriggerTeleports();
243 SendGlobalSysMessage("DB table `areatrigger_teleport` reloaded.");
244 return true;
247 bool ChatHandler::HandleReloadCommandCommand(const char*)
249 load_command_table = true;
250 SendGlobalSysMessage("DB table `command` will be reloaded at next chat command use.");
251 return true;
254 bool ChatHandler::HandleReloadCreatureQuestRelationsCommand(const char*)
256 sLog.outString( "Loading Quests Relations... (`creature_questrelation`)" );
257 sObjectMgr.LoadCreatureQuestRelations();
258 SendGlobalSysMessage("DB table `creature_questrelation` (creature quest givers) reloaded.");
259 return true;
262 bool ChatHandler::HandleReloadCreatureQuestInvRelationsCommand(const char*)
264 sLog.outString( "Loading Quests Relations... (`creature_involvedrelation`)" );
265 sObjectMgr.LoadCreatureInvolvedRelations();
266 SendGlobalSysMessage("DB table `creature_involvedrelation` (creature quest takers) reloaded.");
267 return true;
270 bool ChatHandler::HandleReloadGossipMenuCommand(const char*)
272 sLog.outString( "Re-Loading `gossip_menu` Table!" );
273 sObjectMgr.LoadGossipMenu();
274 SendGlobalSysMessage("DB table `gossip_menu` reloaded.");
275 return true;
278 bool ChatHandler::HandleReloadGossipMenuOptionCommand(const char*)
280 sLog.outString( "Re-Loading `gossip_menu_option` Table!" );
281 sObjectMgr.LoadGossipMenuItems();
282 SendGlobalSysMessage("DB table `gossip_menu_option` reloaded.");
283 return true;
286 bool ChatHandler::HandleReloadGossipScriptsCommand(const char* arg)
288 if(sWorld.IsScriptScheduled())
290 SendSysMessage("DB scripts used currently, please attempt reload later.");
291 SetSentErrorMessage(true);
292 return false;
295 if(*arg!='a')
296 sLog.outString( "Re-Loading Scripts from `gossip_scripts`...");
298 sObjectMgr.LoadGossipScripts();
300 if(*arg!='a')
301 SendGlobalSysMessage("DB table `gossip_scripts` reloaded.");
303 return true;
306 bool ChatHandler::HandleReloadGOQuestRelationsCommand(const char*)
308 sLog.outString( "Loading Quests Relations... (`gameobject_questrelation`)" );
309 sObjectMgr.LoadGameobjectQuestRelations();
310 SendGlobalSysMessage("DB table `gameobject_questrelation` (gameobject quest givers) reloaded.");
311 return true;
314 bool ChatHandler::HandleReloadGOQuestInvRelationsCommand(const char*)
316 sLog.outString( "Loading Quests Relations... (`gameobject_involvedrelation`)" );
317 sObjectMgr.LoadGameobjectInvolvedRelations();
318 SendGlobalSysMessage("DB table `gameobject_involvedrelation` (gameobject quest takers) reloaded.");
319 return true;
322 bool ChatHandler::HandleReloadQuestAreaTriggersCommand(const char*)
324 sLog.outString( "Re-Loading Quest Area Triggers..." );
325 sObjectMgr.LoadQuestAreaTriggers();
326 SendGlobalSysMessage("DB table `areatrigger_involvedrelation` (quest area triggers) reloaded.");
327 return true;
330 bool ChatHandler::HandleReloadQuestTemplateCommand(const char*)
332 sLog.outString( "Re-Loading Quest Templates..." );
333 sObjectMgr.LoadQuests();
334 SendGlobalSysMessage("DB table `quest_template` (quest definitions) reloaded.");
336 /// dependent also from `gameobject` but this table not reloaded anyway
337 sLog.outString( "Re-Loading GameObjects for quests..." );
338 sObjectMgr.LoadGameObjectForQuests();
339 SendGlobalSysMessage("Data GameObjects for quests reloaded.");
340 return true;
343 bool ChatHandler::HandleReloadLootTemplatesCreatureCommand(const char*)
345 sLog.outString( "Re-Loading Loot Tables... (`creature_loot_template`)" );
346 LoadLootTemplates_Creature();
347 LootTemplates_Creature.CheckLootRefs();
348 SendGlobalSysMessage("DB table `creature_loot_template` reloaded.");
349 return true;
352 bool ChatHandler::HandleReloadLootTemplatesDisenchantCommand(const char*)
354 sLog.outString( "Re-Loading Loot Tables... (`disenchant_loot_template`)" );
355 LoadLootTemplates_Disenchant();
356 LootTemplates_Disenchant.CheckLootRefs();
357 SendGlobalSysMessage("DB table `disenchant_loot_template` reloaded.");
358 return true;
361 bool ChatHandler::HandleReloadLootTemplatesFishingCommand(const char*)
363 sLog.outString( "Re-Loading Loot Tables... (`fishing_loot_template`)" );
364 LoadLootTemplates_Fishing();
365 LootTemplates_Fishing.CheckLootRefs();
366 SendGlobalSysMessage("DB table `fishing_loot_template` reloaded.");
367 return true;
370 bool ChatHandler::HandleReloadLootTemplatesGameobjectCommand(const char*)
372 sLog.outString( "Re-Loading Loot Tables... (`gameobject_loot_template`)" );
373 LoadLootTemplates_Gameobject();
374 LootTemplates_Gameobject.CheckLootRefs();
375 SendGlobalSysMessage("DB table `gameobject_loot_template` reloaded.");
376 return true;
379 bool ChatHandler::HandleReloadLootTemplatesItemCommand(const char*)
381 sLog.outString( "Re-Loading Loot Tables... (`item_loot_template`)" );
382 LoadLootTemplates_Item();
383 LootTemplates_Item.CheckLootRefs();
384 SendGlobalSysMessage("DB table `item_loot_template` reloaded.");
385 return true;
388 bool ChatHandler::HandleReloadLootTemplatesMillingCommand(const char*)
390 sLog.outString( "Re-Loading Loot Tables... (`milling_loot_template`)" );
391 LoadLootTemplates_Milling();
392 LootTemplates_Milling.CheckLootRefs();
393 SendGlobalSysMessage("DB table `milling_loot_template` reloaded.");
394 return true;
397 bool ChatHandler::HandleReloadLootTemplatesPickpocketingCommand(const char*)
399 sLog.outString( "Re-Loading Loot Tables... (`pickpocketing_loot_template`)" );
400 LoadLootTemplates_Pickpocketing();
401 LootTemplates_Pickpocketing.CheckLootRefs();
402 SendGlobalSysMessage("DB table `pickpocketing_loot_template` reloaded.");
403 return true;
406 bool ChatHandler::HandleReloadLootTemplatesProspectingCommand(const char*)
408 sLog.outString( "Re-Loading Loot Tables... (`prospecting_loot_template`)" );
409 LoadLootTemplates_Prospecting();
410 LootTemplates_Prospecting.CheckLootRefs();
411 SendGlobalSysMessage("DB table `prospecting_loot_template` reloaded.");
412 return true;
415 bool ChatHandler::HandleReloadLootTemplatesMailCommand(const char*)
417 sLog.outString( "Re-Loading Loot Tables... (`mail_loot_template`)" );
418 LoadLootTemplates_Mail();
419 LootTemplates_Mail.CheckLootRefs();
420 SendGlobalSysMessage("DB table `mail_loot_template` reloaded.");
421 return true;
424 bool ChatHandler::HandleReloadLootTemplatesReferenceCommand(const char*)
426 sLog.outString( "Re-Loading Loot Tables... (`reference_loot_template`)" );
427 LoadLootTemplates_Reference();
428 SendGlobalSysMessage("DB table `reference_loot_template` reloaded.");
429 return true;
432 bool ChatHandler::HandleReloadLootTemplatesSkinningCommand(const char*)
434 sLog.outString( "Re-Loading Loot Tables... (`skinning_loot_template`)" );
435 LoadLootTemplates_Skinning();
436 LootTemplates_Skinning.CheckLootRefs();
437 SendGlobalSysMessage("DB table `skinning_loot_template` reloaded.");
438 return true;
441 bool ChatHandler::HandleReloadLootTemplatesSpellCommand(const char*)
443 sLog.outString( "Re-Loading Loot Tables... (`spell_loot_template`)" );
444 LoadLootTemplates_Spell();
445 LootTemplates_Spell.CheckLootRefs();
446 SendGlobalSysMessage("DB table `spell_loot_template` reloaded.");
447 return true;
450 bool ChatHandler::HandleReloadMangosStringCommand(const char*)
452 sLog.outString( "Re-Loading mangos_string Table!" );
453 sObjectMgr.LoadMangosStrings();
454 SendGlobalSysMessage("DB table `mangos_string` reloaded.");
455 return true;
458 bool ChatHandler::HandleReloadNpcGossipCommand(const char*)
460 sLog.outString( "Re-Loading `npc_gossip` Table!" );
461 sObjectMgr.LoadNpcTextId();
462 SendGlobalSysMessage("DB table `npc_gossip` reloaded.");
463 return true;
466 bool ChatHandler::HandleReloadNpcTrainerCommand(const char*)
468 sLog.outString( "Re-Loading `npc_trainer` Table!" );
469 sObjectMgr.LoadTrainerSpell();
470 SendGlobalSysMessage("DB table `npc_trainer` reloaded.");
471 return true;
474 bool ChatHandler::HandleReloadNpcVendorCommand(const char*)
476 sLog.outString( "Re-Loading `npc_vendor` Table!" );
477 sObjectMgr.LoadVendors();
478 SendGlobalSysMessage("DB table `npc_vendor` reloaded.");
479 return true;
482 bool ChatHandler::HandleReloadPointsOfInterestCommand(const char*)
484 sLog.outString( "Re-Loading `points_of_interest` Table!" );
485 sObjectMgr.LoadPointsOfInterest();
486 SendGlobalSysMessage("DB table `points_of_interest` reloaded.");
487 return true;
490 bool ChatHandler::HandleReloadQuestPOICommand(const char*)
492 sLog.outString( "Re-Loading `quest_poi` and `quest_poi_points` Tables!" );
493 sObjectMgr.LoadQuestPOI();
494 SendGlobalSysMessage("DB Table `quest_poi` and `quest_poi_points` reloaded.");
495 return true;
498 bool ChatHandler::HandleReloadSpellClickSpellsCommand(const char*)
500 sLog.outString( "Re-Loading `npc_spellclick_spells` Table!" );
501 sObjectMgr.LoadNPCSpellClickSpells();
502 SendGlobalSysMessage("DB table `npc_spellclick_spells` reloaded.");
503 return true;
506 bool ChatHandler::HandleReloadReservedNameCommand(const char*)
508 sLog.outString( "Loading ReservedNames... (`reserved_name`)" );
509 sObjectMgr.LoadReservedPlayersNames();
510 SendGlobalSysMessage("DB table `reserved_name` (player reserved names) reloaded.");
511 return true;
514 bool ChatHandler::HandleReloadSkillDiscoveryTemplateCommand(const char* /*args*/)
516 sLog.outString( "Re-Loading Skill Discovery Table..." );
517 LoadSkillDiscoveryTable();
518 SendGlobalSysMessage("DB table `skill_discovery_template` (recipes discovered at crafting) reloaded.");
519 return true;
522 bool ChatHandler::HandleReloadSkillExtraItemTemplateCommand(const char* /*args*/)
524 sLog.outString( "Re-Loading Skill Extra Item Table..." );
525 LoadSkillExtraItemTable();
526 SendGlobalSysMessage("DB table `skill_extra_item_template` (extra item creation when crafting) reloaded.");
527 return true;
530 bool ChatHandler::HandleReloadSkillFishingBaseLevelCommand(const char* /*args*/)
532 sLog.outString( "Re-Loading Skill Fishing base level requirements..." );
533 sObjectMgr.LoadFishingBaseSkillLevel();
534 SendGlobalSysMessage("DB table `skill_fishing_base_level` (fishing base level for zone/subzone) reloaded.");
535 return true;
538 bool ChatHandler::HandleReloadSpellAreaCommand(const char*)
540 sLog.outString( "Re-Loading SpellArea Data..." );
541 sSpellMgr.LoadSpellAreas();
542 SendGlobalSysMessage("DB table `spell_area` (spell dependences from area/quest/auras state) reloaded.");
543 return true;
546 bool ChatHandler::HandleReloadSpellChainCommand(const char*)
548 sLog.outString( "Re-Loading Spell Chain Data... " );
549 sSpellMgr.LoadSpellChains();
550 SendGlobalSysMessage("DB table `spell_chain` (spell ranks) reloaded.");
551 return true;
554 bool ChatHandler::HandleReloadSpellElixirCommand(const char*)
556 sLog.outString( "Re-Loading Spell Elixir types..." );
557 sSpellMgr.LoadSpellElixirs();
558 SendGlobalSysMessage("DB table `spell_elixir` (spell elixir types) reloaded.");
559 return true;
562 bool ChatHandler::HandleReloadSpellLearnSpellCommand(const char*)
564 sLog.outString( "Re-Loading Spell Learn Spells..." );
565 sSpellMgr.LoadSpellLearnSpells();
566 SendGlobalSysMessage("DB table `spell_learn_spell` reloaded.");
567 return true;
570 bool ChatHandler::HandleReloadSpellProcEventCommand(const char*)
572 sLog.outString( "Re-Loading Spell Proc Event conditions..." );
573 sSpellMgr.LoadSpellProcEvents();
574 SendGlobalSysMessage("DB table `spell_proc_event` (spell proc trigger requirements) reloaded.");
575 return true;
578 bool ChatHandler::HandleReloadSpellBonusesCommand(const char*)
580 sLog.outString( "Re-Loading Spell Bonus Data..." );
581 sSpellMgr.LoadSpellBonusess();
582 SendGlobalSysMessage("DB table `spell_bonus_data` (spell damage/healing coefficients) reloaded.");
583 return true;
586 bool ChatHandler::HandleReloadSpellProcItemEnchantCommand(const char*)
588 sLog.outString( "Re-Loading Spell Proc Item Enchant..." );
589 sSpellMgr.LoadSpellProcItemEnchant();
590 SendGlobalSysMessage("DB table `spell_proc_item_enchant` (item enchantment ppm) reloaded.");
591 return true;
594 bool ChatHandler::HandleReloadSpellScriptTargetCommand(const char*)
596 sLog.outString( "Re-Loading SpellsScriptTarget..." );
597 sSpellMgr.LoadSpellScriptTarget();
598 SendGlobalSysMessage("DB table `spell_script_target` (spell targets selection in case specific creature/GO requirements) reloaded.");
599 return true;
602 bool ChatHandler::HandleReloadSpellTargetPositionCommand(const char*)
604 sLog.outString( "Re-Loading Spell target coordinates..." );
605 sSpellMgr.LoadSpellTargetPositions();
606 SendGlobalSysMessage("DB table `spell_target_position` (destination coordinates for spell targets) reloaded.");
607 return true;
610 bool ChatHandler::HandleReloadSpellThreatsCommand(const char*)
612 sLog.outString( "Re-Loading Aggro Spells Definitions...");
613 sSpellMgr.LoadSpellThreats();
614 SendGlobalSysMessage("DB table `spell_threat` (spell aggro definitions) reloaded.");
615 return true;
618 bool ChatHandler::HandleReloadSpellPetAurasCommand(const char*)
620 sLog.outString( "Re-Loading Spell pet auras...");
621 sSpellMgr.LoadSpellPetAuras();
622 SendGlobalSysMessage("DB table `spell_pet_auras` reloaded.");
623 return true;
626 bool ChatHandler::HandleReloadPageTextsCommand(const char*)
628 sLog.outString( "Re-Loading Page Texts..." );
629 sObjectMgr.LoadPageTexts();
630 SendGlobalSysMessage("DB table `page_texts` reloaded.");
631 return true;
634 bool ChatHandler::HandleReloadItemEnchantementsCommand(const char*)
636 sLog.outString( "Re-Loading Item Random Enchantments Table..." );
637 LoadRandomEnchantmentsTable();
638 SendGlobalSysMessage("DB table `item_enchantment_template` reloaded.");
639 return true;
642 bool ChatHandler::HandleReloadItemRequiredTragetCommand(const char*)
644 sLog.outString( "Re-Loading Item Required Targets Table..." );
645 sObjectMgr.LoadItemRequiredTarget();
646 SendGlobalSysMessage("DB table `item_required_target` reloaded.");
647 return true;
650 bool ChatHandler::HandleReloadBattleEventCommand(const char*)
652 sLog.outString( "Re-Loading BattleGround Eventindexes..." );
653 sBattleGroundMgr.LoadBattleEventIndexes();
654 SendGlobalSysMessage("DB table `gameobject_battleground` and `creature_battleground` reloaded.");
655 return true;
658 bool ChatHandler::HandleReloadGameObjectScriptsCommand(const char* arg)
660 if(sWorld.IsScriptScheduled())
662 SendSysMessage("DB scripts used currently, please attempt reload later.");
663 SetSentErrorMessage(true);
664 return false;
667 if(*arg!='a')
668 sLog.outString( "Re-Loading Scripts from `gameobject_scripts`...");
670 sObjectMgr.LoadGameObjectScripts();
672 if(*arg!='a')
673 SendGlobalSysMessage("DB table `gameobject_scripts` reloaded.");
675 return true;
678 bool ChatHandler::HandleReloadEventScriptsCommand(const char* arg)
680 if(sWorld.IsScriptScheduled())
682 SendSysMessage("DB scripts used currently, please attempt reload later.");
683 SetSentErrorMessage(true);
684 return false;
687 if(*arg!='a')
688 sLog.outString( "Re-Loading Scripts from `event_scripts`...");
690 sObjectMgr.LoadEventScripts();
692 if(*arg!='a')
693 SendGlobalSysMessage("DB table `event_scripts` reloaded.");
695 return true;
698 bool ChatHandler::HandleReloadEventAITextsCommand(const char* /*arg*/)
701 sLog.outString( "Re-Loading Texts from `creature_ai_texts`...");
702 sEventAIMgr.LoadCreatureEventAI_Texts(true);
703 SendGlobalSysMessage("DB table `creature_ai_texts` reloaded.");
704 return true;
707 bool ChatHandler::HandleReloadEventAISummonsCommand(const char* /*arg*/)
709 sLog.outString( "Re-Loading Summons from `creature_ai_summons`...");
710 sEventAIMgr.LoadCreatureEventAI_Summons(true);
711 SendGlobalSysMessage("DB table `creature_ai_summons` reloaded.");
712 return true;
715 bool ChatHandler::HandleReloadEventAIScriptsCommand(const char* /*arg*/)
717 sLog.outString( "Re-Loading Scripts from `creature_ai_scripts`...");
718 sEventAIMgr.LoadCreatureEventAI_Scripts();
719 SendGlobalSysMessage("DB table `creature_ai_scripts` reloaded.");
720 return true;
723 bool ChatHandler::HandleReloadQuestEndScriptsCommand(const char* arg)
725 if(sWorld.IsScriptScheduled())
727 SendSysMessage("DB scripts used currently, please attempt reload later.");
728 SetSentErrorMessage(true);
729 return false;
732 if(*arg!='a')
733 sLog.outString( "Re-Loading Scripts from `quest_end_scripts`...");
735 sObjectMgr.LoadQuestEndScripts();
737 if(*arg!='a')
738 SendGlobalSysMessage("DB table `quest_end_scripts` reloaded.");
740 return true;
743 bool ChatHandler::HandleReloadQuestStartScriptsCommand(const char* arg)
745 if(sWorld.IsScriptScheduled())
747 SendSysMessage("DB scripts used currently, please attempt reload later.");
748 SetSentErrorMessage(true);
749 return false;
752 if(*arg!='a')
753 sLog.outString( "Re-Loading Scripts from `quest_start_scripts`...");
755 sObjectMgr.LoadQuestStartScripts();
757 if(*arg!='a')
758 SendGlobalSysMessage("DB table `quest_start_scripts` reloaded.");
760 return true;
763 bool ChatHandler::HandleReloadSpellScriptsCommand(const char* arg)
765 if(sWorld.IsScriptScheduled())
767 SendSysMessage("DB scripts used currently, please attempt reload later.");
768 SetSentErrorMessage(true);
769 return false;
772 if(*arg!='a')
773 sLog.outString( "Re-Loading Scripts from `spell_scripts`...");
775 sObjectMgr.LoadSpellScripts();
777 if(*arg!='a')
778 SendGlobalSysMessage("DB table `spell_scripts` reloaded.");
780 return true;
783 bool ChatHandler::HandleReloadDbScriptStringCommand(const char* /*arg*/)
785 sLog.outString( "Re-Loading Script strings from `db_script_string`...");
786 sObjectMgr.LoadDbScriptStrings();
787 SendGlobalSysMessage("DB table `db_script_string` reloaded.");
788 return true;
791 bool ChatHandler::HandleReloadGameGraveyardZoneCommand(const char* /*arg*/)
793 sLog.outString( "Re-Loading Graveyard-zone links...");
795 sObjectMgr.LoadGraveyardZones();
797 SendGlobalSysMessage("DB table `game_graveyard_zone` reloaded.");
799 return true;
802 bool ChatHandler::HandleReloadGameTeleCommand(const char* /*arg*/)
804 sLog.outString( "Re-Loading Game Tele coordinates...");
806 sObjectMgr.LoadGameTele();
808 SendGlobalSysMessage("DB table `game_tele` reloaded.");
810 return true;
813 bool ChatHandler::HandleReloadLocalesAchievementRewardCommand(const char*)
815 sLog.outString( "Re-Loading Locales Achievement Reward Data..." );
816 sAchievementMgr.LoadRewardLocales();
817 SendGlobalSysMessage("DB table `locales_achievement_reward` reloaded.");
818 return true;
821 bool ChatHandler::HandleReloadLocalesCreatureCommand(const char* /*arg*/)
823 sLog.outString( "Re-Loading Locales Creature ...");
824 sObjectMgr.LoadCreatureLocales();
825 SendGlobalSysMessage("DB table `locales_creature` reloaded.");
826 return true;
829 bool ChatHandler::HandleReloadLocalesGameobjectCommand(const char* /*arg*/)
831 sLog.outString( "Re-Loading Locales Gameobject ... ");
832 sObjectMgr.LoadGameObjectLocales();
833 SendGlobalSysMessage("DB table `locales_gameobject` reloaded.");
834 return true;
837 bool ChatHandler::HandleReloadLocalesGossipMenuOptionCommand(const char* /*arg*/)
839 sLog.outString( "Re-Loading Locales Gossip Menu Option ... ");
840 sObjectMgr.LoadGossipMenuItemsLocales();
841 SendGlobalSysMessage("DB table `locales_gossip_menu_option` reloaded.");
842 return true;
845 bool ChatHandler::HandleReloadLocalesItemCommand(const char* /*arg*/)
847 sLog.outString( "Re-Loading Locales Item ... ");
848 sObjectMgr.LoadItemLocales();
849 SendGlobalSysMessage("DB table `locales_item` reloaded.");
850 return true;
853 bool ChatHandler::HandleReloadLocalesNpcTextCommand(const char* /*arg*/)
855 sLog.outString( "Re-Loading Locales NPC Text ... ");
856 sObjectMgr.LoadNpcTextLocales();
857 SendGlobalSysMessage("DB table `locales_npc_text` reloaded.");
858 return true;
861 bool ChatHandler::HandleReloadLocalesPageTextCommand(const char* /*arg*/)
863 sLog.outString( "Re-Loading Locales Page Text ... ");
864 sObjectMgr.LoadPageTextLocales();
865 SendGlobalSysMessage("DB table `locales_page_text` reloaded.");
866 return true;
869 bool ChatHandler::HandleReloadLocalesPointsOfInterestCommand(const char* /*arg*/)
871 sLog.outString( "Re-Loading Locales Points Of Interest ... ");
872 sObjectMgr.LoadPointOfInterestLocales();
873 SendGlobalSysMessage("DB table `locales_points_of_interest` reloaded.");
874 return true;
877 bool ChatHandler::HandleReloadLocalesQuestCommand(const char* /*arg*/)
879 sLog.outString( "Re-Loading Locales Quest ... ");
880 sObjectMgr.LoadQuestLocales();
881 SendGlobalSysMessage("DB table `locales_quest` reloaded.");
882 return true;
885 bool ChatHandler::HandleReloadMailLevelRewardCommand(const char* /*arg*/)
887 sLog.outString( "Re-Loading Player level dependent mail rewards..." );
888 sObjectMgr.LoadMailLevelRewards();
889 SendGlobalSysMessage("DB table `mail_level_reward` reloaded.");
890 return true;
893 bool ChatHandler::HandleLoadScriptsCommand(const char* args)
895 if(!LoadScriptingModule(args)) return true;
897 sWorld.SendWorldText(LANG_SCRIPTS_RELOADED);
898 return true;
901 bool ChatHandler::HandleAccountSetGmLevelCommand(const char* args)
903 char* arg1 = strtok((char*)args, " ");
904 if( !arg1 )
905 return false;
907 /// must be NULL if targeted syntax and must be not nULL if not targeted
908 char* arg2 = strtok(NULL, " ");
910 std::string targetAccountName;
911 uint32 targetAccountId = 0;
913 /// only target player different from self allowed (if targetPlayer!=NULL then not console)
914 Player* targetPlayer = getSelectedPlayer();
915 if(targetPlayer && m_session->GetPlayer()!=targetPlayer)
917 /// wrong command syntax or unexpected targeting
918 if(arg2)
919 return false;
921 /// security level expected in arg2 after this if.
922 arg2 = arg1;
924 targetAccountId = targetPlayer->GetSession()->GetAccountId();
925 sAccountMgr.GetName(targetAccountId, targetAccountName);
927 else
929 /// wrong command syntax (second arg expected)
930 if(!arg2)
931 return false;
933 targetAccountName = arg1;
934 if (!AccountMgr::normalizeString(targetAccountName))
936 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,targetAccountName.c_str());
937 SetSentErrorMessage(true);
938 return false;
941 targetAccountId = sAccountMgr.GetId(targetAccountName);
942 if(!targetAccountId)
944 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,targetAccountName.c_str());
945 SetSentErrorMessage(true);
946 return false;
950 int32 gm = (int32)atoi(arg2);
951 if ( gm < SEC_PLAYER || gm > SEC_ADMINISTRATOR )
953 SendSysMessage(LANG_BAD_VALUE);
954 SetSentErrorMessage(true);
955 return false;
958 /// can set security level only for target with less security and to less security that we have
959 /// This will reject self apply by specify account name
960 if(HasLowerSecurityAccount(NULL,targetAccountId,true))
961 return false;
963 /// account can't set security to same or grater level, need more power GM or console
964 AccountTypes plSecurity = m_session ? m_session->GetSecurity() : SEC_CONSOLE;
965 if (AccountTypes(gm) >= plSecurity )
967 SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
968 SetSentErrorMessage(true);
969 return false;
972 // This will prevent self apply by self target or no target
973 if(targetPlayer && m_session->GetPlayer()!=targetPlayer)
975 ChatHandler(targetPlayer).PSendSysMessage(LANG_YOURS_SECURITY_CHANGED,GetNameLink().c_str(), gm);
976 targetPlayer->GetSession()->SetSecurity(AccountTypes(gm));
979 PSendSysMessage(LANG_YOU_CHANGE_SECURITY, targetAccountName.c_str(), gm);
980 loginDatabase.PExecute("UPDATE account SET gmlevel = '%i' WHERE id = '%u'", gm, targetAccountId);
982 return true;
985 /// Set password for account
986 bool ChatHandler::HandleAccountSetPasswordCommand(const char* args)
988 if(!*args)
989 return false;
991 ///- Get the command line arguments
992 char *szAccount = strtok ((char*)args," ");
993 char *szPassword1 = strtok (NULL," ");
994 char *szPassword2 = strtok (NULL," ");
996 if (!szAccount||!szPassword1 || !szPassword2)
997 return false;
999 std::string account_name = szAccount;
1000 if (!AccountMgr::normalizeString(account_name))
1002 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
1003 SetSentErrorMessage(true);
1004 return false;
1007 uint32 targetAccountId = sAccountMgr.GetId(account_name);
1008 if (!targetAccountId)
1010 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
1011 SetSentErrorMessage(true);
1012 return false;
1015 /// can set password only for target with less security
1016 /// This is also reject self apply in fact
1017 if(HasLowerSecurityAccount (NULL,targetAccountId,true))
1018 return false;
1020 if (strcmp(szPassword1,szPassword2))
1022 SendSysMessage (LANG_NEW_PASSWORDS_NOT_MATCH);
1023 SetSentErrorMessage (true);
1024 return false;
1027 AccountOpResult result = sAccountMgr.ChangePassword(targetAccountId, szPassword1);
1029 switch(result)
1031 case AOR_OK:
1032 SendSysMessage(LANG_COMMAND_PASSWORD);
1033 break;
1034 case AOR_NAME_NOT_EXIST:
1035 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
1036 SetSentErrorMessage(true);
1037 return false;
1038 case AOR_PASS_TOO_LONG:
1039 SendSysMessage(LANG_PASSWORD_TOO_LONG);
1040 SetSentErrorMessage(true);
1041 return false;
1042 default:
1043 SendSysMessage(LANG_COMMAND_NOTCHANGEPASSWORD);
1044 SetSentErrorMessage(true);
1045 return false;
1048 return true;
1051 bool ChatHandler::HandleMaxSkillCommand(const char* /*args*/)
1053 Player* SelectedPlayer = getSelectedPlayer();
1054 if(!SelectedPlayer)
1056 SendSysMessage(LANG_NO_CHAR_SELECTED);
1057 SetSentErrorMessage(true);
1058 return false;
1061 // each skills that have max skill value dependent from level seted to current level max skill value
1062 SelectedPlayer->UpdateSkillsToMaxSkillsForLevel();
1063 return true;
1066 bool ChatHandler::HandleSetSkillCommand(const char* args)
1068 // number or [name] Shift-click form |color|Hskill:skill_id|h[name]|h|r
1069 char* skill_p = extractKeyFromLink((char*)args,"Hskill");
1070 if(!skill_p)
1071 return false;
1073 char *level_p = strtok (NULL, " ");
1075 if( !level_p)
1076 return false;
1078 char *max_p = strtok (NULL, " ");
1080 int32 skill = atoi(skill_p);
1081 if (skill <= 0)
1083 PSendSysMessage(LANG_INVALID_SKILL_ID, skill);
1084 SetSentErrorMessage(true);
1085 return false;
1088 int32 level = atol (level_p);
1090 Player * target = getSelectedPlayer();
1091 if(!target)
1093 SendSysMessage(LANG_NO_CHAR_SELECTED);
1094 SetSentErrorMessage(true);
1095 return false;
1098 SkillLineEntry const* sl = sSkillLineStore.LookupEntry(skill);
1099 if(!sl)
1101 PSendSysMessage(LANG_INVALID_SKILL_ID, skill);
1102 SetSentErrorMessage(true);
1103 return false;
1106 std::string tNameLink = GetNameLink(target);
1108 if(!target->GetSkillValue(skill))
1110 PSendSysMessage(LANG_SET_SKILL_ERROR, tNameLink.c_str(), skill, sl->name[GetSessionDbcLocale()]);
1111 SetSentErrorMessage(true);
1112 return false;
1115 int32 max = max_p ? atol (max_p) : target->GetPureMaxSkillValue(skill);
1117 if( level <= 0 || level > max || max <= 0 )
1118 return false;
1120 target->SetSkill(skill, level, max);
1121 PSendSysMessage(LANG_SET_SKILL, skill, sl->name[GetSessionDbcLocale()], tNameLink.c_str(), level, max);
1123 return true;
1126 bool ChatHandler::HandleUnLearnCommand(const char* args)
1128 if (!*args)
1129 return false;
1131 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
1132 uint32 spell_id = extractSpellIdFromLink((char*)args);
1133 if(!spell_id)
1134 return false;
1136 char const* allStr = strtok(NULL," ");
1137 bool allRanks = allStr ? (strncmp(allStr, "all", strlen(allStr)) == 0) : false;
1139 Player* target = getSelectedPlayer();
1140 if(!target)
1142 SendSysMessage(LANG_NO_CHAR_SELECTED);
1143 SetSentErrorMessage(true);
1144 return false;
1147 if(allRanks)
1148 spell_id = sSpellMgr.GetFirstSpellInChain (spell_id);
1150 if (target->HasSpell(spell_id))
1151 target->removeSpell(spell_id,false,!allRanks);
1152 else
1153 SendSysMessage(LANG_FORGET_SPELL);
1155 if(GetTalentSpellCost(spell_id))
1156 target->SendTalentsInfoData(false);
1158 return true;
1161 bool ChatHandler::HandleCooldownCommand(const char* args)
1163 Player* target = getSelectedPlayer();
1164 if(!target)
1166 SendSysMessage(LANG_PLAYER_NOT_FOUND);
1167 SetSentErrorMessage(true);
1168 return false;
1171 std::string tNameLink = GetNameLink(target);
1173 if (!*args)
1175 target->RemoveAllSpellCooldown();
1176 PSendSysMessage(LANG_REMOVEALL_COOLDOWN, tNameLink.c_str());
1178 else
1180 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
1181 uint32 spell_id = extractSpellIdFromLink((char*)args);
1182 if(!spell_id)
1183 return false;
1185 if(!sSpellStore.LookupEntry(spell_id))
1187 PSendSysMessage(LANG_UNKNOWN_SPELL, target==m_session->GetPlayer() ? GetMangosString(LANG_YOU) : tNameLink.c_str());
1188 SetSentErrorMessage(true);
1189 return false;
1192 target->RemoveSpellCooldown(spell_id,true);
1193 PSendSysMessage(LANG_REMOVE_COOLDOWN, spell_id, target==m_session->GetPlayer() ? GetMangosString(LANG_YOU) : tNameLink.c_str());
1195 return true;
1198 bool ChatHandler::HandleLearnAllCommand(const char* /*args*/)
1200 static const char *allSpellList[] =
1202 "3365",
1203 "6233",
1204 "6247",
1205 "6246",
1206 "6477",
1207 "6478",
1208 "22810",
1209 "8386",
1210 "21651",
1211 "21652",
1212 "522",
1213 "7266",
1214 "8597",
1215 "2479",
1216 "22027",
1217 "6603",
1218 "5019",
1219 "133",
1220 "168",
1221 "227",
1222 "5009",
1223 "9078",
1224 "668",
1225 "203",
1226 "20599",
1227 "20600",
1228 "81",
1229 "20597",
1230 "20598",
1231 "20864",
1232 "1459",
1233 "5504",
1234 "587",
1235 "5143",
1236 "118",
1237 "5505",
1238 "597",
1239 "604",
1240 "1449",
1241 "1460",
1242 "2855",
1243 "1008",
1244 "475",
1245 "5506",
1246 "1463",
1247 "12824",
1248 "8437",
1249 "990",
1250 "5145",
1251 "8450",
1252 "1461",
1253 "759",
1254 "8494",
1255 "8455",
1256 "8438",
1257 "6127",
1258 "8416",
1259 "6129",
1260 "8451",
1261 "8495",
1262 "8439",
1263 "3552",
1264 "8417",
1265 "10138",
1266 "12825",
1267 "10169",
1268 "10156",
1269 "10144",
1270 "10191",
1271 "10201",
1272 "10211",
1273 "10053",
1274 "10173",
1275 "10139",
1276 "10145",
1277 "10192",
1278 "10170",
1279 "10202",
1280 "10054",
1281 "10174",
1282 "10193",
1283 "12826",
1284 "2136",
1285 "143",
1286 "145",
1287 "2137",
1288 "2120",
1289 "3140",
1290 "543",
1291 "2138",
1292 "2948",
1293 "8400",
1294 "2121",
1295 "8444",
1296 "8412",
1297 "8457",
1298 "8401",
1299 "8422",
1300 "8445",
1301 "8402",
1302 "8413",
1303 "8458",
1304 "8423",
1305 "8446",
1306 "10148",
1307 "10197",
1308 "10205",
1309 "10149",
1310 "10215",
1311 "10223",
1312 "10206",
1313 "10199",
1314 "10150",
1315 "10216",
1316 "10207",
1317 "10225",
1318 "10151",
1319 "116",
1320 "205",
1321 "7300",
1322 "122",
1323 "837",
1324 "10",
1325 "7301",
1326 "7322",
1327 "6143",
1328 "120",
1329 "865",
1330 "8406",
1331 "6141",
1332 "7302",
1333 "8461",
1334 "8407",
1335 "8492",
1336 "8427",
1337 "8408",
1338 "6131",
1339 "7320",
1340 "10159",
1341 "8462",
1342 "10185",
1343 "10179",
1344 "10160",
1345 "10180",
1346 "10219",
1347 "10186",
1348 "10177",
1349 "10230",
1350 "10181",
1351 "10161",
1352 "10187",
1353 "10220",
1354 "2018",
1355 "2663",
1356 "12260",
1357 "2660",
1358 "3115",
1359 "3326",
1360 "2665",
1361 "3116",
1362 "2738",
1363 "3293",
1364 "2661",
1365 "3319",
1366 "2662",
1367 "9983",
1368 "8880",
1369 "2737",
1370 "2739",
1371 "7408",
1372 "3320",
1373 "2666",
1374 "3323",
1375 "3324",
1376 "3294",
1377 "22723",
1378 "23219",
1379 "23220",
1380 "23221",
1381 "23228",
1382 "23338",
1383 "10788",
1384 "10790",
1385 "5611",
1386 "5016",
1387 "5609",
1388 "2060",
1389 "10963",
1390 "10964",
1391 "10965",
1392 "22593",
1393 "22594",
1394 "596",
1395 "996",
1396 "499",
1397 "768",
1398 "17002",
1399 "1448",
1400 "1082",
1401 "16979",
1402 "1079",
1403 "5215",
1404 "20484",
1405 "5221",
1406 "15590",
1407 "17007",
1408 "6795",
1409 "6807",
1410 "5487",
1411 "1446",
1412 "1066",
1413 "5421",
1414 "3139",
1415 "779",
1416 "6811",
1417 "6808",
1418 "1445",
1419 "5216",
1420 "1737",
1421 "5222",
1422 "5217",
1423 "1432",
1424 "6812",
1425 "9492",
1426 "5210",
1427 "3030",
1428 "1441",
1429 "783",
1430 "6801",
1431 "20739",
1432 "8944",
1433 "9491",
1434 "22569",
1435 "5226",
1436 "6786",
1437 "1433",
1438 "8973",
1439 "1828",
1440 "9495",
1441 "9006",
1442 "6794",
1443 "8993",
1444 "5203",
1445 "16914",
1446 "6784",
1447 "9635",
1448 "22830",
1449 "20722",
1450 "9748",
1451 "6790",
1452 "9753",
1453 "9493",
1454 "9752",
1455 "9831",
1456 "9825",
1457 "9822",
1458 "5204",
1459 "5401",
1460 "22831",
1461 "6793",
1462 "9845",
1463 "17401",
1464 "9882",
1465 "9868",
1466 "20749",
1467 "9893",
1468 "9899",
1469 "9895",
1470 "9832",
1471 "9902",
1472 "9909",
1473 "22832",
1474 "9828",
1475 "9851",
1476 "9883",
1477 "9869",
1478 "17406",
1479 "17402",
1480 "9914",
1481 "20750",
1482 "9897",
1483 "9848",
1484 "3127",
1485 "107",
1486 "204",
1487 "9116",
1488 "2457",
1489 "78",
1490 "18848",
1491 "331",
1492 "403",
1493 "2098",
1494 "1752",
1495 "11278",
1496 "11288",
1497 "11284",
1498 "6461",
1499 "2344",
1500 "2345",
1501 "6463",
1502 "2346",
1503 "2352",
1504 "775",
1505 "1434",
1506 "1612",
1507 "71",
1508 "2468",
1509 "2458",
1510 "2467",
1511 "7164",
1512 "7178",
1513 "7367",
1514 "7376",
1515 "7381",
1516 "21156",
1517 "5209",
1518 "3029",
1519 "5201",
1520 "9849",
1521 "9850",
1522 "20719",
1523 "22568",
1524 "22827",
1525 "22828",
1526 "22829",
1527 "6809",
1528 "8972",
1529 "9005",
1530 "9823",
1531 "9827",
1532 "6783",
1533 "9913",
1534 "6785",
1535 "6787",
1536 "9866",
1537 "9867",
1538 "9894",
1539 "9896",
1540 "6800",
1541 "8992",
1542 "9829",
1543 "9830",
1544 "780",
1545 "769",
1546 "6749",
1547 "6750",
1548 "9755",
1549 "9754",
1550 "9908",
1551 "20745",
1552 "20742",
1553 "20747",
1554 "20748",
1555 "9746",
1556 "9745",
1557 "9880",
1558 "9881",
1559 "5391",
1560 "842",
1561 "3025",
1562 "3031",
1563 "3287",
1564 "3329",
1565 "1945",
1566 "3559",
1567 "4933",
1568 "4934",
1569 "4935",
1570 "4936",
1571 "5142",
1572 "5390",
1573 "5392",
1574 "5404",
1575 "5420",
1576 "6405",
1577 "7293",
1578 "7965",
1579 "8041",
1580 "8153",
1581 "9033",
1582 "9034",
1583 //"9036", problems with ghost state
1584 "16421",
1585 "21653",
1586 "22660",
1587 "5225",
1588 "9846",
1589 "2426",
1590 "5916",
1591 "6634",
1592 //"6718", phasing stealth, annoying for learn all case.
1593 "6719",
1594 "8822",
1595 "9591",
1596 "9590",
1597 "10032",
1598 "17746",
1599 "17747",
1600 "8203",
1601 "11392",
1602 "12495",
1603 "16380",
1604 "23452",
1605 "4079",
1606 "4996",
1607 "4997",
1608 "4998",
1609 "4999",
1610 "5000",
1611 "6348",
1612 "6349",
1613 "6481",
1614 "6482",
1615 "6483",
1616 "6484",
1617 "11362",
1618 "11410",
1619 "11409",
1620 "12510",
1621 "12509",
1622 "12885",
1623 "13142",
1624 "21463",
1625 "23460",
1626 "11421",
1627 "11416",
1628 "11418",
1629 "1851",
1630 "10059",
1631 "11423",
1632 "11417",
1633 "11422",
1634 "11419",
1635 "11424",
1636 "11420",
1637 "27",
1638 "31",
1639 "33",
1640 "34",
1641 "35",
1642 "15125",
1643 "21127",
1644 "22950",
1645 "1180",
1646 "201",
1647 "12593",
1648 "12842",
1649 "16770",
1650 "6057",
1651 "12051",
1652 "18468",
1653 "12606",
1654 "12605",
1655 "18466",
1656 "12502",
1657 "12043",
1658 "15060",
1659 "12042",
1660 "12341",
1661 "12848",
1662 "12344",
1663 "12353",
1664 "18460",
1665 "11366",
1666 "12350",
1667 "12352",
1668 "13043",
1669 "11368",
1670 "11113",
1671 "12400",
1672 "11129",
1673 "16766",
1674 "12573",
1675 "15053",
1676 "12580",
1677 "12475",
1678 "12472",
1679 "12953",
1680 "12488",
1681 "11189",
1682 "12985",
1683 "12519",
1684 "16758",
1685 "11958",
1686 "12490",
1687 "11426",
1688 "3565",
1689 "3562",
1690 "18960",
1691 "3567",
1692 "3561",
1693 "3566",
1694 "3563",
1695 "1953",
1696 "2139",
1697 "12505",
1698 "13018",
1699 "12522",
1700 "12523",
1701 "5146",
1702 "5144",
1703 "5148",
1704 "8419",
1705 "8418",
1706 "10213",
1707 "10212",
1708 "10157",
1709 "12524",
1710 "13019",
1711 "12525",
1712 "13020",
1713 "12526",
1714 "13021",
1715 "18809",
1716 "13031",
1717 "13032",
1718 "13033",
1719 "4036",
1720 "3920",
1721 "3919",
1722 "3918",
1723 "7430",
1724 "3922",
1725 "3923",
1726 "7411",
1727 "7418",
1728 "7421",
1729 "13262",
1730 "7412",
1731 "7415",
1732 "7413",
1733 "7416",
1734 "13920",
1735 "13921",
1736 "7745",
1737 "7779",
1738 "7428",
1739 "7457",
1740 "7857",
1741 "7748",
1742 "7426",
1743 "13421",
1744 "7454",
1745 "13378",
1746 "7788",
1747 "14807",
1748 "14293",
1749 "7795",
1750 "6296",
1751 "20608",
1752 "755",
1753 "444",
1754 "427",
1755 "428",
1756 "442",
1757 "447",
1758 "3578",
1759 "3581",
1760 "19027",
1761 "3580",
1762 "665",
1763 "3579",
1764 "3577",
1765 "6755",
1766 "3576",
1767 "2575",
1768 "2577",
1769 "2578",
1770 "2579",
1771 "2580",
1772 "2656",
1773 "2657",
1774 "2576",
1775 "3564",
1776 "10248",
1777 "8388",
1778 "2659",
1779 "14891",
1780 "3308",
1781 "3307",
1782 "10097",
1783 "2658",
1784 "3569",
1785 "16153",
1786 "3304",
1787 "10098",
1788 "4037",
1789 "3929",
1790 "3931",
1791 "3926",
1792 "3924",
1793 "3930",
1794 "3977",
1795 "3925",
1796 "136",
1797 "228",
1798 "5487",
1799 "43",
1800 "202",
1804 int loop = 0;
1805 while(strcmp(allSpellList[loop], "0"))
1807 uint32 spell = atol((char*)allSpellList[loop++]);
1809 if (m_session->GetPlayer()->HasSpell(spell))
1810 continue;
1812 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
1813 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
1815 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
1816 continue;
1819 m_session->GetPlayer()->learnSpell(spell,false);
1822 SendSysMessage(LANG_COMMAND_LEARN_MANY_SPELLS);
1824 return true;
1827 bool ChatHandler::HandleLearnAllGMCommand(const char* /*args*/)
1829 static const char *gmSpellList[] =
1831 "24347", // Become A Fish, No Breath Bar
1832 "35132", // Visual Boom
1833 "38488", // Attack 4000-8000 AOE
1834 "38795", // Attack 2000 AOE + Slow Down 90%
1835 "15712", // Attack 200
1836 "1852", // GM Spell Silence
1837 "31899", // Kill
1838 "31924", // Kill
1839 "29878", // Kill My Self
1840 "26644", // More Kill
1842 "28550", //Invisible 24
1843 "23452", //Invisible + Target
1847 uint16 gmSpellIter = 0;
1848 while( strcmp(gmSpellList[gmSpellIter], "0") )
1850 uint32 spell = atol((char*)gmSpellList[gmSpellIter++]);
1852 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
1853 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
1855 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
1856 continue;
1859 m_session->GetPlayer()->learnSpell(spell,false);
1862 SendSysMessage(LANG_LEARNING_GM_SKILLS);
1863 return true;
1866 bool ChatHandler::HandleLearnAllMyClassCommand(const char* /*args*/)
1868 HandleLearnAllMySpellsCommand("");
1869 HandleLearnAllMyTalentsCommand("");
1870 return true;
1873 bool ChatHandler::HandleLearnAllMySpellsCommand(const char* /*args*/)
1875 ChrClassesEntry const* clsEntry = sChrClassesStore.LookupEntry(m_session->GetPlayer()->getClass());
1876 if(!clsEntry)
1877 return true;
1878 uint32 family = clsEntry->spellfamily;
1880 for (uint32 i = 0; i < sSpellStore.GetNumRows(); ++i)
1882 SpellEntry const *spellInfo = sSpellStore.LookupEntry(i);
1883 if(!spellInfo)
1884 continue;
1886 // skip server-side/triggered spells
1887 if(spellInfo->spellLevel==0)
1888 continue;
1890 // skip wrong class/race skills
1891 if(!m_session->GetPlayer()->IsSpellFitByClassAndRace(spellInfo->Id))
1892 continue;
1894 // skip other spell families
1895 if( spellInfo->SpellFamilyName != family)
1896 continue;
1898 // skip spells with first rank learned as talent (and all talents then also)
1899 uint32 first_rank = sSpellMgr.GetFirstSpellInChain(spellInfo->Id);
1900 if(GetTalentSpellCost(first_rank) > 0 )
1901 continue;
1903 // skip broken spells
1904 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
1905 continue;
1907 m_session->GetPlayer()->learnSpell(i,false);
1910 SendSysMessage(LANG_COMMAND_LEARN_CLASS_SPELLS);
1911 return true;
1914 bool ChatHandler::HandleLearnAllMyTalentsCommand(const char* /*args*/)
1916 Player* player = m_session->GetPlayer();
1917 uint32 classMask = player->getClassMask();
1919 for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
1921 TalentEntry const *talentInfo = sTalentStore.LookupEntry(i);
1922 if(!talentInfo)
1923 continue;
1925 TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab );
1926 if(!talentTabInfo)
1927 continue;
1929 if( (classMask & talentTabInfo->ClassMask) == 0 )
1930 continue;
1932 // search highest talent rank
1933 uint32 spellid = 0;
1935 for(int rank = MAX_TALENT_RANK-1; rank >= 0; --rank)
1937 if(talentInfo->RankID[rank]!=0)
1939 spellid = talentInfo->RankID[rank];
1940 break;
1944 if(!spellid) // ??? none spells in talent
1945 continue;
1947 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid);
1948 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
1949 continue;
1951 // learn highest rank of talent and learn all non-talent spell ranks (recursive by tree)
1952 player->learnSpellHighRank(spellid);
1955 SendSysMessage(LANG_COMMAND_LEARN_CLASS_TALENTS);
1956 return true;
1959 bool ChatHandler::HandleLearnAllMyPetTalentsCommand(const char* /*args*/)
1961 Player* player = m_session->GetPlayer();
1963 Pet* pet = player->GetPet();
1964 if(!pet)
1966 SendSysMessage(LANG_NO_PET_FOUND);
1967 SetSentErrorMessage(true);
1968 return false;
1971 CreatureInfo const *ci = pet->GetCreatureInfo();
1972 if(!ci)
1974 SendSysMessage(LANG_WRONG_PET_TYPE);
1975 SetSentErrorMessage(true);
1976 return false;
1979 CreatureFamilyEntry const *pet_family = sCreatureFamilyStore.LookupEntry(ci->family);
1980 if(!pet_family)
1982 SendSysMessage(LANG_WRONG_PET_TYPE);
1983 SetSentErrorMessage(true);
1984 return false;
1987 if(pet_family->petTalentType < 0) // not hunter pet
1989 SendSysMessage(LANG_WRONG_PET_TYPE);
1990 SetSentErrorMessage(true);
1991 return false;
1994 for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
1996 TalentEntry const *talentInfo = sTalentStore.LookupEntry(i);
1997 if(!talentInfo)
1998 continue;
2000 TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab );
2001 if(!talentTabInfo)
2002 continue;
2004 // prevent learn talent for different family (cheating)
2005 if(((1 << pet_family->petTalentType) & talentTabInfo->petTalentMask)==0)
2006 continue;
2008 // search highest talent rank
2009 uint32 spellid = 0;
2011 for(int rank = MAX_TALENT_RANK-1; rank >= 0; --rank)
2013 if(talentInfo->RankID[rank]!=0)
2015 spellid = talentInfo->RankID[rank];
2016 break;
2020 if(!spellid) // ??? none spells in talent
2021 continue;
2023 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid);
2024 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
2025 continue;
2027 // learn highest rank of talent and learn all non-talent spell ranks (recursive by tree)
2028 pet->learnSpellHighRank(spellid);
2031 SendSysMessage(LANG_COMMAND_LEARN_PET_TALENTS);
2032 return true;
2035 bool ChatHandler::HandleLearnAllLangCommand(const char* /*args*/)
2037 // skipping UNIVERSAL language (0)
2038 for(int i = 1; i < LANGUAGES_COUNT; ++i)
2039 m_session->GetPlayer()->learnSpell(lang_description[i].spell_id,false);
2041 SendSysMessage(LANG_COMMAND_LEARN_ALL_LANG);
2042 return true;
2045 bool ChatHandler::HandleLearnAllDefaultCommand(const char* args)
2047 Player* target;
2048 if(!extractPlayerTarget((char*)args,&target))
2049 return false;
2051 target->learnDefaultSpells();
2052 target->learnQuestRewardedSpells();
2054 PSendSysMessage(LANG_COMMAND_LEARN_ALL_DEFAULT_AND_QUEST,GetNameLink(target).c_str());
2055 return true;
2058 bool ChatHandler::HandleLearnCommand(const char* args)
2060 Player* targetPlayer = getSelectedPlayer();
2062 if(!targetPlayer)
2064 SendSysMessage(LANG_PLAYER_NOT_FOUND);
2065 SetSentErrorMessage(true);
2066 return false;
2069 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
2070 uint32 spell = extractSpellIdFromLink((char*)args);
2071 if(!spell || !sSpellStore.LookupEntry(spell))
2072 return false;
2074 char const* allStr = strtok(NULL," ");
2075 bool allRanks = allStr ? (strncmp(allStr, "all", strlen(allStr)) == 0) : false;
2077 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
2078 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
2080 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
2081 SetSentErrorMessage(true);
2082 return false;
2085 if (!allRanks && targetPlayer->HasSpell(spell))
2087 if(targetPlayer == m_session->GetPlayer())
2088 SendSysMessage(LANG_YOU_KNOWN_SPELL);
2089 else
2090 PSendSysMessage(LANG_TARGET_KNOWN_SPELL,GetNameLink(targetPlayer).c_str());
2091 SetSentErrorMessage(true);
2092 return false;
2095 if(allRanks)
2096 targetPlayer->learnSpellHighRank(spell);
2097 else
2098 targetPlayer->learnSpell(spell,false);
2100 uint32 first_spell = sSpellMgr.GetFirstSpellInChain(spell);
2101 if(GetTalentSpellCost(first_spell))
2102 targetPlayer->SendTalentsInfoData(false);
2104 return true;
2107 bool ChatHandler::HandleAddItemCommand(const char* args)
2109 if (!*args)
2110 return false;
2112 uint32 itemId = 0;
2114 if(args[0]=='[') // [name] manual form
2116 char* citemName = strtok((char*)args, "]");
2118 if(citemName && citemName[0])
2120 std::string itemName = citemName+1;
2121 WorldDatabase.escape_string(itemName);
2122 QueryResult *result = WorldDatabase.PQuery("SELECT entry FROM item_template WHERE name = '%s'", itemName.c_str());
2123 if (!result)
2125 PSendSysMessage(LANG_COMMAND_COULDNOTFIND, citemName+1);
2126 SetSentErrorMessage(true);
2127 return false;
2129 itemId = result->Fetch()->GetUInt16();
2130 delete result;
2132 else
2133 return false;
2135 else // item_id or [name] Shift-click form |color|Hitem:item_id:0:0:0|h[name]|h|r
2137 char* cId = extractKeyFromLink((char*)args,"Hitem");
2138 if(!cId)
2139 return false;
2140 itemId = atol(cId);
2143 char* ccount = strtok(NULL, " ");
2145 int32 count = 1;
2147 if (ccount)
2148 count = strtol(ccount, NULL, 10);
2150 if (count == 0)
2151 count = 1;
2153 Player* pl = m_session->GetPlayer();
2154 Player* plTarget = getSelectedPlayer();
2155 if(!plTarget)
2156 plTarget = pl;
2158 sLog.outDetail(GetMangosString(LANG_ADDITEM), itemId, count);
2160 ItemPrototype const *pProto = ObjectMgr::GetItemPrototype(itemId);
2161 if(!pProto)
2163 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId);
2164 SetSentErrorMessage(true);
2165 return false;
2168 //Subtract
2169 if (count < 0)
2171 plTarget->DestroyItemCount(itemId, -count, true, false);
2172 PSendSysMessage(LANG_REMOVEITEM, itemId, -count, GetNameLink(plTarget).c_str());
2173 return true;
2176 //Adding items
2177 uint32 noSpaceForCount = 0;
2179 // check space and find places
2180 ItemPosCountVec dest;
2181 uint8 msg = plTarget->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, itemId, count, &noSpaceForCount );
2182 if( msg != EQUIP_ERR_OK ) // convert to possible store amount
2183 count -= noSpaceForCount;
2185 if( count == 0 || dest.empty()) // can't add any
2187 PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount );
2188 SetSentErrorMessage(true);
2189 return false;
2192 Item* item = plTarget->StoreNewItem( dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId));
2194 // remove binding (let GM give it to another player later)
2195 if(pl==plTarget)
2196 for(ItemPosCountVec::const_iterator itr = dest.begin(); itr != dest.end(); ++itr)
2197 if(Item* item1 = pl->GetItemByPos(itr->pos))
2198 item1->SetBinding( false );
2200 if(count > 0 && item)
2202 pl->SendNewItem(item,count,false,true);
2203 if(pl!=plTarget)
2204 plTarget->SendNewItem(item,count,true,false);
2207 if(noSpaceForCount > 0)
2208 PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount);
2210 return true;
2213 bool ChatHandler::HandleAddItemSetCommand(const char* args)
2215 if (!*args)
2216 return false;
2218 char* cId = extractKeyFromLink((char*)args,"Hitemset"); // number or [name] Shift-click form |color|Hitemset:itemset_id|h[name]|h|r
2219 if (!cId)
2220 return false;
2222 uint32 itemsetId = atol(cId);
2224 // prevent generation all items with itemset field value '0'
2225 if (itemsetId == 0)
2227 PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND,itemsetId);
2228 SetSentErrorMessage(true);
2229 return false;
2232 Player* pl = m_session->GetPlayer();
2233 Player* plTarget = getSelectedPlayer();
2234 if(!plTarget)
2235 plTarget = pl;
2237 sLog.outDetail(GetMangosString(LANG_ADDITEMSET), itemsetId);
2239 bool found = false;
2240 for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
2242 ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype>(id);
2243 if (!pProto)
2244 continue;
2246 if (pProto->ItemSet == itemsetId)
2248 found = true;
2249 ItemPosCountVec dest;
2250 uint8 msg = plTarget->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, pProto->ItemId, 1 );
2251 if (msg == EQUIP_ERR_OK)
2253 Item* item = plTarget->StoreNewItem( dest, pProto->ItemId, true);
2255 // remove binding (let GM give it to another player later)
2256 if (pl==plTarget)
2257 item->SetBinding( false );
2259 pl->SendNewItem(item,1,false,true);
2260 if (pl!=plTarget)
2261 plTarget->SendNewItem(item,1,true,false);
2263 else
2265 pl->SendEquipError( msg, NULL, NULL );
2266 PSendSysMessage(LANG_ITEM_CANNOT_CREATE, pProto->ItemId, 1);
2271 if (!found)
2273 PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND,itemsetId);
2275 SetSentErrorMessage(true);
2276 return false;
2279 return true;
2282 bool ChatHandler::HandleListItemCommand(const char* args)
2284 if(!*args)
2285 return false;
2287 char* cId = extractKeyFromLink((char*)args,"Hitem");
2288 if(!cId)
2289 return false;
2291 uint32 item_id = atol(cId);
2292 if(!item_id)
2294 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
2295 SetSentErrorMessage(true);
2296 return false;
2299 ItemPrototype const* itemProto = ObjectMgr::GetItemPrototype(item_id);
2300 if(!itemProto)
2302 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
2303 SetSentErrorMessage(true);
2304 return false;
2307 char* c_count = strtok(NULL, " ");
2308 int count = c_count ? atol(c_count) : 10;
2310 if(count < 0)
2311 return false;
2313 QueryResult *result;
2315 // inventory case
2316 uint32 inv_count = 0;
2317 result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM character_inventory WHERE item_template='%u'",item_id);
2318 if(result)
2320 inv_count = (*result)[0].GetUInt32();
2321 delete result;
2324 result=CharacterDatabase.PQuery(
2325 // 0 1 2 3 4 5
2326 "SELECT ci.item, cibag.slot AS bag, ci.slot, ci.guid, characters.account,characters.name "
2327 "FROM character_inventory AS ci LEFT JOIN character_inventory AS cibag ON (cibag.item=ci.bag),characters "
2328 "WHERE ci.item_template='%u' AND ci.guid = characters.guid LIMIT %u ",
2329 item_id,uint32(count));
2331 if(result)
2335 Field *fields = result->Fetch();
2336 uint32 item_guid = fields[0].GetUInt32();
2337 uint32 item_bag = fields[1].GetUInt32();
2338 uint32 item_slot = fields[2].GetUInt32();
2339 uint32 owner_guid = fields[3].GetUInt32();
2340 uint32 owner_acc = fields[4].GetUInt32();
2341 std::string owner_name = fields[5].GetCppString();
2343 char const* item_pos = 0;
2344 if(Player::IsEquipmentPos(item_bag,item_slot))
2345 item_pos = "[equipped]";
2346 else if(Player::IsInventoryPos(item_bag,item_slot))
2347 item_pos = "[in inventory]";
2348 else if(Player::IsBankPos(item_bag,item_slot))
2349 item_pos = "[in bank]";
2350 else
2351 item_pos = "";
2353 PSendSysMessage(LANG_ITEMLIST_SLOT,
2354 item_guid,owner_name.c_str(),owner_guid,owner_acc,item_pos);
2355 } while (result->NextRow());
2357 int res_count = (int)result->GetRowCount();
2359 delete result;
2361 if(count > res_count)
2362 count-=res_count;
2363 else if(count)
2364 count = 0;
2367 // mail case
2368 uint32 mail_count = 0;
2369 result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM mail_items WHERE item_template='%u'", item_id);
2370 if(result)
2372 mail_count = (*result)[0].GetUInt32();
2373 delete result;
2376 if(count > 0)
2378 result=CharacterDatabase.PQuery(
2379 // 0 1 2 3 4 5 6
2380 "SELECT mail_items.item_guid, mail.sender, mail.receiver, char_s.account, char_s.name, char_r.account, char_r.name "
2381 "FROM mail,mail_items,characters as char_s,characters as char_r "
2382 "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",
2383 item_id,uint32(count));
2385 else
2386 result = NULL;
2388 if(result)
2392 Field *fields = result->Fetch();
2393 uint32 item_guid = fields[0].GetUInt32();
2394 uint32 item_s = fields[1].GetUInt32();
2395 uint32 item_r = fields[2].GetUInt32();
2396 uint32 item_s_acc = fields[3].GetUInt32();
2397 std::string item_s_name = fields[4].GetCppString();
2398 uint32 item_r_acc = fields[5].GetUInt32();
2399 std::string item_r_name = fields[6].GetCppString();
2401 char const* item_pos = "[in mail]";
2403 PSendSysMessage(LANG_ITEMLIST_MAIL,
2404 item_guid,item_s_name.c_str(),item_s,item_s_acc,item_r_name.c_str(),item_r,item_r_acc,item_pos);
2405 } while (result->NextRow());
2407 int res_count = (int)result->GetRowCount();
2409 delete result;
2411 if(count > res_count)
2412 count-=res_count;
2413 else if(count)
2414 count = 0;
2417 // auction case
2418 uint32 auc_count = 0;
2419 result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM auctionhouse WHERE item_template='%u'",item_id);
2420 if(result)
2422 auc_count = (*result)[0].GetUInt32();
2423 delete result;
2426 if(count > 0)
2428 result=CharacterDatabase.PQuery(
2429 // 0 1 2 3
2430 "SELECT auctionhouse.itemguid, auctionhouse.itemowner, characters.account, characters.name "
2431 "FROM auctionhouse,characters WHERE auctionhouse.item_template='%u' AND characters.guid = auctionhouse.itemowner LIMIT %u",
2432 item_id,uint32(count));
2434 else
2435 result = NULL;
2437 if(result)
2441 Field *fields = result->Fetch();
2442 uint32 item_guid = fields[0].GetUInt32();
2443 uint32 owner = fields[1].GetUInt32();
2444 uint32 owner_acc = fields[2].GetUInt32();
2445 std::string owner_name = fields[3].GetCppString();
2447 char const* item_pos = "[in auction]";
2449 PSendSysMessage(LANG_ITEMLIST_AUCTION, item_guid, owner_name.c_str(), owner, owner_acc,item_pos);
2450 } while (result->NextRow());
2452 delete result;
2455 // guild bank case
2456 uint32 guild_count = 0;
2457 result=CharacterDatabase.PQuery("SELECT COUNT(item_entry) FROM guild_bank_item WHERE item_entry='%u'",item_id);
2458 if(result)
2460 guild_count = (*result)[0].GetUInt32();
2461 delete result;
2464 result=CharacterDatabase.PQuery(
2465 // 0 1 2
2466 "SELECT gi.item_guid, gi.guildid, guild.name "
2467 "FROM guild_bank_item AS gi, guild WHERE gi.item_entry='%u' AND gi.guildid = guild.guildid LIMIT %u ",
2468 item_id,uint32(count));
2470 if(result)
2474 Field *fields = result->Fetch();
2475 uint32 item_guid = fields[0].GetUInt32();
2476 uint32 guild_guid = fields[1].GetUInt32();
2477 std::string guild_name = fields[2].GetCppString();
2479 char const* item_pos = "[in guild bank]";
2481 PSendSysMessage(LANG_ITEMLIST_GUILD,item_guid,guild_name.c_str(),guild_guid,item_pos);
2482 } while (result->NextRow());
2484 int res_count = (int)result->GetRowCount();
2486 delete result;
2488 if(count > res_count)
2489 count-=res_count;
2490 else if(count)
2491 count = 0;
2494 if(inv_count+mail_count+auc_count+guild_count == 0)
2496 SendSysMessage(LANG_COMMAND_NOITEMFOUND);
2497 SetSentErrorMessage(true);
2498 return false;
2501 PSendSysMessage(LANG_COMMAND_LISTITEMMESSAGE,item_id,inv_count+mail_count+auc_count+guild_count,inv_count,mail_count,auc_count,guild_count);
2503 return true;
2506 bool ChatHandler::HandleListObjectCommand(const char* args)
2508 if(!*args)
2509 return false;
2511 // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r
2512 char* cId = extractKeyFromLink((char*)args,"Hgameobject_entry");
2513 if(!cId)
2514 return false;
2516 uint32 go_id = atol(cId);
2517 if(!go_id)
2519 PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id);
2520 SetSentErrorMessage(true);
2521 return false;
2524 GameObjectInfo const * gInfo = ObjectMgr::GetGameObjectInfo(go_id);
2525 if(!gInfo)
2527 PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id);
2528 SetSentErrorMessage(true);
2529 return false;
2532 char* c_count = strtok(NULL, " ");
2533 int count = c_count ? atol(c_count) : 10;
2535 if(count < 0)
2536 return false;
2538 QueryResult *result;
2540 uint32 obj_count = 0;
2541 result=WorldDatabase.PQuery("SELECT COUNT(guid) FROM gameobject WHERE id='%u'",go_id);
2542 if(result)
2544 obj_count = (*result)[0].GetUInt32();
2545 delete result;
2548 if(m_session)
2550 Player* pl = m_session->GetPlayer();
2551 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",
2552 pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),go_id,uint32(count));
2554 else
2555 result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map FROM gameobject WHERE id = '%u' LIMIT %u",
2556 go_id,uint32(count));
2558 if (result)
2562 Field *fields = result->Fetch();
2563 uint32 guid = fields[0].GetUInt32();
2564 float x = fields[1].GetFloat();
2565 float y = fields[2].GetFloat();
2566 float z = fields[3].GetFloat();
2567 int mapid = fields[4].GetUInt16();
2569 if (m_session)
2570 PSendSysMessage(LANG_GO_LIST_CHAT, guid, guid, gInfo->name, x, y, z, mapid);
2571 else
2572 PSendSysMessage(LANG_GO_LIST_CONSOLE, guid, gInfo->name, x, y, z, mapid);
2573 } while (result->NextRow());
2575 delete result;
2578 PSendSysMessage(LANG_COMMAND_LISTOBJMESSAGE,go_id,obj_count);
2579 return true;
2582 bool ChatHandler::HandleListCreatureCommand(const char* args)
2584 if(!*args)
2585 return false;
2587 // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
2588 char* cId = extractKeyFromLink((char*)args,"Hcreature_entry");
2589 if(!cId)
2590 return false;
2592 uint32 cr_id = atol(cId);
2593 if(!cr_id)
2595 PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id);
2596 SetSentErrorMessage(true);
2597 return false;
2600 CreatureInfo const* cInfo = ObjectMgr::GetCreatureTemplate(cr_id);
2601 if(!cInfo)
2603 PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id);
2604 SetSentErrorMessage(true);
2605 return false;
2608 char* c_count = strtok(NULL, " ");
2609 int count = c_count ? atol(c_count) : 10;
2611 if(count < 0)
2612 return false;
2614 QueryResult *result;
2616 uint32 cr_count = 0;
2617 result=WorldDatabase.PQuery("SELECT COUNT(guid) FROM creature WHERE id='%u'",cr_id);
2618 if(result)
2620 cr_count = (*result)[0].GetUInt32();
2621 delete result;
2624 if(m_session)
2626 Player* pl = m_session->GetPlayer();
2627 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",
2628 pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), cr_id,uint32(count));
2630 else
2631 result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map FROM creature WHERE id = '%u' LIMIT %u",
2632 cr_id,uint32(count));
2634 if (result)
2638 Field *fields = result->Fetch();
2639 uint32 guid = fields[0].GetUInt32();
2640 float x = fields[1].GetFloat();
2641 float y = fields[2].GetFloat();
2642 float z = fields[3].GetFloat();
2643 int mapid = fields[4].GetUInt16();
2645 if (m_session)
2646 PSendSysMessage(LANG_CREATURE_LIST_CHAT, guid, guid, cInfo->Name, x, y, z, mapid);
2647 else
2648 PSendSysMessage(LANG_CREATURE_LIST_CONSOLE, guid, cInfo->Name, x, y, z, mapid);
2649 } while (result->NextRow());
2651 delete result;
2654 PSendSysMessage(LANG_COMMAND_LISTCREATUREMESSAGE,cr_id,cr_count);
2655 return true;
2658 bool ChatHandler::HandleLookupItemCommand(const char* args)
2660 if(!*args)
2661 return false;
2663 std::string namepart = args;
2664 std::wstring wnamepart;
2666 // converting string that we try to find to lower case
2667 if(!Utf8toWStr(namepart,wnamepart))
2668 return false;
2670 wstrToLower(wnamepart);
2672 uint32 counter = 0;
2674 // Search in `item_template`
2675 for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
2677 ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype >(id);
2678 if(!pProto)
2679 continue;
2681 int loc_idx = GetSessionDbLocaleIndex();
2682 if ( loc_idx >= 0 )
2684 ItemLocale const *il = sObjectMgr.GetItemLocale(pProto->ItemId);
2685 if (il)
2687 if ((int32)il->Name.size() > loc_idx && !il->Name[loc_idx].empty())
2689 std::string name = il->Name[loc_idx];
2691 if (Utf8FitTo(name, wnamepart))
2693 if (m_session)
2694 PSendSysMessage(LANG_ITEM_LIST_CHAT, id, id, name.c_str());
2695 else
2696 PSendSysMessage(LANG_ITEM_LIST_CONSOLE, id, name.c_str());
2697 ++counter;
2698 continue;
2704 std::string name = pProto->Name1;
2705 if(name.empty())
2706 continue;
2708 if (Utf8FitTo(name, wnamepart))
2710 if (m_session)
2711 PSendSysMessage(LANG_ITEM_LIST_CHAT, id, id, name.c_str());
2712 else
2713 PSendSysMessage(LANG_ITEM_LIST_CONSOLE, id, name.c_str());
2714 ++counter;
2718 if (counter==0)
2719 SendSysMessage(LANG_COMMAND_NOITEMFOUND);
2721 return true;
2724 bool ChatHandler::HandleLookupItemSetCommand(const char* args)
2726 if(!*args)
2727 return false;
2729 std::string namepart = args;
2730 std::wstring wnamepart;
2732 if(!Utf8toWStr(namepart,wnamepart))
2733 return false;
2735 // converting string that we try to find to lower case
2736 wstrToLower( wnamepart );
2738 uint32 counter = 0; // Counter for figure out that we found smth.
2740 // Search in ItemSet.dbc
2741 for (uint32 id = 0; id < sItemSetStore.GetNumRows(); id++)
2743 ItemSetEntry const *set = sItemSetStore.LookupEntry(id);
2744 if(set)
2746 int loc = GetSessionDbcLocale();
2747 std::string name = set->name[loc];
2748 if(name.empty())
2749 continue;
2751 if (!Utf8FitTo(name, wnamepart))
2753 loc = 0;
2754 for(; loc < MAX_LOCALE; ++loc)
2756 if(loc==GetSessionDbcLocale())
2757 continue;
2759 name = set->name[loc];
2760 if(name.empty())
2761 continue;
2763 if (Utf8FitTo(name, wnamepart))
2764 break;
2768 if(loc < MAX_LOCALE)
2770 // send item set in "id - [namedlink locale]" format
2771 if (m_session)
2772 PSendSysMessage(LANG_ITEMSET_LIST_CHAT,id,id,name.c_str(),localeNames[loc]);
2773 else
2774 PSendSysMessage(LANG_ITEMSET_LIST_CONSOLE,id,name.c_str(),localeNames[loc]);
2775 ++counter;
2779 if (counter == 0) // if counter == 0 then we found nth
2780 SendSysMessage(LANG_COMMAND_NOITEMSETFOUND);
2781 return true;
2784 bool ChatHandler::HandleLookupSkillCommand(const char* args)
2786 if(!*args)
2787 return false;
2789 // can be NULL in console call
2790 Player* target = getSelectedPlayer();
2792 std::string namepart = args;
2793 std::wstring wnamepart;
2795 if(!Utf8toWStr(namepart,wnamepart))
2796 return false;
2798 // converting string that we try to find to lower case
2799 wstrToLower( wnamepart );
2801 uint32 counter = 0; // Counter for figure out that we found smth.
2803 // Search in SkillLine.dbc
2804 for (uint32 id = 0; id < sSkillLineStore.GetNumRows(); id++)
2806 SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(id);
2807 if(skillInfo)
2809 int loc = GetSessionDbcLocale();
2810 std::string name = skillInfo->name[loc];
2811 if(name.empty())
2812 continue;
2814 if (!Utf8FitTo(name, wnamepart))
2816 loc = 0;
2817 for(; loc < MAX_LOCALE; ++loc)
2819 if(loc==GetSessionDbcLocale())
2820 continue;
2822 name = skillInfo->name[loc];
2823 if(name.empty())
2824 continue;
2826 if (Utf8FitTo(name, wnamepart))
2827 break;
2831 if(loc < MAX_LOCALE)
2833 char valStr[50] = "";
2834 char const* knownStr = "";
2835 if(target && target->HasSkill(id))
2837 knownStr = GetMangosString(LANG_KNOWN);
2838 uint32 curValue = target->GetPureSkillValue(id);
2839 uint32 maxValue = target->GetPureMaxSkillValue(id);
2840 uint32 permValue = target->GetSkillPermBonusValue(id);
2841 uint32 tempValue = target->GetSkillTempBonusValue(id);
2843 char const* valFormat = GetMangosString(LANG_SKILL_VALUES);
2844 snprintf(valStr,50,valFormat,curValue,maxValue,permValue,tempValue);
2847 // send skill in "id - [namedlink locale]" format
2848 if (m_session)
2849 PSendSysMessage(LANG_SKILL_LIST_CHAT,id,id,name.c_str(),localeNames[loc],knownStr,valStr);
2850 else
2851 PSendSysMessage(LANG_SKILL_LIST_CONSOLE,id,name.c_str(),localeNames[loc],knownStr,valStr);
2853 ++counter;
2857 if (counter == 0) // if counter == 0 then we found nth
2858 SendSysMessage(LANG_COMMAND_NOSKILLFOUND);
2859 return true;
2862 bool ChatHandler::HandleLookupSpellCommand(const char* args)
2864 if(!*args)
2865 return false;
2867 // can be NULL at console call
2868 Player* target = getSelectedPlayer();
2870 std::string namepart = args;
2871 std::wstring wnamepart;
2873 if(!Utf8toWStr(namepart,wnamepart))
2874 return false;
2876 // converting string that we try to find to lower case
2877 wstrToLower( wnamepart );
2879 uint32 counter = 0; // Counter for figure out that we found smth.
2881 // Search in Spell.dbc
2882 for (uint32 id = 0; id < sSpellStore.GetNumRows(); id++)
2884 SpellEntry const *spellInfo = sSpellStore.LookupEntry(id);
2885 if(spellInfo)
2887 int loc = GetSessionDbcLocale();
2888 std::string name = spellInfo->SpellName[loc];
2889 if(name.empty())
2890 continue;
2892 if (!Utf8FitTo(name, wnamepart))
2894 loc = 0;
2895 for(; loc < MAX_LOCALE; ++loc)
2897 if(loc==GetSessionDbcLocale())
2898 continue;
2900 name = spellInfo->SpellName[loc];
2901 if(name.empty())
2902 continue;
2904 if (Utf8FitTo(name, wnamepart))
2905 break;
2909 if(loc < MAX_LOCALE)
2911 bool known = target && target->HasSpell(id);
2912 bool learn = (spellInfo->Effect[EFFECT_INDEX_0] == SPELL_EFFECT_LEARN_SPELL);
2914 uint32 talentCost = GetTalentSpellCost(id);
2916 bool talent = (talentCost > 0);
2917 bool passive = IsPassiveSpell(id);
2918 bool active = target && target->HasAura(id);
2920 // unit32 used to prevent interpreting uint8 as char at output
2921 // find rank of learned spell for learning spell, or talent rank
2922 uint32 rank = talentCost ? talentCost : sSpellMgr.GetSpellRank(learn ? spellInfo->EffectTriggerSpell[EFFECT_INDEX_0] : id);
2924 // send spell in "id - [name, rank N] [talent] [passive] [learn] [known]" format
2925 std::ostringstream ss;
2926 if (m_session)
2927 ss << id << " - |cffffffff|Hspell:" << id << "|h[" << name;
2928 else
2929 ss << id << " - " << name;
2931 // include rank in link name
2932 if(rank)
2933 ss << GetMangosString(LANG_SPELL_RANK) << rank;
2935 if (m_session)
2936 ss << " " << localeNames[loc] << "]|h|r";
2937 else
2938 ss << " " << localeNames[loc];
2940 if(talent)
2941 ss << GetMangosString(LANG_TALENT);
2942 if(passive)
2943 ss << GetMangosString(LANG_PASSIVE);
2944 if(learn)
2945 ss << GetMangosString(LANG_LEARN);
2946 if(known)
2947 ss << GetMangosString(LANG_KNOWN);
2948 if(active)
2949 ss << GetMangosString(LANG_ACTIVE);
2951 SendSysMessage(ss.str().c_str());
2953 ++counter;
2957 if (counter == 0) // if counter == 0 then we found nth
2958 SendSysMessage(LANG_COMMAND_NOSPELLFOUND);
2959 return true;
2962 bool ChatHandler::HandleLookupQuestCommand(const char* args)
2964 if(!*args)
2965 return false;
2967 // can be NULL at console call
2968 Player* target = getSelectedPlayer();
2970 std::string namepart = args;
2971 std::wstring wnamepart;
2973 // converting string that we try to find to lower case
2974 if(!Utf8toWStr(namepart,wnamepart))
2975 return false;
2977 wstrToLower(wnamepart);
2979 uint32 counter = 0 ;
2981 ObjectMgr::QuestMap const& qTemplates = sObjectMgr.GetQuestTemplates();
2982 for (ObjectMgr::QuestMap::const_iterator iter = qTemplates.begin(); iter != qTemplates.end(); ++iter)
2984 Quest * qinfo = iter->second;
2986 int loc_idx = GetSessionDbLocaleIndex();
2987 if ( loc_idx >= 0 )
2989 QuestLocale const *il = sObjectMgr.GetQuestLocale(qinfo->GetQuestId());
2990 if (il)
2992 if ((int32)il->Title.size() > loc_idx && !il->Title[loc_idx].empty())
2994 std::string title = il->Title[loc_idx];
2996 if (Utf8FitTo(title, wnamepart))
2998 char const* statusStr = "";
3000 if(target)
3002 QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId());
3004 if(status == QUEST_STATUS_COMPLETE)
3006 if(target->GetQuestRewardStatus(qinfo->GetQuestId()))
3007 statusStr = GetMangosString(LANG_COMMAND_QUEST_REWARDED);
3008 else
3009 statusStr = GetMangosString(LANG_COMMAND_QUEST_COMPLETE);
3011 else if(status == QUEST_STATUS_INCOMPLETE)
3012 statusStr = GetMangosString(LANG_COMMAND_QUEST_ACTIVE);
3015 if (m_session)
3016 PSendSysMessage(LANG_QUEST_LIST_CHAT,qinfo->GetQuestId(),qinfo->GetQuestId(),qinfo->GetQuestLevel(),title.c_str(),statusStr);
3017 else
3018 PSendSysMessage(LANG_QUEST_LIST_CONSOLE,qinfo->GetQuestId(),title.c_str(),statusStr);
3019 ++counter;
3020 continue;
3026 std::string title = qinfo->GetTitle();
3027 if(title.empty())
3028 continue;
3030 if (Utf8FitTo(title, wnamepart))
3032 char const* statusStr = "";
3034 if(target)
3036 QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId());
3038 if(status == QUEST_STATUS_COMPLETE)
3040 if(target->GetQuestRewardStatus(qinfo->GetQuestId()))
3041 statusStr = GetMangosString(LANG_COMMAND_QUEST_REWARDED);
3042 else
3043 statusStr = GetMangosString(LANG_COMMAND_QUEST_COMPLETE);
3045 else if(status == QUEST_STATUS_INCOMPLETE)
3046 statusStr = GetMangosString(LANG_COMMAND_QUEST_ACTIVE);
3049 if (m_session)
3050 PSendSysMessage(LANG_QUEST_LIST_CHAT,qinfo->GetQuestId(),qinfo->GetQuestId(),qinfo->GetQuestLevel(),title.c_str(),statusStr);
3051 else
3052 PSendSysMessage(LANG_QUEST_LIST_CONSOLE,qinfo->GetQuestId(),title.c_str(),statusStr);
3054 ++counter;
3058 if (counter==0)
3059 SendSysMessage(LANG_COMMAND_NOQUESTFOUND);
3061 return true;
3064 bool ChatHandler::HandleLookupCreatureCommand(const char* args)
3066 if (!*args)
3067 return false;
3069 std::string namepart = args;
3070 std::wstring wnamepart;
3072 // converting string that we try to find to lower case
3073 if (!Utf8toWStr (namepart,wnamepart))
3074 return false;
3076 wstrToLower (wnamepart);
3078 uint32 counter = 0;
3080 for (uint32 id = 0; id< sCreatureStorage.MaxEntry; ++id)
3082 CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo> (id);
3083 if(!cInfo)
3084 continue;
3086 int loc_idx = GetSessionDbLocaleIndex();
3087 if (loc_idx >= 0)
3089 CreatureLocale const *cl = sObjectMgr.GetCreatureLocale (id);
3090 if (cl)
3092 if ((int32)cl->Name.size() > loc_idx && !cl->Name[loc_idx].empty ())
3094 std::string name = cl->Name[loc_idx];
3096 if (Utf8FitTo (name, wnamepart))
3098 if (m_session)
3099 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CHAT, id, id, name.c_str ());
3100 else
3101 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CONSOLE, id, name.c_str ());
3102 ++counter;
3103 continue;
3109 std::string name = cInfo->Name;
3110 if (name.empty ())
3111 continue;
3113 if (Utf8FitTo(name, wnamepart))
3115 if (m_session)
3116 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CHAT, id, id, name.c_str ());
3117 else
3118 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CONSOLE, id, name.c_str ());
3119 ++counter;
3123 if (counter==0)
3124 SendSysMessage (LANG_COMMAND_NOCREATUREFOUND);
3126 return true;
3129 bool ChatHandler::HandleLookupObjectCommand(const char* args)
3131 if(!*args)
3132 return false;
3134 std::string namepart = args;
3135 std::wstring wnamepart;
3137 // converting string that we try to find to lower case
3138 if(!Utf8toWStr(namepart,wnamepart))
3139 return false;
3141 wstrToLower(wnamepart);
3143 uint32 counter = 0;
3145 for (uint32 id = 0; id< sGOStorage.MaxEntry; id++ )
3147 GameObjectInfo const* gInfo = sGOStorage.LookupEntry<GameObjectInfo>(id);
3148 if(!gInfo)
3149 continue;
3151 int loc_idx = GetSessionDbLocaleIndex();
3152 if ( loc_idx >= 0 )
3154 GameObjectLocale const *gl = sObjectMgr.GetGameObjectLocale(id);
3155 if (gl)
3157 if ((int32)gl->Name.size() > loc_idx && !gl->Name[loc_idx].empty())
3159 std::string name = gl->Name[loc_idx];
3161 if (Utf8FitTo(name, wnamepart))
3163 if (m_session)
3164 PSendSysMessage(LANG_GO_ENTRY_LIST_CHAT, id, id, name.c_str());
3165 else
3166 PSendSysMessage(LANG_GO_ENTRY_LIST_CONSOLE, id, name.c_str());
3167 ++counter;
3168 continue;
3174 std::string name = gInfo->name;
3175 if(name.empty())
3176 continue;
3178 if(Utf8FitTo(name, wnamepart))
3180 if (m_session)
3181 PSendSysMessage(LANG_GO_ENTRY_LIST_CHAT, id, id, name.c_str());
3182 else
3183 PSendSysMessage(LANG_GO_ENTRY_LIST_CONSOLE, id, name.c_str());
3184 ++counter;
3188 if(counter==0)
3189 SendSysMessage(LANG_COMMAND_NOGAMEOBJECTFOUND);
3191 return true;
3194 bool ChatHandler::HandleLookupTaxiNodeCommand(const char * args)
3196 if(!*args)
3197 return false;
3199 std::string namepart = args;
3200 std::wstring wnamepart;
3202 if(!Utf8toWStr(namepart,wnamepart))
3203 return false;
3205 // converting string that we try to find to lower case
3206 wstrToLower( wnamepart );
3208 uint32 counter = 0; // Counter for figure out that we found smth.
3210 // Search in TaxiNodes.dbc
3211 for (uint32 id = 0; id < sTaxiNodesStore.GetNumRows(); id++)
3213 TaxiNodesEntry const *nodeEntry = sTaxiNodesStore.LookupEntry(id);
3214 if(nodeEntry)
3216 int loc = GetSessionDbcLocale();
3217 std::string name = nodeEntry->name[loc];
3218 if(name.empty())
3219 continue;
3221 if (!Utf8FitTo(name, wnamepart))
3223 loc = 0;
3224 for(; loc < MAX_LOCALE; ++loc)
3226 if(loc==GetSessionDbcLocale())
3227 continue;
3229 name = nodeEntry->name[loc];
3230 if(name.empty())
3231 continue;
3233 if (Utf8FitTo(name, wnamepart))
3234 break;
3238 if(loc < MAX_LOCALE)
3240 // send taxinode in "id - [name] (Map:m X:x Y:y Z:z)" format
3241 if (m_session)
3242 PSendSysMessage (LANG_TAXINODE_ENTRY_LIST_CHAT, id, id, name.c_str(),localeNames[loc],
3243 nodeEntry->map_id,nodeEntry->x,nodeEntry->y,nodeEntry->z);
3244 else
3245 PSendSysMessage (LANG_TAXINODE_ENTRY_LIST_CONSOLE, id, name.c_str(), localeNames[loc],
3246 nodeEntry->map_id,nodeEntry->x,nodeEntry->y,nodeEntry->z);
3247 ++counter;
3251 if (counter == 0) // if counter == 0 then we found nth
3252 SendSysMessage(LANG_COMMAND_NOTAXINODEFOUND);
3253 return true;
3256 /** \brief GM command level 3 - Create a guild.
3258 * This command allows a GM (level 3) to create a guild.
3260 * The "args" parameter contains the name of the guild leader
3261 * and then the name of the guild.
3264 bool ChatHandler::HandleGuildCreateCommand(const char* args)
3266 if(!*args)
3267 return false;
3269 // if not guild name only (in "") then player name
3270 Player* target;
3271 if(!extractPlayerTarget(*args!='"' ? (char*)args : NULL, &target))
3272 return false;
3274 char* tailStr = *args!='"' ? strtok(NULL, "") : (char*)args;
3275 if(!tailStr)
3276 return false;
3278 char* guildStr = extractQuotedArg(tailStr);
3279 if(!guildStr)
3280 return false;
3282 std::string guildname = guildStr;
3284 if (target->GetGuildId())
3286 SendSysMessage (LANG_PLAYER_IN_GUILD);
3287 return true;
3290 Guild *guild = new Guild;
3291 if (!guild->Create (target,guildname))
3293 delete guild;
3294 SendSysMessage (LANG_GUILD_NOT_CREATED);
3295 SetSentErrorMessage (true);
3296 return false;
3299 sObjectMgr.AddGuild (guild);
3300 return true;
3303 bool ChatHandler::HandleGuildInviteCommand(const char *args)
3305 if(!*args)
3306 return false;
3308 // if not guild name only (in "") then player name
3309 uint64 target_guid;
3310 if(!extractPlayerTarget(*args!='"' ? (char*)args : NULL, NULL, &target_guid))
3311 return false;
3313 char* tailStr = *args!='"' ? strtok(NULL, "") : (char*)args;
3314 if(!tailStr)
3315 return false;
3317 char* guildStr = extractQuotedArg(tailStr);
3318 if(!guildStr)
3319 return false;
3321 std::string glName = guildStr;
3322 Guild* targetGuild = sObjectMgr.GetGuildByName (glName);
3323 if (!targetGuild)
3324 return false;
3326 // player's guild membership checked in AddMember before add
3327 if (!targetGuild->AddMember (target_guid,targetGuild->GetLowestRank ()))
3328 return false;
3330 return true;
3333 bool ChatHandler::HandleGuildUninviteCommand(const char *args)
3335 Player* target;
3336 uint64 target_guid;
3337 if(!extractPlayerTarget((char*)args,&target,&target_guid))
3338 return false;
3340 uint32 glId = target ? target->GetGuildId () : Player::GetGuildIdFromDB (target_guid);
3341 if (!glId)
3342 return false;
3344 Guild* targetGuild = sObjectMgr.GetGuildById (glId);
3345 if (!targetGuild)
3346 return false;
3348 targetGuild->DelMember (target_guid);
3349 return true;
3352 bool ChatHandler::HandleGuildRankCommand(const char *args)
3354 char* nameStr;
3355 char* rankStr;
3356 extractOptFirstArg((char*)args,&nameStr,&rankStr);
3357 if(!rankStr)
3358 return false;
3360 Player* target;
3361 uint64 target_guid;
3362 std::string target_name;
3363 if(!extractPlayerTarget(nameStr,&target,&target_guid,&target_name))
3364 return false;
3366 uint32 glId = target ? target->GetGuildId () : Player::GetGuildIdFromDB (target_guid);
3367 if (!glId)
3368 return false;
3370 Guild* targetGuild = sObjectMgr.GetGuildById (glId);
3371 if (!targetGuild)
3372 return false;
3374 uint32 newrank = uint32 (atoi (rankStr));
3375 if (newrank > targetGuild->GetLowestRank ())
3376 return false;
3378 targetGuild->ChangeRank (target_guid,newrank);
3379 return true;
3382 bool ChatHandler::HandleGuildDeleteCommand(const char* args)
3384 if (!*args)
3385 return false;
3387 char* guildStr = extractQuotedArg((char*)args);
3388 if(!guildStr)
3389 return false;
3391 std::string gld = guildStr;
3393 Guild* targetGuild = sObjectMgr.GetGuildByName (gld);
3394 if (!targetGuild)
3395 return false;
3397 targetGuild->Disband ();
3399 return true;
3402 bool ChatHandler::HandleGetDistanceCommand(const char* args)
3404 WorldObject* obj = NULL;
3406 if (*args)
3408 uint64 guid = extractGuidFromLink((char*)args);
3409 if(guid)
3410 obj = (WorldObject*)ObjectAccessor::GetObjectByTypeMask(*m_session->GetPlayer(),guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
3412 if(!obj)
3414 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3415 SetSentErrorMessage(true);
3416 return false;
3419 else
3421 obj = getSelectedUnit();
3423 if(!obj)
3425 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3426 SetSentErrorMessage(true);
3427 return false;
3431 PSendSysMessage(LANG_DISTANCE, m_session->GetPlayer()->GetDistance(obj),m_session->GetPlayer()->GetDistance2d(obj));
3433 return true;
3436 bool ChatHandler::HandleDieCommand(const char* /*args*/)
3438 Unit* target = getSelectedUnit();
3440 if(!target || !m_session->GetPlayer()->GetSelection())
3442 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3443 SetSentErrorMessage(true);
3444 return false;
3447 if(target->GetTypeId()==TYPEID_PLAYER)
3449 if(HasLowerSecurity((Player*)target,0,false))
3450 return false;
3453 if( target->isAlive() )
3455 m_session->GetPlayer()->DealDamage(target, target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
3458 return true;
3461 bool ChatHandler::HandleDamageCommand(const char * args)
3463 if (!*args)
3464 return false;
3466 Unit* target = getSelectedUnit();
3468 if (!target || !m_session->GetPlayer()->GetSelection())
3470 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3471 SetSentErrorMessage(true);
3472 return false;
3475 if (!target->isAlive())
3476 return true;
3478 char* damageStr = strtok((char*)args, " ");
3479 if (!damageStr)
3480 return false;
3482 int32 damage_int = atoi((char*)damageStr);
3483 if(damage_int <=0)
3484 return true;
3486 uint32 damage = damage_int;
3488 char* schoolStr = strtok((char*)NULL, " ");
3490 // flat melee damage without resistence/etc reduction
3491 if (!schoolStr)
3493 m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
3494 if (target != m_session->GetPlayer())
3495 m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, SPELL_SCHOOL_MASK_NORMAL, damage, 0, 0, VICTIMSTATE_NORMAL, 0);
3496 return true;
3499 uint32 school = schoolStr ? atoi((char*)schoolStr) : SPELL_SCHOOL_NORMAL;
3500 if(school >= MAX_SPELL_SCHOOL)
3501 return false;
3503 SpellSchoolMask schoolmask = SpellSchoolMask(1 << school);
3505 if ( schoolmask & SPELL_SCHOOL_MASK_NORMAL )
3506 damage = m_session->GetPlayer()->CalcArmorReducedDamage(target, damage);
3508 char* spellStr = strtok((char*)NULL, " ");
3510 // melee damage by specific school
3511 if (!spellStr)
3513 uint32 absorb = 0;
3514 uint32 resist = 0;
3516 m_session->GetPlayer()->CalcAbsorbResist(target,schoolmask, SPELL_DIRECT_DAMAGE, damage, &absorb, &resist);
3518 if (damage <= absorb + resist)
3519 return true;
3521 damage -= absorb + resist;
3523 m_session->GetPlayer()->DealDamageMods(target,damage,&absorb);
3524 m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, schoolmask, NULL, false);
3525 m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, schoolmask, damage, absorb, resist, VICTIMSTATE_NORMAL, 0);
3526 return true;
3529 // non-melee damage
3531 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
3532 uint32 spellid = extractSpellIdFromLink((char*)args);
3533 if (!spellid || !sSpellStore.LookupEntry(spellid))
3534 return false;
3536 m_session->GetPlayer()->SpellNonMeleeDamageLog(target, spellid, damage);
3537 return true;
3540 bool ChatHandler::HandleModifyArenaCommand(const char * args)
3542 if (!*args)
3543 return false;
3545 Player *target = getSelectedPlayer();
3546 if(!target)
3548 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3549 SetSentErrorMessage(true);
3550 return false;
3553 int32 amount = (uint32)atoi(args);
3555 target->ModifyArenaPoints(amount);
3557 PSendSysMessage(LANG_COMMAND_MODIFY_ARENA, GetNameLink(target).c_str(), target->GetArenaPoints());
3559 return true;
3562 bool ChatHandler::HandleReviveCommand(const char* args)
3564 Player* target;
3565 uint64 target_guid;
3566 if(!extractPlayerTarget((char*)args,&target,&target_guid))
3567 return false;
3569 if (target)
3571 target->ResurrectPlayer(0.5f);
3572 target->SpawnCorpseBones();
3574 else
3575 // will resurrected at login without corpse
3576 sObjectAccessor.ConvertCorpseForPlayer(target_guid);
3578 return true;
3581 bool ChatHandler::HandleAuraCommand(const char* args)
3583 Unit *target = getSelectedUnit();
3584 if(!target)
3586 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3587 SetSentErrorMessage(true);
3588 return false;
3591 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
3592 uint32 spellID = extractSpellIdFromLink((char*)args);
3594 SpellEntry const *spellInfo = sSpellStore.LookupEntry( spellID );
3595 if(spellInfo)
3597 for(uint32 i = 0; i < MAX_EFFECT_INDEX; ++i)
3599 uint8 eff = spellInfo->Effect[i];
3600 if (eff>=TOTAL_SPELL_EFFECTS)
3601 continue;
3602 if( IsAreaAuraEffect(eff) ||
3603 eff == SPELL_EFFECT_APPLY_AURA ||
3604 eff == SPELL_EFFECT_PERSISTENT_AREA_AURA )
3606 Aura *Aur = CreateAura(spellInfo, SpellEffectIndex(i), NULL, target);
3607 target->AddAura(Aur);
3612 return true;
3615 bool ChatHandler::HandleUnAuraCommand(const char* args)
3617 Unit *target = getSelectedUnit();
3618 if(!target)
3620 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3621 SetSentErrorMessage(true);
3622 return false;
3625 std::string argstr = args;
3626 if (argstr == "all")
3628 target->RemoveAllAuras();
3629 return true;
3632 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
3633 uint32 spellID = extractSpellIdFromLink((char*)args);
3634 if(!spellID)
3635 return false;
3637 target->RemoveAurasDueToSpell(spellID);
3639 return true;
3642 bool ChatHandler::HandleLinkGraveCommand(const char* args)
3644 if(!*args)
3645 return false;
3647 char* px = strtok((char*)args, " ");
3648 if (!px)
3649 return false;
3651 uint32 g_id = (uint32)atoi(px);
3653 uint32 g_team;
3655 char* px2 = strtok(NULL, " ");
3657 if (!px2)
3658 g_team = 0;
3659 else if (strncmp(px2,"horde",6)==0)
3660 g_team = HORDE;
3661 else if (strncmp(px2,"alliance",9)==0)
3662 g_team = ALLIANCE;
3663 else
3664 return false;
3666 WorldSafeLocsEntry const* graveyard = sWorldSafeLocsStore.LookupEntry(g_id);
3668 if(!graveyard )
3670 PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST, g_id);
3671 SetSentErrorMessage(true);
3672 return false;
3675 Player* player = m_session->GetPlayer();
3677 uint32 zoneId = player->GetZoneId();
3679 AreaTableEntry const *areaEntry = GetAreaEntryByAreaID(zoneId);
3680 if(!areaEntry || areaEntry->zone !=0 )
3682 PSendSysMessage(LANG_COMMAND_GRAVEYARDWRONGZONE, g_id,zoneId);
3683 SetSentErrorMessage(true);
3684 return false;
3687 if(sObjectMgr.AddGraveYardLink(g_id,zoneId,g_team))
3688 PSendSysMessage(LANG_COMMAND_GRAVEYARDLINKED, g_id,zoneId);
3689 else
3690 PSendSysMessage(LANG_COMMAND_GRAVEYARDALRLINKED, g_id,zoneId);
3692 return true;
3695 bool ChatHandler::HandleNearGraveCommand(const char* args)
3697 uint32 g_team;
3699 size_t argslen = strlen(args);
3701 if(!*args)
3702 g_team = 0;
3703 else if (strncmp((char*)args,"horde",argslen)==0)
3704 g_team = HORDE;
3705 else if (strncmp((char*)args,"alliance",argslen)==0)
3706 g_team = ALLIANCE;
3707 else
3708 return false;
3710 Player* player = m_session->GetPlayer();
3711 uint32 zone_id = player->GetZoneId();
3713 WorldSafeLocsEntry const* graveyard = sObjectMgr.GetClosestGraveYard(
3714 player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(),player->GetMapId(),g_team);
3716 if(graveyard)
3718 uint32 g_id = graveyard->ID;
3720 GraveYardData const* data = sObjectMgr.FindGraveYardData(g_id,zone_id);
3721 if (!data)
3723 PSendSysMessage(LANG_COMMAND_GRAVEYARDERROR,g_id);
3724 SetSentErrorMessage(true);
3725 return false;
3728 g_team = data->team;
3730 std::string team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_NOTEAM);
3732 if(g_team == 0)
3733 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ANY);
3734 else if(g_team == HORDE)
3735 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_HORDE);
3736 else if(g_team == ALLIANCE)
3737 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ALLIANCE);
3739 PSendSysMessage(LANG_COMMAND_GRAVEYARDNEAREST, g_id,team_name.c_str(),zone_id);
3741 else
3743 std::string team_name;
3745 if(g_team == 0)
3746 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ANY);
3747 else if(g_team == HORDE)
3748 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_HORDE);
3749 else if(g_team == ALLIANCE)
3750 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ALLIANCE);
3752 if(g_team == ~uint32(0))
3753 PSendSysMessage(LANG_COMMAND_ZONENOGRAVEYARDS, zone_id);
3754 else
3755 PSendSysMessage(LANG_COMMAND_ZONENOGRAFACTION, zone_id,team_name.c_str());
3758 return true;
3761 //-----------------------Npc Commands-----------------------
3762 bool ChatHandler::HandleNpcAllowMovementCommand(const char* /*args*/)
3764 if(sWorld.getAllowMovement())
3766 sWorld.SetAllowMovement(false);
3767 SendSysMessage(LANG_CREATURE_MOVE_DISABLED);
3769 else
3771 sWorld.SetAllowMovement(true);
3772 SendSysMessage(LANG_CREATURE_MOVE_ENABLED);
3774 return true;
3777 bool ChatHandler::HandleNpcChangeEntryCommand(const char *args)
3779 if (!*args)
3780 return false;
3782 uint32 newEntryNum = atoi(args);
3783 if(!newEntryNum)
3784 return false;
3786 Unit* unit = getSelectedUnit();
3787 if(!unit || unit->GetTypeId() != TYPEID_UNIT)
3789 SendSysMessage(LANG_SELECT_CREATURE);
3790 SetSentErrorMessage(true);
3791 return false;
3793 Creature* creature = (Creature*)unit;
3794 if(creature->UpdateEntry(newEntryNum))
3795 SendSysMessage(LANG_DONE);
3796 else
3797 SendSysMessage(LANG_ERROR);
3798 return true;
3801 bool ChatHandler::HandleNpcInfoCommand(const char* /*args*/)
3803 Creature* target = getSelectedCreature();
3805 if(!target)
3807 SendSysMessage(LANG_SELECT_CREATURE);
3808 SetSentErrorMessage(true);
3809 return false;
3812 uint32 faction = target->getFaction();
3813 uint32 npcflags = target->GetUInt32Value(UNIT_NPC_FLAGS);
3814 uint32 displayid = target->GetDisplayId();
3815 uint32 nativeid = target->GetNativeDisplayId();
3816 uint32 Entry = target->GetEntry();
3817 CreatureInfo const* cInfo = target->GetCreatureInfo();
3819 time_t curRespawnDelay = target->GetRespawnTimeEx()-time(NULL);
3820 if(curRespawnDelay < 0)
3821 curRespawnDelay = 0;
3822 std::string curRespawnDelayStr = secsToTimeString(curRespawnDelay,true);
3823 std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(),true);
3825 PSendSysMessage(LANG_NPCINFO_CHAR, target->GetDBTableGUIDLow(), faction, npcflags, Entry, displayid, nativeid);
3826 PSendSysMessage(LANG_NPCINFO_LEVEL, target->getLevel());
3827 PSendSysMessage(LANG_NPCINFO_HEALTH,target->GetCreateHealth(), target->GetMaxHealth(), target->GetHealth());
3828 PSendSysMessage(LANG_NPCINFO_FLAGS, target->GetUInt32Value(UNIT_FIELD_FLAGS), target->GetUInt32Value(UNIT_DYNAMIC_FLAGS), target->getFaction());
3829 PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES, defRespawnDelayStr.c_str(),curRespawnDelayStr.c_str());
3830 PSendSysMessage(LANG_NPCINFO_LOOT, cInfo->lootid,cInfo->pickpocketLootId,cInfo->SkinLootId);
3831 PSendSysMessage(LANG_NPCINFO_DUNGEON_ID, target->GetInstanceId());
3832 PSendSysMessage(LANG_NPCINFO_POSITION,float(target->GetPositionX()), float(target->GetPositionY()), float(target->GetPositionZ()));
3834 if ((npcflags & UNIT_NPC_FLAG_VENDOR) )
3836 SendSysMessage(LANG_NPCINFO_VENDOR);
3838 if ((npcflags & UNIT_NPC_FLAG_TRAINER) )
3840 SendSysMessage(LANG_NPCINFO_TRAINER);
3843 return true;
3846 //play npc emote
3847 bool ChatHandler::HandleNpcPlayEmoteCommand(const char* args)
3849 uint32 emote = atoi((char*)args);
3851 Creature* target = getSelectedCreature();
3852 if(!target)
3854 SendSysMessage(LANG_SELECT_CREATURE);
3855 SetSentErrorMessage(true);
3856 return false;
3859 target->SetUInt32Value(UNIT_NPC_EMOTESTATE,emote);
3861 return true;
3864 //TODO: NpcCommands that needs to be fixed :
3866 bool ChatHandler::HandleNpcAddWeaponCommand(const char* /*args*/)
3868 /*if (!*args)
3869 return false;
3871 uint64 guid = m_session->GetPlayer()->GetSelection();
3872 if (guid == 0)
3874 SendSysMessage(LANG_NO_SELECTION);
3875 return true;
3878 Creature *pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
3880 if(!pCreature)
3882 SendSysMessage(LANG_SELECT_CREATURE);
3883 return true;
3886 char* pSlotID = strtok((char*)args, " ");
3887 if (!pSlotID)
3888 return false;
3890 char* pItemID = strtok(NULL, " ");
3891 if (!pItemID)
3892 return false;
3894 uint32 ItemID = atoi(pItemID);
3895 uint32 SlotID = atoi(pSlotID);
3897 ItemPrototype* tmpItem = ObjectMgr::GetItemPrototype(ItemID);
3899 bool added = false;
3900 if(tmpItem)
3902 switch(SlotID)
3904 case 1:
3905 pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, ItemID);
3906 added = true;
3907 break;
3908 case 2:
3909 pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_01, ItemID);
3910 added = true;
3911 break;
3912 case 3:
3913 pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_02, ItemID);
3914 added = true;
3915 break;
3916 default:
3917 PSendSysMessage(LANG_ITEM_SLOT_NOT_EXIST,SlotID);
3918 added = false;
3919 break;
3922 if(added)
3923 PSendSysMessage(LANG_ITEM_ADDED_TO_SLOT,ItemID,tmpItem->Name1,SlotID);
3925 else
3927 PSendSysMessage(LANG_ITEM_NOT_FOUND,ItemID);
3928 return true;
3931 return true;
3933 //----------------------------------------------------------
3935 bool ChatHandler::HandleExploreCheatCommand(const char* args)
3937 if (!*args)
3938 return false;
3940 int flag = atoi((char*)args);
3942 Player *chr = getSelectedPlayer();
3943 if (chr == NULL)
3945 SendSysMessage(LANG_NO_CHAR_SELECTED);
3946 SetSentErrorMessage(true);
3947 return false;
3950 if (flag != 0)
3952 PSendSysMessage(LANG_YOU_SET_EXPLORE_ALL, GetNameLink(chr).c_str());
3953 if (needReportToTarget(chr))
3954 ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_ALL,GetNameLink().c_str());
3956 else
3958 PSendSysMessage(LANG_YOU_SET_EXPLORE_NOTHING, GetNameLink(chr).c_str());
3959 if (needReportToTarget(chr))
3960 ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_NOTHING,GetNameLink().c_str());
3963 for (uint8 i=0; i<128; ++i)
3965 if (flag != 0)
3967 m_session->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i,0xFFFFFFFF);
3969 else
3971 m_session->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i,0);
3975 return true;
3978 bool ChatHandler::HandleHoverCommand(const char* args)
3980 char* px = strtok((char*)args, " ");
3981 uint32 flag;
3982 if (!px)
3983 flag = 1;
3984 else
3985 flag = atoi(px);
3987 m_session->GetPlayer()->SetHover(flag);
3989 if (flag)
3990 SendSysMessage(LANG_HOVER_ENABLED);
3991 else
3992 SendSysMessage(LANG_HOVER_DISABLED);
3994 return true;
3997 void ChatHandler::HandleCharacterLevel(Player* player, uint64 player_guid, uint32 oldlevel, uint32 newlevel)
3999 if(player)
4001 player->GiveLevel(newlevel);
4002 player->InitTalentForLevel();
4003 player->SetUInt32Value(PLAYER_XP,0);
4005 if(needReportToTarget(player))
4007 if(oldlevel == newlevel)
4008 ChatHandler(player).PSendSysMessage(LANG_YOURS_LEVEL_PROGRESS_RESET,GetNameLink().c_str());
4009 else if(oldlevel < newlevel)
4010 ChatHandler(player).PSendSysMessage(LANG_YOURS_LEVEL_UP,GetNameLink().c_str(),newlevel);
4011 else // if(oldlevel > newlevel)
4012 ChatHandler(player).PSendSysMessage(LANG_YOURS_LEVEL_DOWN,GetNameLink().c_str(),newlevel);
4015 else
4017 // update level and XP at level, all other will be updated at loading
4018 CharacterDatabase.PExecute("UPDATE characters SET level = '%u', xp = 0 WHERE guid = '%u'", newlevel, GUID_LOPART(player_guid));
4022 bool ChatHandler::HandleCharacterLevelCommand(const char* args)
4024 char* nameStr;
4025 char* levelStr;
4026 extractOptFirstArg((char*)args,&nameStr,&levelStr);
4027 if(!levelStr)
4028 return false;
4030 // exception opt second arg: .character level $name
4031 if(isalpha(levelStr[0]))
4033 nameStr = levelStr;
4034 levelStr = NULL; // current level will used
4037 Player* target;
4038 uint64 target_guid;
4039 std::string target_name;
4040 if(!extractPlayerTarget(nameStr,&target,&target_guid,&target_name))
4041 return false;
4043 int32 oldlevel = target ? target->getLevel() : Player::GetLevelFromDB(target_guid);
4044 int32 newlevel = levelStr ? atoi(levelStr) : oldlevel;
4046 if(newlevel < 1)
4047 return false; // invalid level
4049 if(newlevel > STRONG_MAX_LEVEL) // hardcoded maximum level
4050 newlevel = STRONG_MAX_LEVEL;
4052 HandleCharacterLevel(target,target_guid,oldlevel,newlevel);
4054 if(!m_session || m_session->GetPlayer() != target) // including player==NULL
4056 std::string nameLink = playerLink(target_name);
4057 PSendSysMessage(LANG_YOU_CHANGE_LVL,nameLink.c_str(),newlevel);
4060 return true;
4063 bool ChatHandler::HandleLevelUpCommand(const char* args)
4065 char* nameStr;
4066 char* levelStr;
4067 extractOptFirstArg((char*)args,&nameStr,&levelStr);
4069 // exception opt second arg: .character level $name
4070 if(levelStr && isalpha(levelStr[0]))
4072 nameStr = levelStr;
4073 levelStr = NULL; // current level will used
4076 Player* target;
4077 uint64 target_guid;
4078 std::string target_name;
4079 if(!extractPlayerTarget(nameStr,&target,&target_guid,&target_name))
4080 return false;
4082 int32 oldlevel = target ? target->getLevel() : Player::GetLevelFromDB(target_guid);
4083 int32 addlevel = levelStr ? atoi(levelStr) : 1;
4084 int32 newlevel = oldlevel + addlevel;
4086 if(newlevel < 1)
4087 newlevel = 1;
4089 if(newlevel > STRONG_MAX_LEVEL) // hardcoded maximum level
4090 newlevel = STRONG_MAX_LEVEL;
4092 HandleCharacterLevel(target,target_guid,oldlevel,newlevel);
4094 if(!m_session || m_session->GetPlayer() != target) // including chr==NULL
4096 std::string nameLink = playerLink(target_name);
4097 PSendSysMessage(LANG_YOU_CHANGE_LVL,nameLink.c_str(),newlevel);
4100 return true;
4103 bool ChatHandler::HandleShowAreaCommand(const char* args)
4105 if (!*args)
4106 return false;
4108 Player *chr = getSelectedPlayer();
4109 if (chr == NULL)
4111 SendSysMessage(LANG_NO_CHAR_SELECTED);
4112 SetSentErrorMessage(true);
4113 return false;
4116 int area = GetAreaFlagByAreaID(atoi((char*)args));
4117 int offset = area / 32;
4118 uint32 val = (uint32)(1 << (area % 32));
4120 if(area<0 || offset >= 128)
4122 SendSysMessage(LANG_BAD_VALUE);
4123 SetSentErrorMessage(true);
4124 return false;
4127 uint32 currFields = chr->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset);
4128 chr->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields | val));
4130 SendSysMessage(LANG_EXPLORE_AREA);
4131 return true;
4134 bool ChatHandler::HandleHideAreaCommand(const char* args)
4136 if (!*args)
4137 return false;
4139 Player *chr = getSelectedPlayer();
4140 if (chr == NULL)
4142 SendSysMessage(LANG_NO_CHAR_SELECTED);
4143 SetSentErrorMessage(true);
4144 return false;
4147 int area = GetAreaFlagByAreaID(atoi((char*)args));
4148 int offset = area / 32;
4149 uint32 val = (uint32)(1 << (area % 32));
4151 if(area<0 || offset >= 128)
4153 SendSysMessage(LANG_BAD_VALUE);
4154 SetSentErrorMessage(true);
4155 return false;
4158 uint32 currFields = chr->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset);
4159 chr->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields ^ val));
4161 SendSysMessage(LANG_UNEXPLORE_AREA);
4162 return true;
4165 bool ChatHandler::HandleBankCommand(const char* /*args*/)
4167 m_session->SendShowBank( m_session->GetPlayer()->GetGUID() );
4169 return true;
4172 bool ChatHandler::HandleChangeWeather(const char* args)
4174 if(!*args)
4175 return false;
4177 //Weather is OFF
4178 if (!sWorld.getConfig(CONFIG_BOOL_WEATHER))
4180 SendSysMessage(LANG_WEATHER_DISABLED);
4181 SetSentErrorMessage(true);
4182 return false;
4185 //*Change the weather of a cell
4186 char* px = strtok((char*)args, " ");
4187 char* py = strtok(NULL, " ");
4189 if (!px || !py)
4190 return false;
4192 uint32 type = (uint32)atoi(px); //0 to 3, 0: fine, 1: rain, 2: snow, 3: sand
4193 float grade = (float)atof(py); //0 to 1, sending -1 is instand good weather
4195 Player *player = m_session->GetPlayer();
4196 uint32 zoneid = player->GetZoneId();
4198 Weather* wth = sWorld.FindWeather(zoneid);
4200 if(!wth)
4201 wth = sWorld.AddWeather(zoneid);
4202 if(!wth)
4204 SendSysMessage(LANG_NO_WEATHER);
4205 SetSentErrorMessage(true);
4206 return false;
4209 wth->SetWeather(WeatherType(type), grade);
4211 return true;
4214 bool ChatHandler::HandleTeleAddCommand(const char * args)
4216 if(!*args)
4217 return false;
4219 Player *player=m_session->GetPlayer();
4220 if (!player)
4221 return false;
4223 std::string name = args;
4225 if(sObjectMgr.GetGameTele(name))
4227 SendSysMessage(LANG_COMMAND_TP_ALREADYEXIST);
4228 SetSentErrorMessage(true);
4229 return false;
4232 GameTele tele;
4233 tele.position_x = player->GetPositionX();
4234 tele.position_y = player->GetPositionY();
4235 tele.position_z = player->GetPositionZ();
4236 tele.orientation = player->GetOrientation();
4237 tele.mapId = player->GetMapId();
4238 tele.name = name;
4240 if(sObjectMgr.AddGameTele(tele))
4242 SendSysMessage(LANG_COMMAND_TP_ADDED);
4244 else
4246 SendSysMessage(LANG_COMMAND_TP_ADDEDERR);
4247 SetSentErrorMessage(true);
4248 return false;
4251 return true;
4254 bool ChatHandler::HandleTeleDelCommand(const char * args)
4256 if(!*args)
4257 return false;
4259 std::string name = args;
4261 if(!sObjectMgr.DeleteGameTele(name))
4263 SendSysMessage(LANG_COMMAND_TELE_NOTFOUND);
4264 SetSentErrorMessage(true);
4265 return false;
4268 SendSysMessage(LANG_COMMAND_TP_DELETED);
4269 return true;
4272 bool ChatHandler::HandleListAurasCommand (const char * /*args*/)
4274 Unit *unit = getSelectedUnit();
4275 if(!unit)
4277 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
4278 SetSentErrorMessage(true);
4279 return false;
4282 char const* talentStr = GetMangosString(LANG_TALENT);
4283 char const* passiveStr = GetMangosString(LANG_PASSIVE);
4285 Unit::AuraMap const& uAuras = unit->GetAuras();
4286 PSendSysMessage(LANG_COMMAND_TARGET_LISTAURAS, uAuras.size());
4287 for (Unit::AuraMap::const_iterator itr = uAuras.begin(); itr != uAuras.end(); ++itr)
4289 bool talent = GetTalentSpellCost(itr->second->GetId()) > 0;
4291 char const* name = itr->second->GetSpellProto()->SpellName[GetSessionDbcLocale()];
4293 if (m_session)
4295 std::ostringstream ss_name;
4296 ss_name << "|cffffffff|Hspell:" << itr->second->GetId() << "|h[" << name << "]|h|r";
4298 PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffIndex(),
4299 itr->second->GetModifier()->m_auraname, itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(),
4300 ss_name.str().c_str(),
4301 (itr->second->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
4302 IS_PLAYER_GUID(itr->second->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(itr->second->GetCasterGUID()));
4304 else
4306 PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffIndex(),
4307 itr->second->GetModifier()->m_auraname, itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(),
4308 name,
4309 (itr->second->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
4310 IS_PLAYER_GUID(itr->second->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(itr->second->GetCasterGUID()));
4313 for (int i = 0; i < TOTAL_AURAS; ++i)
4315 Unit::AuraList const& uAuraList = unit->GetAurasByType(AuraType(i));
4316 if (uAuraList.empty()) continue;
4317 PSendSysMessage(LANG_COMMAND_TARGET_LISTAURATYPE, uAuraList.size(), i);
4318 for (Unit::AuraList::const_iterator itr = uAuraList.begin(); itr != uAuraList.end(); ++itr)
4320 bool talent = GetTalentSpellCost((*itr)->GetId()) > 0;
4322 char const* name = (*itr)->GetSpellProto()->SpellName[GetSessionDbcLocale()];
4324 if (m_session)
4326 std::ostringstream ss_name;
4327 ss_name << "|cffffffff|Hspell:" << (*itr)->GetId() << "|h[" << name << "]|h|r";
4329 PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(),
4330 ss_name.str().c_str(),((*itr)->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
4331 IS_PLAYER_GUID((*itr)->GetCasterGUID()) ? "player" : "creature",GUID_LOPART((*itr)->GetCasterGUID()));
4333 else
4335 PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(),
4336 name,((*itr)->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
4337 IS_PLAYER_GUID((*itr)->GetCasterGUID()) ? "player" : "creature",GUID_LOPART((*itr)->GetCasterGUID()));
4341 return true;
4344 bool ChatHandler::HandleResetAchievementsCommand (const char * args)
4346 Player* target;
4347 uint64 target_guid;
4348 if (!extractPlayerTarget((char*)args,&target,&target_guid))
4349 return false;
4351 if(target)
4352 target->GetAchievementMgr().Reset();
4353 else
4354 AchievementMgr::DeleteFromDB(GUID_LOPART(target_guid));
4356 return true;
4359 bool ChatHandler::HandleResetHonorCommand (const char * args)
4361 Player* target;
4362 if (!extractPlayerTarget((char*)args,&target))
4363 return false;
4365 target->SetUInt32Value(PLAYER_FIELD_KILLS, 0);
4366 target->SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORBALE_KILLS, 0);
4367 target->SetUInt32Value(PLAYER_FIELD_HONOR_CURRENCY, 0);
4368 target->SetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, 0);
4369 target->SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, 0);
4370 target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL);
4372 return true;
4375 static bool HandleResetStatsOrLevelHelper(Player* player)
4377 ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(player->getClass());
4378 if(!cEntry)
4380 sLog.outError("Class %u not found in DBC (Wrong DBC files?)",player->getClass());
4381 return false;
4384 uint8 powertype = cEntry->powerType;
4386 // reset m_form if no aura
4387 if(!player->HasAuraType(SPELL_AURA_MOD_SHAPESHIFT))
4388 player->m_form = FORM_NONE;
4390 player->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE );
4391 player->SetFloatValue(UNIT_FIELD_COMBATREACH, 1.5f );
4393 player->setFactionForRace(player->getRace());
4395 player->SetUInt32Value(UNIT_FIELD_BYTES_0, ( ( player->getRace() ) | ( player->getClass() << 8 ) | ( player->getGender() << 16 ) | ( powertype << 24 ) ) );
4397 // reset only if player not in some form;
4398 if(player->m_form==FORM_NONE)
4399 player->InitDisplayIds();
4401 player->SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP );
4402 player->SetByteValue(UNIT_FIELD_BYTES_2, 3, player->m_form);
4404 player->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
4406 //-1 is default value
4407 player->SetInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, -1);
4409 //player->SetUInt32Value(PLAYER_FIELD_BYTES, 0xEEE00000 );
4410 return true;
4413 bool ChatHandler::HandleResetLevelCommand(const char * args)
4415 Player* target;
4416 if(!extractPlayerTarget((char*)args,&target))
4417 return false;
4419 if(!HandleResetStatsOrLevelHelper(target))
4420 return false;
4422 // set starting level
4423 uint32 start_level = target->getClass() != CLASS_DEATH_KNIGHT
4424 ? sWorld.getConfig(CONFIG_UINT32_START_PLAYER_LEVEL)
4425 : sWorld.getConfig(CONFIG_UINT32_START_HEROIC_PLAYER_LEVEL);
4427 target->_ApplyAllLevelScaleItemMods(false);
4429 target->SetLevel(start_level);
4430 target->InitRunes();
4431 target->InitStatsForLevel(true);
4432 target->InitTaxiNodesForLevel();
4433 target->InitGlyphsForLevel();
4434 target->InitTalentForLevel();
4435 target->SetUInt32Value(PLAYER_XP,0);
4437 target->_ApplyAllLevelScaleItemMods(true);
4439 // reset level for pet
4440 if(Pet* pet = target->GetPet())
4441 pet->SynchronizeLevelWithOwner();
4443 return true;
4446 bool ChatHandler::HandleResetStatsCommand(const char * args)
4448 Player* target;
4449 if (!extractPlayerTarget((char*)args,&target))
4450 return false;
4452 if (!HandleResetStatsOrLevelHelper(target))
4453 return false;
4455 target->InitRunes();
4456 target->InitStatsForLevel(true);
4457 target->InitTaxiNodesForLevel();
4458 target->InitGlyphsForLevel();
4459 target->InitTalentForLevel();
4461 return true;
4464 bool ChatHandler::HandleResetSpellsCommand(const char * args)
4466 Player* target;
4467 uint64 target_guid;
4468 std::string target_name;
4469 if(!extractPlayerTarget((char*)args, &target, &target_guid, &target_name))
4470 return false;
4472 if(target)
4474 target->resetSpells();
4476 ChatHandler(target).SendSysMessage(LANG_RESET_SPELLS);
4477 if(!m_session || m_session->GetPlayer()!=target)
4478 PSendSysMessage(LANG_RESET_SPELLS_ONLINE,GetNameLink(target).c_str());
4480 else
4482 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",uint32(AT_LOGIN_RESET_SPELLS), GUID_LOPART(target_guid));
4483 PSendSysMessage(LANG_RESET_SPELLS_OFFLINE,target_name.c_str());
4486 return true;
4489 bool ChatHandler::HandleResetTalentsCommand(const char * args)
4491 Player* target;
4492 uint64 target_guid;
4493 std::string target_name;
4494 if (!extractPlayerTarget((char*)args, &target, &target_guid, &target_name))
4496 // Try reset talents as Hunter Pet
4497 Creature* creature = getSelectedCreature();
4498 if (!*args && creature && creature->isPet())
4500 Unit *owner = creature->GetOwner();
4501 if(owner && owner->GetTypeId() == TYPEID_PLAYER && ((Pet *)creature)->IsPermanentPetFor((Player*)owner))
4503 ((Pet *)creature)->resetTalents(true);
4504 ((Player*)owner)->SendTalentsInfoData(true);
4506 ChatHandler((Player*)owner).SendSysMessage(LANG_RESET_PET_TALENTS);
4507 if(!m_session || m_session->GetPlayer() != ((Player*)owner))
4508 PSendSysMessage(LANG_RESET_PET_TALENTS_ONLINE,GetNameLink((Player*)owner).c_str());
4510 return true;
4513 SendSysMessage(LANG_NO_CHAR_SELECTED);
4514 SetSentErrorMessage(true);
4515 return false;
4518 if (target)
4520 target->resetTalents(true);
4521 target->SendTalentsInfoData(false);
4522 ChatHandler(target).SendSysMessage(LANG_RESET_TALENTS);
4523 if (!m_session || m_session->GetPlayer() != target)
4524 PSendSysMessage(LANG_RESET_TALENTS_ONLINE,GetNameLink(target).c_str());
4526 Pet* pet = target->GetPet();
4527 Pet::resetTalentsForAllPetsOf(target, pet);
4528 if(pet)
4529 target->SendTalentsInfoData(true);
4530 return true;
4532 else if (target_guid)
4534 uint32 at_flags = AT_LOGIN_RESET_PET_TALENTS;
4535 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'", at_flags, GUID_LOPART(target_guid) );
4536 std::string nameLink = playerLink(target_name);
4537 PSendSysMessage(LANG_RESET_TALENTS_OFFLINE, nameLink.c_str());
4538 return true;
4541 SendSysMessage(LANG_NO_CHAR_SELECTED);
4542 SetSentErrorMessage(true);
4543 return false;
4546 bool ChatHandler::HandleResetAllCommand(const char * args)
4548 if(!*args)
4549 return false;
4551 std::string casename = args;
4553 AtLoginFlags atLogin;
4555 // Command specially created as single command to prevent using short case names
4556 if(casename=="spells")
4558 atLogin = AT_LOGIN_RESET_SPELLS;
4559 sWorld.SendWorldText(LANG_RESETALL_SPELLS);
4560 if(!m_session)
4561 SendSysMessage(LANG_RESETALL_SPELLS);
4563 else if(casename=="talents")
4565 atLogin = AtLoginFlags(AT_LOGIN_RESET_TALENTS | AT_LOGIN_RESET_PET_TALENTS);
4566 sWorld.SendWorldText(LANG_RESETALL_TALENTS);
4567 if(!m_session)
4568 SendSysMessage(LANG_RESETALL_TALENTS);
4570 else
4572 PSendSysMessage(LANG_RESETALL_UNKNOWN_CASE,args);
4573 SetSentErrorMessage(true);
4574 return false;
4577 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE (at_login & '%u') = '0'",atLogin,atLogin);
4578 HashMapHolder<Player>::MapType const& plist = sObjectAccessor.GetPlayers();
4579 for(HashMapHolder<Player>::MapType::const_iterator itr = plist.begin(); itr != plist.end(); ++itr)
4580 itr->second->SetAtLoginFlag(atLogin);
4582 return true;
4585 bool ChatHandler::HandleServerShutDownCancelCommand(const char* /*args*/)
4587 sWorld.ShutdownCancel();
4588 return true;
4591 bool ChatHandler::HandleServerShutDownCommand(const char* args)
4593 if(!*args)
4594 return false;
4596 char* time_str = strtok ((char*) args, " ");
4597 char* exitcode_str = strtok (NULL, "");
4599 int32 time = atoi (time_str);
4601 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4602 if ((time == 0 && (time_str[0]!='0' || time_str[1]!='\0')) || time < 0)
4603 return false;
4605 if (exitcode_str)
4607 int32 exitcode = atoi (exitcode_str);
4609 // Handle atoi() errors
4610 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4611 return false;
4613 // Exit code should be in range of 0-125, 126-255 is used
4614 // in many shells for their own return codes and code > 255
4615 // is not supported in many others
4616 if (exitcode < 0 || exitcode > 125)
4617 return false;
4619 sWorld.ShutdownServ (time, 0, exitcode);
4621 else
4622 sWorld.ShutdownServ(time,0,SHUTDOWN_EXIT_CODE);
4623 return true;
4626 bool ChatHandler::HandleServerRestartCommand(const char* args)
4628 if(!*args)
4629 return false;
4631 char* time_str = strtok ((char*) args, " ");
4632 char* exitcode_str = strtok (NULL, "");
4634 int32 time = atoi (time_str);
4636 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4637 if ((time == 0 && (time_str[0]!='0' || time_str[1]!='\0')) || time < 0)
4638 return false;
4640 if (exitcode_str)
4642 int32 exitcode = atoi (exitcode_str);
4644 // Handle atoi() errors
4645 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4646 return false;
4648 // Exit code should be in range of 0-125, 126-255 is used
4649 // in many shells for their own return codes and code > 255
4650 // is not supported in many others
4651 if (exitcode < 0 || exitcode > 125)
4652 return false;
4654 sWorld.ShutdownServ (time, SHUTDOWN_MASK_RESTART, exitcode);
4656 else
4657 sWorld.ShutdownServ(time, SHUTDOWN_MASK_RESTART, RESTART_EXIT_CODE);
4658 return true;
4661 bool ChatHandler::HandleServerIdleRestartCommand(const char* args)
4663 if(!*args)
4664 return false;
4666 char* time_str = strtok ((char*) args, " ");
4667 char* exitcode_str = strtok (NULL, "");
4669 int32 time = atoi (time_str);
4671 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4672 if ((time == 0 && (time_str[0]!='0' || time_str[1]!='\0')) || time < 0)
4673 return false;
4675 if (exitcode_str)
4677 int32 exitcode = atoi (exitcode_str);
4679 // Handle atoi() errors
4680 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4681 return false;
4683 // Exit code should be in range of 0-125, 126-255 is used
4684 // in many shells for their own return codes and code > 255
4685 // is not supported in many others
4686 if (exitcode < 0 || exitcode > 125)
4687 return false;
4689 sWorld.ShutdownServ (time, SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE, exitcode);
4691 else
4692 sWorld.ShutdownServ(time,SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE,RESTART_EXIT_CODE);
4693 return true;
4696 bool ChatHandler::HandleServerIdleShutDownCommand(const char* args)
4698 if(!*args)
4699 return false;
4701 char* time_str = strtok ((char*) args, " ");
4702 char* exitcode_str = strtok (NULL, "");
4704 int32 time = atoi (time_str);
4706 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4707 if ((time == 0 && (time_str[0]!='0' || time_str[1]!='\0')) || time < 0)
4708 return false;
4710 if (exitcode_str)
4712 int32 exitcode = atoi (exitcode_str);
4714 // Handle atoi() errors
4715 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4716 return false;
4718 // Exit code should be in range of 0-125, 126-255 is used
4719 // in many shells for their own return codes and code > 255
4720 // is not supported in many others
4721 if (exitcode < 0 || exitcode > 125)
4722 return false;
4724 sWorld.ShutdownServ (time, SHUTDOWN_MASK_IDLE, exitcode);
4726 else
4727 sWorld.ShutdownServ(time,SHUTDOWN_MASK_IDLE,SHUTDOWN_EXIT_CODE);
4728 return true;
4731 bool ChatHandler::HandleQuestAdd(const char* args)
4733 Player* player = getSelectedPlayer();
4734 if(!player)
4736 SendSysMessage(LANG_NO_CHAR_SELECTED);
4737 SetSentErrorMessage(true);
4738 return false;
4741 // .addquest #entry'
4742 // number or [name] Shift-click form |color|Hquest:quest_id:quest_level|h[name]|h|r
4743 char* cId = extractKeyFromLink((char*)args,"Hquest");
4744 if(!cId)
4745 return false;
4747 uint32 entry = atol(cId);
4749 Quest const* pQuest = sObjectMgr.GetQuestTemplate(entry);
4751 if(!pQuest)
4753 PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND,entry);
4754 SetSentErrorMessage(true);
4755 return false;
4758 // check item starting quest (it can work incorrectly if added without item in inventory)
4759 for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
4761 ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype>(id);
4762 if (!pProto)
4763 continue;
4765 if (pProto->StartQuest == entry)
4767 PSendSysMessage(LANG_COMMAND_QUEST_STARTFROMITEM, entry, pProto->ItemId);
4768 SetSentErrorMessage(true);
4769 return false;
4773 // ok, normal (creature/GO starting) quest
4774 if( player->CanAddQuest( pQuest, true ) )
4776 player->AddQuest( pQuest, NULL );
4778 if ( player->CanCompleteQuest( entry ) )
4779 player->CompleteQuest( entry );
4782 return true;
4785 bool ChatHandler::HandleQuestRemove(const char* args)
4787 Player* player = getSelectedPlayer();
4788 if(!player)
4790 SendSysMessage(LANG_NO_CHAR_SELECTED);
4791 SetSentErrorMessage(true);
4792 return false;
4795 // .removequest #entry'
4796 // number or [name] Shift-click form |color|Hquest:quest_id:quest_level|h[name]|h|r
4797 char* cId = extractKeyFromLink((char*)args,"Hquest");
4798 if(!cId)
4799 return false;
4801 uint32 entry = atol(cId);
4803 Quest const* pQuest = sObjectMgr.GetQuestTemplate(entry);
4805 if(!pQuest)
4807 PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry);
4808 SetSentErrorMessage(true);
4809 return false;
4812 // remove all quest entries for 'entry' from quest log
4813 for(uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot )
4815 uint32 quest = player->GetQuestSlotQuestId(slot);
4816 if(quest==entry)
4818 player->SetQuestSlot(slot,0);
4820 // we ignore unequippable quest items in this case, its' still be equipped
4821 player->TakeQuestSourceItem( quest, false );
4825 // set quest status to not started (will updated in DB at next save)
4826 player->SetQuestStatus( entry, QUEST_STATUS_NONE);
4828 // reset rewarded for restart repeatable quest
4829 player->getQuestStatusMap()[entry].m_rewarded = false;
4831 SendSysMessage(LANG_COMMAND_QUEST_REMOVED);
4832 return true;
4835 bool ChatHandler::HandleQuestComplete(const char* args)
4837 Player* player = getSelectedPlayer();
4838 if(!player)
4840 SendSysMessage(LANG_NO_CHAR_SELECTED);
4841 SetSentErrorMessage(true);
4842 return false;
4845 // .quest complete #entry
4846 // number or [name] Shift-click form |color|Hquest:quest_id:quest_level|h[name]|h|r
4847 char* cId = extractKeyFromLink((char*)args,"Hquest");
4848 if(!cId)
4849 return false;
4851 uint32 entry = atol(cId);
4853 Quest const* pQuest = sObjectMgr.GetQuestTemplate(entry);
4855 // If player doesn't have the quest
4856 if(!pQuest || player->GetQuestStatus(entry) == QUEST_STATUS_NONE)
4858 PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry);
4859 SetSentErrorMessage(true);
4860 return false;
4863 // Add quest items for quests that require items
4864 for(uint8 x = 0; x < QUEST_ITEM_OBJECTIVES_COUNT; ++x)
4866 uint32 id = pQuest->ReqItemId[x];
4867 uint32 count = pQuest->ReqItemCount[x];
4868 if(!id || !count)
4869 continue;
4871 uint32 curItemCount = player->GetItemCount(id,true);
4873 ItemPosCountVec dest;
4874 uint8 msg = player->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, id, count - curItemCount );
4875 if( msg == EQUIP_ERR_OK )
4877 Item* item = player->StoreNewItem( dest, id, true);
4878 player->SendNewItem(item,count-curItemCount, true, false);
4882 // All creature/GO slain/casted (not required, but otherwise it will display "Creature slain 0/10")
4883 for(uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
4885 int32 creature = pQuest->ReqCreatureOrGOId[i];
4886 uint32 creaturecount = pQuest->ReqCreatureOrGOCount[i];
4888 if(uint32 spell_id = pQuest->ReqSpell[i])
4890 for(uint16 z = 0; z < creaturecount; ++z)
4891 player->CastedCreatureOrGO(creature,0,spell_id);
4893 else if(creature > 0)
4895 if(CreatureInfo const* cInfo = ObjectMgr::GetCreatureTemplate(creature))
4896 for(uint16 z = 0; z < creaturecount; ++z)
4897 player->KilledMonster(cInfo,0);
4899 else if(creature < 0)
4901 for(uint16 z = 0; z < creaturecount; ++z)
4902 player->CastedCreatureOrGO(-(creature),0,0);
4906 // If the quest requires reputation to complete
4907 if(uint32 repFaction = pQuest->GetRepObjectiveFaction())
4909 uint32 repValue = pQuest->GetRepObjectiveValue();
4910 uint32 curRep = player->GetReputationMgr().GetReputation(repFaction);
4911 if(curRep < repValue)
4912 if(FactionEntry const *factionEntry = sFactionStore.LookupEntry(repFaction))
4913 player->GetReputationMgr().SetReputation(factionEntry,repValue);
4916 // If the quest requires money
4917 int32 ReqOrRewMoney = pQuest->GetRewOrReqMoney();
4918 if(ReqOrRewMoney < 0)
4919 player->ModifyMoney(-ReqOrRewMoney);
4921 player->CompleteQuest(entry);
4922 return true;
4925 bool ChatHandler::HandleBanAccountCommand(const char* args)
4927 return HandleBanHelper(BAN_ACCOUNT,args);
4930 bool ChatHandler::HandleBanCharacterCommand(const char* args)
4932 return HandleBanHelper(BAN_CHARACTER,args);
4935 bool ChatHandler::HandleBanIPCommand(const char* args)
4937 return HandleBanHelper(BAN_IP,args);
4940 bool ChatHandler::HandleBanHelper(BanMode mode, const char* args)
4942 if (!*args)
4943 return false;
4945 char* cnameOrIP = strtok ((char*)args, " ");
4946 if (!cnameOrIP)
4947 return false;
4949 std::string nameOrIP = cnameOrIP;
4951 char* duration = strtok (NULL," ");
4952 if(!duration || !atoi(duration))
4953 return false;
4955 char* reason = strtok (NULL,"");
4956 if(!reason)
4957 return false;
4959 switch(mode)
4961 case BAN_ACCOUNT:
4962 if (!AccountMgr::normalizeString(nameOrIP))
4964 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,nameOrIP.c_str());
4965 SetSentErrorMessage(true);
4966 return false;
4968 break;
4969 case BAN_CHARACTER:
4970 if(!normalizePlayerName(nameOrIP))
4972 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4973 SetSentErrorMessage(true);
4974 return false;
4976 break;
4977 case BAN_IP:
4978 if(!IsIPAddress(nameOrIP.c_str()))
4979 return false;
4980 break;
4983 switch(sWorld.BanAccount(mode, nameOrIP, duration, reason,m_session ? m_session->GetPlayerName() : ""))
4985 case BAN_SUCCESS:
4986 if(atoi(duration)>0)
4987 PSendSysMessage(LANG_BAN_YOUBANNED,nameOrIP.c_str(),secsToTimeString(TimeStringToSecs(duration),true).c_str(),reason);
4988 else
4989 PSendSysMessage(LANG_BAN_YOUPERMBANNED,nameOrIP.c_str(),reason);
4990 break;
4991 case BAN_SYNTAX_ERROR:
4992 return false;
4993 case BAN_NOTFOUND:
4994 switch(mode)
4996 default:
4997 PSendSysMessage(LANG_BAN_NOTFOUND,"account",nameOrIP.c_str());
4998 break;
4999 case BAN_CHARACTER:
5000 PSendSysMessage(LANG_BAN_NOTFOUND,"character",nameOrIP.c_str());
5001 break;
5002 case BAN_IP:
5003 PSendSysMessage(LANG_BAN_NOTFOUND,"ip",nameOrIP.c_str());
5004 break;
5006 SetSentErrorMessage(true);
5007 return false;
5010 return true;
5013 bool ChatHandler::HandleUnBanAccountCommand(const char* args)
5015 return HandleUnBanHelper(BAN_ACCOUNT,args);
5018 bool ChatHandler::HandleUnBanCharacterCommand(const char* args)
5020 return HandleUnBanHelper(BAN_CHARACTER,args);
5023 bool ChatHandler::HandleUnBanIPCommand(const char* args)
5025 return HandleUnBanHelper(BAN_IP,args);
5028 bool ChatHandler::HandleUnBanHelper(BanMode mode, const char* args)
5030 if (!*args)
5031 return false;
5033 char* cnameOrIP = strtok ((char*)args, " ");
5034 if(!cnameOrIP)
5035 return false;
5037 std::string nameOrIP = cnameOrIP;
5039 switch(mode)
5041 case BAN_ACCOUNT:
5042 if (!AccountMgr::normalizeString(nameOrIP))
5044 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,nameOrIP.c_str());
5045 SetSentErrorMessage(true);
5046 return false;
5048 break;
5049 case BAN_CHARACTER:
5050 if(!normalizePlayerName(nameOrIP))
5052 SendSysMessage(LANG_PLAYER_NOT_FOUND);
5053 SetSentErrorMessage(true);
5054 return false;
5056 break;
5057 case BAN_IP:
5058 if(!IsIPAddress(nameOrIP.c_str()))
5059 return false;
5060 break;
5063 if(sWorld.RemoveBanAccount(mode,nameOrIP))
5064 PSendSysMessage(LANG_UNBAN_UNBANNED,nameOrIP.c_str());
5065 else
5066 PSendSysMessage(LANG_UNBAN_ERROR,nameOrIP.c_str());
5068 return true;
5071 bool ChatHandler::HandleBanInfoAccountCommand(const char* args)
5073 if (!*args)
5074 return false;
5076 char* cname = strtok((char*)args, "");
5077 if (!cname)
5078 return false;
5080 std::string account_name = cname;
5081 if (!AccountMgr::normalizeString(account_name))
5083 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5084 SetSentErrorMessage(true);
5085 return false;
5088 uint32 accountid = sAccountMgr.GetId(account_name);
5089 if (!accountid)
5091 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5092 return true;
5095 return HandleBanInfoHelper(accountid,account_name.c_str());
5098 bool ChatHandler::HandleBanInfoCharacterCommand(const char* args)
5100 Player* target;
5101 uint64 target_guid;
5102 if (!extractPlayerTarget((char*)args,&target,&target_guid))
5103 return false;
5105 uint32 accountid = target ? target->GetSession()->GetAccountId() : sObjectMgr.GetPlayerAccountIdByGUID(target_guid);
5107 std::string accountname;
5108 if (!sAccountMgr.GetName(accountid,accountname))
5110 PSendSysMessage(LANG_BANINFO_NOCHARACTER);
5111 return true;
5114 return HandleBanInfoHelper(accountid,accountname.c_str());
5117 bool ChatHandler::HandleBanInfoHelper(uint32 accountid, char const* accountname)
5119 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);
5120 if(!result)
5122 PSendSysMessage(LANG_BANINFO_NOACCOUNTBAN, accountname);
5123 return true;
5126 PSendSysMessage(LANG_BANINFO_BANHISTORY,accountname);
5129 Field* fields = result->Fetch();
5131 time_t unbandate = time_t(fields[3].GetUInt64());
5132 bool active = false;
5133 if(fields[2].GetBool() && (fields[1].GetUInt64() == (uint64)0 ||unbandate >= time(NULL)) )
5134 active = true;
5135 bool permanent = (fields[1].GetUInt64() == (uint64)0);
5136 std::string bantime = permanent?GetMangosString(LANG_BANINFO_INFINITE):secsToTimeString(fields[1].GetUInt64(), true);
5137 PSendSysMessage(LANG_BANINFO_HISTORYENTRY,
5138 fields[0].GetString(), bantime.c_str(), active ? GetMangosString(LANG_BANINFO_YES):GetMangosString(LANG_BANINFO_NO), fields[4].GetString(), fields[5].GetString());
5139 }while (result->NextRow());
5141 delete result;
5142 return true;
5145 bool ChatHandler::HandleBanInfoIPCommand(const char* args)
5147 if (!*args)
5148 return false;
5150 char* cIP = strtok ((char*)args, "");
5151 if(!cIP)
5152 return false;
5154 if (!IsIPAddress(cIP))
5155 return false;
5157 std::string IP = cIP;
5159 loginDatabase.escape_string(IP);
5160 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());
5161 if(!result)
5163 PSendSysMessage(LANG_BANINFO_NOIP);
5164 return true;
5167 Field *fields = result->Fetch();
5168 bool permanent = !fields[6].GetUInt64();
5169 PSendSysMessage(LANG_BANINFO_IPENTRY,
5170 fields[0].GetString(), fields[1].GetString(), permanent ? GetMangosString(LANG_BANINFO_NEVER):fields[2].GetString(),
5171 permanent ? GetMangosString(LANG_BANINFO_INFINITE):secsToTimeString(fields[3].GetUInt64(), true).c_str(), fields[4].GetString(), fields[5].GetString());
5172 delete result;
5173 return true;
5176 bool ChatHandler::HandleBanListCharacterCommand(const char* args)
5178 loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
5180 char* cFilter = strtok ((char*)args, " ");
5181 if(!cFilter)
5182 return false;
5184 std::string filter = cFilter;
5185 loginDatabase.escape_string(filter);
5186 QueryResult* result = CharacterDatabase.PQuery("SELECT account FROM characters WHERE name "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'"),filter.c_str());
5187 if (!result)
5189 PSendSysMessage(LANG_BANLIST_NOCHARACTER);
5190 return true;
5193 return HandleBanListHelper(result);
5196 bool ChatHandler::HandleBanListAccountCommand(const char* args)
5198 loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
5200 char* cFilter = strtok((char*)args, " ");
5201 std::string filter = cFilter ? cFilter : "";
5202 loginDatabase.escape_string(filter);
5204 QueryResult* result;
5206 if(filter.empty())
5208 result = loginDatabase.Query("SELECT account.id, username FROM account, account_banned"
5209 " WHERE account.id = account_banned.id AND active = 1 GROUP BY account.id");
5211 else
5213 result = loginDatabase.PQuery("SELECT account.id, username FROM account, account_banned"
5214 " WHERE account.id = account_banned.id AND active = 1 AND username "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")" GROUP BY account.id",
5215 filter.c_str());
5218 if (!result)
5220 PSendSysMessage(LANG_BANLIST_NOACCOUNT);
5221 return true;
5224 return HandleBanListHelper(result);
5227 bool ChatHandler::HandleBanListHelper(QueryResult* result)
5229 PSendSysMessage(LANG_BANLIST_MATCHINGACCOUNT);
5231 // Chat short output
5232 if(m_session)
5236 Field* fields = result->Fetch();
5237 uint32 accountid = fields[0].GetUInt32();
5239 QueryResult* banresult = loginDatabase.PQuery("SELECT account.username FROM account,account_banned WHERE account_banned.id='%u' AND account_banned.id=account.id",accountid);
5240 if(banresult)
5242 Field* fields2 = banresult->Fetch();
5243 PSendSysMessage("%s",fields2[0].GetString());
5244 delete banresult;
5246 } while (result->NextRow());
5248 // Console wide output
5249 else
5251 SendSysMessage(LANG_BANLIST_ACCOUNTS);
5252 SendSysMessage("===============================================================================");
5253 SendSysMessage(LANG_BANLIST_ACCOUNTS_HEADER);
5256 SendSysMessage("-------------------------------------------------------------------------------");
5257 Field *fields = result->Fetch();
5258 uint32 account_id = fields[0].GetUInt32 ();
5260 std::string account_name;
5262 // "account" case, name can be get in same query
5263 if(result->GetFieldCount() > 1)
5264 account_name = fields[1].GetCppString();
5265 // "character" case, name need extract from another DB
5266 else
5267 sAccountMgr.GetName (account_id,account_name);
5269 // No SQL injection. id is uint32.
5270 QueryResult *banInfo = loginDatabase.PQuery("SELECT bandate,unbandate,bannedby,banreason FROM account_banned WHERE id = %u ORDER BY unbandate", account_id);
5271 if (banInfo)
5273 Field *fields2 = banInfo->Fetch();
5276 time_t t_ban = fields2[0].GetUInt64();
5277 tm* aTm_ban = localtime(&t_ban);
5279 if (fields2[0].GetUInt64() == fields2[1].GetUInt64())
5281 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|",
5282 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,
5283 fields2[2].GetString(),fields2[3].GetString());
5285 else
5287 time_t t_unban = fields2[1].GetUInt64();
5288 tm* aTm_unban = localtime(&t_unban);
5289 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|",
5290 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,
5291 aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min,
5292 fields2[2].GetString(),fields2[3].GetString());
5294 }while ( banInfo->NextRow() );
5295 delete banInfo;
5297 }while( result->NextRow() );
5298 SendSysMessage("===============================================================================");
5301 delete result;
5302 return true;
5305 bool ChatHandler::HandleBanListIPCommand(const char* args)
5307 loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
5309 char* cFilter = strtok((char*)args, " ");
5310 std::string filter = cFilter ? cFilter : "";
5311 loginDatabase.escape_string(filter);
5313 QueryResult* result;
5315 if(filter.empty())
5317 result = loginDatabase.Query ("SELECT ip,bandate,unbandate,bannedby,banreason FROM ip_banned"
5318 " WHERE (bandate=unbandate OR unbandate>UNIX_TIMESTAMP())"
5319 " ORDER BY unbandate" );
5321 else
5323 result = loginDatabase.PQuery( "SELECT ip,bandate,unbandate,bannedby,banreason FROM ip_banned"
5324 " WHERE (bandate=unbandate OR unbandate>UNIX_TIMESTAMP()) AND ip "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")
5325 " ORDER BY unbandate",filter.c_str() );
5328 if(!result)
5330 PSendSysMessage(LANG_BANLIST_NOIP);
5331 return true;
5334 PSendSysMessage(LANG_BANLIST_MATCHINGIP);
5335 // Chat short output
5336 if(m_session)
5340 Field* fields = result->Fetch();
5341 PSendSysMessage("%s",fields[0].GetString());
5342 } while (result->NextRow());
5344 // Console wide output
5345 else
5347 SendSysMessage(LANG_BANLIST_IPS);
5348 SendSysMessage("===============================================================================");
5349 SendSysMessage(LANG_BANLIST_IPS_HEADER);
5352 SendSysMessage("-------------------------------------------------------------------------------");
5353 Field *fields = result->Fetch();
5354 time_t t_ban = fields[1].GetUInt64();
5355 tm* aTm_ban = localtime(&t_ban);
5356 if ( fields[1].GetUInt64() == fields[2].GetUInt64() )
5358 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|",
5359 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,
5360 fields[3].GetString(), fields[4].GetString());
5362 else
5364 time_t t_unban = fields[2].GetUInt64();
5365 tm* aTm_unban = localtime(&t_unban);
5366 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|",
5367 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,
5368 aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min,
5369 fields[3].GetString(), fields[4].GetString());
5371 }while( result->NextRow() );
5372 SendSysMessage("===============================================================================");
5375 delete result;
5376 return true;
5379 bool ChatHandler::HandleRespawnCommand(const char* /*args*/)
5381 Player* pl = m_session->GetPlayer();
5383 // accept only explicitly selected target (not implicitly self targeting case)
5384 Unit* target = getSelectedUnit();
5385 if(pl->GetSelection() && target)
5387 if(target->GetTypeId()!=TYPEID_UNIT)
5389 SendSysMessage(LANG_SELECT_CREATURE);
5390 SetSentErrorMessage(true);
5391 return false;
5394 if(target->isDead())
5395 ((Creature*)target)->Respawn();
5396 return true;
5399 CellPair p(MaNGOS::ComputeCellPair(pl->GetPositionX(), pl->GetPositionY()));
5400 Cell cell(p);
5401 cell.data.Part.reserved = ALL_DISTRICT;
5402 cell.SetNoCreate();
5404 MaNGOS::RespawnDo u_do;
5405 MaNGOS::WorldObjectWorker<MaNGOS::RespawnDo> worker(pl,u_do);
5407 TypeContainerVisitor<MaNGOS::WorldObjectWorker<MaNGOS::RespawnDo>, GridTypeMapContainer > obj_worker(worker);
5408 cell.Visit(p, obj_worker, *pl->GetMap());
5410 return true;
5413 bool ChatHandler::HandleGMFlyCommand(const char* args)
5415 if (!*args)
5416 return false;
5418 Player *target = getSelectedPlayer();
5419 if (!target)
5420 target = m_session->GetPlayer();
5422 WorldPacket data(12);
5423 if (strncmp(args, "on", 3) == 0)
5424 data.SetOpcode(SMSG_MOVE_SET_CAN_FLY);
5425 else if (strncmp(args, "off", 4) == 0)
5426 data.SetOpcode(SMSG_MOVE_UNSET_CAN_FLY);
5427 else
5429 SendSysMessage(LANG_USE_BOL);
5430 return false;
5432 data.append(target->GetPackGUID());
5433 data << uint32(0); // unknown
5434 target->SendMessageToSet(&data, true);
5435 PSendSysMessage(LANG_COMMAND_FLYMODE_STATUS, GetNameLink(target).c_str(), args);
5436 return true;
5439 bool ChatHandler::HandlePDumpLoadCommand(const char *args)
5441 if (!*args)
5442 return false;
5444 char * file = strtok((char*)args, " ");
5445 if (!file)
5446 return false;
5448 char * account = strtok(NULL, " ");
5449 if (!account)
5450 return false;
5452 std::string account_name = account;
5453 if (!AccountMgr::normalizeString(account_name))
5455 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5456 SetSentErrorMessage(true);
5457 return false;
5460 uint32 account_id = sAccountMgr.GetId(account_name);
5461 if (!account_id)
5463 account_id = atoi(account); // use original string
5464 if (!account_id)
5466 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5467 SetSentErrorMessage(true);
5468 return false;
5472 if (!sAccountMgr.GetName(account_id,account_name))
5474 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5475 SetSentErrorMessage(true);
5476 return false;
5479 char* guid_str = NULL;
5480 char* name_str = strtok(NULL, " ");
5482 std::string name;
5483 if (name_str)
5485 name = name_str;
5486 // normalize the name if specified and check if it exists
5487 if (!normalizePlayerName(name))
5489 PSendSysMessage(LANG_INVALID_CHARACTER_NAME);
5490 SetSentErrorMessage(true);
5491 return false;
5494 if (ObjectMgr::CheckPlayerName(name,true) != CHAR_NAME_SUCCESS)
5496 PSendSysMessage(LANG_INVALID_CHARACTER_NAME);
5497 SetSentErrorMessage(true);
5498 return false;
5501 guid_str = strtok(NULL, " ");
5504 uint32 guid = 0;
5506 if (guid_str)
5508 guid = atoi(guid_str);
5509 if (!guid)
5511 PSendSysMessage(LANG_INVALID_CHARACTER_GUID);
5512 SetSentErrorMessage(true);
5513 return false;
5516 if (sObjectMgr.GetPlayerAccountIdByGUID(guid))
5518 PSendSysMessage(LANG_CHARACTER_GUID_IN_USE,guid);
5519 SetSentErrorMessage(true);
5520 return false;
5524 switch(PlayerDumpReader().LoadDump(file, account_id, name, guid))
5526 case DUMP_SUCCESS:
5527 PSendSysMessage(LANG_COMMAND_IMPORT_SUCCESS);
5528 break;
5529 case DUMP_FILE_OPEN_ERROR:
5530 PSendSysMessage(LANG_FILE_OPEN_FAIL,file);
5531 SetSentErrorMessage(true);
5532 return false;
5533 case DUMP_FILE_BROKEN:
5534 PSendSysMessage(LANG_DUMP_BROKEN,file);
5535 SetSentErrorMessage(true);
5536 return false;
5537 case DUMP_TOO_MANY_CHARS:
5538 PSendSysMessage(LANG_ACCOUNT_CHARACTER_LIST_FULL,account_name.c_str(),account_id);
5539 SetSentErrorMessage(true);
5540 return false;
5541 default:
5542 PSendSysMessage(LANG_COMMAND_IMPORT_FAILED);
5543 SetSentErrorMessage(true);
5544 return false;
5547 return true;
5550 bool ChatHandler::HandlePDumpWriteCommand(const char *args)
5552 if (!*args)
5553 return false;
5555 char* file = strtok((char*)args, " ");
5556 char* p2 = strtok(NULL, " ");
5558 if(!file || !p2)
5559 return false;
5561 uint32 guid;
5562 // character name can't start from number
5563 if (isNumeric(p2[0]))
5564 guid = atoi(p2);
5565 else
5567 std::string name = extractPlayerNameFromLink(p2);
5568 if(name.empty())
5570 SendSysMessage(LANG_PLAYER_NOT_FOUND);
5571 SetSentErrorMessage(true);
5572 return false;
5575 guid = GUID_LOPART(sObjectMgr.GetPlayerGUIDByName(name));
5578 if(!sObjectMgr.GetPlayerAccountIdByGUID(guid))
5580 PSendSysMessage(LANG_PLAYER_NOT_FOUND);
5581 SetSentErrorMessage(true);
5582 return false;
5585 switch(PlayerDumpWriter().WriteDump(file, guid))
5587 case DUMP_SUCCESS:
5588 PSendSysMessage(LANG_COMMAND_EXPORT_SUCCESS);
5589 break;
5590 case DUMP_FILE_OPEN_ERROR:
5591 PSendSysMessage(LANG_FILE_OPEN_FAIL,file);
5592 SetSentErrorMessage(true);
5593 return false;
5594 default:
5595 PSendSysMessage(LANG_COMMAND_EXPORT_FAILED);
5596 SetSentErrorMessage(true);
5597 return false;
5600 return true;
5603 bool ChatHandler::HandleMovegensCommand(const char* /*args*/)
5605 Unit* unit = getSelectedUnit();
5606 if(!unit)
5608 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5609 SetSentErrorMessage(true);
5610 return false;
5613 PSendSysMessage(LANG_MOVEGENS_LIST,(unit->GetTypeId()==TYPEID_PLAYER ? "Player" : "Creature" ),unit->GetGUIDLow());
5615 MotionMaster* mm = unit->GetMotionMaster();
5616 for(MotionMaster::const_iterator itr = mm->begin(); itr != mm->end(); ++itr)
5618 switch((*itr)->GetMovementGeneratorType())
5620 case IDLE_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_IDLE); break;
5621 case RANDOM_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_RANDOM); break;
5622 case WAYPOINT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_WAYPOINT); break;
5623 case ANIMAL_RANDOM_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_ANIMAL_RANDOM); break;
5624 case CONFUSED_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_CONFUSED); break;
5625 case CHASE_MOTION_TYPE:
5627 Unit* target = NULL;
5628 if(unit->GetTypeId()==TYPEID_PLAYER)
5629 target = static_cast<ChaseMovementGenerator<Player> const*>(*itr)->GetTarget();
5630 else
5631 target = static_cast<ChaseMovementGenerator<Creature> const*>(*itr)->GetTarget();
5633 if (!target)
5634 SendSysMessage(LANG_MOVEGENS_CHASE_NULL);
5635 else if (target->GetTypeId()==TYPEID_PLAYER)
5636 PSendSysMessage(LANG_MOVEGENS_CHASE_PLAYER,target->GetName(),target->GetGUIDLow());
5637 else
5638 PSendSysMessage(LANG_MOVEGENS_CHASE_CREATURE,target->GetName(),target->GetGUIDLow());
5639 break;
5641 case FOLLOW_MOTION_TYPE:
5643 Unit* target = NULL;
5644 if(unit->GetTypeId()==TYPEID_PLAYER)
5645 target = static_cast<FollowMovementGenerator<Player> const*>(*itr)->GetTarget();
5646 else
5647 target = static_cast<FollowMovementGenerator<Creature> const*>(*itr)->GetTarget();
5649 if (!target)
5650 SendSysMessage(LANG_MOVEGENS_FOLLOW_NULL);
5651 else if (target->GetTypeId()==TYPEID_PLAYER)
5652 PSendSysMessage(LANG_MOVEGENS_FOLLOW_PLAYER,target->GetName(),target->GetGUIDLow());
5653 else
5654 PSendSysMessage(LANG_MOVEGENS_FOLLOW_CREATURE,target->GetName(),target->GetGUIDLow());
5655 break;
5657 case HOME_MOTION_TYPE:
5658 if(unit->GetTypeId()==TYPEID_UNIT)
5660 float x,y,z;
5661 (*itr)->GetDestination(x,y,z);
5662 PSendSysMessage(LANG_MOVEGENS_HOME_CREATURE,x,y,z);
5664 else
5665 SendSysMessage(LANG_MOVEGENS_HOME_PLAYER);
5666 break;
5667 case FLIGHT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_FLIGHT); break;
5668 case POINT_MOTION_TYPE:
5670 float x,y,z;
5671 (*itr)->GetDestination(x,y,z);
5672 PSendSysMessage(LANG_MOVEGENS_POINT,x,y,z);
5673 break;
5675 case FLEEING_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_FEAR); break;
5676 case DISTRACT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_DISTRACT); break;
5677 default:
5678 PSendSysMessage(LANG_MOVEGENS_UNKNOWN,(*itr)->GetMovementGeneratorType());
5679 break;
5682 return true;
5685 bool ChatHandler::HandleServerPLimitCommand(const char *args)
5687 if(*args)
5689 char* param = strtok((char*)args, " ");
5690 if(!param)
5691 return false;
5693 int l = strlen(param);
5695 if( strncmp(param,"player",l) == 0 )
5696 sWorld.SetPlayerLimit(-SEC_PLAYER);
5697 else if(strncmp(param,"moderator",l) == 0 )
5698 sWorld.SetPlayerLimit(-SEC_MODERATOR);
5699 else if(strncmp(param,"gamemaster",l) == 0 )
5700 sWorld.SetPlayerLimit(-SEC_GAMEMASTER);
5701 else if(strncmp(param,"administrator",l) == 0 )
5702 sWorld.SetPlayerLimit(-SEC_ADMINISTRATOR);
5703 else if(strncmp(param,"reset",l) == 0 )
5704 sWorld.SetPlayerLimit( sConfig.GetIntDefault("PlayerLimit", DEFAULT_PLAYER_LIMIT) );
5705 else
5707 int val = atoi(param);
5708 if(val < -SEC_ADMINISTRATOR) val = -SEC_ADMINISTRATOR;
5710 sWorld.SetPlayerLimit(val);
5713 // kick all low security level players
5714 if(sWorld.GetPlayerAmountLimit() > SEC_PLAYER)
5715 sWorld.KickAllLess(sWorld.GetPlayerSecurityLimit());
5718 uint32 pLimit = sWorld.GetPlayerAmountLimit();
5719 AccountTypes allowedAccountType = sWorld.GetPlayerSecurityLimit();
5720 char const* secName = "";
5721 switch(allowedAccountType)
5723 case SEC_PLAYER: secName = "Player"; break;
5724 case SEC_MODERATOR: secName = "Moderator"; break;
5725 case SEC_GAMEMASTER: secName = "Gamemaster"; break;
5726 case SEC_ADMINISTRATOR: secName = "Administrator"; break;
5727 default: secName = "<unknown>"; break;
5730 PSendSysMessage("Player limits: amount %u, min. security level %s.",pLimit,secName);
5732 return true;
5735 bool ChatHandler::HandleCastCommand(const char* args)
5737 if(!*args)
5738 return false;
5740 Unit* target = getSelectedUnit();
5742 if(!target)
5744 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5745 SetSentErrorMessage(true);
5746 return false;
5749 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5750 uint32 spell = extractSpellIdFromLink((char*)args);
5751 if(!spell)
5752 return false;
5754 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
5755 if(!spellInfo)
5756 return false;
5758 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
5760 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
5761 SetSentErrorMessage(true);
5762 return false;
5765 char* trig_str = strtok(NULL, " ");
5766 if(trig_str)
5768 int l = strlen(trig_str);
5769 if(strncmp(trig_str,"triggered",l) != 0 )
5770 return false;
5773 bool triggered = (trig_str != NULL);
5775 m_session->GetPlayer()->CastSpell(target,spell,triggered);
5777 return true;
5780 bool ChatHandler::HandleCastBackCommand(const char* args)
5782 Creature* caster = getSelectedCreature();
5784 if(!caster)
5786 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5787 SetSentErrorMessage(true);
5788 return false;
5791 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
5792 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5793 uint32 spell = extractSpellIdFromLink((char*)args);
5794 if(!spell || !sSpellStore.LookupEntry(spell))
5795 return false;
5797 char* trig_str = strtok(NULL, " ");
5798 if(trig_str)
5800 int l = strlen(trig_str);
5801 if(strncmp(trig_str,"triggered",l) != 0 )
5802 return false;
5805 bool triggered = (trig_str != NULL);
5807 caster->SetFacingToObject(m_session->GetPlayer());
5809 caster->CastSpell(m_session->GetPlayer(),spell,triggered);
5811 return true;
5814 bool ChatHandler::HandleCastDistCommand(const char* args)
5816 if(!*args)
5817 return false;
5819 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5820 uint32 spell = extractSpellIdFromLink((char*)args);
5821 if(!spell)
5822 return false;
5824 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
5825 if(!spellInfo)
5826 return false;
5828 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
5830 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
5831 SetSentErrorMessage(true);
5832 return false;
5835 char *distStr = strtok(NULL, " ");
5837 float dist = 0;
5839 if(distStr)
5840 sscanf(distStr, "%f", &dist);
5842 char* trig_str = strtok(NULL, " ");
5843 if(trig_str)
5845 int l = strlen(trig_str);
5846 if(strncmp(trig_str,"triggered",l) != 0 )
5847 return false;
5850 bool triggered = (trig_str != NULL);
5852 float x,y,z;
5853 m_session->GetPlayer()->GetClosePoint(x,y,z,dist);
5855 m_session->GetPlayer()->CastSpell(x,y,z,spell,triggered);
5856 return true;
5859 bool ChatHandler::HandleCastTargetCommand(const char* args)
5861 Creature* caster = getSelectedCreature();
5863 if(!caster)
5865 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5866 SetSentErrorMessage(true);
5867 return false;
5870 if(!caster->getVictim())
5872 SendSysMessage(LANG_SELECTED_TARGET_NOT_HAVE_VICTIM);
5873 SetSentErrorMessage(true);
5874 return false;
5877 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5878 uint32 spell = extractSpellIdFromLink((char*)args);
5879 if(!spell || !sSpellStore.LookupEntry(spell))
5880 return false;
5882 char* trig_str = strtok(NULL, " ");
5883 if(trig_str)
5885 int l = strlen(trig_str);
5886 if(strncmp(trig_str,"triggered",l) != 0 )
5887 return false;
5890 bool triggered = (trig_str != NULL);
5892 caster->SetFacingToObject(m_session->GetPlayer());
5894 caster->CastSpell(caster->getVictim(),spell,triggered);
5896 return true;
5900 ComeToMe command REQUIRED for 3rd party scripting library to have access to PointMovementGenerator
5901 Without this function 3rd party scripting library will get linking errors (unresolved external)
5902 when attempting to use the PointMovementGenerator
5904 bool ChatHandler::HandleComeToMeCommand(const char *args)
5906 Creature* caster = getSelectedCreature();
5908 if(!caster)
5910 SendSysMessage(LANG_SELECT_CREATURE);
5911 SetSentErrorMessage(true);
5912 return false;
5915 char* newFlagStr = strtok((char*)args, " ");
5917 if(!newFlagStr)
5918 return false;
5920 uint32 newFlags = atoi(newFlagStr);
5922 caster->SetSplineFlags(SplineFlags(newFlags));
5924 Player* pl = m_session->GetPlayer();
5926 caster->GetMotionMaster()->MovePoint(0, pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ());
5927 return true;
5930 bool ChatHandler::HandleCastSelfCommand(const char* args)
5932 if(!*args)
5933 return false;
5935 Unit* target = getSelectedUnit();
5937 if(!target)
5939 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5940 SetSentErrorMessage(true);
5941 return false;
5944 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5945 uint32 spell = extractSpellIdFromLink((char*)args);
5946 if(!spell)
5947 return false;
5949 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
5950 if(!spellInfo)
5951 return false;
5953 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
5955 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
5956 SetSentErrorMessage(true);
5957 return false;
5960 target->CastSpell(target,spell,false);
5962 return true;
5965 std::string GetTimeString(time_t time)
5967 time_t days = time / DAY;
5968 time_t hours = (time % DAY) / HOUR;
5969 time_t minute = (time % HOUR) / MINUTE;
5970 std::ostringstream ss;
5971 if(days)
5972 ss << days << "d ";
5973 if(hours)
5974 ss << hours << "h ";
5975 ss << minute << "m";
5976 return ss.str();
5979 bool ChatHandler::HandleInstanceListBindsCommand(const char* /*args*/)
5981 Player* player = getSelectedPlayer();
5982 if (!player) player = m_session->GetPlayer();
5983 uint32 counter = 0;
5984 for(uint8 i = 0; i < MAX_DIFFICULTY; ++i)
5986 Player::BoundInstancesMap &binds = player->GetBoundInstances(Difficulty(i));
5987 for(Player::BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end(); ++itr)
5989 InstanceSave *save = itr->second.save;
5990 std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
5991 if (const MapEntry* entry = sMapStore.LookupEntry(itr->first))
5993 PSendSysMessage("map: %d (%s) inst: %d perm: %s diff: %d canReset: %s TTR: %s",
5994 itr->first, entry->name[m_session->GetSessionDbcLocale()], save->GetInstanceId(), itr->second.perm ? "yes" : "no",
5995 save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str());
5997 else
5998 PSendSysMessage("bound for a nonexistant map %u", itr->first);
5999 counter++;
6002 PSendSysMessage("player binds: %d", counter);
6003 counter = 0;
6004 Group *group = player->GetGroup();
6005 if(group)
6007 for(uint8 i = 0; i < MAX_DIFFICULTY; ++i)
6009 Group::BoundInstancesMap &binds = group->GetBoundInstances(Difficulty(i));
6010 for(Group::BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end(); ++itr)
6012 InstanceSave *save = itr->second.save;
6013 std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
6014 if (const MapEntry* entry = sMapStore.LookupEntry(itr->first))
6016 PSendSysMessage("map: %d (%s) inst: %d perm: %s diff: %d canReset: %s TTR: %s",
6017 itr->first, entry->name[m_session->GetSessionDbcLocale()], save->GetInstanceId(), itr->second.perm ? "yes" : "no",
6018 save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str());
6020 else
6021 PSendSysMessage("bound for a nonexistant map %u", itr->first);
6022 counter++;
6026 PSendSysMessage("group binds: %d", counter);
6028 return true;
6031 bool ChatHandler::HandleInstanceUnbindCommand(const char* args)
6033 if(!*args)
6034 return false;
6036 Player* player = getSelectedPlayer();
6037 if (!player)
6038 player = m_session->GetPlayer();
6039 uint32 counter = 0;
6040 uint32 mapid = 0;
6041 bool got_map = false;
6043 if (strncmp(args,"all",strlen(args)) != 0)
6045 if(!isNumeric(args[0]))
6046 return false;
6048 got_map = true;
6049 mapid = atoi(args);
6052 for(uint8 i = 0; i < MAX_DIFFICULTY; ++i)
6054 Player::BoundInstancesMap &binds = player->GetBoundInstances(Difficulty(i));
6055 for(Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end();)
6057 if (got_map && mapid != itr->first)
6059 ++itr;
6060 continue;
6062 if(itr->first != player->GetMapId())
6064 InstanceSave *save = itr->second.save;
6065 std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
6067 if (const MapEntry* entry = sMapStore.LookupEntry(itr->first))
6069 PSendSysMessage("unbinding map: %d (%s) inst: %d perm: %s diff: %d canReset: %s TTR: %s",
6070 itr->first, entry->name[m_session->GetSessionDbcLocale()], save->GetInstanceId(), itr->second.perm ? "yes" : "no",
6071 save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str());
6073 else
6074 PSendSysMessage("bound for a nonexistant map %u", itr->first);
6075 player->UnbindInstance(itr, Difficulty(i));
6076 counter++;
6078 else
6079 ++itr;
6082 PSendSysMessage("instances unbound: %d", counter);
6083 return true;
6086 bool ChatHandler::HandleInstanceStatsCommand(const char* /*args*/)
6088 PSendSysMessage("instances loaded: %d", sMapMgr.GetNumInstances());
6089 PSendSysMessage("players in instances: %d", sMapMgr.GetNumPlayersInInstances());
6090 PSendSysMessage("instance saves: %d", sInstanceSaveMgr.GetNumInstanceSaves());
6091 PSendSysMessage("players bound: %d", sInstanceSaveMgr.GetNumBoundPlayersTotal());
6092 PSendSysMessage("groups bound: %d", sInstanceSaveMgr.GetNumBoundGroupsTotal());
6093 return true;
6096 bool ChatHandler::HandleInstanceSaveDataCommand(const char * /*args*/)
6098 Player* pl = m_session->GetPlayer();
6100 Map* map = pl->GetMap();
6101 if (!map->IsDungeon())
6103 PSendSysMessage("Map is not a dungeon.");
6104 SetSentErrorMessage(true);
6105 return false;
6108 if (!((InstanceMap*)map)->GetInstanceData())
6110 PSendSysMessage("Map has no instance data.");
6111 SetSentErrorMessage(true);
6112 return false;
6115 ((InstanceMap*)map)->GetInstanceData()->SaveToDB();
6116 return true;
6119 /// Display the list of GMs
6120 bool ChatHandler::HandleGMListFullCommand(const char* /*args*/)
6122 ///- Get the accounts with GM Level >0
6123 QueryResult *result = loginDatabase.Query( "SELECT username,gmlevel FROM account WHERE gmlevel > 0" );
6124 if(result)
6126 SendSysMessage(LANG_GMLIST);
6127 SendSysMessage("========================");
6128 SendSysMessage(LANG_GMLIST_HEADER);
6129 SendSysMessage("========================");
6131 ///- Circle through them. Display username and GM level
6134 Field *fields = result->Fetch();
6135 PSendSysMessage("|%15s|%6s|", fields[0].GetString(),fields[1].GetString());
6136 }while( result->NextRow() );
6138 PSendSysMessage("========================");
6139 delete result;
6141 else
6142 PSendSysMessage(LANG_GMLIST_EMPTY);
6143 return true;
6146 /// Define the 'Message of the day' for the realm
6147 bool ChatHandler::HandleServerSetMotdCommand(const char* args)
6149 sWorld.SetMotd(args);
6150 PSendSysMessage(LANG_MOTD_NEW, args);
6151 return true;
6154 /// Set/Unset the expansion level for an account
6155 bool ChatHandler::HandleAccountSetAddonCommand(const char* args)
6157 ///- Get the command line arguments
6158 char *szAcc = strtok((char*)args," ");
6159 char *szExp = strtok(NULL," ");
6161 if(!szAcc)
6162 return false;
6164 std::string account_name;
6165 uint32 account_id;
6167 if (!szExp)
6169 Player* player = getSelectedPlayer();
6170 if (!player)
6171 return false;
6173 account_id = player->GetSession()->GetAccountId();
6174 sAccountMgr.GetName(account_id,account_name);
6175 szExp = szAcc;
6177 else
6179 ///- Convert Account name to Upper Format
6180 account_name = szAcc;
6181 if (!AccountMgr::normalizeString(account_name))
6183 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
6184 SetSentErrorMessage(true);
6185 return false;
6188 account_id = sAccountMgr.GetId(account_name);
6189 if (!account_id)
6191 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
6192 SetSentErrorMessage(true);
6193 return false;
6198 // Let set addon state only for lesser (strong) security level
6199 // or to self account
6200 if (m_session && m_session->GetAccountId () != account_id &&
6201 HasLowerSecurityAccount (NULL,account_id,true))
6202 return false;
6204 int lev=atoi(szExp); //get int anyway (0 if error)
6205 if(lev < 0)
6206 return false;
6208 // No SQL injection
6209 loginDatabase.PExecute("UPDATE account SET expansion = '%d' WHERE id = '%u'",lev,account_id);
6210 PSendSysMessage(LANG_ACCOUNT_SETADDON,account_name.c_str(),account_id,lev);
6211 return true;
6214 //Send items by mail
6215 bool ChatHandler::HandleSendItemsCommand(const char* args)
6217 // format: name "subject text" "mail text" item1[:count1] item2[:count2] ... item12[:count12]
6218 Player* receiver;
6219 uint64 receiver_guid;
6220 std::string receiver_name;
6221 if(!extractPlayerTarget((char*)args,&receiver,&receiver_guid,&receiver_name))
6222 return false;
6224 char* tail1 = strtok(NULL, "");
6225 if(!tail1)
6226 return false;
6228 char* msgSubject = extractQuotedArg(tail1);
6229 if (!msgSubject)
6230 return false;
6232 char* tail2 = strtok(NULL, "");
6233 if(!tail2)
6234 return false;
6236 char* msgText = extractQuotedArg(tail2);
6237 if (!msgText)
6238 return false;
6240 // msgSubject, msgText isn't NUL after prev. check
6241 std::string subject = msgSubject;
6242 std::string text = msgText;
6244 // extract items
6245 typedef std::pair<uint32,uint32> ItemPair;
6246 typedef std::list< ItemPair > ItemPairs;
6247 ItemPairs items;
6249 // get all tail string
6250 char* tail = strtok(NULL, "");
6252 // get from tail next item str
6253 while(char* itemStr = strtok(tail, " "))
6255 // and get new tail
6256 tail = strtok(NULL, "");
6258 // parse item str
6259 char* itemIdStr = strtok(itemStr, ":");
6260 char* itemCountStr = strtok(NULL, " ");
6262 uint32 item_id = atoi(itemIdStr);
6263 if(!item_id)
6264 return false;
6266 ItemPrototype const* item_proto = ObjectMgr::GetItemPrototype(item_id);
6267 if(!item_proto)
6269 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
6270 SetSentErrorMessage(true);
6271 return false;
6274 uint32 item_count = itemCountStr ? atoi(itemCountStr) : 1;
6275 if (item_count < 1 || (item_proto->MaxCount > 0 && item_count > uint32(item_proto->MaxCount)))
6277 PSendSysMessage(LANG_COMMAND_INVALID_ITEM_COUNT, item_count,item_id);
6278 SetSentErrorMessage(true);
6279 return false;
6282 while(item_count > item_proto->GetMaxStackSize())
6284 items.push_back(ItemPair(item_id,item_proto->GetMaxStackSize()));
6285 item_count -= item_proto->GetMaxStackSize();
6288 items.push_back(ItemPair(item_id,item_count));
6290 if(items.size() > MAX_MAIL_ITEMS)
6292 PSendSysMessage(LANG_COMMAND_MAIL_ITEMS_LIMIT, MAX_MAIL_ITEMS);
6293 SetSentErrorMessage(true);
6294 return false;
6298 // from console show not existed sender
6299 MailSender sender(MAIL_NORMAL,m_session ? m_session->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM);
6301 uint32 itemTextId = !text.empty() ? sObjectMgr.CreateItemText( text ) : 0;
6303 // fill mail
6304 MailDraft draft(subject, itemTextId);
6306 for(ItemPairs::const_iterator itr = items.begin(); itr != items.end(); ++itr)
6308 if(Item* item = Item::CreateItem(itr->first,itr->second,m_session ? m_session->GetPlayer() : 0))
6310 item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted
6311 draft.AddItem(item);
6315 draft.SendMailTo(MailReceiver(receiver,GUID_LOPART(receiver_guid)), sender);
6317 std::string nameLink = playerLink(receiver_name);
6318 PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
6319 return true;
6322 ///Send money by mail
6323 bool ChatHandler::HandleSendMoneyCommand(const char* args)
6325 /// format: name "subject text" "mail text" money
6327 Player* receiver;
6328 uint64 receiver_guid;
6329 std::string receiver_name;
6330 if(!extractPlayerTarget((char*)args,&receiver,&receiver_guid,&receiver_name))
6331 return false;
6333 char* tail1 = strtok(NULL, "");
6334 if (!tail1)
6335 return false;
6337 char* msgSubject = extractQuotedArg(tail1);
6338 if (!msgSubject)
6339 return false;
6341 char* tail2 = strtok(NULL, "");
6342 if (!tail2)
6343 return false;
6345 char* msgText = extractQuotedArg(tail2);
6346 if (!msgText)
6347 return false;
6349 char* money_str = strtok(NULL, "");
6350 int32 money = money_str ? atoi(money_str) : 0;
6351 if (money <= 0)
6352 return false;
6354 // msgSubject, msgText isn't NUL after prev. check
6355 std::string subject = msgSubject;
6356 std::string text = msgText;
6358 // from console show not existed sender
6359 MailSender sender(MAIL_NORMAL,m_session ? m_session->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM);
6361 uint32 itemTextId = !text.empty() ? sObjectMgr.CreateItemText( text ) : 0;
6363 MailDraft(subject, itemTextId)
6364 .AddMoney(money)
6365 .SendMailTo(MailReceiver(receiver,GUID_LOPART(receiver_guid)),sender);
6367 std::string nameLink = playerLink(receiver_name);
6368 PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
6369 return true;
6372 /// Send a message to a player in game
6373 bool ChatHandler::HandleSendMessageCommand(const char* args)
6375 ///- Find the player
6376 Player *rPlayer;
6377 if(!extractPlayerTarget((char*)args,&rPlayer))
6378 return false;
6380 char* msg_str = strtok(NULL, "");
6381 if(!msg_str)
6382 return false;
6384 ///- Check that he is not logging out.
6385 if(rPlayer->GetSession()->isLogingOut())
6387 SendSysMessage(LANG_PLAYER_NOT_FOUND);
6388 SetSentErrorMessage(true);
6389 return false;
6392 ///- Send the message
6393 //Use SendAreaTriggerMessage for fastest delivery.
6394 rPlayer->GetSession()->SendAreaTriggerMessage("%s", msg_str);
6395 rPlayer->GetSession()->SendAreaTriggerMessage("|cffff0000[Message from administrator]:|r");
6397 //Confirmation message
6398 std::string nameLink = GetNameLink(rPlayer);
6399 PSendSysMessage(LANG_SENDMESSAGE,nameLink.c_str(),msg_str);
6400 return true;
6403 bool ChatHandler::HandleFlushArenaPointsCommand(const char * /*args*/)
6405 sBattleGroundMgr.DistributeArenaPoints();
6406 return true;
6409 bool ChatHandler::HandleModifyGenderCommand(const char *args)
6411 if(!*args)
6412 return false;
6414 Player *player = getSelectedPlayer();
6416 if(!player)
6418 PSendSysMessage(LANG_PLAYER_NOT_FOUND);
6419 SetSentErrorMessage(true);
6420 return false;
6423 PlayerInfo const* info = sObjectMgr.GetPlayerInfo(player->getRace(), player->getClass());
6424 if(!info)
6425 return false;
6427 char const* gender_str = (char*)args;
6428 int gender_len = strlen(gender_str);
6430 Gender gender;
6432 if(!strncmp(gender_str, "male", gender_len)) // MALE
6434 if(player->getGender() == GENDER_MALE)
6435 return true;
6437 gender = GENDER_MALE;
6439 else if (!strncmp(gender_str, "female", gender_len)) // FEMALE
6441 if(player->getGender() == GENDER_FEMALE)
6442 return true;
6444 gender = GENDER_FEMALE;
6446 else
6448 SendSysMessage(LANG_MUST_MALE_OR_FEMALE);
6449 SetSentErrorMessage(true);
6450 return false;
6453 // Set gender
6454 player->SetByteValue(UNIT_FIELD_BYTES_0, 2, gender);
6455 player->SetByteValue(PLAYER_BYTES_3, 0, gender);
6457 // Change display ID
6458 player->InitDisplayIds();
6460 char const* gender_full = gender ? "female" : "male";
6462 PSendSysMessage(LANG_YOU_CHANGE_GENDER, GetNameLink(player).c_str(), gender_full);
6464 if (needReportToTarget(player))
6465 ChatHandler(player).PSendSysMessage(LANG_YOUR_GENDER_CHANGED, gender_full, GetNameLink().c_str());
6467 return true;