[7986] MaNGOS 0.13 release.
[getmangos.git] / src / game / Level3.cpp
blob6eeaff488aeed68c616452d3181b30ae49f3ab61
1 /*
2 * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include "Common.h"
20 #include "Database/DatabaseEnv.h"
21 #include "WorldPacket.h"
22 #include "WorldSession.h"
23 #include "World.h"
24 #include "ObjectMgr.h"
25 #include "AccountMgr.h"
26 #include "PlayerDump.h"
27 #include "SpellMgr.h"
28 #include "Player.h"
29 #include "Opcodes.h"
30 #include "GameObject.h"
31 #include "Chat.h"
32 #include "Log.h"
33 #include "Guild.h"
34 #include "ObjectAccessor.h"
35 #include "MapManager.h"
36 #include "ScriptCalls.h"
37 #include "Language.h"
38 #include "GridNotifiersImpl.h"
39 #include "CellImpl.h"
40 #include "Weather.h"
41 #include "PointMovementGenerator.h"
42 #include "TargetedMovementGenerator.h"
43 #include "SkillDiscovery.h"
44 #include "SkillExtraItems.h"
45 #include "SystemConfig.h"
46 #include "Config/ConfigEnv.h"
47 #include "Util.h"
48 #include "ItemEnchantmentMgr.h"
49 #include "BattleGroundMgr.h"
50 #include "InstanceSaveMgr.h"
51 #include "InstanceData.h"
52 #include "CreatureEventAIMgr.h"
54 //reload commands
55 bool ChatHandler::HandleReloadAllCommand(const char*)
57 HandleReloadSkillFishingBaseLevelCommand("");
59 HandleReloadAllAchievementCommand("");
60 HandleReloadAllAreaCommand("");
61 HandleReloadAllEventAICommand("");
62 HandleReloadAllLootCommand("");
63 HandleReloadAllNpcCommand("");
64 HandleReloadAllQuestCommand("");
65 HandleReloadAllSpellCommand("");
66 HandleReloadAllItemCommand("");
67 HandleReloadAllLocalesCommand("");
69 HandleReloadCommandCommand("");
70 HandleReloadReservedNameCommand("");
71 HandleReloadMangosStringCommand("");
72 HandleReloadGameTeleCommand("");
73 return true;
76 bool ChatHandler::HandleReloadAllAchievementCommand(const char*)
78 HandleReloadAchievementCriteriaDataCommand("");
79 HandleReloadAchievementRewardCommand("");
80 return true;
83 bool ChatHandler::HandleReloadAllAreaCommand(const char*)
85 //HandleReloadQuestAreaTriggersCommand(""); -- reloaded in HandleReloadAllQuestCommand
86 HandleReloadAreaTriggerTeleportCommand("");
87 HandleReloadAreaTriggerTavernCommand("");
88 HandleReloadGameGraveyardZoneCommand("");
89 return true;
92 bool ChatHandler::HandleReloadAllLootCommand(const char*)
94 sLog.outString( "Re-Loading Loot Tables..." );
95 LoadLootTables();
96 SendGlobalSysMessage("DB tables `*_loot_template` reloaded.");
97 return true;
100 bool ChatHandler::HandleReloadAllNpcCommand(const char* /*args*/)
102 HandleReloadNpcGossipCommand("a");
103 HandleReloadNpcOptionCommand("a");
104 HandleReloadNpcTrainerCommand("a");
105 HandleReloadNpcVendorCommand("a");
106 HandleReloadPointsOfInterestCommand("a");
107 HandleReloadSpellClickSpellsCommand("a");
108 return true;
111 bool ChatHandler::HandleReloadAllQuestCommand(const char* /*args*/)
113 HandleReloadQuestAreaTriggersCommand("a");
114 HandleReloadQuestTemplateCommand("a");
116 sLog.outString( "Re-Loading Quests Relations..." );
117 objmgr.LoadQuestRelations();
118 SendGlobalSysMessage("DB tables `*_questrelation` and `*_involvedrelation` reloaded.");
119 return true;
122 bool ChatHandler::HandleReloadAllScriptsCommand(const char*)
124 if(sWorld.IsScriptScheduled())
126 PSendSysMessage("DB scripts used currently, please attempt reload later.");
127 SetSentErrorMessage(true);
128 return false;
131 sLog.outString( "Re-Loading Scripts..." );
132 HandleReloadGameObjectScriptsCommand("a");
133 HandleReloadEventScriptsCommand("a");
134 HandleReloadQuestEndScriptsCommand("a");
135 HandleReloadQuestStartScriptsCommand("a");
136 HandleReloadSpellScriptsCommand("a");
137 SendGlobalSysMessage("DB tables `*_scripts` reloaded.");
138 HandleReloadDbScriptStringCommand("a");
139 return true;
142 bool ChatHandler::HandleReloadAllEventAICommand(const char*)
144 HandleReloadEventAITextsCommand("a");
145 HandleReloadEventAISummonsCommand("a");
146 HandleReloadEventAIScriptsCommand("a");
147 return true;
150 bool ChatHandler::HandleReloadAllSpellCommand(const char*)
152 HandleReloadSkillDiscoveryTemplateCommand("a");
153 HandleReloadSkillExtraItemTemplateCommand("a");
154 HandleReloadSpellAffectCommand("a");
155 HandleReloadSpellAreaCommand("a");
156 HandleReloadSpellChainCommand("a");
157 HandleReloadSpellElixirCommand("a");
158 HandleReloadSpellLearnSpellCommand("a");
159 HandleReloadSpellProcEventCommand("a");
160 HandleReloadSpellBonusesCommand("a");
161 HandleReloadSpellScriptTargetCommand("a");
162 HandleReloadSpellTargetPositionCommand("a");
163 HandleReloadSpellThreatsCommand("a");
164 HandleReloadSpellPetAurasCommand("a");
165 return true;
168 bool ChatHandler::HandleReloadAllItemCommand(const char*)
170 HandleReloadPageTextsCommand("a");
171 HandleReloadItemEnchantementsCommand("a");
172 HandleReloadItemRequiredTragetCommand("a");
173 return true;
176 bool ChatHandler::HandleReloadAllLocalesCommand(const char* /*args*/)
178 HandleReloadLocalesAchievementRewardCommand("a");
179 HandleReloadLocalesCreatureCommand("a");
180 HandleReloadLocalesGameobjectCommand("a");
181 HandleReloadLocalesItemCommand("a");
182 HandleReloadLocalesNpcTextCommand("a");
183 HandleReloadLocalesPageTextCommand("a");
184 HandleReloadLocalesPointsOfInterestCommand("a");
185 HandleReloadLocalesQuestCommand("a");
186 return true;
189 bool ChatHandler::HandleReloadConfigCommand(const char* /*args*/)
191 sLog.outString( "Re-Loading config settings..." );
192 sWorld.LoadConfigSettings(true);
193 SendGlobalSysMessage("World config settings reloaded.");
194 return true;
197 bool ChatHandler::HandleReloadAchievementCriteriaDataCommand(const char*)
199 sLog.outString( "Re-Loading Additional Achievement Criteria Data..." );
200 achievementmgr.LoadAchievementCriteriaData();
201 SendGlobalSysMessage("DB table `achievement_criteria_data` reloaded.");
202 return true;
205 bool ChatHandler::HandleReloadAchievementRewardCommand(const char*)
207 sLog.outString( "Re-Loading Achievement Reward Data..." );
208 achievementmgr.LoadRewards();
209 SendGlobalSysMessage("DB table `achievement_reward` reloaded.");
210 return true;
213 bool ChatHandler::HandleReloadAreaTriggerTavernCommand(const char*)
215 sLog.outString( "Re-Loading Tavern Area Triggers..." );
216 objmgr.LoadTavernAreaTriggers();
217 SendGlobalSysMessage("DB table `areatrigger_tavern` reloaded.");
218 return true;
221 bool ChatHandler::HandleReloadAreaTriggerTeleportCommand(const char*)
223 sLog.outString( "Re-Loading AreaTrigger teleport definitions..." );
224 objmgr.LoadAreaTriggerTeleports();
225 SendGlobalSysMessage("DB table `areatrigger_teleport` reloaded.");
226 return true;
229 bool ChatHandler::HandleReloadCommandCommand(const char*)
231 load_command_table = true;
232 SendGlobalSysMessage("DB table `command` will be reloaded at next chat command use.");
233 return true;
236 bool ChatHandler::HandleReloadCreatureQuestRelationsCommand(const char*)
238 sLog.outString( "Loading Quests Relations... (`creature_questrelation`)" );
239 objmgr.LoadCreatureQuestRelations();
240 SendGlobalSysMessage("DB table `creature_questrelation` (creature quest givers) reloaded.");
241 return true;
244 bool ChatHandler::HandleReloadCreatureQuestInvRelationsCommand(const char*)
246 sLog.outString( "Loading Quests Relations... (`creature_involvedrelation`)" );
247 objmgr.LoadCreatureInvolvedRelations();
248 SendGlobalSysMessage("DB table `creature_involvedrelation` (creature quest takers) reloaded.");
249 return true;
252 bool ChatHandler::HandleReloadGOQuestRelationsCommand(const char*)
254 sLog.outString( "Loading Quests Relations... (`gameobject_questrelation`)" );
255 objmgr.LoadGameobjectQuestRelations();
256 SendGlobalSysMessage("DB table `gameobject_questrelation` (gameobject quest givers) reloaded.");
257 return true;
260 bool ChatHandler::HandleReloadGOQuestInvRelationsCommand(const char*)
262 sLog.outString( "Loading Quests Relations... (`gameobject_involvedrelation`)" );
263 objmgr.LoadGameobjectInvolvedRelations();
264 SendGlobalSysMessage("DB table `gameobject_involvedrelation` (gameobject quest takers) reloaded.");
265 return true;
268 bool ChatHandler::HandleReloadQuestAreaTriggersCommand(const char*)
270 sLog.outString( "Re-Loading Quest Area Triggers..." );
271 objmgr.LoadQuestAreaTriggers();
272 SendGlobalSysMessage("DB table `areatrigger_involvedrelation` (quest area triggers) reloaded.");
273 return true;
276 bool ChatHandler::HandleReloadQuestTemplateCommand(const char*)
278 sLog.outString( "Re-Loading Quest Templates..." );
279 objmgr.LoadQuests();
280 SendGlobalSysMessage("DB table `quest_template` (quest definitions) reloaded.");
282 /// dependent also from `gameobject` but this table not reloaded anyway
283 sLog.outString( "Re-Loading GameObjects for quests..." );
284 objmgr.LoadGameObjectForQuests();
285 SendGlobalSysMessage("Data GameObjects for quests reloaded.");
286 return true;
289 bool ChatHandler::HandleReloadLootTemplatesCreatureCommand(const char*)
291 sLog.outString( "Re-Loading Loot Tables... (`creature_loot_template`)" );
292 LoadLootTemplates_Creature();
293 LootTemplates_Creature.CheckLootRefs();
294 SendGlobalSysMessage("DB table `creature_loot_template` reloaded.");
295 return true;
298 bool ChatHandler::HandleReloadLootTemplatesDisenchantCommand(const char*)
300 sLog.outString( "Re-Loading Loot Tables... (`disenchant_loot_template`)" );
301 LoadLootTemplates_Disenchant();
302 LootTemplates_Disenchant.CheckLootRefs();
303 SendGlobalSysMessage("DB table `disenchant_loot_template` reloaded.");
304 return true;
307 bool ChatHandler::HandleReloadLootTemplatesFishingCommand(const char*)
309 sLog.outString( "Re-Loading Loot Tables... (`fishing_loot_template`)" );
310 LoadLootTemplates_Fishing();
311 LootTemplates_Fishing.CheckLootRefs();
312 SendGlobalSysMessage("DB table `fishing_loot_template` reloaded.");
313 return true;
316 bool ChatHandler::HandleReloadLootTemplatesGameobjectCommand(const char*)
318 sLog.outString( "Re-Loading Loot Tables... (`gameobject_loot_template`)" );
319 LoadLootTemplates_Gameobject();
320 LootTemplates_Gameobject.CheckLootRefs();
321 SendGlobalSysMessage("DB table `gameobject_loot_template` reloaded.");
322 return true;
325 bool ChatHandler::HandleReloadLootTemplatesItemCommand(const char*)
327 sLog.outString( "Re-Loading Loot Tables... (`item_loot_template`)" );
328 LoadLootTemplates_Item();
329 LootTemplates_Item.CheckLootRefs();
330 SendGlobalSysMessage("DB table `item_loot_template` reloaded.");
331 return true;
334 bool ChatHandler::HandleReloadLootTemplatesMillingCommand(const char*)
336 sLog.outString( "Re-Loading Loot Tables... (`milling_loot_template`)" );
337 LoadLootTemplates_Milling();
338 LootTemplates_Milling.CheckLootRefs();
339 SendGlobalSysMessage("DB table `milling_loot_template` reloaded.");
340 return true;
343 bool ChatHandler::HandleReloadLootTemplatesPickpocketingCommand(const char*)
345 sLog.outString( "Re-Loading Loot Tables... (`pickpocketing_loot_template`)" );
346 LoadLootTemplates_Pickpocketing();
347 LootTemplates_Pickpocketing.CheckLootRefs();
348 SendGlobalSysMessage("DB table `pickpocketing_loot_template` reloaded.");
349 return true;
352 bool ChatHandler::HandleReloadLootTemplatesProspectingCommand(const char*)
354 sLog.outString( "Re-Loading Loot Tables... (`prospecting_loot_template`)" );
355 LoadLootTemplates_Prospecting();
356 LootTemplates_Prospecting.CheckLootRefs();
357 SendGlobalSysMessage("DB table `prospecting_loot_template` reloaded.");
358 return true;
361 bool ChatHandler::HandleReloadLootTemplatesQuestMailCommand(const char*)
363 sLog.outString( "Re-Loading Loot Tables... (`quest_mail_loot_template`)" );
364 LoadLootTemplates_QuestMail();
365 LootTemplates_QuestMail.CheckLootRefs();
366 SendGlobalSysMessage("DB table `quest_mail_loot_template` reloaded.");
367 return true;
370 bool ChatHandler::HandleReloadLootTemplatesReferenceCommand(const char*)
372 sLog.outString( "Re-Loading Loot Tables... (`reference_loot_template`)" );
373 LoadLootTemplates_Reference();
374 SendGlobalSysMessage("DB table `reference_loot_template` reloaded.");
375 return true;
378 bool ChatHandler::HandleReloadLootTemplatesSkinningCommand(const char*)
380 sLog.outString( "Re-Loading Loot Tables... (`skinning_loot_template`)" );
381 LoadLootTemplates_Skinning();
382 LootTemplates_Skinning.CheckLootRefs();
383 SendGlobalSysMessage("DB table `skinning_loot_template` reloaded.");
384 return true;
387 bool ChatHandler::HandleReloadLootTemplatesSpellCommand(const char*)
389 sLog.outString( "Re-Loading Loot Tables... (`spell_loot_template`)" );
390 LoadLootTemplates_Spell();
391 LootTemplates_Spell.CheckLootRefs();
392 SendGlobalSysMessage("DB table `spell_loot_template` reloaded.");
393 return true;
396 bool ChatHandler::HandleReloadMangosStringCommand(const char*)
398 sLog.outString( "Re-Loading mangos_string Table!" );
399 objmgr.LoadMangosStrings();
400 SendGlobalSysMessage("DB table `mangos_string` reloaded.");
401 return true;
404 bool ChatHandler::HandleReloadNpcOptionCommand(const char*)
406 sLog.outString( "Re-Loading `npc_option` Table!" );
407 objmgr.LoadNpcOptions();
408 SendGlobalSysMessage("DB table `npc_option` reloaded.");
409 return true;
412 bool ChatHandler::HandleReloadNpcGossipCommand(const char*)
414 sLog.outString( "Re-Loading `npc_gossip` Table!" );
415 objmgr.LoadNpcTextId();
416 SendGlobalSysMessage("DB table `npc_gossip` reloaded.");
417 return true;
420 bool ChatHandler::HandleReloadNpcTrainerCommand(const char*)
422 sLog.outString( "Re-Loading `npc_trainer` Table!" );
423 objmgr.LoadTrainerSpell();
424 SendGlobalSysMessage("DB table `npc_trainer` reloaded.");
425 return true;
428 bool ChatHandler::HandleReloadNpcVendorCommand(const char*)
430 sLog.outString( "Re-Loading `npc_vendor` Table!" );
431 objmgr.LoadVendors();
432 SendGlobalSysMessage("DB table `npc_vendor` reloaded.");
433 return true;
436 bool ChatHandler::HandleReloadPointsOfInterestCommand(const char*)
438 sLog.outString( "Re-Loading `points_of_interest` Table!" );
439 objmgr.LoadPointsOfInterest();
440 SendGlobalSysMessage("DB table `points_of_interest` reloaded.");
441 return true;
444 bool ChatHandler::HandleReloadSpellClickSpellsCommand(const char*)
446 sLog.outString( "Re-Loading `npc_spellclick_spells` Table!" );
447 objmgr.LoadNPCSpellClickSpells();
448 SendGlobalSysMessage("DB table `npc_spellclick_spells` reloaded.");
449 return true;
452 bool ChatHandler::HandleReloadReservedNameCommand(const char*)
454 sLog.outString( "Loading ReservedNames... (`reserved_name`)" );
455 objmgr.LoadReservedPlayersNames();
456 SendGlobalSysMessage("DB table `reserved_name` (player reserved names) reloaded.");
457 return true;
460 bool ChatHandler::HandleReloadSkillDiscoveryTemplateCommand(const char* /*args*/)
462 sLog.outString( "Re-Loading Skill Discovery Table..." );
463 LoadSkillDiscoveryTable();
464 SendGlobalSysMessage("DB table `skill_discovery_template` (recipes discovered at crafting) reloaded.");
465 return true;
468 bool ChatHandler::HandleReloadSkillExtraItemTemplateCommand(const char* /*args*/)
470 sLog.outString( "Re-Loading Skill Extra Item Table..." );
471 LoadSkillExtraItemTable();
472 SendGlobalSysMessage("DB table `skill_extra_item_template` (extra item creation when crafting) reloaded.");
473 return true;
476 bool ChatHandler::HandleReloadSkillFishingBaseLevelCommand(const char* /*args*/)
478 sLog.outString( "Re-Loading Skill Fishing base level requirements..." );
479 objmgr.LoadFishingBaseSkillLevel();
480 SendGlobalSysMessage("DB table `skill_fishing_base_level` (fishing base level for zone/subzone) reloaded.");
481 return true;
484 bool ChatHandler::HandleReloadSpellAffectCommand(const char*)
486 sLog.outString( "Re-Loading SpellAffect definitions..." );
487 spellmgr.LoadSpellAffects();
488 SendGlobalSysMessage("DB table `spell_affect` (spell mods apply requirements) reloaded.");
489 return true;
492 bool ChatHandler::HandleReloadSpellAreaCommand(const char*)
494 sLog.outString( "Re-Loading SpellArea Data..." );
495 spellmgr.LoadSpellAreas();
496 SendGlobalSysMessage("DB table `spell_area` (spell dependences from area/quest/auras state) reloaded.");
497 return true;
500 bool ChatHandler::HandleReloadSpellChainCommand(const char*)
502 sLog.outString( "Re-Loading Spell Chain Data... " );
503 spellmgr.LoadSpellChains();
504 SendGlobalSysMessage("DB table `spell_chain` (spell ranks) reloaded.");
505 return true;
508 bool ChatHandler::HandleReloadSpellElixirCommand(const char*)
510 sLog.outString( "Re-Loading Spell Elixir types..." );
511 spellmgr.LoadSpellElixirs();
512 SendGlobalSysMessage("DB table `spell_elixir` (spell elixir types) reloaded.");
513 return true;
516 bool ChatHandler::HandleReloadSpellLearnSpellCommand(const char*)
518 sLog.outString( "Re-Loading Spell Learn Spells..." );
519 spellmgr.LoadSpellLearnSpells();
520 SendGlobalSysMessage("DB table `spell_learn_spell` reloaded.");
521 return true;
524 bool ChatHandler::HandleReloadSpellProcEventCommand(const char*)
526 sLog.outString( "Re-Loading Spell Proc Event conditions..." );
527 spellmgr.LoadSpellProcEvents();
528 SendGlobalSysMessage("DB table `spell_proc_event` (spell proc trigger requirements) reloaded.");
529 return true;
532 bool ChatHandler::HandleReloadSpellBonusesCommand(const char*)
534 sLog.outString( "Re-Loading Spell Bonus Data..." );
535 spellmgr.LoadSpellBonusess();
536 SendGlobalSysMessage("DB table `spell_bonus_data` (spell damage/healing coefficients) reloaded.");
537 return true;
540 bool ChatHandler::HandleReloadSpellScriptTargetCommand(const char*)
542 sLog.outString( "Re-Loading SpellsScriptTarget..." );
543 spellmgr.LoadSpellScriptTarget();
544 SendGlobalSysMessage("DB table `spell_script_target` (spell targets selection in case specific creature/GO requirements) reloaded.");
545 return true;
548 bool ChatHandler::HandleReloadSpellTargetPositionCommand(const char*)
550 sLog.outString( "Re-Loading Spell target coordinates..." );
551 spellmgr.LoadSpellTargetPositions();
552 SendGlobalSysMessage("DB table `spell_target_position` (destination coordinates for spell targets) reloaded.");
553 return true;
556 bool ChatHandler::HandleReloadSpellThreatsCommand(const char*)
558 sLog.outString( "Re-Loading Aggro Spells Definitions...");
559 spellmgr.LoadSpellThreats();
560 SendGlobalSysMessage("DB table `spell_threat` (spell aggro definitions) reloaded.");
561 return true;
564 bool ChatHandler::HandleReloadSpellPetAurasCommand(const char*)
566 sLog.outString( "Re-Loading Spell pet auras...");
567 spellmgr.LoadSpellPetAuras();
568 SendGlobalSysMessage("DB table `spell_pet_auras` reloaded.");
569 return true;
572 bool ChatHandler::HandleReloadPageTextsCommand(const char*)
574 sLog.outString( "Re-Loading Page Texts..." );
575 objmgr.LoadPageTexts();
576 SendGlobalSysMessage("DB table `page_texts` reloaded.");
577 return true;
580 bool ChatHandler::HandleReloadItemEnchantementsCommand(const char*)
582 sLog.outString( "Re-Loading Item Random Enchantments Table..." );
583 LoadRandomEnchantmentsTable();
584 SendGlobalSysMessage("DB table `item_enchantment_template` reloaded.");
585 return true;
588 bool ChatHandler::HandleReloadItemRequiredTragetCommand(const char*)
590 sLog.outString( "Re-Loading Item Required Targets Table..." );
591 objmgr.LoadItemRequiredTarget();
592 SendGlobalSysMessage("DB table `item_required_target` reloaded.");
593 return true;
596 bool ChatHandler::HandleReloadGameObjectScriptsCommand(const char* arg)
598 if(sWorld.IsScriptScheduled())
600 SendSysMessage("DB scripts used currently, please attempt reload later.");
601 SetSentErrorMessage(true);
602 return false;
605 if(*arg!='a')
606 sLog.outString( "Re-Loading Scripts from `gameobject_scripts`...");
608 objmgr.LoadGameObjectScripts();
610 if(*arg!='a')
611 SendGlobalSysMessage("DB table `gameobject_scripts` reloaded.");
613 return true;
616 bool ChatHandler::HandleReloadEventScriptsCommand(const char* arg)
618 if(sWorld.IsScriptScheduled())
620 SendSysMessage("DB scripts used currently, please attempt reload later.");
621 SetSentErrorMessage(true);
622 return false;
625 if(*arg!='a')
626 sLog.outString( "Re-Loading Scripts from `event_scripts`...");
628 objmgr.LoadEventScripts();
630 if(*arg!='a')
631 SendGlobalSysMessage("DB table `event_scripts` reloaded.");
633 return true;
636 bool ChatHandler::HandleReloadEventAITextsCommand(const char* arg)
639 sLog.outString( "Re-Loading Texts from `creature_ai_texts`...");
640 CreatureEAI_Mgr.LoadCreatureEventAI_Texts();
641 SendGlobalSysMessage("DB table `creature_ai_texts` reloaded.");
642 return true;
645 bool ChatHandler::HandleReloadEventAISummonsCommand(const char* arg)
647 sLog.outString( "Re-Loading Summons from `creature_ai_summons`...");
648 CreatureEAI_Mgr.LoadCreatureEventAI_Summons();
649 SendGlobalSysMessage("DB table `creature_ai_summons` reloaded.");
650 return true;
653 bool ChatHandler::HandleReloadEventAIScriptsCommand(const char* arg)
655 sLog.outString( "Re-Loading Scripts from `creature_ai_scripts`...");
656 CreatureEAI_Mgr.LoadCreatureEventAI_Scripts();
657 SendGlobalSysMessage("DB table `creature_ai_scripts` reloaded.");
658 return true;
661 bool ChatHandler::HandleReloadQuestEndScriptsCommand(const char* arg)
663 if(sWorld.IsScriptScheduled())
665 SendSysMessage("DB scripts used currently, please attempt reload later.");
666 SetSentErrorMessage(true);
667 return false;
670 if(*arg!='a')
671 sLog.outString( "Re-Loading Scripts from `quest_end_scripts`...");
673 objmgr.LoadQuestEndScripts();
675 if(*arg!='a')
676 SendGlobalSysMessage("DB table `quest_end_scripts` reloaded.");
678 return true;
681 bool ChatHandler::HandleReloadQuestStartScriptsCommand(const char* arg)
683 if(sWorld.IsScriptScheduled())
685 SendSysMessage("DB scripts used currently, please attempt reload later.");
686 SetSentErrorMessage(true);
687 return false;
690 if(*arg!='a')
691 sLog.outString( "Re-Loading Scripts from `quest_start_scripts`...");
693 objmgr.LoadQuestStartScripts();
695 if(*arg!='a')
696 SendGlobalSysMessage("DB table `quest_start_scripts` reloaded.");
698 return true;
701 bool ChatHandler::HandleReloadSpellScriptsCommand(const char* arg)
703 if(sWorld.IsScriptScheduled())
705 SendSysMessage("DB scripts used currently, please attempt reload later.");
706 SetSentErrorMessage(true);
707 return false;
710 if(*arg!='a')
711 sLog.outString( "Re-Loading Scripts from `spell_scripts`...");
713 objmgr.LoadSpellScripts();
715 if(*arg!='a')
716 SendGlobalSysMessage("DB table `spell_scripts` reloaded.");
718 return true;
721 bool ChatHandler::HandleReloadDbScriptStringCommand(const char* /*arg*/)
723 sLog.outString( "Re-Loading Script strings from `db_script_string`...");
724 objmgr.LoadDbScriptStrings();
725 SendGlobalSysMessage("DB table `db_script_string` reloaded.");
726 return true;
729 bool ChatHandler::HandleReloadGameGraveyardZoneCommand(const char* /*arg*/)
731 sLog.outString( "Re-Loading Graveyard-zone links...");
733 objmgr.LoadGraveyardZones();
735 SendGlobalSysMessage("DB table `game_graveyard_zone` reloaded.");
737 return true;
740 bool ChatHandler::HandleReloadGameTeleCommand(const char* /*arg*/)
742 sLog.outString( "Re-Loading Game Tele coordinates...");
744 objmgr.LoadGameTele();
746 SendGlobalSysMessage("DB table `game_tele` reloaded.");
748 return true;
751 bool ChatHandler::HandleReloadLocalesAchievementRewardCommand(const char*)
753 sLog.outString( "Re-Loading Locales Achievement Reward Data..." );
754 achievementmgr.LoadRewardLocales();
755 SendGlobalSysMessage("DB table `locales_achievement_reward` reloaded.");
756 return true;
759 bool ChatHandler::HandleReloadLocalesCreatureCommand(const char* /*arg*/)
761 sLog.outString( "Re-Loading Locales Creature ...");
762 objmgr.LoadCreatureLocales();
763 SendGlobalSysMessage("DB table `locales_creature` reloaded.");
764 return true;
767 bool ChatHandler::HandleReloadLocalesGameobjectCommand(const char* /*arg*/)
769 sLog.outString( "Re-Loading Locales Gameobject ... ");
770 objmgr.LoadGameObjectLocales();
771 SendGlobalSysMessage("DB table `locales_gameobject` reloaded.");
772 return true;
775 bool ChatHandler::HandleReloadLocalesItemCommand(const char* /*arg*/)
777 sLog.outString( "Re-Loading Locales Item ... ");
778 objmgr.LoadItemLocales();
779 SendGlobalSysMessage("DB table `locales_item` reloaded.");
780 return true;
783 bool ChatHandler::HandleReloadLocalesNpcTextCommand(const char* /*arg*/)
785 sLog.outString( "Re-Loading Locales NPC Text ... ");
786 objmgr.LoadNpcTextLocales();
787 SendGlobalSysMessage("DB table `locales_npc_text` reloaded.");
788 return true;
791 bool ChatHandler::HandleReloadLocalesPageTextCommand(const char* /*arg*/)
793 sLog.outString( "Re-Loading Locales Page Text ... ");
794 objmgr.LoadPageTextLocales();
795 SendGlobalSysMessage("DB table `locales_page_text` reloaded.");
796 return true;
799 bool ChatHandler::HandleReloadLocalesPointsOfInterestCommand(const char* /*arg*/)
801 sLog.outString( "Re-Loading Locales Points Of Interest ... ");
802 objmgr.LoadPointOfInterestLocales();
803 SendGlobalSysMessage("DB table `locales_points_of_interest` reloaded.");
804 return true;
807 bool ChatHandler::HandleReloadLocalesQuestCommand(const char* /*arg*/)
809 sLog.outString( "Re-Loading Locales Quest ... ");
810 objmgr.LoadQuestLocales();
811 SendGlobalSysMessage("DB table `locales_quest` reloaded.");
812 return true;
815 bool ChatHandler::HandleLoadScriptsCommand(const char* args)
817 if(!LoadScriptingModule(args)) return true;
819 sWorld.SendWorldText(LANG_SCRIPTS_RELOADED);
820 return true;
823 bool ChatHandler::HandleAccountSetGmLevelCommand(const char* args)
825 char* arg1 = strtok((char*)args, " ");
826 if( !arg1 )
827 return false;
829 /// must be NULL if targeted syntax and must be not nULL if not targeted
830 char* arg2 = strtok(NULL, " ");
832 std::string targetAccountName;
833 uint32 targetAccountId = 0;
835 /// only target player different from self allowed (if targetPlayer!=NULL then not console)
836 Player* targetPlayer = getSelectedPlayer();
837 if(targetPlayer && m_session->GetPlayer()!=targetPlayer)
839 /// wrong command syntax or unexpected targeting
840 if(arg2)
841 return false;
843 /// security level expected in arg2 after this if.
844 arg2 = arg1;
846 targetAccountId = targetPlayer->GetSession()->GetAccountId();
847 accmgr.GetName(targetAccountId, targetAccountName);
849 else
851 /// wrong command syntax (second arg expected)
852 if(!arg2)
853 return false;
855 targetAccountName = arg1;
856 if(!AccountMgr::normilizeString(targetAccountName))
858 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,targetAccountName.c_str());
859 SetSentErrorMessage(true);
860 return false;
863 targetAccountId = accmgr.GetId(targetAccountName);
864 if(!targetAccountId)
866 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,targetAccountName.c_str());
867 SetSentErrorMessage(true);
868 return false;
872 int32 gm = (int32)atoi(arg2);
873 if ( gm < SEC_PLAYER || gm > SEC_ADMINISTRATOR )
875 SendSysMessage(LANG_BAD_VALUE);
876 SetSentErrorMessage(true);
877 return false;
880 /// can set security level only for target with less security and to less security that we have
881 /// This will reject self apply by specify account name
882 if(HasLowerSecurityAccount(NULL,targetAccountId,true))
883 return false;
885 /// account can't set security to same or grater level, need more power GM or console
886 AccountTypes plSecurity = m_session ? m_session->GetSecurity() : SEC_CONSOLE;
887 if (AccountTypes(gm) >= plSecurity )
889 SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
890 SetSentErrorMessage(true);
891 return false;
894 // This will prevent self apply by self target or no target
895 if(targetPlayer && m_session->GetPlayer()!=targetPlayer)
897 ChatHandler(targetPlayer).PSendSysMessage(LANG_YOURS_SECURITY_CHANGED,GetNameLink().c_str(), gm);
898 targetPlayer->GetSession()->SetSecurity(AccountTypes(gm));
901 PSendSysMessage(LANG_YOU_CHANGE_SECURITY, targetAccountName.c_str(), gm);
902 loginDatabase.PExecute("UPDATE account SET gmlevel = '%i' WHERE id = '%u'", gm, targetAccountId);
904 return true;
907 /// Set password for account
908 bool ChatHandler::HandleAccountSetPasswordCommand(const char* args)
910 if(!*args)
911 return false;
913 ///- Get the command line arguments
914 char *szAccount = strtok ((char*)args," ");
915 char *szPassword1 = strtok (NULL," ");
916 char *szPassword2 = strtok (NULL," ");
918 if (!szAccount||!szPassword1 || !szPassword2)
919 return false;
921 std::string account_name = szAccount;
922 if(!AccountMgr::normilizeString(account_name))
924 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
925 SetSentErrorMessage(true);
926 return false;
929 uint32 targetAccountId = accmgr.GetId(account_name);
930 if (!targetAccountId)
932 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
933 SetSentErrorMessage(true);
934 return false;
937 /// can set password only for target with less security
938 /// This is also reject self apply in fact
939 if(HasLowerSecurityAccount (NULL,targetAccountId,true))
940 return false;
942 if (strcmp(szPassword1,szPassword2))
944 SendSysMessage (LANG_NEW_PASSWORDS_NOT_MATCH);
945 SetSentErrorMessage (true);
946 return false;
949 AccountOpResult result = accmgr.ChangePassword(targetAccountId, szPassword1);
951 switch(result)
953 case AOR_OK:
954 SendSysMessage(LANG_COMMAND_PASSWORD);
955 break;
956 case AOR_NAME_NOT_EXIST:
957 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
958 SetSentErrorMessage(true);
959 return false;
960 case AOR_PASS_TOO_LONG:
961 SendSysMessage(LANG_PASSWORD_TOO_LONG);
962 SetSentErrorMessage(true);
963 return false;
964 default:
965 SendSysMessage(LANG_COMMAND_NOTCHANGEPASSWORD);
966 SetSentErrorMessage(true);
967 return false;
970 return true;
973 bool ChatHandler::HandleMaxSkillCommand(const char* /*args*/)
975 Player* SelectedPlayer = getSelectedPlayer();
976 if(!SelectedPlayer)
978 SendSysMessage(LANG_NO_CHAR_SELECTED);
979 SetSentErrorMessage(true);
980 return false;
983 // each skills that have max skill value dependent from level seted to current level max skill value
984 SelectedPlayer->UpdateSkillsToMaxSkillsForLevel();
985 return true;
988 bool ChatHandler::HandleSetSkillCommand(const char* args)
990 // number or [name] Shift-click form |color|Hskill:skill_id|h[name]|h|r
991 char* skill_p = extractKeyFromLink((char*)args,"Hskill");
992 if(!skill_p)
993 return false;
995 char *level_p = strtok (NULL, " ");
997 if( !level_p)
998 return false;
1000 char *max_p = strtok (NULL, " ");
1002 int32 skill = atoi(skill_p);
1003 if (skill <= 0)
1005 PSendSysMessage(LANG_INVALID_SKILL_ID, skill);
1006 SetSentErrorMessage(true);
1007 return false;
1010 int32 level = atol (level_p);
1012 Player * target = getSelectedPlayer();
1013 if(!target)
1015 SendSysMessage(LANG_NO_CHAR_SELECTED);
1016 SetSentErrorMessage(true);
1017 return false;
1020 SkillLineEntry const* sl = sSkillLineStore.LookupEntry(skill);
1021 if(!sl)
1023 PSendSysMessage(LANG_INVALID_SKILL_ID, skill);
1024 SetSentErrorMessage(true);
1025 return false;
1028 std::string tNameLink = GetNameLink(target);
1030 if(!target->GetSkillValue(skill))
1032 PSendSysMessage(LANG_SET_SKILL_ERROR, tNameLink.c_str(), skill, sl->name[0]);
1033 SetSentErrorMessage(true);
1034 return false;
1037 int32 max = max_p ? atol (max_p) : target->GetPureMaxSkillValue(skill);
1039 if( level <= 0 || level > max || max <= 0 )
1040 return false;
1042 target->SetSkill(skill, level, max);
1043 PSendSysMessage(LANG_SET_SKILL, skill, sl->name[0], tNameLink.c_str(), level, max);
1045 return true;
1048 bool ChatHandler::HandleUnLearnCommand(const char* args)
1050 if (!*args)
1051 return false;
1053 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
1054 uint32 spell_id = extractSpellIdFromLink((char*)args);
1055 if(!spell_id)
1056 return false;
1058 char const* allStr = strtok(NULL," ");
1059 bool allRanks = allStr ? (strncmp(allStr, "all", strlen(allStr)) == 0) : false;
1061 Player* target = getSelectedPlayer();
1062 if(!target)
1064 SendSysMessage(LANG_NO_CHAR_SELECTED);
1065 SetSentErrorMessage(true);
1066 return false;
1069 if(allRanks)
1070 spell_id = spellmgr.GetFirstSpellInChain (spell_id);
1072 if (target->HasSpell(spell_id))
1073 target->removeSpell(spell_id,false,!allRanks);
1074 else
1075 SendSysMessage(LANG_FORGET_SPELL);
1077 return true;
1080 bool ChatHandler::HandleCooldownCommand(const char* args)
1082 Player* target = getSelectedPlayer();
1083 if(!target)
1085 SendSysMessage(LANG_PLAYER_NOT_FOUND);
1086 SetSentErrorMessage(true);
1087 return false;
1090 std::string tNameLink = GetNameLink(target);
1092 if (!*args)
1094 target->RemoveAllSpellCooldown();
1095 PSendSysMessage(LANG_REMOVEALL_COOLDOWN, tNameLink.c_str());
1097 else
1099 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
1100 uint32 spell_id = extractSpellIdFromLink((char*)args);
1101 if(!spell_id)
1102 return false;
1104 if(!sSpellStore.LookupEntry(spell_id))
1106 PSendSysMessage(LANG_UNKNOWN_SPELL, target==m_session->GetPlayer() ? GetMangosString(LANG_YOU) : tNameLink.c_str());
1107 SetSentErrorMessage(true);
1108 return false;
1111 target->RemoveSpellCooldown(spell_id,true);
1112 PSendSysMessage(LANG_REMOVE_COOLDOWN, spell_id, target==m_session->GetPlayer() ? GetMangosString(LANG_YOU) : tNameLink.c_str());
1114 return true;
1117 bool ChatHandler::HandleLearnAllCommand(const char* /*args*/)
1119 static const char *allSpellList[] =
1121 "3365",
1122 "6233",
1123 "6247",
1124 "6246",
1125 "6477",
1126 "6478",
1127 "22810",
1128 "8386",
1129 "21651",
1130 "21652",
1131 "522",
1132 "7266",
1133 "8597",
1134 "2479",
1135 "22027",
1136 "6603",
1137 "5019",
1138 "133",
1139 "168",
1140 "227",
1141 "5009",
1142 "9078",
1143 "668",
1144 "203",
1145 "20599",
1146 "20600",
1147 "81",
1148 "20597",
1149 "20598",
1150 "20864",
1151 "1459",
1152 "5504",
1153 "587",
1154 "5143",
1155 "118",
1156 "5505",
1157 "597",
1158 "604",
1159 "1449",
1160 "1460",
1161 "2855",
1162 "1008",
1163 "475",
1164 "5506",
1165 "1463",
1166 "12824",
1167 "8437",
1168 "990",
1169 "5145",
1170 "8450",
1171 "1461",
1172 "759",
1173 "8494",
1174 "8455",
1175 "8438",
1176 "6127",
1177 "8416",
1178 "6129",
1179 "8451",
1180 "8495",
1181 "8439",
1182 "3552",
1183 "8417",
1184 "10138",
1185 "12825",
1186 "10169",
1187 "10156",
1188 "10144",
1189 "10191",
1190 "10201",
1191 "10211",
1192 "10053",
1193 "10173",
1194 "10139",
1195 "10145",
1196 "10192",
1197 "10170",
1198 "10202",
1199 "10054",
1200 "10174",
1201 "10193",
1202 "12826",
1203 "2136",
1204 "143",
1205 "145",
1206 "2137",
1207 "2120",
1208 "3140",
1209 "543",
1210 "2138",
1211 "2948",
1212 "8400",
1213 "2121",
1214 "8444",
1215 "8412",
1216 "8457",
1217 "8401",
1218 "8422",
1219 "8445",
1220 "8402",
1221 "8413",
1222 "8458",
1223 "8423",
1224 "8446",
1225 "10148",
1226 "10197",
1227 "10205",
1228 "10149",
1229 "10215",
1230 "10223",
1231 "10206",
1232 "10199",
1233 "10150",
1234 "10216",
1235 "10207",
1236 "10225",
1237 "10151",
1238 "116",
1239 "205",
1240 "7300",
1241 "122",
1242 "837",
1243 "10",
1244 "7301",
1245 "7322",
1246 "6143",
1247 "120",
1248 "865",
1249 "8406",
1250 "6141",
1251 "7302",
1252 "8461",
1253 "8407",
1254 "8492",
1255 "8427",
1256 "8408",
1257 "6131",
1258 "7320",
1259 "10159",
1260 "8462",
1261 "10185",
1262 "10179",
1263 "10160",
1264 "10180",
1265 "10219",
1266 "10186",
1267 "10177",
1268 "10230",
1269 "10181",
1270 "10161",
1271 "10187",
1272 "10220",
1273 "2018",
1274 "2663",
1275 "12260",
1276 "2660",
1277 "3115",
1278 "3326",
1279 "2665",
1280 "3116",
1281 "2738",
1282 "3293",
1283 "2661",
1284 "3319",
1285 "2662",
1286 "9983",
1287 "8880",
1288 "2737",
1289 "2739",
1290 "7408",
1291 "3320",
1292 "2666",
1293 "3323",
1294 "3324",
1295 "3294",
1296 "22723",
1297 "23219",
1298 "23220",
1299 "23221",
1300 "23228",
1301 "23338",
1302 "10788",
1303 "10790",
1304 "5611",
1305 "5016",
1306 "5609",
1307 "2060",
1308 "10963",
1309 "10964",
1310 "10965",
1311 "22593",
1312 "22594",
1313 "596",
1314 "996",
1315 "499",
1316 "768",
1317 "17002",
1318 "1448",
1319 "1082",
1320 "16979",
1321 "1079",
1322 "5215",
1323 "20484",
1324 "5221",
1325 "15590",
1326 "17007",
1327 "6795",
1328 "6807",
1329 "5487",
1330 "1446",
1331 "1066",
1332 "5421",
1333 "3139",
1334 "779",
1335 "6811",
1336 "6808",
1337 "1445",
1338 "5216",
1339 "1737",
1340 "5222",
1341 "5217",
1342 "1432",
1343 "6812",
1344 "9492",
1345 "5210",
1346 "3030",
1347 "1441",
1348 "783",
1349 "6801",
1350 "20739",
1351 "8944",
1352 "9491",
1353 "22569",
1354 "5226",
1355 "6786",
1356 "1433",
1357 "8973",
1358 "1828",
1359 "9495",
1360 "9006",
1361 "6794",
1362 "8993",
1363 "5203",
1364 "16914",
1365 "6784",
1366 "9635",
1367 "22830",
1368 "20722",
1369 "9748",
1370 "6790",
1371 "9753",
1372 "9493",
1373 "9752",
1374 "9831",
1375 "9825",
1376 "9822",
1377 "5204",
1378 "5401",
1379 "22831",
1380 "6793",
1381 "9845",
1382 "17401",
1383 "9882",
1384 "9868",
1385 "20749",
1386 "9893",
1387 "9899",
1388 "9895",
1389 "9832",
1390 "9902",
1391 "9909",
1392 "22832",
1393 "9828",
1394 "9851",
1395 "9883",
1396 "9869",
1397 "17406",
1398 "17402",
1399 "9914",
1400 "20750",
1401 "9897",
1402 "9848",
1403 "3127",
1404 "107",
1405 "204",
1406 "9116",
1407 "2457",
1408 "78",
1409 "18848",
1410 "331",
1411 "403",
1412 "2098",
1413 "1752",
1414 "11278",
1415 "11288",
1416 "11284",
1417 "6461",
1418 "2344",
1419 "2345",
1420 "6463",
1421 "2346",
1422 "2352",
1423 "775",
1424 "1434",
1425 "1612",
1426 "71",
1427 "2468",
1428 "2458",
1429 "2467",
1430 "7164",
1431 "7178",
1432 "7367",
1433 "7376",
1434 "7381",
1435 "21156",
1436 "5209",
1437 "3029",
1438 "5201",
1439 "9849",
1440 "9850",
1441 "20719",
1442 "22568",
1443 "22827",
1444 "22828",
1445 "22829",
1446 "6809",
1447 "8972",
1448 "9005",
1449 "9823",
1450 "9827",
1451 "6783",
1452 "9913",
1453 "6785",
1454 "6787",
1455 "9866",
1456 "9867",
1457 "9894",
1458 "9896",
1459 "6800",
1460 "8992",
1461 "9829",
1462 "9830",
1463 "780",
1464 "769",
1465 "6749",
1466 "6750",
1467 "9755",
1468 "9754",
1469 "9908",
1470 "20745",
1471 "20742",
1472 "20747",
1473 "20748",
1474 "9746",
1475 "9745",
1476 "9880",
1477 "9881",
1478 "5391",
1479 "842",
1480 "3025",
1481 "3031",
1482 "3287",
1483 "3329",
1484 "1945",
1485 "3559",
1486 "4933",
1487 "4934",
1488 "4935",
1489 "4936",
1490 "5142",
1491 "5390",
1492 "5392",
1493 "5404",
1494 "5420",
1495 "6405",
1496 "7293",
1497 "7965",
1498 "8041",
1499 "8153",
1500 "9033",
1501 "9034",
1502 //"9036", problems with ghost state
1503 "16421",
1504 "21653",
1505 "22660",
1506 "5225",
1507 "9846",
1508 "2426",
1509 "5916",
1510 "6634",
1511 //"6718", phasing stealth, annoying for learn all case.
1512 "6719",
1513 "8822",
1514 "9591",
1515 "9590",
1516 "10032",
1517 "17746",
1518 "17747",
1519 "8203",
1520 "11392",
1521 "12495",
1522 "16380",
1523 "23452",
1524 "4079",
1525 "4996",
1526 "4997",
1527 "4998",
1528 "4999",
1529 "5000",
1530 "6348",
1531 "6349",
1532 "6481",
1533 "6482",
1534 "6483",
1535 "6484",
1536 "11362",
1537 "11410",
1538 "11409",
1539 "12510",
1540 "12509",
1541 "12885",
1542 "13142",
1543 "21463",
1544 "23460",
1545 "11421",
1546 "11416",
1547 "11418",
1548 "1851",
1549 "10059",
1550 "11423",
1551 "11417",
1552 "11422",
1553 "11419",
1554 "11424",
1555 "11420",
1556 "27",
1557 "31",
1558 "33",
1559 "34",
1560 "35",
1561 "15125",
1562 "21127",
1563 "22950",
1564 "1180",
1565 "201",
1566 "12593",
1567 "12842",
1568 "16770",
1569 "6057",
1570 "12051",
1571 "18468",
1572 "12606",
1573 "12605",
1574 "18466",
1575 "12502",
1576 "12043",
1577 "15060",
1578 "12042",
1579 "12341",
1580 "12848",
1581 "12344",
1582 "12353",
1583 "18460",
1584 "11366",
1585 "12350",
1586 "12352",
1587 "13043",
1588 "11368",
1589 "11113",
1590 "12400",
1591 "11129",
1592 "16766",
1593 "12573",
1594 "15053",
1595 "12580",
1596 "12475",
1597 "12472",
1598 "12953",
1599 "12488",
1600 "11189",
1601 "12985",
1602 "12519",
1603 "16758",
1604 "11958",
1605 "12490",
1606 "11426",
1607 "3565",
1608 "3562",
1609 "18960",
1610 "3567",
1611 "3561",
1612 "3566",
1613 "3563",
1614 "1953",
1615 "2139",
1616 "12505",
1617 "13018",
1618 "12522",
1619 "12523",
1620 "5146",
1621 "5144",
1622 "5148",
1623 "8419",
1624 "8418",
1625 "10213",
1626 "10212",
1627 "10157",
1628 "12524",
1629 "13019",
1630 "12525",
1631 "13020",
1632 "12526",
1633 "13021",
1634 "18809",
1635 "13031",
1636 "13032",
1637 "13033",
1638 "4036",
1639 "3920",
1640 "3919",
1641 "3918",
1642 "7430",
1643 "3922",
1644 "3923",
1645 "7411",
1646 "7418",
1647 "7421",
1648 "13262",
1649 "7412",
1650 "7415",
1651 "7413",
1652 "7416",
1653 "13920",
1654 "13921",
1655 "7745",
1656 "7779",
1657 "7428",
1658 "7457",
1659 "7857",
1660 "7748",
1661 "7426",
1662 "13421",
1663 "7454",
1664 "13378",
1665 "7788",
1666 "14807",
1667 "14293",
1668 "7795",
1669 "6296",
1670 "20608",
1671 "755",
1672 "444",
1673 "427",
1674 "428",
1675 "442",
1676 "447",
1677 "3578",
1678 "3581",
1679 "19027",
1680 "3580",
1681 "665",
1682 "3579",
1683 "3577",
1684 "6755",
1685 "3576",
1686 "2575",
1687 "2577",
1688 "2578",
1689 "2579",
1690 "2580",
1691 "2656",
1692 "2657",
1693 "2576",
1694 "3564",
1695 "10248",
1696 "8388",
1697 "2659",
1698 "14891",
1699 "3308",
1700 "3307",
1701 "10097",
1702 "2658",
1703 "3569",
1704 "16153",
1705 "3304",
1706 "10098",
1707 "4037",
1708 "3929",
1709 "3931",
1710 "3926",
1711 "3924",
1712 "3930",
1713 "3977",
1714 "3925",
1715 "136",
1716 "228",
1717 "5487",
1718 "43",
1719 "202",
1723 int loop = 0;
1724 while(strcmp(allSpellList[loop], "0"))
1726 uint32 spell = atol((char*)allSpellList[loop++]);
1728 if (m_session->GetPlayer()->HasSpell(spell))
1729 continue;
1731 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
1732 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
1734 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
1735 continue;
1738 m_session->GetPlayer()->learnSpell(spell,false);
1741 SendSysMessage(LANG_COMMAND_LEARN_MANY_SPELLS);
1743 return true;
1746 bool ChatHandler::HandleLearnAllGMCommand(const char* /*args*/)
1748 static const char *gmSpellList[] =
1750 "24347", // Become A Fish, No Breath Bar
1751 "35132", // Visual Boom
1752 "38488", // Attack 4000-8000 AOE
1753 "38795", // Attack 2000 AOE + Slow Down 90%
1754 "15712", // Attack 200
1755 "1852", // GM Spell Silence
1756 "31899", // Kill
1757 "31924", // Kill
1758 "29878", // Kill My Self
1759 "26644", // More Kill
1761 "28550", //Invisible 24
1762 "23452", //Invisible + Target
1766 uint16 gmSpellIter = 0;
1767 while( strcmp(gmSpellList[gmSpellIter], "0") )
1769 uint32 spell = atol((char*)gmSpellList[gmSpellIter++]);
1771 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
1772 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
1774 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
1775 continue;
1778 m_session->GetPlayer()->learnSpell(spell,false);
1781 SendSysMessage(LANG_LEARNING_GM_SKILLS);
1782 return true;
1785 bool ChatHandler::HandleLearnAllMyClassCommand(const char* /*args*/)
1787 HandleLearnAllMySpellsCommand("");
1788 HandleLearnAllMyTalentsCommand("");
1789 return true;
1792 bool ChatHandler::HandleLearnAllMySpellsCommand(const char* /*args*/)
1794 ChrClassesEntry const* clsEntry = sChrClassesStore.LookupEntry(m_session->GetPlayer()->getClass());
1795 if(!clsEntry)
1796 return true;
1797 uint32 family = clsEntry->spellfamily;
1799 for (uint32 i = 0; i < sSpellStore.GetNumRows(); ++i)
1801 SpellEntry const *spellInfo = sSpellStore.LookupEntry(i);
1802 if(!spellInfo)
1803 continue;
1805 // skip server-side/triggered spells
1806 if(spellInfo->spellLevel==0)
1807 continue;
1809 // skip wrong class/race skills
1810 if(!m_session->GetPlayer()->IsSpellFitByClassAndRace(spellInfo->Id))
1811 continue;
1813 // skip other spell families
1814 if( spellInfo->SpellFamilyName != family)
1815 continue;
1817 // skip spells with first rank learned as talent (and all talents then also)
1818 uint32 first_rank = spellmgr.GetFirstSpellInChain(spellInfo->Id);
1819 if(GetTalentSpellCost(first_rank) > 0 )
1820 continue;
1822 // skip broken spells
1823 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
1824 continue;
1826 m_session->GetPlayer()->learnSpell(i,false);
1829 SendSysMessage(LANG_COMMAND_LEARN_CLASS_SPELLS);
1830 return true;
1833 bool ChatHandler::HandleLearnAllMyTalentsCommand(const char* /*args*/)
1835 Player* player = m_session->GetPlayer();
1836 uint32 classMask = player->getClassMask();
1838 for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
1840 TalentEntry const *talentInfo = sTalentStore.LookupEntry(i);
1841 if(!talentInfo)
1842 continue;
1844 TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab );
1845 if(!talentTabInfo)
1846 continue;
1848 if( (classMask & talentTabInfo->ClassMask) == 0 )
1849 continue;
1851 // search highest talent rank
1852 uint32 spellid = 0;
1854 for(int rank = MAX_TALENT_RANK-1; rank >= 0; --rank)
1856 if(talentInfo->RankID[rank]!=0)
1858 spellid = talentInfo->RankID[rank];
1859 break;
1863 if(!spellid) // ??? none spells in talent
1864 continue;
1866 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid);
1867 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
1868 continue;
1870 // learn highest rank of talent and learn all non-talent spell ranks (recursive by tree)
1871 player->learnSpellHighRank(spellid);
1874 SendSysMessage(LANG_COMMAND_LEARN_CLASS_TALENTS);
1875 return true;
1878 bool ChatHandler::HandleLearnAllMyPetTalentsCommand(const char* /*args*/)
1880 Player* player = m_session->GetPlayer();
1882 Pet* pet = player->GetPet();
1883 if(!pet)
1885 SendSysMessage(LANG_NO_PET_FOUND);
1886 SetSentErrorMessage(true);
1887 return false;
1890 CreatureInfo const *ci = pet->GetCreatureInfo();
1891 if(!ci)
1893 SendSysMessage(LANG_WRONG_PET_TYPE);
1894 SetSentErrorMessage(true);
1895 return false;
1898 CreatureFamilyEntry const *pet_family = sCreatureFamilyStore.LookupEntry(ci->family);
1899 if(!pet_family)
1901 SendSysMessage(LANG_WRONG_PET_TYPE);
1902 SetSentErrorMessage(true);
1903 return false;
1906 if(pet_family->petTalentType < 0) // not hunter pet
1908 SendSysMessage(LANG_WRONG_PET_TYPE);
1909 SetSentErrorMessage(true);
1910 return false;
1913 for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
1915 TalentEntry const *talentInfo = sTalentStore.LookupEntry(i);
1916 if(!talentInfo)
1917 continue;
1919 TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab );
1920 if(!talentTabInfo)
1921 continue;
1923 // prevent learn talent for different family (cheating)
1924 if(((1 << pet_family->petTalentType) & talentTabInfo->petTalentMask)==0)
1925 continue;
1927 // search highest talent rank
1928 uint32 spellid = 0;
1930 for(int rank = MAX_TALENT_RANK-1; rank >= 0; --rank)
1932 if(talentInfo->RankID[rank]!=0)
1934 spellid = talentInfo->RankID[rank];
1935 break;
1939 if(!spellid) // ??? none spells in talent
1940 continue;
1942 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid);
1943 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
1944 continue;
1946 // learn highest rank of talent and learn all non-talent spell ranks (recursive by tree)
1947 pet->learnSpellHighRank(spellid);
1950 SendSysMessage(LANG_COMMAND_LEARN_PET_TALENTS);
1951 return true;
1954 bool ChatHandler::HandleLearnAllLangCommand(const char* /*args*/)
1956 // skipping UNIVERSAL language (0)
1957 for(int i = 1; i < LANGUAGES_COUNT; ++i)
1958 m_session->GetPlayer()->learnSpell(lang_description[i].spell_id,false);
1960 SendSysMessage(LANG_COMMAND_LEARN_ALL_LANG);
1961 return true;
1964 bool ChatHandler::HandleLearnAllDefaultCommand(const char* args)
1966 Player* target;
1967 if(!extractPlayerTarget((char*)args,&target))
1968 return false;
1970 target->learnDefaultSpells();
1971 target->learnQuestRewardedSpells();
1973 PSendSysMessage(LANG_COMMAND_LEARN_ALL_DEFAULT_AND_QUEST,GetNameLink(target).c_str());
1974 return true;
1977 bool ChatHandler::HandleLearnCommand(const char* args)
1979 Player* targetPlayer = getSelectedPlayer();
1981 if(!targetPlayer)
1983 SendSysMessage(LANG_PLAYER_NOT_FOUND);
1984 SetSentErrorMessage(true);
1985 return false;
1988 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
1989 uint32 spell = extractSpellIdFromLink((char*)args);
1990 if(!spell || !sSpellStore.LookupEntry(spell))
1991 return false;
1993 char const* allStr = strtok(NULL," ");
1994 bool allRanks = allStr ? (strncmp(allStr, "all", strlen(allStr)) == 0) : false;
1996 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
1997 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
1999 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
2000 SetSentErrorMessage(true);
2001 return false;
2004 if (!allRanks && targetPlayer->HasSpell(spell))
2006 if(targetPlayer == m_session->GetPlayer())
2007 SendSysMessage(LANG_YOU_KNOWN_SPELL);
2008 else
2009 PSendSysMessage(LANG_TARGET_KNOWN_SPELL,GetNameLink(targetPlayer).c_str());
2010 SetSentErrorMessage(true);
2011 return false;
2014 if(allRanks)
2015 targetPlayer->learnSpellHighRank(spell);
2016 else
2017 targetPlayer->learnSpell(spell,false);
2019 return true;
2022 bool ChatHandler::HandleAddItemCommand(const char* args)
2024 if (!*args)
2025 return false;
2027 uint32 itemId = 0;
2029 if(args[0]=='[') // [name] manual form
2031 char* citemName = strtok((char*)args, "]");
2033 if(citemName && citemName[0])
2035 std::string itemName = citemName+1;
2036 WorldDatabase.escape_string(itemName);
2037 QueryResult *result = WorldDatabase.PQuery("SELECT entry FROM item_template WHERE name = '%s'", itemName.c_str());
2038 if (!result)
2040 PSendSysMessage(LANG_COMMAND_COULDNOTFIND, citemName+1);
2041 SetSentErrorMessage(true);
2042 return false;
2044 itemId = result->Fetch()->GetUInt16();
2045 delete result;
2047 else
2048 return false;
2050 else // item_id or [name] Shift-click form |color|Hitem:item_id:0:0:0|h[name]|h|r
2052 char* cId = extractKeyFromLink((char*)args,"Hitem");
2053 if(!cId)
2054 return false;
2055 itemId = atol(cId);
2058 char* ccount = strtok(NULL, " ");
2060 int32 count = 1;
2062 if (ccount)
2063 count = strtol(ccount, NULL, 10);
2065 if (count == 0)
2066 count = 1;
2068 Player* pl = m_session->GetPlayer();
2069 Player* plTarget = getSelectedPlayer();
2070 if(!plTarget)
2071 plTarget = pl;
2073 sLog.outDetail(GetMangosString(LANG_ADDITEM), itemId, count);
2075 ItemPrototype const *pProto = objmgr.GetItemPrototype(itemId);
2076 if(!pProto)
2078 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId);
2079 SetSentErrorMessage(true);
2080 return false;
2083 //Subtract
2084 if (count < 0)
2086 plTarget->DestroyItemCount(itemId, -count, true, false);
2087 PSendSysMessage(LANG_REMOVEITEM, itemId, -count, GetNameLink(plTarget).c_str());
2088 return true;
2091 //Adding items
2092 uint32 noSpaceForCount = 0;
2094 // check space and find places
2095 ItemPosCountVec dest;
2096 uint8 msg = plTarget->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, itemId, count, &noSpaceForCount );
2097 if( msg != EQUIP_ERR_OK ) // convert to possible store amount
2098 count -= noSpaceForCount;
2100 if( count == 0 || dest.empty()) // can't add any
2102 PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount );
2103 SetSentErrorMessage(true);
2104 return false;
2107 Item* item = plTarget->StoreNewItem( dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId));
2109 // remove binding (let GM give it to another player later)
2110 if(pl==plTarget)
2111 for(ItemPosCountVec::const_iterator itr = dest.begin(); itr != dest.end(); ++itr)
2112 if(Item* item1 = pl->GetItemByPos(itr->pos))
2113 item1->SetBinding( false );
2115 if(count > 0 && item)
2117 pl->SendNewItem(item,count,false,true);
2118 if(pl!=plTarget)
2119 plTarget->SendNewItem(item,count,true,false);
2122 if(noSpaceForCount > 0)
2123 PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount);
2125 return true;
2128 bool ChatHandler::HandleAddItemSetCommand(const char* args)
2130 if (!*args)
2131 return false;
2133 char* cId = extractKeyFromLink((char*)args,"Hitemset"); // number or [name] Shift-click form |color|Hitemset:itemset_id|h[name]|h|r
2134 if (!cId)
2135 return false;
2137 uint32 itemsetId = atol(cId);
2139 // prevent generation all items with itemset field value '0'
2140 if (itemsetId == 0)
2142 PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND,itemsetId);
2143 SetSentErrorMessage(true);
2144 return false;
2147 Player* pl = m_session->GetPlayer();
2148 Player* plTarget = getSelectedPlayer();
2149 if(!plTarget)
2150 plTarget = pl;
2152 sLog.outDetail(GetMangosString(LANG_ADDITEMSET), itemsetId);
2154 bool found = false;
2155 for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
2157 ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype>(id);
2158 if (!pProto)
2159 continue;
2161 if (pProto->ItemSet == itemsetId)
2163 found = true;
2164 ItemPosCountVec dest;
2165 uint8 msg = plTarget->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, pProto->ItemId, 1 );
2166 if (msg == EQUIP_ERR_OK)
2168 Item* item = plTarget->StoreNewItem( dest, pProto->ItemId, true);
2170 // remove binding (let GM give it to another player later)
2171 if (pl==plTarget)
2172 item->SetBinding( false );
2174 pl->SendNewItem(item,1,false,true);
2175 if (pl!=plTarget)
2176 plTarget->SendNewItem(item,1,true,false);
2178 else
2180 pl->SendEquipError( msg, NULL, NULL );
2181 PSendSysMessage(LANG_ITEM_CANNOT_CREATE, pProto->ItemId, 1);
2186 if (!found)
2188 PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND,itemsetId);
2190 SetSentErrorMessage(true);
2191 return false;
2194 return true;
2197 bool ChatHandler::HandleListItemCommand(const char* args)
2199 if(!*args)
2200 return false;
2202 char* cId = extractKeyFromLink((char*)args,"Hitem");
2203 if(!cId)
2204 return false;
2206 uint32 item_id = atol(cId);
2207 if(!item_id)
2209 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
2210 SetSentErrorMessage(true);
2211 return false;
2214 ItemPrototype const* itemProto = objmgr.GetItemPrototype(item_id);
2215 if(!itemProto)
2217 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
2218 SetSentErrorMessage(true);
2219 return false;
2222 char* c_count = strtok(NULL, " ");
2223 int count = c_count ? atol(c_count) : 10;
2225 if(count < 0)
2226 return false;
2228 QueryResult *result;
2230 // inventory case
2231 uint32 inv_count = 0;
2232 result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM character_inventory WHERE item_template='%u'",item_id);
2233 if(result)
2235 inv_count = (*result)[0].GetUInt32();
2236 delete result;
2239 result=CharacterDatabase.PQuery(
2240 // 0 1 2 3 4 5
2241 "SELECT ci.item, cibag.slot AS bag, ci.slot, ci.guid, characters.account,characters.name "
2242 "FROM character_inventory AS ci LEFT JOIN character_inventory AS cibag ON (cibag.item=ci.bag),characters "
2243 "WHERE ci.item_template='%u' AND ci.guid = characters.guid LIMIT %u ",
2244 item_id,uint32(count));
2246 if(result)
2250 Field *fields = result->Fetch();
2251 uint32 item_guid = fields[0].GetUInt32();
2252 uint32 item_bag = fields[1].GetUInt32();
2253 uint32 item_slot = fields[2].GetUInt32();
2254 uint32 owner_guid = fields[3].GetUInt32();
2255 uint32 owner_acc = fields[4].GetUInt32();
2256 std::string owner_name = fields[5].GetCppString();
2258 char const* item_pos = 0;
2259 if(Player::IsEquipmentPos(item_bag,item_slot))
2260 item_pos = "[equipped]";
2261 else if(Player::IsInventoryPos(item_bag,item_slot))
2262 item_pos = "[in inventory]";
2263 else if(Player::IsBankPos(item_bag,item_slot))
2264 item_pos = "[in bank]";
2265 else
2266 item_pos = "";
2268 PSendSysMessage(LANG_ITEMLIST_SLOT,
2269 item_guid,owner_name.c_str(),owner_guid,owner_acc,item_pos);
2270 } while (result->NextRow());
2272 int64 res_count = result->GetRowCount();
2274 delete result;
2276 if(count > res_count)
2277 count-=res_count;
2278 else if(count)
2279 count = 0;
2282 // mail case
2283 uint32 mail_count = 0;
2284 result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM mail_items WHERE item_template='%u'", item_id);
2285 if(result)
2287 mail_count = (*result)[0].GetUInt32();
2288 delete result;
2291 if(count > 0)
2293 result=CharacterDatabase.PQuery(
2294 // 0 1 2 3 4 5 6
2295 "SELECT mail_items.item_guid, mail.sender, mail.receiver, char_s.account, char_s.name, char_r.account, char_r.name "
2296 "FROM mail,mail_items,characters as char_s,characters as char_r "
2297 "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",
2298 item_id,uint32(count));
2300 else
2301 result = NULL;
2303 if(result)
2307 Field *fields = result->Fetch();
2308 uint32 item_guid = fields[0].GetUInt32();
2309 uint32 item_s = fields[1].GetUInt32();
2310 uint32 item_r = fields[2].GetUInt32();
2311 uint32 item_s_acc = fields[3].GetUInt32();
2312 std::string item_s_name = fields[4].GetCppString();
2313 uint32 item_r_acc = fields[5].GetUInt32();
2314 std::string item_r_name = fields[6].GetCppString();
2316 char const* item_pos = "[in mail]";
2318 PSendSysMessage(LANG_ITEMLIST_MAIL,
2319 item_guid,item_s_name.c_str(),item_s,item_s_acc,item_r_name.c_str(),item_r,item_r_acc,item_pos);
2320 } while (result->NextRow());
2322 int64 res_count = result->GetRowCount();
2324 delete result;
2326 if(count > res_count)
2327 count-=res_count;
2328 else if(count)
2329 count = 0;
2332 // auction case
2333 uint32 auc_count = 0;
2334 result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM auctionhouse WHERE item_template='%u'",item_id);
2335 if(result)
2337 auc_count = (*result)[0].GetUInt32();
2338 delete result;
2341 if(count > 0)
2343 result=CharacterDatabase.PQuery(
2344 // 0 1 2 3
2345 "SELECT auctionhouse.itemguid, auctionhouse.itemowner, characters.account, characters.name "
2346 "FROM auctionhouse,characters WHERE auctionhouse.item_template='%u' AND characters.guid = auctionhouse.itemowner LIMIT %u",
2347 item_id,uint32(count));
2349 else
2350 result = NULL;
2352 if(result)
2356 Field *fields = result->Fetch();
2357 uint32 item_guid = fields[0].GetUInt32();
2358 uint32 owner = fields[1].GetUInt32();
2359 uint32 owner_acc = fields[2].GetUInt32();
2360 std::string owner_name = fields[3].GetCppString();
2362 char const* item_pos = "[in auction]";
2364 PSendSysMessage(LANG_ITEMLIST_AUCTION, item_guid, owner_name.c_str(), owner, owner_acc,item_pos);
2365 } while (result->NextRow());
2367 delete result;
2370 // guild bank case
2371 uint32 guild_count = 0;
2372 result=CharacterDatabase.PQuery("SELECT COUNT(item_entry) FROM guild_bank_item WHERE item_entry='%u'",item_id);
2373 if(result)
2375 guild_count = (*result)[0].GetUInt32();
2376 delete result;
2379 result=CharacterDatabase.PQuery(
2380 // 0 1 2
2381 "SELECT gi.item_guid, gi.guildid, guild.name "
2382 "FROM guild_bank_item AS gi, guild WHERE gi.item_entry='%u' AND gi.guildid = guild.guildid LIMIT %u ",
2383 item_id,uint32(count));
2385 if(result)
2389 Field *fields = result->Fetch();
2390 uint32 item_guid = fields[0].GetUInt32();
2391 uint32 guild_guid = fields[1].GetUInt32();
2392 std::string guild_name = fields[2].GetCppString();
2394 char const* item_pos = "[in guild bank]";
2396 PSendSysMessage(LANG_ITEMLIST_GUILD,item_guid,guild_name.c_str(),guild_guid,item_pos);
2397 } while (result->NextRow());
2399 int64 res_count = result->GetRowCount();
2401 delete result;
2403 if(count > res_count)
2404 count-=res_count;
2405 else if(count)
2406 count = 0;
2409 if(inv_count+mail_count+auc_count+guild_count == 0)
2411 SendSysMessage(LANG_COMMAND_NOITEMFOUND);
2412 SetSentErrorMessage(true);
2413 return false;
2416 PSendSysMessage(LANG_COMMAND_LISTITEMMESSAGE,item_id,inv_count+mail_count+auc_count+guild_count,inv_count,mail_count,auc_count,guild_count);
2418 return true;
2421 bool ChatHandler::HandleListObjectCommand(const char* args)
2423 if(!*args)
2424 return false;
2426 // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r
2427 char* cId = extractKeyFromLink((char*)args,"Hgameobject_entry");
2428 if(!cId)
2429 return false;
2431 uint32 go_id = atol(cId);
2432 if(!go_id)
2434 PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id);
2435 SetSentErrorMessage(true);
2436 return false;
2439 GameObjectInfo const * gInfo = objmgr.GetGameObjectInfo(go_id);
2440 if(!gInfo)
2442 PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id);
2443 SetSentErrorMessage(true);
2444 return false;
2447 char* c_count = strtok(NULL, " ");
2448 int count = c_count ? atol(c_count) : 10;
2450 if(count < 0)
2451 return false;
2453 QueryResult *result;
2455 uint32 obj_count = 0;
2456 result=WorldDatabase.PQuery("SELECT COUNT(guid) FROM gameobject WHERE id='%u'",go_id);
2457 if(result)
2459 obj_count = (*result)[0].GetUInt32();
2460 delete result;
2463 if(m_session)
2465 Player* pl = m_session->GetPlayer();
2466 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",
2467 pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),go_id,uint32(count));
2469 else
2470 result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map FROM gameobject WHERE id = '%u' LIMIT %u",
2471 go_id,uint32(count));
2473 if (result)
2477 Field *fields = result->Fetch();
2478 uint32 guid = fields[0].GetUInt32();
2479 float x = fields[1].GetFloat();
2480 float y = fields[2].GetFloat();
2481 float z = fields[3].GetFloat();
2482 int mapid = fields[4].GetUInt16();
2484 if (m_session)
2485 PSendSysMessage(LANG_GO_LIST_CHAT, guid, guid, gInfo->name, x, y, z, mapid);
2486 else
2487 PSendSysMessage(LANG_GO_LIST_CONSOLE, guid, gInfo->name, x, y, z, mapid);
2488 } while (result->NextRow());
2490 delete result;
2493 PSendSysMessage(LANG_COMMAND_LISTOBJMESSAGE,go_id,obj_count);
2494 return true;
2497 bool ChatHandler::HandleListCreatureCommand(const char* args)
2499 if(!*args)
2500 return false;
2502 // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
2503 char* cId = extractKeyFromLink((char*)args,"Hcreature_entry");
2504 if(!cId)
2505 return false;
2507 uint32 cr_id = atol(cId);
2508 if(!cr_id)
2510 PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id);
2511 SetSentErrorMessage(true);
2512 return false;
2515 CreatureInfo const* cInfo = objmgr.GetCreatureTemplate(cr_id);
2516 if(!cInfo)
2518 PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id);
2519 SetSentErrorMessage(true);
2520 return false;
2523 char* c_count = strtok(NULL, " ");
2524 int count = c_count ? atol(c_count) : 10;
2526 if(count < 0)
2527 return false;
2529 QueryResult *result;
2531 uint32 cr_count = 0;
2532 result=WorldDatabase.PQuery("SELECT COUNT(guid) FROM creature WHERE id='%u'",cr_id);
2533 if(result)
2535 cr_count = (*result)[0].GetUInt32();
2536 delete result;
2539 if(m_session)
2541 Player* pl = m_session->GetPlayer();
2542 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",
2543 pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), cr_id,uint32(count));
2545 else
2546 result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map FROM creature WHERE id = '%u' LIMIT %u",
2547 cr_id,uint32(count));
2549 if (result)
2553 Field *fields = result->Fetch();
2554 uint32 guid = fields[0].GetUInt32();
2555 float x = fields[1].GetFloat();
2556 float y = fields[2].GetFloat();
2557 float z = fields[3].GetFloat();
2558 int mapid = fields[4].GetUInt16();
2560 if (m_session)
2561 PSendSysMessage(LANG_CREATURE_LIST_CHAT, guid, guid, cInfo->Name, x, y, z, mapid);
2562 else
2563 PSendSysMessage(LANG_CREATURE_LIST_CONSOLE, guid, cInfo->Name, x, y, z, mapid);
2564 } while (result->NextRow());
2566 delete result;
2569 PSendSysMessage(LANG_COMMAND_LISTCREATUREMESSAGE,cr_id,cr_count);
2570 return true;
2573 bool ChatHandler::HandleLookupItemCommand(const char* args)
2575 if(!*args)
2576 return false;
2578 std::string namepart = args;
2579 std::wstring wnamepart;
2581 // converting string that we try to find to lower case
2582 if(!Utf8toWStr(namepart,wnamepart))
2583 return false;
2585 wstrToLower(wnamepart);
2587 uint32 counter = 0;
2589 // Search in `item_template`
2590 for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
2592 ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype >(id);
2593 if(!pProto)
2594 continue;
2596 int loc_idx = GetSessionDbLocaleIndex();
2597 if ( loc_idx >= 0 )
2599 ItemLocale const *il = objmgr.GetItemLocale(pProto->ItemId);
2600 if (il)
2602 if (il->Name.size() > loc_idx && !il->Name[loc_idx].empty())
2604 std::string name = il->Name[loc_idx];
2606 if (Utf8FitTo(name, wnamepart))
2608 if (m_session)
2609 PSendSysMessage(LANG_ITEM_LIST_CHAT, id, id, name.c_str());
2610 else
2611 PSendSysMessage(LANG_ITEM_LIST_CONSOLE, id, name.c_str());
2612 ++counter;
2613 continue;
2619 std::string name = pProto->Name1;
2620 if(name.empty())
2621 continue;
2623 if (Utf8FitTo(name, wnamepart))
2625 if (m_session)
2626 PSendSysMessage(LANG_ITEM_LIST_CHAT, id, id, name.c_str());
2627 else
2628 PSendSysMessage(LANG_ITEM_LIST_CONSOLE, id, name.c_str());
2629 ++counter;
2633 if (counter==0)
2634 SendSysMessage(LANG_COMMAND_NOITEMFOUND);
2636 return true;
2639 bool ChatHandler::HandleLookupItemSetCommand(const char* args)
2641 if(!*args)
2642 return false;
2644 std::string namepart = args;
2645 std::wstring wnamepart;
2647 if(!Utf8toWStr(namepart,wnamepart))
2648 return false;
2650 // converting string that we try to find to lower case
2651 wstrToLower( wnamepart );
2653 uint32 counter = 0; // Counter for figure out that we found smth.
2655 // Search in ItemSet.dbc
2656 for (uint32 id = 0; id < sItemSetStore.GetNumRows(); id++)
2658 ItemSetEntry const *set = sItemSetStore.LookupEntry(id);
2659 if(set)
2661 int loc = GetSessionDbcLocale();
2662 std::string name = set->name[loc];
2663 if(name.empty())
2664 continue;
2666 if (!Utf8FitTo(name, wnamepart))
2668 loc = 0;
2669 for(; loc < MAX_LOCALE; ++loc)
2671 if(loc==GetSessionDbcLocale())
2672 continue;
2674 name = set->name[loc];
2675 if(name.empty())
2676 continue;
2678 if (Utf8FitTo(name, wnamepart))
2679 break;
2683 if(loc < MAX_LOCALE)
2685 // send item set in "id - [namedlink locale]" format
2686 if (m_session)
2687 PSendSysMessage(LANG_ITEMSET_LIST_CHAT,id,id,name.c_str(),localeNames[loc]);
2688 else
2689 PSendSysMessage(LANG_ITEMSET_LIST_CONSOLE,id,name.c_str(),localeNames[loc]);
2690 ++counter;
2694 if (counter == 0) // if counter == 0 then we found nth
2695 SendSysMessage(LANG_COMMAND_NOITEMSETFOUND);
2696 return true;
2699 bool ChatHandler::HandleLookupSkillCommand(const char* args)
2701 if(!*args)
2702 return false;
2704 // can be NULL in console call
2705 Player* target = getSelectedPlayer();
2707 std::string namepart = args;
2708 std::wstring wnamepart;
2710 if(!Utf8toWStr(namepart,wnamepart))
2711 return false;
2713 // converting string that we try to find to lower case
2714 wstrToLower( wnamepart );
2716 uint32 counter = 0; // Counter for figure out that we found smth.
2718 // Search in SkillLine.dbc
2719 for (uint32 id = 0; id < sSkillLineStore.GetNumRows(); id++)
2721 SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(id);
2722 if(skillInfo)
2724 int loc = GetSessionDbcLocale();
2725 std::string name = skillInfo->name[loc];
2726 if(name.empty())
2727 continue;
2729 if (!Utf8FitTo(name, wnamepart))
2731 loc = 0;
2732 for(; loc < MAX_LOCALE; ++loc)
2734 if(loc==GetSessionDbcLocale())
2735 continue;
2737 name = skillInfo->name[loc];
2738 if(name.empty())
2739 continue;
2741 if (Utf8FitTo(name, wnamepart))
2742 break;
2746 if(loc < MAX_LOCALE)
2748 char valStr[50] = "";
2749 char const* knownStr = "";
2750 if(target && target->HasSkill(id))
2752 knownStr = GetMangosString(LANG_KNOWN);
2753 uint32 curValue = target->GetPureSkillValue(id);
2754 uint32 maxValue = target->GetPureMaxSkillValue(id);
2755 uint32 permValue = target->GetSkillPermBonusValue(id);
2756 uint32 tempValue = target->GetSkillTempBonusValue(id);
2758 char const* valFormat = GetMangosString(LANG_SKILL_VALUES);
2759 snprintf(valStr,50,valFormat,curValue,maxValue,permValue,tempValue);
2762 // send skill in "id - [namedlink locale]" format
2763 if (m_session)
2764 PSendSysMessage(LANG_SKILL_LIST_CHAT,id,id,name.c_str(),localeNames[loc],knownStr,valStr);
2765 else
2766 PSendSysMessage(LANG_SKILL_LIST_CONSOLE,id,name.c_str(),localeNames[loc],knownStr,valStr);
2768 ++counter;
2772 if (counter == 0) // if counter == 0 then we found nth
2773 SendSysMessage(LANG_COMMAND_NOSKILLFOUND);
2774 return true;
2777 bool ChatHandler::HandleLookupSpellCommand(const char* args)
2779 if(!*args)
2780 return false;
2782 // can be NULL at console call
2783 Player* target = getSelectedPlayer();
2785 std::string namepart = args;
2786 std::wstring wnamepart;
2788 if(!Utf8toWStr(namepart,wnamepart))
2789 return false;
2791 // converting string that we try to find to lower case
2792 wstrToLower( wnamepart );
2794 uint32 counter = 0; // Counter for figure out that we found smth.
2796 // Search in Spell.dbc
2797 for (uint32 id = 0; id < sSpellStore.GetNumRows(); id++)
2799 SpellEntry const *spellInfo = sSpellStore.LookupEntry(id);
2800 if(spellInfo)
2802 int loc = GetSessionDbcLocale();
2803 std::string name = spellInfo->SpellName[loc];
2804 if(name.empty())
2805 continue;
2807 if (!Utf8FitTo(name, wnamepart))
2809 loc = 0;
2810 for(; loc < MAX_LOCALE; ++loc)
2812 if(loc==GetSessionDbcLocale())
2813 continue;
2815 name = spellInfo->SpellName[loc];
2816 if(name.empty())
2817 continue;
2819 if (Utf8FitTo(name, wnamepart))
2820 break;
2824 if(loc < MAX_LOCALE)
2826 bool known = target && target->HasSpell(id);
2827 bool learn = (spellInfo->Effect[0] == SPELL_EFFECT_LEARN_SPELL);
2829 uint32 talentCost = GetTalentSpellCost(id);
2831 bool talent = (talentCost > 0);
2832 bool passive = IsPassiveSpell(id);
2833 bool active = target && target->HasAura(id);
2835 // unit32 used to prevent interpreting uint8 as char at output
2836 // find rank of learned spell for learning spell, or talent rank
2837 uint32 rank = talentCost ? talentCost : spellmgr.GetSpellRank(learn ? spellInfo->EffectTriggerSpell[0] : id);
2839 // send spell in "id - [name, rank N] [talent] [passive] [learn] [known]" format
2840 std::ostringstream ss;
2841 if (m_session)
2842 ss << id << " - |cffffffff|Hspell:" << id << "|h[" << name;
2843 else
2844 ss << id << " - " << name;
2846 // include rank in link name
2847 if(rank)
2848 ss << GetMangosString(LANG_SPELL_RANK) << rank;
2850 if (m_session)
2851 ss << " " << localeNames[loc] << "]|h|r";
2852 else
2853 ss << " " << localeNames[loc];
2855 if(talent)
2856 ss << GetMangosString(LANG_TALENT);
2857 if(passive)
2858 ss << GetMangosString(LANG_PASSIVE);
2859 if(learn)
2860 ss << GetMangosString(LANG_LEARN);
2861 if(known)
2862 ss << GetMangosString(LANG_KNOWN);
2863 if(active)
2864 ss << GetMangosString(LANG_ACTIVE);
2866 SendSysMessage(ss.str().c_str());
2868 ++counter;
2872 if (counter == 0) // if counter == 0 then we found nth
2873 SendSysMessage(LANG_COMMAND_NOSPELLFOUND);
2874 return true;
2877 bool ChatHandler::HandleLookupQuestCommand(const char* args)
2879 if(!*args)
2880 return false;
2882 // can be NULL at console call
2883 Player* target = getSelectedPlayer();
2885 std::string namepart = args;
2886 std::wstring wnamepart;
2888 // converting string that we try to find to lower case
2889 if(!Utf8toWStr(namepart,wnamepart))
2890 return false;
2892 wstrToLower(wnamepart);
2894 uint32 counter = 0 ;
2896 ObjectMgr::QuestMap const& qTemplates = objmgr.GetQuestTemplates();
2897 for (ObjectMgr::QuestMap::const_iterator iter = qTemplates.begin(); iter != qTemplates.end(); ++iter)
2899 Quest * qinfo = iter->second;
2901 int loc_idx = GetSessionDbLocaleIndex();
2902 if ( loc_idx >= 0 )
2904 QuestLocale const *il = objmgr.GetQuestLocale(qinfo->GetQuestId());
2905 if (il)
2907 if (il->Title.size() > loc_idx && !il->Title[loc_idx].empty())
2909 std::string title = il->Title[loc_idx];
2911 if (Utf8FitTo(title, wnamepart))
2913 char const* statusStr = "";
2915 if(target)
2917 QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId());
2919 if(status == QUEST_STATUS_COMPLETE)
2921 if(target->GetQuestRewardStatus(qinfo->GetQuestId()))
2922 statusStr = GetMangosString(LANG_COMMAND_QUEST_REWARDED);
2923 else
2924 statusStr = GetMangosString(LANG_COMMAND_QUEST_COMPLETE);
2926 else if(status == QUEST_STATUS_INCOMPLETE)
2927 statusStr = GetMangosString(LANG_COMMAND_QUEST_ACTIVE);
2930 if (m_session)
2931 PSendSysMessage(LANG_QUEST_LIST_CHAT,qinfo->GetQuestId(),qinfo->GetQuestId(),title.c_str(),statusStr);
2932 else
2933 PSendSysMessage(LANG_QUEST_LIST_CONSOLE,qinfo->GetQuestId(),title.c_str(),statusStr);
2934 ++counter;
2935 continue;
2941 std::string title = qinfo->GetTitle();
2942 if(title.empty())
2943 continue;
2945 if (Utf8FitTo(title, wnamepart))
2947 char const* statusStr = "";
2949 if(target)
2951 QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId());
2953 if(status == QUEST_STATUS_COMPLETE)
2955 if(target->GetQuestRewardStatus(qinfo->GetQuestId()))
2956 statusStr = GetMangosString(LANG_COMMAND_QUEST_REWARDED);
2957 else
2958 statusStr = GetMangosString(LANG_COMMAND_QUEST_COMPLETE);
2960 else if(status == QUEST_STATUS_INCOMPLETE)
2961 statusStr = GetMangosString(LANG_COMMAND_QUEST_ACTIVE);
2964 if (m_session)
2965 PSendSysMessage(LANG_QUEST_LIST_CHAT,qinfo->GetQuestId(),qinfo->GetQuestId(),title.c_str(),statusStr);
2966 else
2967 PSendSysMessage(LANG_QUEST_LIST_CONSOLE,qinfo->GetQuestId(),title.c_str(),statusStr);
2969 ++counter;
2973 if (counter==0)
2974 SendSysMessage(LANG_COMMAND_NOQUESTFOUND);
2976 return true;
2979 bool ChatHandler::HandleLookupCreatureCommand(const char* args)
2981 if (!*args)
2982 return false;
2984 std::string namepart = args;
2985 std::wstring wnamepart;
2987 // converting string that we try to find to lower case
2988 if (!Utf8toWStr (namepart,wnamepart))
2989 return false;
2991 wstrToLower (wnamepart);
2993 uint32 counter = 0;
2995 for (uint32 id = 0; id< sCreatureStorage.MaxEntry; ++id)
2997 CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo> (id);
2998 if(!cInfo)
2999 continue;
3001 int loc_idx = GetSessionDbLocaleIndex();
3002 if (loc_idx >= 0)
3004 CreatureLocale const *cl = objmgr.GetCreatureLocale (id);
3005 if (cl)
3007 if (cl->Name.size() > loc_idx && !cl->Name[loc_idx].empty ())
3009 std::string name = cl->Name[loc_idx];
3011 if (Utf8FitTo (name, wnamepart))
3013 if (m_session)
3014 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CHAT, id, id, name.c_str ());
3015 else
3016 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CONSOLE, id, name.c_str ());
3017 ++counter;
3018 continue;
3024 std::string name = cInfo->Name;
3025 if (name.empty ())
3026 continue;
3028 if (Utf8FitTo(name, wnamepart))
3030 if (m_session)
3031 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CHAT, id, id, name.c_str ());
3032 else
3033 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CONSOLE, id, name.c_str ());
3034 ++counter;
3038 if (counter==0)
3039 SendSysMessage (LANG_COMMAND_NOCREATUREFOUND);
3041 return true;
3044 bool ChatHandler::HandleLookupObjectCommand(const char* args)
3046 if(!*args)
3047 return false;
3049 std::string namepart = args;
3050 std::wstring wnamepart;
3052 // converting string that we try to find to lower case
3053 if(!Utf8toWStr(namepart,wnamepart))
3054 return false;
3056 wstrToLower(wnamepart);
3058 uint32 counter = 0;
3060 for (uint32 id = 0; id< sGOStorage.MaxEntry; id++ )
3062 GameObjectInfo const* gInfo = sGOStorage.LookupEntry<GameObjectInfo>(id);
3063 if(!gInfo)
3064 continue;
3066 int loc_idx = GetSessionDbLocaleIndex();
3067 if ( loc_idx >= 0 )
3069 GameObjectLocale const *gl = objmgr.GetGameObjectLocale(id);
3070 if (gl)
3072 if (gl->Name.size() > loc_idx && !gl->Name[loc_idx].empty())
3074 std::string name = gl->Name[loc_idx];
3076 if (Utf8FitTo(name, wnamepart))
3078 if (m_session)
3079 PSendSysMessage(LANG_GO_ENTRY_LIST_CHAT, id, id, name.c_str());
3080 else
3081 PSendSysMessage(LANG_GO_ENTRY_LIST_CONSOLE, id, name.c_str());
3082 ++counter;
3083 continue;
3089 std::string name = gInfo->name;
3090 if(name.empty())
3091 continue;
3093 if(Utf8FitTo(name, wnamepart))
3095 if (m_session)
3096 PSendSysMessage(LANG_GO_ENTRY_LIST_CHAT, id, id, name.c_str());
3097 else
3098 PSendSysMessage(LANG_GO_ENTRY_LIST_CONSOLE, id, name.c_str());
3099 ++counter;
3103 if(counter==0)
3104 SendSysMessage(LANG_COMMAND_NOGAMEOBJECTFOUND);
3106 return true;
3109 bool ChatHandler::HandleLookupTaxiNodeCommand(const char * args)
3111 if(!*args)
3112 return false;
3114 std::string namepart = args;
3115 std::wstring wnamepart;
3117 if(!Utf8toWStr(namepart,wnamepart))
3118 return false;
3120 // converting string that we try to find to lower case
3121 wstrToLower( wnamepart );
3123 uint32 counter = 0; // Counter for figure out that we found smth.
3125 // Search in TaxiNodes.dbc
3126 for (uint32 id = 0; id < sTaxiNodesStore.GetNumRows(); id++)
3128 TaxiNodesEntry const *nodeEntry = sTaxiNodesStore.LookupEntry(id);
3129 if(nodeEntry)
3131 int loc = GetSessionDbcLocale();
3132 std::string name = nodeEntry->name[loc];
3133 if(name.empty())
3134 continue;
3136 if (!Utf8FitTo(name, wnamepart))
3138 loc = 0;
3139 for(; loc < MAX_LOCALE; ++loc)
3141 if(loc==GetSessionDbcLocale())
3142 continue;
3144 name = nodeEntry->name[loc];
3145 if(name.empty())
3146 continue;
3148 if (Utf8FitTo(name, wnamepart))
3149 break;
3153 if(loc < MAX_LOCALE)
3155 // send taxinode in "id - [name] (Map:m X:x Y:y Z:z)" format
3156 if (m_session)
3157 PSendSysMessage (LANG_TAXINODE_ENTRY_LIST_CHAT, id, id, name.c_str(),localeNames[loc],
3158 nodeEntry->map_id,nodeEntry->x,nodeEntry->y,nodeEntry->z);
3159 else
3160 PSendSysMessage (LANG_TAXINODE_ENTRY_LIST_CONSOLE, id, name.c_str(), localeNames[loc],
3161 nodeEntry->map_id,nodeEntry->x,nodeEntry->y,nodeEntry->z);
3162 ++counter;
3166 if (counter == 0) // if counter == 0 then we found nth
3167 SendSysMessage(LANG_COMMAND_NOSPELLFOUND);
3168 return true;
3171 /** \brief GM command level 3 - Create a guild.
3173 * This command allows a GM (level 3) to create a guild.
3175 * The "args" parameter contains the name of the guild leader
3176 * and then the name of the guild.
3179 bool ChatHandler::HandleGuildCreateCommand(const char* args)
3181 if(!*args)
3182 return false;
3184 // if not guild name only (in "") then player name
3185 Player* target;
3186 if(!extractPlayerTarget(*args!='"' ? (char*)args : NULL, &target))
3187 return false;
3189 char* tailStr = *args!='"' ? strtok(NULL, "") : (char*)args;
3190 if(!tailStr)
3191 return false;
3193 char* guildStr = extractQuotedArg(tailStr);
3194 if(!guildStr)
3195 return false;
3197 std::string guildname = guildStr;
3199 if (target->GetGuildId())
3201 SendSysMessage (LANG_PLAYER_IN_GUILD);
3202 return true;
3205 Guild *guild = new Guild;
3206 if (!guild->create (target,guildname))
3208 delete guild;
3209 SendSysMessage (LANG_GUILD_NOT_CREATED);
3210 SetSentErrorMessage (true);
3211 return false;
3214 objmgr.AddGuild (guild);
3215 return true;
3218 bool ChatHandler::HandleGuildInviteCommand(const char *args)
3220 if(!*args)
3221 return false;
3223 // if not guild name only (in "") then player name
3224 uint64 target_guid;
3225 if(!extractPlayerTarget(*args!='"' ? (char*)args : NULL, NULL, &target_guid))
3226 return false;
3228 char* tailStr = *args!='"' ? strtok(NULL, "") : (char*)args;
3229 if(!tailStr)
3230 return false;
3232 char* guildStr = extractQuotedArg(tailStr);
3233 if(!guildStr)
3234 return false;
3236 std::string glName = guildStr;
3237 Guild* targetGuild = objmgr.GetGuildByName (glName);
3238 if (!targetGuild)
3239 return false;
3241 // player's guild membership checked in AddMember before add
3242 if (!targetGuild->AddMember (target_guid,targetGuild->GetLowestRank ()))
3243 return false;
3245 return true;
3248 bool ChatHandler::HandleGuildUninviteCommand(const char *args)
3250 Player* target;
3251 uint64 target_guid;
3252 if(!extractPlayerTarget((char*)args,&target,&target_guid))
3253 return false;
3255 uint32 glId = target ? target->GetGuildId () : Player::GetGuildIdFromDB (target_guid);
3256 if (!glId)
3257 return false;
3259 Guild* targetGuild = objmgr.GetGuildById (glId);
3260 if (!targetGuild)
3261 return false;
3263 targetGuild->DelMember (target_guid);
3264 return true;
3267 bool ChatHandler::HandleGuildRankCommand(const char *args)
3269 char* nameStr;
3270 char* rankStr;
3271 extractOptFirstArg((char*)args,&nameStr,&rankStr);
3272 if(!rankStr)
3273 return false;
3275 Player* target;
3276 uint64 target_guid;
3277 std::string target_name;
3278 if(!extractPlayerTarget(nameStr,&target,&target_guid,&target_name))
3279 return false;
3281 uint32 glId = target ? target->GetGuildId () : Player::GetGuildIdFromDB (target_guid);
3282 if (!glId)
3283 return false;
3285 Guild* targetGuild = objmgr.GetGuildById (glId);
3286 if (!targetGuild)
3287 return false;
3289 uint32 newrank = uint32 (atoi (rankStr));
3290 if (newrank > targetGuild->GetLowestRank ())
3291 return false;
3293 targetGuild->ChangeRank (target_guid,newrank);
3294 return true;
3297 bool ChatHandler::HandleGuildDeleteCommand(const char* args)
3299 if (!*args)
3300 return false;
3302 char* guildStr = extractQuotedArg((char*)args);
3303 if(!guildStr)
3304 return false;
3306 std::string gld = guildStr;
3308 Guild* targetGuild = objmgr.GetGuildByName (gld);
3309 if (!targetGuild)
3310 return false;
3312 targetGuild->Disband ();
3314 return true;
3317 bool ChatHandler::HandleGetDistanceCommand(const char* args)
3319 WorldObject* obj = NULL;
3321 if (*args)
3323 uint64 guid = extractGuidFromLink((char*)args);
3324 if(guid)
3325 obj = (WorldObject*)ObjectAccessor::GetObjectByTypeMask(*m_session->GetPlayer(),guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
3327 if(!obj)
3329 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3330 SetSentErrorMessage(true);
3331 return false;
3334 else
3336 obj = getSelectedUnit();
3338 if(!obj)
3340 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3341 SetSentErrorMessage(true);
3342 return false;
3346 PSendSysMessage(LANG_DISTANCE, m_session->GetPlayer()->GetDistance(obj),m_session->GetPlayer()->GetDistance2d(obj));
3348 return true;
3351 bool ChatHandler::HandleDieCommand(const char* /*args*/)
3353 Unit* target = getSelectedUnit();
3355 if(!target || !m_session->GetPlayer()->GetSelection())
3357 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3358 SetSentErrorMessage(true);
3359 return false;
3362 if(target->GetTypeId()==TYPEID_PLAYER)
3364 if(HasLowerSecurity((Player*)target,0,false))
3365 return false;
3368 if( target->isAlive() )
3370 m_session->GetPlayer()->DealDamage(target, target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
3373 return true;
3376 bool ChatHandler::HandleDamageCommand(const char * args)
3378 if (!*args)
3379 return false;
3381 Unit* target = getSelectedUnit();
3383 if (!target || !m_session->GetPlayer()->GetSelection())
3385 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3386 SetSentErrorMessage(true);
3387 return false;
3390 if (!target->isAlive())
3391 return true;
3393 char* damageStr = strtok((char*)args, " ");
3394 if (!damageStr)
3395 return false;
3397 int32 damage_int = atoi((char*)damageStr);
3398 if(damage_int <=0)
3399 return true;
3401 uint32 damage = damage_int;
3403 char* schoolStr = strtok((char*)NULL, " ");
3405 // flat melee damage without resistence/etc reduction
3406 if (!schoolStr)
3408 m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
3409 if (target != m_session->GetPlayer())
3410 m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, SPELL_SCHOOL_MASK_NORMAL, damage, 0, 0, VICTIMSTATE_NORMAL, 0);
3411 return true;
3414 uint32 school = schoolStr ? atoi((char*)schoolStr) : SPELL_SCHOOL_NORMAL;
3415 if(school >= MAX_SPELL_SCHOOL)
3416 return false;
3418 SpellSchoolMask schoolmask = SpellSchoolMask(1 << school);
3420 if ( schoolmask & SPELL_SCHOOL_MASK_NORMAL )
3421 damage = m_session->GetPlayer()->CalcArmorReducedDamage(target, damage);
3423 char* spellStr = strtok((char*)NULL, " ");
3425 // melee damage by specific school
3426 if (!spellStr)
3428 uint32 absorb = 0;
3429 uint32 resist = 0;
3431 m_session->GetPlayer()->CalcAbsorbResist(target,schoolmask, SPELL_DIRECT_DAMAGE, damage, &absorb, &resist);
3433 if (damage <= absorb + resist)
3434 return true;
3436 damage -= absorb + resist;
3438 m_session->GetPlayer()->DealDamageMods(target,damage,&absorb);
3439 m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, schoolmask, NULL, false);
3440 m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, schoolmask, damage, absorb, resist, VICTIMSTATE_NORMAL, 0);
3441 return true;
3444 // non-melee damage
3446 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
3447 uint32 spellid = extractSpellIdFromLink((char*)args);
3448 if (!spellid || !sSpellStore.LookupEntry(spellid))
3449 return false;
3451 m_session->GetPlayer()->SpellNonMeleeDamageLog(target, spellid, damage);
3452 return true;
3455 bool ChatHandler::HandleModifyArenaCommand(const char * args)
3457 if (!*args)
3458 return false;
3460 Player *target = getSelectedPlayer();
3461 if(!target)
3463 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3464 SetSentErrorMessage(true);
3465 return false;
3468 int32 amount = (uint32)atoi(args);
3470 target->ModifyArenaPoints(amount);
3472 PSendSysMessage(LANG_COMMAND_MODIFY_ARENA, GetNameLink(target).c_str(), target->GetArenaPoints());
3474 return true;
3477 bool ChatHandler::HandleReviveCommand(const char* args)
3479 Player* target;
3480 uint64 target_guid;
3481 if(!extractPlayerTarget((char*)args,&target,&target_guid))
3482 return false;
3484 if (target)
3486 target->ResurrectPlayer(0.5f);
3487 target->SpawnCorpseBones();
3488 target->SaveToDB();
3490 else
3491 // will resurrected at login without corpse
3492 ObjectAccessor::Instance().ConvertCorpseForPlayer(target_guid);
3494 return true;
3497 bool ChatHandler::HandleAuraCommand(const char* args)
3499 Unit *target = getSelectedUnit();
3500 if(!target)
3502 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3503 SetSentErrorMessage(true);
3504 return false;
3507 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
3508 uint32 spellID = extractSpellIdFromLink((char*)args);
3510 SpellEntry const *spellInfo = sSpellStore.LookupEntry( spellID );
3511 if(spellInfo)
3513 for(uint32 i = 0;i<3;++i)
3515 uint8 eff = spellInfo->Effect[i];
3516 if (eff>=TOTAL_SPELL_EFFECTS)
3517 continue;
3518 if( IsAreaAuraEffect(eff) ||
3519 eff == SPELL_EFFECT_APPLY_AURA ||
3520 eff == SPELL_EFFECT_PERSISTENT_AREA_AURA )
3522 Aura *Aur = CreateAura(spellInfo, i, NULL, target);
3523 target->AddAura(Aur);
3528 return true;
3531 bool ChatHandler::HandleUnAuraCommand(const char* args)
3533 Unit *target = getSelectedUnit();
3534 if(!target)
3536 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3537 SetSentErrorMessage(true);
3538 return false;
3541 std::string argstr = args;
3542 if (argstr == "all")
3544 target->RemoveAllAuras();
3545 return true;
3548 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
3549 uint32 spellID = extractSpellIdFromLink((char*)args);
3550 if(!spellID)
3551 return false;
3553 target->RemoveAurasDueToSpell(spellID);
3555 return true;
3558 bool ChatHandler::HandleLinkGraveCommand(const char* args)
3560 if(!*args)
3561 return false;
3563 char* px = strtok((char*)args, " ");
3564 if (!px)
3565 return false;
3567 uint32 g_id = (uint32)atoi(px);
3569 uint32 g_team;
3571 char* px2 = strtok(NULL, " ");
3573 if (!px2)
3574 g_team = 0;
3575 else if (strncmp(px2,"horde",6)==0)
3576 g_team = HORDE;
3577 else if (strncmp(px2,"alliance",9)==0)
3578 g_team = ALLIANCE;
3579 else
3580 return false;
3582 WorldSafeLocsEntry const* graveyard = sWorldSafeLocsStore.LookupEntry(g_id);
3584 if(!graveyard )
3586 PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST, g_id);
3587 SetSentErrorMessage(true);
3588 return false;
3591 Player* player = m_session->GetPlayer();
3593 uint32 zoneId = player->GetZoneId();
3595 AreaTableEntry const *areaEntry = GetAreaEntryByAreaID(zoneId);
3596 if(!areaEntry || areaEntry->zone !=0 )
3598 PSendSysMessage(LANG_COMMAND_GRAVEYARDWRONGZONE, g_id,zoneId);
3599 SetSentErrorMessage(true);
3600 return false;
3603 if(objmgr.AddGraveYardLink(g_id,zoneId,g_team))
3604 PSendSysMessage(LANG_COMMAND_GRAVEYARDLINKED, g_id,zoneId);
3605 else
3606 PSendSysMessage(LANG_COMMAND_GRAVEYARDALRLINKED, g_id,zoneId);
3608 return true;
3611 bool ChatHandler::HandleNearGraveCommand(const char* args)
3613 uint32 g_team;
3615 size_t argslen = strlen(args);
3617 if(!*args)
3618 g_team = 0;
3619 else if (strncmp((char*)args,"horde",argslen)==0)
3620 g_team = HORDE;
3621 else if (strncmp((char*)args,"alliance",argslen)==0)
3622 g_team = ALLIANCE;
3623 else
3624 return false;
3626 Player* player = m_session->GetPlayer();
3627 uint32 zone_id = player->GetZoneId();
3629 WorldSafeLocsEntry const* graveyard = objmgr.GetClosestGraveYard(
3630 player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(),player->GetMapId(),g_team);
3632 if(graveyard)
3634 uint32 g_id = graveyard->ID;
3636 GraveYardData const* data = objmgr.FindGraveYardData(g_id,zone_id);
3637 if (!data)
3639 PSendSysMessage(LANG_COMMAND_GRAVEYARDERROR,g_id);
3640 SetSentErrorMessage(true);
3641 return false;
3644 g_team = data->team;
3646 std::string team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_NOTEAM);
3648 if(g_team == 0)
3649 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ANY);
3650 else if(g_team == HORDE)
3651 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_HORDE);
3652 else if(g_team == ALLIANCE)
3653 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ALLIANCE);
3655 PSendSysMessage(LANG_COMMAND_GRAVEYARDNEAREST, g_id,team_name.c_str(),zone_id);
3657 else
3659 std::string team_name;
3661 if(g_team == 0)
3662 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ANY);
3663 else if(g_team == HORDE)
3664 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_HORDE);
3665 else if(g_team == ALLIANCE)
3666 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ALLIANCE);
3668 if(g_team == ~uint32(0))
3669 PSendSysMessage(LANG_COMMAND_ZONENOGRAVEYARDS, zone_id);
3670 else
3671 PSendSysMessage(LANG_COMMAND_ZONENOGRAFACTION, zone_id,team_name.c_str());
3674 return true;
3677 //-----------------------Npc Commands-----------------------
3678 bool ChatHandler::HandleNpcAllowMovementCommand(const char* /*args*/)
3680 if(sWorld.getAllowMovement())
3682 sWorld.SetAllowMovement(false);
3683 SendSysMessage(LANG_CREATURE_MOVE_DISABLED);
3685 else
3687 sWorld.SetAllowMovement(true);
3688 SendSysMessage(LANG_CREATURE_MOVE_ENABLED);
3690 return true;
3693 bool ChatHandler::HandleNpcChangeEntryCommand(const char *args)
3695 if (!*args)
3696 return false;
3698 uint32 newEntryNum = atoi(args);
3699 if(!newEntryNum)
3700 return false;
3702 Unit* unit = getSelectedUnit();
3703 if(!unit || unit->GetTypeId() != TYPEID_UNIT)
3705 SendSysMessage(LANG_SELECT_CREATURE);
3706 SetSentErrorMessage(true);
3707 return false;
3709 Creature* creature = (Creature*)unit;
3710 if(creature->UpdateEntry(newEntryNum))
3711 SendSysMessage(LANG_DONE);
3712 else
3713 SendSysMessage(LANG_ERROR);
3714 return true;
3717 bool ChatHandler::HandleNpcInfoCommand(const char* /*args*/)
3719 Creature* target = getSelectedCreature();
3721 if(!target)
3723 SendSysMessage(LANG_SELECT_CREATURE);
3724 SetSentErrorMessage(true);
3725 return false;
3728 uint32 faction = target->getFaction();
3729 uint32 npcflags = target->GetUInt32Value(UNIT_NPC_FLAGS);
3730 uint32 displayid = target->GetDisplayId();
3731 uint32 nativeid = target->GetNativeDisplayId();
3732 uint32 Entry = target->GetEntry();
3733 CreatureInfo const* cInfo = target->GetCreatureInfo();
3735 int32 curRespawnDelay = target->GetRespawnTimeEx()-time(NULL);
3736 if(curRespawnDelay < 0)
3737 curRespawnDelay = 0;
3738 std::string curRespawnDelayStr = secsToTimeString(curRespawnDelay,true);
3739 std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(),true);
3741 PSendSysMessage(LANG_NPCINFO_CHAR, target->GetDBTableGUIDLow(), faction, npcflags, Entry, displayid, nativeid);
3742 PSendSysMessage(LANG_NPCINFO_LEVEL, target->getLevel());
3743 PSendSysMessage(LANG_NPCINFO_HEALTH,target->GetCreateHealth(), target->GetMaxHealth(), target->GetHealth());
3744 PSendSysMessage(LANG_NPCINFO_FLAGS, target->GetUInt32Value(UNIT_FIELD_FLAGS), target->GetUInt32Value(UNIT_DYNAMIC_FLAGS), target->getFaction());
3745 PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES, defRespawnDelayStr.c_str(),curRespawnDelayStr.c_str());
3746 PSendSysMessage(LANG_NPCINFO_LOOT, cInfo->lootid,cInfo->pickpocketLootId,cInfo->SkinLootId);
3747 PSendSysMessage(LANG_NPCINFO_DUNGEON_ID, target->GetInstanceId());
3748 PSendSysMessage(LANG_NPCINFO_POSITION,float(target->GetPositionX()), float(target->GetPositionY()), float(target->GetPositionZ()));
3750 if ((npcflags & UNIT_NPC_FLAG_VENDOR) )
3752 SendSysMessage(LANG_NPCINFO_VENDOR);
3754 if ((npcflags & UNIT_NPC_FLAG_TRAINER) )
3756 SendSysMessage(LANG_NPCINFO_TRAINER);
3759 return true;
3762 //play npc emote
3763 bool ChatHandler::HandleNpcPlayEmoteCommand(const char* args)
3765 uint32 emote = atoi((char*)args);
3767 Creature* target = getSelectedCreature();
3768 if(!target)
3770 SendSysMessage(LANG_SELECT_CREATURE);
3771 SetSentErrorMessage(true);
3772 return false;
3775 target->SetUInt32Value(UNIT_NPC_EMOTESTATE,emote);
3777 return true;
3780 //TODO: NpcCommands that needs to be fixed :
3782 bool ChatHandler::HandleNpcAddWeaponCommand(const char* /*args*/)
3784 /*if (!*args)
3785 return false;
3787 uint64 guid = m_session->GetPlayer()->GetSelection();
3788 if (guid == 0)
3790 SendSysMessage(LANG_NO_SELECTION);
3791 return true;
3794 Creature *pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
3796 if(!pCreature)
3798 SendSysMessage(LANG_SELECT_CREATURE);
3799 return true;
3802 char* pSlotID = strtok((char*)args, " ");
3803 if (!pSlotID)
3804 return false;
3806 char* pItemID = strtok(NULL, " ");
3807 if (!pItemID)
3808 return false;
3810 uint32 ItemID = atoi(pItemID);
3811 uint32 SlotID = atoi(pSlotID);
3813 ItemPrototype* tmpItem = objmgr.GetItemPrototype(ItemID);
3815 bool added = false;
3816 if(tmpItem)
3818 switch(SlotID)
3820 case 1:
3821 pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, ItemID);
3822 added = true;
3823 break;
3824 case 2:
3825 pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_01, ItemID);
3826 added = true;
3827 break;
3828 case 3:
3829 pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_02, ItemID);
3830 added = true;
3831 break;
3832 default:
3833 PSendSysMessage(LANG_ITEM_SLOT_NOT_EXIST,SlotID);
3834 added = false;
3835 break;
3838 if(added)
3839 PSendSysMessage(LANG_ITEM_ADDED_TO_SLOT,ItemID,tmpItem->Name1,SlotID);
3841 else
3843 PSendSysMessage(LANG_ITEM_NOT_FOUND,ItemID);
3844 return true;
3847 return true;
3849 //----------------------------------------------------------
3851 bool ChatHandler::HandleExploreCheatCommand(const char* args)
3853 if (!*args)
3854 return false;
3856 int flag = atoi((char*)args);
3858 Player *chr = getSelectedPlayer();
3859 if (chr == NULL)
3861 SendSysMessage(LANG_NO_CHAR_SELECTED);
3862 SetSentErrorMessage(true);
3863 return false;
3866 if (flag != 0)
3868 PSendSysMessage(LANG_YOU_SET_EXPLORE_ALL, GetNameLink(chr).c_str());
3869 if (needReportToTarget(chr))
3870 ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_ALL,GetNameLink().c_str());
3872 else
3874 PSendSysMessage(LANG_YOU_SET_EXPLORE_NOTHING, GetNameLink(chr).c_str());
3875 if (needReportToTarget(chr))
3876 ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_NOTHING,GetNameLink().c_str());
3879 for (uint8 i=0; i<128; ++i)
3881 if (flag != 0)
3883 m_session->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i,0xFFFFFFFF);
3885 else
3887 m_session->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i,0);
3891 return true;
3894 bool ChatHandler::HandleHoverCommand(const char* args)
3896 char* px = strtok((char*)args, " ");
3897 uint32 flag;
3898 if (!px)
3899 flag = 1;
3900 else
3901 flag = atoi(px);
3903 m_session->GetPlayer()->SetHover(flag);
3905 if (flag)
3906 SendSysMessage(LANG_HOVER_ENABLED);
3907 else
3908 SendSysMessage(LANG_HOVER_DISABLED);
3910 return true;
3913 void ChatHandler::HandleCharacterLevel(Player* player, uint64 player_guid, uint32 oldlevel, uint32 newlevel)
3915 if(player)
3917 player->GiveLevel(newlevel);
3918 player->InitTalentForLevel();
3919 player->SetUInt32Value(PLAYER_XP,0);
3921 if(needReportToTarget(player))
3923 if(oldlevel == newlevel)
3924 ChatHandler(player).PSendSysMessage(LANG_YOURS_LEVEL_PROGRESS_RESET,GetNameLink().c_str());
3925 else if(oldlevel < newlevel)
3926 ChatHandler(player).PSendSysMessage(LANG_YOURS_LEVEL_UP,GetNameLink().c_str(),newlevel);
3927 else // if(oldlevel > newlevel)
3928 ChatHandler(player).PSendSysMessage(LANG_YOURS_LEVEL_DOWN,GetNameLink().c_str(),newlevel);
3931 else
3933 // update level and XP at level, all other will be updated at loading
3934 Tokens values;
3935 Player::LoadValuesArrayFromDB(values,player_guid);
3936 Player::SetUInt32ValueInArray(values,UNIT_FIELD_LEVEL,newlevel);
3937 Player::SetUInt32ValueInArray(values,PLAYER_XP,0);
3938 Player::SaveValuesArrayInDB(values,player_guid);
3942 bool ChatHandler::HandleCharacterLevelCommand(const char* args)
3944 char* nameStr;
3945 char* levelStr;
3946 extractOptFirstArg((char*)args,&nameStr,&levelStr);
3947 if(!levelStr)
3948 return false;
3950 // exception opt second arg: .character level $name
3951 if(isalpha(levelStr[0]))
3953 nameStr = levelStr;
3954 levelStr = NULL; // current level will used
3957 Player* target;
3958 uint64 target_guid;
3959 std::string target_name;
3960 if(!extractPlayerTarget(nameStr,&target,&target_guid,&target_name))
3961 return false;
3963 int32 oldlevel = target ? target->getLevel() : Player::GetUInt32ValueFromDB(UNIT_FIELD_LEVEL,target_guid);
3964 int32 newlevel = levelStr ? atoi(levelStr) : oldlevel;
3966 if(newlevel < 1)
3967 return false; // invalid level
3969 if(newlevel > STRONG_MAX_LEVEL) // hardcoded maximum level
3970 newlevel = STRONG_MAX_LEVEL;
3972 HandleCharacterLevel(target,target_guid,oldlevel,newlevel);
3974 if(!m_session || m_session->GetPlayer() != target) // including player==NULL
3976 std::string nameLink = playerLink(target_name);
3977 PSendSysMessage(LANG_YOU_CHANGE_LVL,nameLink.c_str(),newlevel);
3980 return true;
3983 bool ChatHandler::HandleLevelUpCommand(const char* args)
3985 char* nameStr;
3986 char* levelStr;
3987 extractOptFirstArg((char*)args,&nameStr,&levelStr);
3989 // exception opt second arg: .character level $name
3990 if(levelStr && isalpha(levelStr[0]))
3992 nameStr = levelStr;
3993 levelStr = NULL; // current level will used
3996 Player* target;
3997 uint64 target_guid;
3998 std::string target_name;
3999 if(!extractPlayerTarget(nameStr,&target,&target_guid,&target_name))
4000 return false;
4002 int32 oldlevel = target ? target->getLevel() : Player::GetUInt32ValueFromDB(UNIT_FIELD_LEVEL,target_guid);
4003 int32 addlevel = levelStr ? atoi(levelStr) : 1;
4004 int32 newlevel = oldlevel + addlevel;
4006 if(newlevel < 1)
4007 newlevel = 1;
4009 if(newlevel > STRONG_MAX_LEVEL) // hardcoded maximum level
4010 newlevel = STRONG_MAX_LEVEL;
4012 HandleCharacterLevel(target,target_guid,oldlevel,newlevel);
4014 if(!m_session || m_session->GetPlayer() != target) // including chr==NULL
4016 std::string nameLink = playerLink(target_name);
4017 PSendSysMessage(LANG_YOU_CHANGE_LVL,nameLink.c_str(),newlevel);
4020 return true;
4023 bool ChatHandler::HandleShowAreaCommand(const char* args)
4025 if (!*args)
4026 return false;
4028 Player *chr = getSelectedPlayer();
4029 if (chr == NULL)
4031 SendSysMessage(LANG_NO_CHAR_SELECTED);
4032 SetSentErrorMessage(true);
4033 return false;
4036 int area = GetAreaFlagByAreaID(atoi((char*)args));
4037 int offset = area / 32;
4038 uint32 val = (uint32)(1 << (area % 32));
4040 if(area<0 || offset >= 128)
4042 SendSysMessage(LANG_BAD_VALUE);
4043 SetSentErrorMessage(true);
4044 return false;
4047 uint32 currFields = chr->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset);
4048 chr->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields | val));
4050 SendSysMessage(LANG_EXPLORE_AREA);
4051 return true;
4054 bool ChatHandler::HandleHideAreaCommand(const char* args)
4056 if (!*args)
4057 return false;
4059 Player *chr = getSelectedPlayer();
4060 if (chr == NULL)
4062 SendSysMessage(LANG_NO_CHAR_SELECTED);
4063 SetSentErrorMessage(true);
4064 return false;
4067 int area = GetAreaFlagByAreaID(atoi((char*)args));
4068 int offset = area / 32;
4069 uint32 val = (uint32)(1 << (area % 32));
4071 if(area<0 || offset >= 128)
4073 SendSysMessage(LANG_BAD_VALUE);
4074 SetSentErrorMessage(true);
4075 return false;
4078 uint32 currFields = chr->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset);
4079 chr->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields ^ val));
4081 SendSysMessage(LANG_UNEXPLORE_AREA);
4082 return true;
4085 bool ChatHandler::HandleDebugUpdate(const char* args)
4087 if(!*args)
4088 return false;
4090 uint32 updateIndex;
4091 uint32 value;
4093 char* pUpdateIndex = strtok((char*)args, " ");
4095 Unit* chr = getSelectedUnit();
4096 if (chr == NULL)
4098 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
4099 SetSentErrorMessage(true);
4100 return false;
4103 if(!pUpdateIndex)
4105 return true;
4107 updateIndex = atoi(pUpdateIndex);
4108 //check updateIndex
4109 if(chr->GetTypeId() == TYPEID_PLAYER)
4111 if (updateIndex>=PLAYER_END) return true;
4113 else
4115 if (updateIndex>=UNIT_END) return true;
4118 char* pvalue = strtok(NULL, " ");
4119 if (!pvalue)
4121 value=chr->GetUInt32Value(updateIndex);
4123 PSendSysMessage(LANG_UPDATE, chr->GetGUIDLow(),updateIndex,value);
4124 return true;
4127 value=atoi(pvalue);
4129 PSendSysMessage(LANG_UPDATE_CHANGE, chr->GetGUIDLow(),updateIndex,value);
4131 chr->SetUInt32Value(updateIndex,value);
4133 return true;
4136 bool ChatHandler::HandleBankCommand(const char* /*args*/)
4138 m_session->SendShowBank( m_session->GetPlayer()->GetGUID() );
4140 return true;
4143 bool ChatHandler::HandleChangeWeather(const char* args)
4145 if(!*args)
4146 return false;
4148 //Weather is OFF
4149 if (!sWorld.getConfig(CONFIG_WEATHER))
4151 SendSysMessage(LANG_WEATHER_DISABLED);
4152 SetSentErrorMessage(true);
4153 return false;
4156 //*Change the weather of a cell
4157 char* px = strtok((char*)args, " ");
4158 char* py = strtok(NULL, " ");
4160 if (!px || !py)
4161 return false;
4163 uint32 type = (uint32)atoi(px); //0 to 3, 0: fine, 1: rain, 2: snow, 3: sand
4164 float grade = (float)atof(py); //0 to 1, sending -1 is instand good weather
4166 Player *player = m_session->GetPlayer();
4167 uint32 zoneid = player->GetZoneId();
4169 Weather* wth = sWorld.FindWeather(zoneid);
4171 if(!wth)
4172 wth = sWorld.AddWeather(zoneid);
4173 if(!wth)
4175 SendSysMessage(LANG_NO_WEATHER);
4176 SetSentErrorMessage(true);
4177 return false;
4180 wth->SetWeather(WeatherType(type), grade);
4182 return true;
4185 bool ChatHandler::HandleDebugSetValue(const char* args)
4187 if(!*args)
4188 return false;
4190 char* px = strtok((char*)args, " ");
4191 char* py = strtok(NULL, " ");
4192 char* pz = strtok(NULL, " ");
4194 if (!px || !py)
4195 return false;
4197 Unit* target = getSelectedUnit();
4198 if(!target)
4200 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
4201 SetSentErrorMessage(true);
4202 return false;
4205 uint64 guid = target->GetGUID();
4207 uint32 Opcode = (uint32)atoi(px);
4208 if(Opcode >= target->GetValuesCount())
4210 PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, GUID_LOPART(guid), target->GetValuesCount());
4211 return false;
4213 uint32 iValue;
4214 float fValue;
4215 bool isint32 = true;
4216 if(pz)
4217 isint32 = (bool)atoi(pz);
4218 if(isint32)
4220 iValue = (uint32)atoi(py);
4221 sLog.outDebug(GetMangosString(LANG_SET_UINT), GUID_LOPART(guid), Opcode, iValue);
4222 target->SetUInt32Value( Opcode , iValue );
4223 PSendSysMessage(LANG_SET_UINT_FIELD, GUID_LOPART(guid), Opcode,iValue);
4225 else
4227 fValue = (float)atof(py);
4228 sLog.outDebug(GetMangosString(LANG_SET_FLOAT), GUID_LOPART(guid), Opcode, fValue);
4229 target->SetFloatValue( Opcode , fValue );
4230 PSendSysMessage(LANG_SET_FLOAT_FIELD, GUID_LOPART(guid), Opcode,fValue);
4233 return true;
4236 bool ChatHandler::HandleDebugGetValue(const char* args)
4238 if(!*args)
4239 return false;
4241 char* px = strtok((char*)args, " ");
4242 char* pz = strtok(NULL, " ");
4244 if (!px)
4245 return false;
4247 Unit* target = getSelectedUnit();
4248 if(!target)
4250 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
4251 SetSentErrorMessage(true);
4252 return false;
4255 uint64 guid = target->GetGUID();
4257 uint32 Opcode = (uint32)atoi(px);
4258 if(Opcode >= target->GetValuesCount())
4260 PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, GUID_LOPART(guid), target->GetValuesCount());
4261 return false;
4263 uint32 iValue;
4264 float fValue;
4265 bool isint32 = true;
4266 if(pz)
4267 isint32 = (bool)atoi(pz);
4269 if(isint32)
4271 iValue = target->GetUInt32Value( Opcode );
4272 sLog.outDebug(GetMangosString(LANG_GET_UINT), GUID_LOPART(guid), Opcode, iValue);
4273 PSendSysMessage(LANG_GET_UINT_FIELD, GUID_LOPART(guid), Opcode, iValue);
4275 else
4277 fValue = target->GetFloatValue( Opcode );
4278 sLog.outDebug(GetMangosString(LANG_GET_FLOAT), GUID_LOPART(guid), Opcode, fValue);
4279 PSendSysMessage(LANG_GET_FLOAT_FIELD, GUID_LOPART(guid), Opcode, fValue);
4282 return true;
4285 bool ChatHandler::HandleSet32Bit(const char* args)
4287 if(!*args)
4288 return false;
4290 char* px = strtok((char*)args, " ");
4291 char* py = strtok(NULL, " ");
4293 if (!px || !py)
4294 return false;
4296 uint32 Opcode = (uint32)atoi(px);
4297 uint32 Value = (uint32)atoi(py);
4298 if (Value > 32) //uint32 = 32 bits
4299 return false;
4301 sLog.outDebug(GetMangosString(LANG_SET_32BIT), Opcode, Value);
4303 m_session->GetPlayer( )->SetUInt32Value( Opcode , 2^Value );
4305 PSendSysMessage(LANG_SET_32BIT_FIELD, Opcode,1);
4306 return true;
4309 bool ChatHandler::HandleDebugMod32Value(const char* args)
4311 if(!*args)
4312 return false;
4314 char* px = strtok((char*)args, " ");
4315 char* py = strtok(NULL, " ");
4317 if (!px || !py)
4318 return false;
4320 uint32 Opcode = (uint32)atoi(px);
4321 int Value = atoi(py);
4323 if(Opcode >= m_session->GetPlayer()->GetValuesCount())
4325 PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, m_session->GetPlayer()->GetGUIDLow(), m_session->GetPlayer( )->GetValuesCount());
4326 return false;
4329 sLog.outDebug(GetMangosString(LANG_CHANGE_32BIT), Opcode, Value);
4331 int CurrentValue = (int)m_session->GetPlayer( )->GetUInt32Value( Opcode );
4333 CurrentValue += Value;
4334 m_session->GetPlayer( )->SetUInt32Value( Opcode , (uint32)CurrentValue );
4336 PSendSysMessage(LANG_CHANGE_32BIT_FIELD, Opcode,CurrentValue);
4338 return true;
4341 bool ChatHandler::HandleTeleAddCommand(const char * args)
4343 if(!*args)
4344 return false;
4346 Player *player=m_session->GetPlayer();
4347 if (!player)
4348 return false;
4350 std::string name = args;
4352 if(objmgr.GetGameTele(name))
4354 SendSysMessage(LANG_COMMAND_TP_ALREADYEXIST);
4355 SetSentErrorMessage(true);
4356 return false;
4359 GameTele tele;
4360 tele.position_x = player->GetPositionX();
4361 tele.position_y = player->GetPositionY();
4362 tele.position_z = player->GetPositionZ();
4363 tele.orientation = player->GetOrientation();
4364 tele.mapId = player->GetMapId();
4365 tele.name = name;
4367 if(objmgr.AddGameTele(tele))
4369 SendSysMessage(LANG_COMMAND_TP_ADDED);
4371 else
4373 SendSysMessage(LANG_COMMAND_TP_ADDEDERR);
4374 SetSentErrorMessage(true);
4375 return false;
4378 return true;
4381 bool ChatHandler::HandleTeleDelCommand(const char * args)
4383 if(!*args)
4384 return false;
4386 std::string name = args;
4388 if(!objmgr.DeleteGameTele(name))
4390 SendSysMessage(LANG_COMMAND_TELE_NOTFOUND);
4391 SetSentErrorMessage(true);
4392 return false;
4395 SendSysMessage(LANG_COMMAND_TP_DELETED);
4396 return true;
4399 bool ChatHandler::HandleListAurasCommand (const char * /*args*/)
4401 Unit *unit = getSelectedUnit();
4402 if(!unit)
4404 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
4405 SetSentErrorMessage(true);
4406 return false;
4409 char const* talentStr = GetMangosString(LANG_TALENT);
4410 char const* passiveStr = GetMangosString(LANG_PASSIVE);
4412 Unit::AuraMap const& uAuras = unit->GetAuras();
4413 PSendSysMessage(LANG_COMMAND_TARGET_LISTAURAS, uAuras.size());
4414 for (Unit::AuraMap::const_iterator itr = uAuras.begin(); itr != uAuras.end(); ++itr)
4416 bool talent = GetTalentSpellCost(itr->second->GetId()) > 0;
4418 char const* name = itr->second->GetSpellProto()->SpellName[GetSessionDbcLocale()];
4420 if (m_session)
4422 std::ostringstream ss_name;
4423 ss_name << "|cffffffff|Hspell:" << itr->second->GetId() << "|h[" << name << "]|h|r";
4425 PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffIndex(),
4426 itr->second->GetModifier()->m_auraname, itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(),
4427 ss_name.str().c_str(),
4428 (itr->second->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
4429 IS_PLAYER_GUID(itr->second->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(itr->second->GetCasterGUID()));
4431 else
4433 PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffIndex(),
4434 itr->second->GetModifier()->m_auraname, itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(),
4435 name,
4436 (itr->second->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
4437 IS_PLAYER_GUID(itr->second->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(itr->second->GetCasterGUID()));
4440 for (int i = 0; i < TOTAL_AURAS; ++i)
4442 Unit::AuraList const& uAuraList = unit->GetAurasByType(AuraType(i));
4443 if (uAuraList.empty()) continue;
4444 PSendSysMessage(LANG_COMMAND_TARGET_LISTAURATYPE, uAuraList.size(), i);
4445 for (Unit::AuraList::const_iterator itr = uAuraList.begin(); itr != uAuraList.end(); ++itr)
4447 bool talent = GetTalentSpellCost((*itr)->GetId()) > 0;
4449 char const* name = (*itr)->GetSpellProto()->SpellName[GetSessionDbcLocale()];
4451 if (m_session)
4453 std::ostringstream ss_name;
4454 ss_name << "|cffffffff|Hspell:" << (*itr)->GetId() << "|h[" << name << "]|h|r";
4456 PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(),
4457 ss_name.str().c_str(),((*itr)->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
4458 IS_PLAYER_GUID((*itr)->GetCasterGUID()) ? "player" : "creature",GUID_LOPART((*itr)->GetCasterGUID()));
4460 else
4462 PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(),
4463 name,((*itr)->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
4464 IS_PLAYER_GUID((*itr)->GetCasterGUID()) ? "player" : "creature",GUID_LOPART((*itr)->GetCasterGUID()));
4468 return true;
4471 bool ChatHandler::HandleResetAchievementsCommand (const char * args)
4473 Player* target;
4474 uint64 target_guid;
4475 if (!extractPlayerTarget((char*)args,&target,&target_guid))
4476 return false;
4478 if(target)
4479 target->GetAchievementMgr().Reset();
4480 else
4481 AchievementMgr::DeleteFromDB(GUID_LOPART(target_guid));
4483 return true;
4486 bool ChatHandler::HandleResetHonorCommand (const char * args)
4488 Player* target;
4489 if (!extractPlayerTarget((char*)args,&target))
4490 return false;
4492 target->SetUInt32Value(PLAYER_FIELD_KILLS, 0);
4493 target->SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORBALE_KILLS, 0);
4494 target->SetUInt32Value(PLAYER_FIELD_HONOR_CURRENCY, 0);
4495 target->SetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, 0);
4496 target->SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, 0);
4497 target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL);
4499 return true;
4502 static bool HandleResetStatsOrLevelHelper(Player* player)
4504 PlayerInfo const *info = objmgr.GetPlayerInfo(player->getRace(), player->getClass());
4505 if(!info) return false;
4507 ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(player->getClass());
4508 if(!cEntry)
4510 sLog.outError("Class %u not found in DBC (Wrong DBC files?)",player->getClass());
4511 return false;
4514 uint8 powertype = cEntry->powerType;
4516 // reset m_form if no aura
4517 if(!player->HasAuraType(SPELL_AURA_MOD_SHAPESHIFT))
4518 player->m_form = FORM_NONE;
4520 player->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE );
4521 player->SetFloatValue(UNIT_FIELD_COMBATREACH, 1.5f );
4523 player->setFactionForRace(player->getRace());
4525 player->SetUInt32Value(UNIT_FIELD_BYTES_0, ( ( player->getRace() ) | ( player->getClass() << 8 ) | ( player->getGender() << 16 ) | ( powertype << 24 ) ) );
4527 // reset only if player not in some form;
4528 if(player->m_form==FORM_NONE)
4530 switch(player->getGender())
4532 case GENDER_FEMALE:
4533 player->SetDisplayId(info->displayId_f);
4534 player->SetNativeDisplayId(info->displayId_f);
4535 break;
4536 case GENDER_MALE:
4537 player->SetDisplayId(info->displayId_m);
4538 player->SetNativeDisplayId(info->displayId_m);
4539 break;
4540 default:
4541 break;
4545 player->SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP );
4546 player->SetByteValue(UNIT_FIELD_BYTES_2, 3, player->m_form);
4548 player->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
4550 //-1 is default value
4551 player->SetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, uint32(-1));
4553 //player->SetUInt32Value(PLAYER_FIELD_BYTES, 0xEEE00000 );
4554 return true;
4557 bool ChatHandler::HandleResetLevelCommand(const char * args)
4559 Player* target;
4560 if(!extractPlayerTarget((char*)args,&target))
4561 return false;
4563 if(!HandleResetStatsOrLevelHelper(target))
4564 return false;
4566 // set starting level
4567 uint32 start_level = target->getClass() != CLASS_DEATH_KNIGHT
4568 ? sWorld.getConfig(CONFIG_START_PLAYER_LEVEL)
4569 : sWorld.getConfig(CONFIG_START_HEROIC_PLAYER_LEVEL);
4571 target->SetLevel(start_level);
4572 target->InitRunes();
4573 target->InitStatsForLevel(true);
4574 target->InitTaxiNodesForLevel();
4575 target->InitGlyphsForLevel();
4576 target->InitTalentForLevel();
4577 target->SetUInt32Value(PLAYER_XP,0);
4579 // reset level for pet
4580 if(Pet* pet = target->GetPet())
4581 pet->SynchronizeLevelWithOwner();
4583 return true;
4586 bool ChatHandler::HandleResetStatsCommand(const char * args)
4588 Player* target;
4589 if (!extractPlayerTarget((char*)args,&target))
4590 return false;
4592 if (!HandleResetStatsOrLevelHelper(target))
4593 return false;
4595 target->InitRunes();
4596 target->InitStatsForLevel(true);
4597 target->InitTaxiNodesForLevel();
4598 target->InitGlyphsForLevel();
4599 target->InitTalentForLevel();
4601 return true;
4604 bool ChatHandler::HandleResetSpellsCommand(const char * args)
4606 Player* target;
4607 uint64 target_guid;
4608 std::string target_name;
4609 if(!extractPlayerTarget((char*)args,&target,&target_guid,&target_name))
4610 return false;
4612 if(target)
4614 target->resetSpells();
4616 ChatHandler(target).SendSysMessage(LANG_RESET_SPELLS);
4617 if(!m_session || m_session->GetPlayer()!=target)
4618 PSendSysMessage(LANG_RESET_SPELLS_ONLINE,GetNameLink(target).c_str());
4620 else
4622 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",uint32(AT_LOGIN_RESET_SPELLS), GUID_LOPART(target_guid));
4623 PSendSysMessage(LANG_RESET_SPELLS_OFFLINE,target_name.c_str());
4626 return true;
4629 bool ChatHandler::HandleResetTalentsCommand(const char * args)
4631 Player* target;
4632 uint64 target_guid;
4633 std::string target_name;
4634 if (!extractPlayerTarget((char*)args,&target,&target_guid,&target_name))
4635 return false;
4637 if (target)
4639 target->resetTalents(true);
4641 ChatHandler(target).SendSysMessage(LANG_RESET_TALENTS);
4642 if (!m_session || m_session->GetPlayer()!=target)
4643 PSendSysMessage(LANG_RESET_TALENTS_ONLINE,GetNameLink(target).c_str());
4645 return true;
4647 else if (target_guid)
4649 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",uint32(AT_LOGIN_RESET_TALENTS), GUID_LOPART(target_guid) );
4650 std::string nameLink = playerLink(target_name);
4651 PSendSysMessage(LANG_RESET_TALENTS_OFFLINE,nameLink.c_str());
4652 return true;
4655 // Try reset talenents as Hunter Pet
4656 Creature* creature = getSelectedCreature();
4657 if (creature && creature->isPet() && ((Pet *)creature)->getPetType() == HUNTER_PET)
4659 ((Pet *)creature)->resetTalents(true);
4660 Unit *owner = creature->GetOwner();
4661 if (owner && owner->GetTypeId() == TYPEID_PLAYER)
4663 Player* owner_player = (Player *)owner;
4664 ChatHandler(owner_player).SendSysMessage(LANG_RESET_PET_TALENTS);
4665 if(!m_session || m_session->GetPlayer()!=owner_player)
4666 PSendSysMessage(LANG_RESET_PET_TALENTS_ONLINE,GetNameLink(owner_player).c_str());
4668 return true;
4671 SendSysMessage(LANG_NO_CHAR_SELECTED);
4672 SetSentErrorMessage(true);
4673 return false;
4676 bool ChatHandler::HandleResetAllCommand(const char * args)
4678 if(!*args)
4679 return false;
4681 std::string casename = args;
4683 AtLoginFlags atLogin;
4685 // Command specially created as single command to prevent using short case names
4686 if(casename=="spells")
4688 atLogin = AT_LOGIN_RESET_SPELLS;
4689 sWorld.SendWorldText(LANG_RESETALL_SPELLS);
4690 if(!m_session)
4691 SendSysMessage(LANG_RESETALL_SPELLS);
4693 else if(casename=="talents")
4695 atLogin = AT_LOGIN_RESET_TALENTS;
4696 sWorld.SendWorldText(LANG_RESETALL_TALENTS);
4697 if(!m_session)
4698 SendSysMessage(LANG_RESETALL_TALENTS);
4700 else
4702 PSendSysMessage(LANG_RESETALL_UNKNOWN_CASE,args);
4703 SetSentErrorMessage(true);
4704 return false;
4707 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE (at_login & '%u') = '0'",atLogin,atLogin);
4708 HashMapHolder<Player>::MapType const& plist = ObjectAccessor::Instance().GetPlayers();
4709 for(HashMapHolder<Player>::MapType::const_iterator itr = plist.begin(); itr != plist.end(); ++itr)
4710 itr->second->SetAtLoginFlag(atLogin);
4712 return true;
4715 bool ChatHandler::HandleServerShutDownCancelCommand(const char* /*args*/)
4717 sWorld.ShutdownCancel();
4718 return true;
4721 bool ChatHandler::HandleServerShutDownCommand(const char* args)
4723 if(!*args)
4724 return false;
4726 char* time_str = strtok ((char*) args, " ");
4727 char* exitcode_str = strtok (NULL, "");
4729 int32 time = atoi (time_str);
4731 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4732 if ((time == 0 && (time_str[0]!='0' || time_str[1]!='\0')) || time < 0)
4733 return false;
4735 if (exitcode_str)
4737 int32 exitcode = atoi (exitcode_str);
4739 // Handle atoi() errors
4740 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4741 return false;
4743 // Exit code should be in range of 0-125, 126-255 is used
4744 // in many shells for their own return codes and code > 255
4745 // is not supported in many others
4746 if (exitcode < 0 || exitcode > 125)
4747 return false;
4749 sWorld.ShutdownServ (time, 0, exitcode);
4751 else
4752 sWorld.ShutdownServ(time,0,SHUTDOWN_EXIT_CODE);
4753 return true;
4756 bool ChatHandler::HandleServerRestartCommand(const char* args)
4758 if(!*args)
4759 return false;
4761 char* time_str = strtok ((char*) args, " ");
4762 char* exitcode_str = strtok (NULL, "");
4764 int32 time = atoi (time_str);
4766 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4767 if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0)
4768 return false;
4770 if (exitcode_str)
4772 int32 exitcode = atoi (exitcode_str);
4774 // Handle atoi() errors
4775 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4776 return false;
4778 // Exit code should be in range of 0-125, 126-255 is used
4779 // in many shells for their own return codes and code > 255
4780 // is not supported in many others
4781 if (exitcode < 0 || exitcode > 125)
4782 return false;
4784 sWorld.ShutdownServ (time, SHUTDOWN_MASK_RESTART, exitcode);
4786 else
4787 sWorld.ShutdownServ(time, SHUTDOWN_MASK_RESTART, RESTART_EXIT_CODE);
4788 return true;
4791 bool ChatHandler::HandleServerIdleRestartCommand(const char* args)
4793 if(!*args)
4794 return false;
4796 char* time_str = strtok ((char*) args, " ");
4797 char* exitcode_str = strtok (NULL, "");
4799 int32 time = atoi (time_str);
4801 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4802 if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0)
4803 return false;
4805 if (exitcode_str)
4807 int32 exitcode = atoi (exitcode_str);
4809 // Handle atoi() errors
4810 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4811 return false;
4813 // Exit code should be in range of 0-125, 126-255 is used
4814 // in many shells for their own return codes and code > 255
4815 // is not supported in many others
4816 if (exitcode < 0 || exitcode > 125)
4817 return false;
4819 sWorld.ShutdownServ (time, SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE, exitcode);
4821 else
4822 sWorld.ShutdownServ(time,SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE,RESTART_EXIT_CODE);
4823 return true;
4826 bool ChatHandler::HandleServerIdleShutDownCommand(const char* args)
4828 if(!*args)
4829 return false;
4831 char* time_str = strtok ((char*) args, " ");
4832 char* exitcode_str = strtok (NULL, "");
4834 int32 time = atoi (time_str);
4836 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4837 if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0)
4838 return false;
4840 if (exitcode_str)
4842 int32 exitcode = atoi (exitcode_str);
4844 // Handle atoi() errors
4845 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4846 return false;
4848 // Exit code should be in range of 0-125, 126-255 is used
4849 // in many shells for their own return codes and code > 255
4850 // is not supported in many others
4851 if (exitcode < 0 || exitcode > 125)
4852 return false;
4854 sWorld.ShutdownServ (time, SHUTDOWN_MASK_IDLE, exitcode);
4856 else
4857 sWorld.ShutdownServ(time,SHUTDOWN_MASK_IDLE,SHUTDOWN_EXIT_CODE);
4858 return true;
4861 bool ChatHandler::HandleQuestAdd(const char* args)
4863 Player* player = getSelectedPlayer();
4864 if(!player)
4866 SendSysMessage(LANG_NO_CHAR_SELECTED);
4867 SetSentErrorMessage(true);
4868 return false;
4871 // .addquest #entry'
4872 // number or [name] Shift-click form |color|Hquest:quest_id|h[name]|h|r
4873 char* cId = extractKeyFromLink((char*)args,"Hquest");
4874 if(!cId)
4875 return false;
4877 uint32 entry = atol(cId);
4879 Quest const* pQuest = objmgr.GetQuestTemplate(entry);
4881 if(!pQuest)
4883 PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND,entry);
4884 SetSentErrorMessage(true);
4885 return false;
4888 // check item starting quest (it can work incorrectly if added without item in inventory)
4889 for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
4891 ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype>(id);
4892 if (!pProto)
4893 continue;
4895 if (pProto->StartQuest == entry)
4897 PSendSysMessage(LANG_COMMAND_QUEST_STARTFROMITEM, entry, pProto->ItemId);
4898 SetSentErrorMessage(true);
4899 return false;
4903 // ok, normal (creature/GO starting) quest
4904 if( player->CanAddQuest( pQuest, true ) )
4906 player->AddQuest( pQuest, NULL );
4908 if ( player->CanCompleteQuest( entry ) )
4909 player->CompleteQuest( entry );
4912 return true;
4915 bool ChatHandler::HandleQuestRemove(const char* args)
4917 Player* player = getSelectedPlayer();
4918 if(!player)
4920 SendSysMessage(LANG_NO_CHAR_SELECTED);
4921 SetSentErrorMessage(true);
4922 return false;
4925 // .removequest #entry'
4926 // number or [name] Shift-click form |color|Hquest:quest_id|h[name]|h|r
4927 char* cId = extractKeyFromLink((char*)args,"Hquest");
4928 if(!cId)
4929 return false;
4931 uint32 entry = atol(cId);
4933 Quest const* pQuest = objmgr.GetQuestTemplate(entry);
4935 if(!pQuest)
4937 PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry);
4938 SetSentErrorMessage(true);
4939 return false;
4942 // remove all quest entries for 'entry' from quest log
4943 for(uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot )
4945 uint32 quest = player->GetQuestSlotQuestId(slot);
4946 if(quest==entry)
4948 player->SetQuestSlot(slot,0);
4950 // we ignore unequippable quest items in this case, its' still be equipped
4951 player->TakeQuestSourceItem( quest, false );
4955 // set quest status to not started (will updated in DB at next save)
4956 player->SetQuestStatus( entry, QUEST_STATUS_NONE);
4958 // reset rewarded for restart repeatable quest
4959 player->getQuestStatusMap()[entry].m_rewarded = false;
4961 SendSysMessage(LANG_COMMAND_QUEST_REMOVED);
4962 return true;
4965 bool ChatHandler::HandleQuestComplete(const char* args)
4967 Player* player = getSelectedPlayer();
4968 if(!player)
4970 SendSysMessage(LANG_NO_CHAR_SELECTED);
4971 SetSentErrorMessage(true);
4972 return false;
4975 // .quest complete #entry
4976 // number or [name] Shift-click form |color|Hquest:quest_id|h[name]|h|r
4977 char* cId = extractKeyFromLink((char*)args,"Hquest");
4978 if(!cId)
4979 return false;
4981 uint32 entry = atol(cId);
4983 Quest const* pQuest = objmgr.GetQuestTemplate(entry);
4985 // If player doesn't have the quest
4986 if(!pQuest || player->GetQuestStatus(entry) == QUEST_STATUS_NONE)
4988 PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry);
4989 SetSentErrorMessage(true);
4990 return false;
4993 // Add quest items for quests that require items
4994 for(uint8 x = 0; x < QUEST_OBJECTIVES_COUNT; ++x)
4996 uint32 id = pQuest->ReqItemId[x];
4997 uint32 count = pQuest->ReqItemCount[x];
4998 if(!id || !count)
4999 continue;
5001 uint32 curItemCount = player->GetItemCount(id,true);
5003 ItemPosCountVec dest;
5004 uint8 msg = player->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, id, count-curItemCount );
5005 if( msg == EQUIP_ERR_OK )
5007 Item* item = player->StoreNewItem( dest, id, true);
5008 player->SendNewItem(item,count-curItemCount,true,false);
5012 // All creature/GO slain/casted (not required, but otherwise it will display "Creature slain 0/10")
5013 for(uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
5015 uint32 creature = pQuest->ReqCreatureOrGOId[i];
5016 uint32 creaturecount = pQuest->ReqCreatureOrGOCount[i];
5018 if(uint32 spell_id = pQuest->ReqSpell[i])
5020 for(uint16 z = 0; z < creaturecount; ++z)
5021 player->CastedCreatureOrGO(creature,0,spell_id);
5023 else if(creature > 0)
5025 for(uint16 z = 0; z < creaturecount; ++z)
5026 player->KilledMonster(creature,0);
5028 else if(creature < 0)
5030 for(uint16 z = 0; z < creaturecount; ++z)
5031 player->CastedCreatureOrGO(creature,0,0);
5035 // If the quest requires reputation to complete
5036 if(uint32 repFaction = pQuest->GetRepObjectiveFaction())
5038 uint32 repValue = pQuest->GetRepObjectiveValue();
5039 uint32 curRep = player->GetReputationMgr().GetReputation(repFaction);
5040 if(curRep < repValue)
5041 if(FactionEntry const *factionEntry = sFactionStore.LookupEntry(repFaction))
5042 player->GetReputationMgr().SetReputation(factionEntry,repValue);
5045 // If the quest requires money
5046 int32 ReqOrRewMoney = pQuest->GetRewOrReqMoney();
5047 if(ReqOrRewMoney < 0)
5048 player->ModifyMoney(-ReqOrRewMoney);
5050 player->CompleteQuest(entry);
5051 return true;
5054 bool ChatHandler::HandleBanAccountCommand(const char* args)
5056 return HandleBanHelper(BAN_ACCOUNT,args);
5059 bool ChatHandler::HandleBanCharacterCommand(const char* args)
5061 return HandleBanHelper(BAN_CHARACTER,args);
5064 bool ChatHandler::HandleBanIPCommand(const char* args)
5066 return HandleBanHelper(BAN_IP,args);
5069 bool ChatHandler::HandleBanHelper(BanMode mode, const char* args)
5071 if (!*args)
5072 return false;
5074 char* cnameOrIP = strtok ((char*)args, " ");
5075 if (!cnameOrIP)
5076 return false;
5078 std::string nameOrIP = cnameOrIP;
5080 char* duration = strtok (NULL," ");
5081 if(!duration || !atoi(duration))
5082 return false;
5084 char* reason = strtok (NULL,"");
5085 if(!reason)
5086 return false;
5088 switch(mode)
5090 case BAN_ACCOUNT:
5091 if(!AccountMgr::normilizeString(nameOrIP))
5093 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,nameOrIP.c_str());
5094 SetSentErrorMessage(true);
5095 return false;
5097 break;
5098 case BAN_CHARACTER:
5099 if(!normalizePlayerName(nameOrIP))
5101 SendSysMessage(LANG_PLAYER_NOT_FOUND);
5102 SetSentErrorMessage(true);
5103 return false;
5105 break;
5106 case BAN_IP:
5107 if(!IsIPAddress(nameOrIP.c_str()))
5108 return false;
5109 break;
5112 switch(sWorld.BanAccount(mode, nameOrIP, duration, reason,m_session ? m_session->GetPlayerName() : ""))
5114 case BAN_SUCCESS:
5115 if(atoi(duration)>0)
5116 PSendSysMessage(LANG_BAN_YOUBANNED,nameOrIP.c_str(),secsToTimeString(TimeStringToSecs(duration),true).c_str(),reason);
5117 else
5118 PSendSysMessage(LANG_BAN_YOUPERMBANNED,nameOrIP.c_str(),reason);
5119 break;
5120 case BAN_SYNTAX_ERROR:
5121 return false;
5122 case BAN_NOTFOUND:
5123 switch(mode)
5125 default:
5126 PSendSysMessage(LANG_BAN_NOTFOUND,"account",nameOrIP.c_str());
5127 break;
5128 case BAN_CHARACTER:
5129 PSendSysMessage(LANG_BAN_NOTFOUND,"character",nameOrIP.c_str());
5130 break;
5131 case BAN_IP:
5132 PSendSysMessage(LANG_BAN_NOTFOUND,"ip",nameOrIP.c_str());
5133 break;
5135 SetSentErrorMessage(true);
5136 return false;
5139 return true;
5142 bool ChatHandler::HandleUnBanAccountCommand(const char* args)
5144 return HandleUnBanHelper(BAN_ACCOUNT,args);
5147 bool ChatHandler::HandleUnBanCharacterCommand(const char* args)
5149 return HandleUnBanHelper(BAN_CHARACTER,args);
5152 bool ChatHandler::HandleUnBanIPCommand(const char* args)
5154 return HandleUnBanHelper(BAN_IP,args);
5157 bool ChatHandler::HandleUnBanHelper(BanMode mode, const char* args)
5159 if (!*args)
5160 return false;
5162 char* cnameOrIP = strtok ((char*)args, " ");
5163 if(!cnameOrIP)
5164 return false;
5166 std::string nameOrIP = cnameOrIP;
5168 switch(mode)
5170 case BAN_ACCOUNT:
5171 if(!AccountMgr::normilizeString(nameOrIP))
5173 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,nameOrIP.c_str());
5174 SetSentErrorMessage(true);
5175 return false;
5177 break;
5178 case BAN_CHARACTER:
5179 if(!normalizePlayerName(nameOrIP))
5181 SendSysMessage(LANG_PLAYER_NOT_FOUND);
5182 SetSentErrorMessage(true);
5183 return false;
5185 break;
5186 case BAN_IP:
5187 if(!IsIPAddress(nameOrIP.c_str()))
5188 return false;
5189 break;
5192 if(sWorld.RemoveBanAccount(mode,nameOrIP))
5193 PSendSysMessage(LANG_UNBAN_UNBANNED,nameOrIP.c_str());
5194 else
5195 PSendSysMessage(LANG_UNBAN_ERROR,nameOrIP.c_str());
5197 return true;
5200 bool ChatHandler::HandleBanInfoAccountCommand(const char* args)
5202 if (!*args)
5203 return false;
5205 char* cname = strtok((char*)args, "");
5206 if(!cname)
5207 return false;
5209 std::string account_name = cname;
5210 if(!AccountMgr::normilizeString(account_name))
5212 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5213 SetSentErrorMessage(true);
5214 return false;
5217 uint32 accountid = accmgr.GetId(account_name);
5218 if(!accountid)
5220 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5221 return true;
5224 return HandleBanInfoHelper(accountid,account_name.c_str());
5227 bool ChatHandler::HandleBanInfoCharacterCommand(const char* args)
5229 Player* target;
5230 uint64 target_guid;
5231 if(!extractPlayerTarget((char*)args,&target,&target_guid))
5232 return false;
5234 uint32 accountid = target ? target->GetSession()->GetAccountId() : objmgr.GetPlayerAccountIdByGUID(target_guid);
5236 std::string accountname;
5237 if(!accmgr.GetName(accountid,accountname))
5239 PSendSysMessage(LANG_BANINFO_NOCHARACTER);
5240 return true;
5243 return HandleBanInfoHelper(accountid,accountname.c_str());
5246 bool ChatHandler::HandleBanInfoHelper(uint32 accountid, char const* accountname)
5248 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);
5249 if(!result)
5251 PSendSysMessage(LANG_BANINFO_NOACCOUNTBAN, accountname);
5252 return true;
5255 PSendSysMessage(LANG_BANINFO_BANHISTORY,accountname);
5258 Field* fields = result->Fetch();
5260 time_t unbandate = time_t(fields[3].GetUInt64());
5261 bool active = false;
5262 if(fields[2].GetBool() && (fields[1].GetUInt64() == (uint64)0 ||unbandate >= time(NULL)) )
5263 active = true;
5264 bool permanent = (fields[1].GetUInt64() == (uint64)0);
5265 std::string bantime = permanent?GetMangosString(LANG_BANINFO_INFINITE):secsToTimeString(fields[1].GetUInt64(), true);
5266 PSendSysMessage(LANG_BANINFO_HISTORYENTRY,
5267 fields[0].GetString(), bantime.c_str(), active ? GetMangosString(LANG_BANINFO_YES):GetMangosString(LANG_BANINFO_NO), fields[4].GetString(), fields[5].GetString());
5268 }while (result->NextRow());
5270 delete result;
5271 return true;
5274 bool ChatHandler::HandleBanInfoIPCommand(const char* args)
5276 if (!*args)
5277 return false;
5279 char* cIP = strtok ((char*)args, "");
5280 if(!cIP)
5281 return false;
5283 if (!IsIPAddress(cIP))
5284 return false;
5286 std::string IP = cIP;
5288 loginDatabase.escape_string(IP);
5289 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());
5290 if(!result)
5292 PSendSysMessage(LANG_BANINFO_NOIP);
5293 return true;
5296 Field *fields = result->Fetch();
5297 bool permanent = !fields[6].GetUInt64();
5298 PSendSysMessage(LANG_BANINFO_IPENTRY,
5299 fields[0].GetString(), fields[1].GetString(), permanent ? GetMangosString(LANG_BANINFO_NEVER):fields[2].GetString(),
5300 permanent ? GetMangosString(LANG_BANINFO_INFINITE):secsToTimeString(fields[3].GetUInt64(), true).c_str(), fields[4].GetString(), fields[5].GetString());
5301 delete result;
5302 return true;
5305 bool ChatHandler::HandleBanListCharacterCommand(const char* args)
5307 loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
5309 char* cFilter = strtok ((char*)args, " ");
5310 if(!cFilter)
5311 return false;
5313 std::string filter = cFilter;
5314 loginDatabase.escape_string(filter);
5315 QueryResult* result = CharacterDatabase.PQuery("SELECT account FROM characters WHERE name "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'"),filter.c_str());
5316 if (!result)
5318 PSendSysMessage(LANG_BANLIST_NOCHARACTER);
5319 return true;
5322 return HandleBanListHelper(result);
5325 bool ChatHandler::HandleBanListAccountCommand(const char* args)
5327 loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
5329 char* cFilter = strtok((char*)args, " ");
5330 std::string filter = cFilter ? cFilter : "";
5331 loginDatabase.escape_string(filter);
5333 QueryResult* result;
5335 if(filter.empty())
5337 result = loginDatabase.Query("SELECT account.id, username FROM account, account_banned"
5338 " WHERE account.id = account_banned.id AND active = 1 GROUP BY account.id");
5340 else
5342 result = loginDatabase.PQuery("SELECT account.id, username FROM account, account_banned"
5343 " WHERE account.id = account_banned.id AND active = 1 AND username "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")" GROUP BY account.id",
5344 filter.c_str());
5347 if (!result)
5349 PSendSysMessage(LANG_BANLIST_NOACCOUNT);
5350 return true;
5353 return HandleBanListHelper(result);
5356 bool ChatHandler::HandleBanListHelper(QueryResult* result)
5358 PSendSysMessage(LANG_BANLIST_MATCHINGACCOUNT);
5360 // Chat short output
5361 if(m_session)
5365 Field* fields = result->Fetch();
5366 uint32 accountid = fields[0].GetUInt32();
5368 QueryResult* banresult = loginDatabase.PQuery("SELECT account.username FROM account,account_banned WHERE account_banned.id='%u' AND account_banned.id=account.id",accountid);
5369 if(banresult)
5371 Field* fields2 = banresult->Fetch();
5372 PSendSysMessage("%s",fields2[0].GetString());
5373 delete banresult;
5375 } while (result->NextRow());
5377 // Console wide output
5378 else
5380 SendSysMessage(LANG_BANLIST_ACCOUNTS);
5381 SendSysMessage("===============================================================================");
5382 SendSysMessage(LANG_BANLIST_ACCOUNTS_HEADER);
5385 SendSysMessage("-------------------------------------------------------------------------------");
5386 Field *fields = result->Fetch();
5387 uint32 account_id = fields[0].GetUInt32 ();
5389 std::string account_name;
5391 // "account" case, name can be get in same query
5392 if(result->GetFieldCount() > 1)
5393 account_name = fields[1].GetCppString();
5394 // "character" case, name need extract from another DB
5395 else
5396 accmgr.GetName (account_id,account_name);
5398 // No SQL injection. id is uint32.
5399 QueryResult *banInfo = loginDatabase.PQuery("SELECT bandate,unbandate,bannedby,banreason FROM account_banned WHERE id = %u ORDER BY unbandate", account_id);
5400 if (banInfo)
5402 Field *fields2 = banInfo->Fetch();
5405 time_t t_ban = fields2[0].GetUInt64();
5406 tm* aTm_ban = localtime(&t_ban);
5408 if (fields2[0].GetUInt64() == fields2[1].GetUInt64())
5410 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|",
5411 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,
5412 fields2[2].GetString(),fields2[3].GetString());
5414 else
5416 time_t t_unban = fields2[1].GetUInt64();
5417 tm* aTm_unban = localtime(&t_unban);
5418 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|",
5419 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,
5420 aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min,
5421 fields2[2].GetString(),fields2[3].GetString());
5423 }while ( banInfo->NextRow() );
5424 delete banInfo;
5426 }while( result->NextRow() );
5427 SendSysMessage("===============================================================================");
5430 delete result;
5431 return true;
5434 bool ChatHandler::HandleBanListIPCommand(const char* args)
5436 loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
5438 char* cFilter = strtok((char*)args, " ");
5439 std::string filter = cFilter ? cFilter : "";
5440 loginDatabase.escape_string(filter);
5442 QueryResult* result;
5444 if(filter.empty())
5446 result = loginDatabase.Query ("SELECT ip,bandate,unbandate,bannedby,banreason FROM ip_banned"
5447 " WHERE (bandate=unbandate OR unbandate>UNIX_TIMESTAMP())"
5448 " ORDER BY unbandate" );
5450 else
5452 result = loginDatabase.PQuery( "SELECT ip,bandate,unbandate,bannedby,banreason FROM ip_banned"
5453 " WHERE (bandate=unbandate OR unbandate>UNIX_TIMESTAMP()) AND ip "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")
5454 " ORDER BY unbandate",filter.c_str() );
5457 if(!result)
5459 PSendSysMessage(LANG_BANLIST_NOIP);
5460 return true;
5463 PSendSysMessage(LANG_BANLIST_MATCHINGIP);
5464 // Chat short output
5465 if(m_session)
5469 Field* fields = result->Fetch();
5470 PSendSysMessage("%s",fields[0].GetString());
5471 } while (result->NextRow());
5473 // Console wide output
5474 else
5476 SendSysMessage(LANG_BANLIST_IPS);
5477 SendSysMessage("===============================================================================");
5478 SendSysMessage(LANG_BANLIST_IPS_HEADER);
5481 SendSysMessage("-------------------------------------------------------------------------------");
5482 Field *fields = result->Fetch();
5483 time_t t_ban = fields[1].GetUInt64();
5484 tm* aTm_ban = localtime(&t_ban);
5485 if ( fields[1].GetUInt64() == fields[2].GetUInt64() )
5487 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|",
5488 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,
5489 fields[3].GetString(), fields[4].GetString());
5491 else
5493 time_t t_unban = fields[2].GetUInt64();
5494 tm* aTm_unban = localtime(&t_unban);
5495 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|",
5496 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,
5497 aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min,
5498 fields[3].GetString(), fields[4].GetString());
5500 }while( result->NextRow() );
5501 SendSysMessage("===============================================================================");
5504 delete result;
5505 return true;
5508 bool ChatHandler::HandleRespawnCommand(const char* /*args*/)
5510 Player* pl = m_session->GetPlayer();
5512 // accept only explicitly selected target (not implicitly self targeting case)
5513 Unit* target = getSelectedUnit();
5514 if(pl->GetSelection() && target)
5516 if(target->GetTypeId()!=TYPEID_UNIT)
5518 SendSysMessage(LANG_SELECT_CREATURE);
5519 SetSentErrorMessage(true);
5520 return false;
5523 if(target->isDead())
5524 ((Creature*)target)->Respawn();
5525 return true;
5528 CellPair p(MaNGOS::ComputeCellPair(pl->GetPositionX(), pl->GetPositionY()));
5529 Cell cell(p);
5530 cell.data.Part.reserved = ALL_DISTRICT;
5531 cell.SetNoCreate();
5533 MaNGOS::RespawnDo u_do;
5534 MaNGOS::WorldObjectWorker<MaNGOS::RespawnDo> worker(pl,u_do);
5536 TypeContainerVisitor<MaNGOS::WorldObjectWorker<MaNGOS::RespawnDo>, GridTypeMapContainer > obj_worker(worker);
5537 CellLock<GridReadGuard> cell_lock(cell, p);
5538 cell_lock->Visit(cell_lock, obj_worker, *pl->GetMap());
5540 return true;
5543 bool ChatHandler::HandleGMFlyCommand(const char* args)
5545 if (!*args)
5546 return false;
5548 Player *target = getSelectedPlayer();
5549 if (!target)
5550 target = m_session->GetPlayer();
5552 WorldPacket data(12);
5553 if (strncmp(args, "on", 3) == 0)
5554 data.SetOpcode(SMSG_MOVE_SET_CAN_FLY);
5555 else if (strncmp(args, "off", 4) == 0)
5556 data.SetOpcode(SMSG_MOVE_UNSET_CAN_FLY);
5557 else
5559 SendSysMessage(LANG_USE_BOL);
5560 return false;
5562 data.append(target->GetPackGUID());
5563 data << uint32(0); // unknown
5564 target->SendMessageToSet(&data, true);
5565 PSendSysMessage(LANG_COMMAND_FLYMODE_STATUS, GetNameLink(target).c_str(), args);
5566 return true;
5569 bool ChatHandler::HandlePDumpLoadCommand(const char *args)
5571 if (!*args)
5572 return false;
5574 char * file = strtok((char*)args, " ");
5575 if(!file)
5576 return false;
5578 char * account = strtok(NULL, " ");
5579 if(!account)
5580 return false;
5582 std::string account_name = account;
5583 if(!AccountMgr::normilizeString(account_name))
5585 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5586 SetSentErrorMessage(true);
5587 return false;
5590 uint32 account_id = accmgr.GetId(account_name);
5591 if(!account_id)
5593 account_id = atoi(account); // use original string
5594 if(!account_id)
5596 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5597 SetSentErrorMessage(true);
5598 return false;
5602 if(!accmgr.GetName(account_id,account_name))
5604 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5605 SetSentErrorMessage(true);
5606 return false;
5609 char* guid_str = NULL;
5610 char* name_str = strtok(NULL, " ");
5612 std::string name;
5613 if(name_str)
5615 name = name_str;
5616 // normalize the name if specified and check if it exists
5617 if(!normalizePlayerName(name))
5619 PSendSysMessage(LANG_INVALID_CHARACTER_NAME);
5620 SetSentErrorMessage(true);
5621 return false;
5624 if(!ObjectMgr::IsValidName(name,true))
5626 PSendSysMessage(LANG_INVALID_CHARACTER_NAME);
5627 SetSentErrorMessage(true);
5628 return false;
5631 guid_str = strtok(NULL, " ");
5634 uint32 guid = 0;
5636 if(guid_str)
5638 guid = atoi(guid_str);
5639 if(!guid)
5641 PSendSysMessage(LANG_INVALID_CHARACTER_GUID);
5642 SetSentErrorMessage(true);
5643 return false;
5646 if(objmgr.GetPlayerAccountIdByGUID(guid))
5648 PSendSysMessage(LANG_CHARACTER_GUID_IN_USE,guid);
5649 SetSentErrorMessage(true);
5650 return false;
5654 switch(PlayerDumpReader().LoadDump(file, account_id, name, guid))
5656 case DUMP_SUCCESS:
5657 PSendSysMessage(LANG_COMMAND_IMPORT_SUCCESS);
5658 break;
5659 case DUMP_FILE_OPEN_ERROR:
5660 PSendSysMessage(LANG_FILE_OPEN_FAIL,file);
5661 SetSentErrorMessage(true);
5662 return false;
5663 case DUMP_FILE_BROKEN:
5664 PSendSysMessage(LANG_DUMP_BROKEN,file);
5665 SetSentErrorMessage(true);
5666 return false;
5667 case DUMP_TOO_MANY_CHARS:
5668 PSendSysMessage(LANG_ACCOUNT_CHARACTER_LIST_FULL,account_name.c_str(),account_id);
5669 SetSentErrorMessage(true);
5670 return false;
5671 default:
5672 PSendSysMessage(LANG_COMMAND_IMPORT_FAILED);
5673 SetSentErrorMessage(true);
5674 return false;
5677 return true;
5680 bool ChatHandler::HandlePDumpWriteCommand(const char *args)
5682 if (!*args)
5683 return false;
5685 char* file = strtok((char*)args, " ");
5686 char* p2 = strtok(NULL, " ");
5688 if(!file || !p2)
5689 return false;
5691 uint32 guid;
5692 // character name can't start from number
5693 if (isNumeric(p2[0]))
5694 guid = atoi(p2);
5695 else
5697 std::string name = extractPlayerNameFromLink(p2);
5698 if(name.empty())
5700 SendSysMessage(LANG_PLAYER_NOT_FOUND);
5701 SetSentErrorMessage(true);
5702 return false;
5705 guid = objmgr.GetPlayerGUIDByName(name);
5708 if(!objmgr.GetPlayerAccountIdByGUID(guid))
5710 PSendSysMessage(LANG_PLAYER_NOT_FOUND);
5711 SetSentErrorMessage(true);
5712 return false;
5715 switch(PlayerDumpWriter().WriteDump(file, guid))
5717 case DUMP_SUCCESS:
5718 PSendSysMessage(LANG_COMMAND_EXPORT_SUCCESS);
5719 break;
5720 case DUMP_FILE_OPEN_ERROR:
5721 PSendSysMessage(LANG_FILE_OPEN_FAIL,file);
5722 SetSentErrorMessage(true);
5723 return false;
5724 default:
5725 PSendSysMessage(LANG_COMMAND_EXPORT_FAILED);
5726 SetSentErrorMessage(true);
5727 return false;
5730 return true;
5733 bool ChatHandler::HandleMovegensCommand(const char* /*args*/)
5735 Unit* unit = getSelectedUnit();
5736 if(!unit)
5738 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5739 SetSentErrorMessage(true);
5740 return false;
5743 PSendSysMessage(LANG_MOVEGENS_LIST,(unit->GetTypeId()==TYPEID_PLAYER ? "Player" : "Creature" ),unit->GetGUIDLow());
5745 MotionMaster* mm = unit->GetMotionMaster();
5746 for(MotionMaster::const_iterator itr = mm->begin(); itr != mm->end(); ++itr)
5748 switch((*itr)->GetMovementGeneratorType())
5750 case IDLE_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_IDLE); break;
5751 case RANDOM_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_RANDOM); break;
5752 case WAYPOINT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_WAYPOINT); break;
5753 case ANIMAL_RANDOM_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_ANIMAL_RANDOM); break;
5754 case CONFUSED_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_CONFUSED); break;
5755 case TARGETED_MOTION_TYPE:
5757 if(unit->GetTypeId()==TYPEID_PLAYER)
5759 TargetedMovementGenerator<Player> const* mgen = static_cast<TargetedMovementGenerator<Player> const*>(*itr);
5760 Unit* target = mgen->GetTarget();
5761 if(target)
5762 PSendSysMessage(LANG_MOVEGENS_TARGETED_PLAYER,target->GetName(),target->GetGUIDLow());
5763 else
5764 SendSysMessage(LANG_MOVEGENS_TARGETED_NULL);
5766 else
5768 TargetedMovementGenerator<Creature> const* mgen = static_cast<TargetedMovementGenerator<Creature> const*>(*itr);
5769 Unit* target = mgen->GetTarget();
5770 if(target)
5771 PSendSysMessage(LANG_MOVEGENS_TARGETED_CREATURE,target->GetName(),target->GetGUIDLow());
5772 else
5773 SendSysMessage(LANG_MOVEGENS_TARGETED_NULL);
5775 break;
5777 case HOME_MOTION_TYPE:
5778 if(unit->GetTypeId()==TYPEID_UNIT)
5780 float x,y,z;
5781 (*itr)->GetDestination(x,y,z);
5782 PSendSysMessage(LANG_MOVEGENS_HOME_CREATURE,x,y,z);
5784 else
5785 SendSysMessage(LANG_MOVEGENS_HOME_PLAYER);
5786 break;
5787 case FLIGHT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_FLIGHT); break;
5788 case POINT_MOTION_TYPE:
5790 float x,y,z;
5791 (*itr)->GetDestination(x,y,z);
5792 PSendSysMessage(LANG_MOVEGENS_POINT,x,y,z);
5793 break;
5795 case FLEEING_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_FEAR); break;
5796 case DISTRACT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_DISTRACT); break;
5797 default:
5798 PSendSysMessage(LANG_MOVEGENS_UNKNOWN,(*itr)->GetMovementGeneratorType());
5799 break;
5802 return true;
5805 bool ChatHandler::HandleServerPLimitCommand(const char *args)
5807 if(*args)
5809 char* param = strtok((char*)args, " ");
5810 if(!param)
5811 return false;
5813 int l = strlen(param);
5815 if( strncmp(param,"player",l) == 0 )
5816 sWorld.SetPlayerLimit(-SEC_PLAYER);
5817 else if(strncmp(param,"moderator",l) == 0 )
5818 sWorld.SetPlayerLimit(-SEC_MODERATOR);
5819 else if(strncmp(param,"gamemaster",l) == 0 )
5820 sWorld.SetPlayerLimit(-SEC_GAMEMASTER);
5821 else if(strncmp(param,"administrator",l) == 0 )
5822 sWorld.SetPlayerLimit(-SEC_ADMINISTRATOR);
5823 else if(strncmp(param,"reset",l) == 0 )
5824 sWorld.SetPlayerLimit( sConfig.GetIntDefault("PlayerLimit", DEFAULT_PLAYER_LIMIT) );
5825 else
5827 int val = atoi(param);
5828 if(val < -SEC_ADMINISTRATOR) val = -SEC_ADMINISTRATOR;
5830 sWorld.SetPlayerLimit(val);
5833 // kick all low security level players
5834 if(sWorld.GetPlayerAmountLimit() > SEC_PLAYER)
5835 sWorld.KickAllLess(sWorld.GetPlayerSecurityLimit());
5838 uint32 pLimit = sWorld.GetPlayerAmountLimit();
5839 AccountTypes allowedAccountType = sWorld.GetPlayerSecurityLimit();
5840 char const* secName = "";
5841 switch(allowedAccountType)
5843 case SEC_PLAYER: secName = "Player"; break;
5844 case SEC_MODERATOR: secName = "Moderator"; break;
5845 case SEC_GAMEMASTER: secName = "Gamemaster"; break;
5846 case SEC_ADMINISTRATOR: secName = "Administrator"; break;
5847 default: secName = "<unknown>"; break;
5850 PSendSysMessage("Player limits: amount %u, min. security level %s.",pLimit,secName);
5852 return true;
5855 bool ChatHandler::HandleCastCommand(const char* args)
5857 if(!*args)
5858 return false;
5860 Unit* target = getSelectedUnit();
5862 if(!target)
5864 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5865 SetSentErrorMessage(true);
5866 return false;
5869 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5870 uint32 spell = extractSpellIdFromLink((char*)args);
5871 if(!spell)
5872 return false;
5874 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
5875 if(!spellInfo)
5876 return false;
5878 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
5880 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
5881 SetSentErrorMessage(true);
5882 return false;
5885 char* trig_str = strtok(NULL, " ");
5886 if(trig_str)
5888 int l = strlen(trig_str);
5889 if(strncmp(trig_str,"triggered",l) != 0 )
5890 return false;
5893 bool triggered = (trig_str != NULL);
5895 m_session->GetPlayer()->CastSpell(target,spell,triggered);
5897 return true;
5900 bool ChatHandler::HandleCastBackCommand(const char* args)
5902 Creature* caster = getSelectedCreature();
5904 if(!caster)
5906 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5907 SetSentErrorMessage(true);
5908 return false;
5911 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
5912 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5913 uint32 spell = extractSpellIdFromLink((char*)args);
5914 if(!spell || !sSpellStore.LookupEntry(spell))
5915 return false;
5917 char* trig_str = strtok(NULL, " ");
5918 if(trig_str)
5920 int l = strlen(trig_str);
5921 if(strncmp(trig_str,"triggered",l) != 0 )
5922 return false;
5925 bool triggered = (trig_str != NULL);
5927 // update orientation at server
5928 caster->SetOrientation(caster->GetAngle(m_session->GetPlayer()));
5930 // and client
5931 WorldPacket data;
5932 caster->BuildHeartBeatMsg(&data);
5933 caster->SendMessageToSet(&data,true);
5935 caster->CastSpell(m_session->GetPlayer(),spell,triggered);
5937 return true;
5940 bool ChatHandler::HandleCastDistCommand(const char* args)
5942 if(!*args)
5943 return false;
5945 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5946 uint32 spell = extractSpellIdFromLink((char*)args);
5947 if(!spell)
5948 return false;
5950 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
5951 if(!spellInfo)
5952 return false;
5954 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
5956 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
5957 SetSentErrorMessage(true);
5958 return false;
5961 char *distStr = strtok(NULL, " ");
5963 float dist = 0;
5965 if(distStr)
5966 sscanf(distStr, "%f", &dist);
5968 char* trig_str = strtok(NULL, " ");
5969 if(trig_str)
5971 int l = strlen(trig_str);
5972 if(strncmp(trig_str,"triggered",l) != 0 )
5973 return false;
5976 bool triggered = (trig_str != NULL);
5978 float x,y,z;
5979 m_session->GetPlayer()->GetClosePoint(x,y,z,dist);
5981 m_session->GetPlayer()->CastSpell(x,y,z,spell,triggered);
5982 return true;
5985 bool ChatHandler::HandleCastTargetCommand(const char* args)
5987 Creature* caster = getSelectedCreature();
5989 if(!caster)
5991 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5992 SetSentErrorMessage(true);
5993 return false;
5996 if(!caster->getVictim())
5998 SendSysMessage(LANG_SELECTED_TARGET_NOT_HAVE_VICTIM);
5999 SetSentErrorMessage(true);
6000 return false;
6003 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
6004 uint32 spell = extractSpellIdFromLink((char*)args);
6005 if(!spell || !sSpellStore.LookupEntry(spell))
6006 return false;
6008 char* trig_str = strtok(NULL, " ");
6009 if(trig_str)
6011 int l = strlen(trig_str);
6012 if(strncmp(trig_str,"triggered",l) != 0 )
6013 return false;
6016 bool triggered = (trig_str != NULL);
6018 // update orientation at server
6019 caster->SetOrientation(caster->GetAngle(m_session->GetPlayer()));
6021 // and client
6022 WorldPacket data;
6023 caster->BuildHeartBeatMsg(&data);
6024 caster->SendMessageToSet(&data,true);
6026 caster->CastSpell(caster->getVictim(),spell,triggered);
6028 return true;
6032 ComeToMe command REQUIRED for 3rd party scripting library to have access to PointMovementGenerator
6033 Without this function 3rd party scripting library will get linking errors (unresolved external)
6034 when attempting to use the PointMovementGenerator
6036 bool ChatHandler::HandleComeToMeCommand(const char *args)
6038 Creature* caster = getSelectedCreature();
6040 if(!caster)
6042 SendSysMessage(LANG_SELECT_CREATURE);
6043 SetSentErrorMessage(true);
6044 return false;
6047 char* newFlagStr = strtok((char*)args, " ");
6049 if(!newFlagStr)
6050 return false;
6052 uint32 newFlags = atoi(newFlagStr);
6054 caster->SetUnitMovementFlags(newFlags);
6056 Player* pl = m_session->GetPlayer();
6058 caster->GetMotionMaster()->MovePoint(0, pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ());
6059 return true;
6062 bool ChatHandler::HandleCastSelfCommand(const char* args)
6064 if(!*args)
6065 return false;
6067 Unit* target = getSelectedUnit();
6069 if(!target)
6071 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
6072 SetSentErrorMessage(true);
6073 return false;
6076 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
6077 uint32 spell = extractSpellIdFromLink((char*)args);
6078 if(!spell)
6079 return false;
6081 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
6082 if(!spellInfo)
6083 return false;
6085 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
6087 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
6088 SetSentErrorMessage(true);
6089 return false;
6092 target->CastSpell(target,spell,false);
6094 return true;
6097 std::string GetTimeString(uint32 time)
6099 uint16 days = time / DAY, hours = (time % DAY) / HOUR, minute = (time % HOUR) / MINUTE;
6100 std::ostringstream ss;
6101 if(days) ss << days << "d ";
6102 if(hours) ss << hours << "h ";
6103 ss << minute << "m";
6104 return ss.str();
6107 bool ChatHandler::HandleInstanceListBindsCommand(const char* /*args*/)
6109 Player* player = getSelectedPlayer();
6110 if (!player) player = m_session->GetPlayer();
6111 uint32 counter = 0;
6112 for(uint8 i = 0; i < TOTAL_DIFFICULTIES; ++i)
6114 Player::BoundInstancesMap &binds = player->GetBoundInstances(i);
6115 for(Player::BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end(); ++itr)
6117 InstanceSave *save = itr->second.save;
6118 std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
6119 PSendSysMessage("map: %d inst: %d perm: %s diff: %s canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty() == DIFFICULTY_NORMAL ? "normal" : "heroic", save->CanReset() ? "yes" : "no", timeleft.c_str());
6120 counter++;
6123 PSendSysMessage("player binds: %d", counter);
6124 counter = 0;
6125 Group *group = player->GetGroup();
6126 if(group)
6128 for(uint8 i = 0; i < TOTAL_DIFFICULTIES; ++i)
6130 Group::BoundInstancesMap &binds = group->GetBoundInstances(i);
6131 for(Group::BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end(); ++itr)
6133 InstanceSave *save = itr->second.save;
6134 std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
6135 PSendSysMessage("map: %d inst: %d perm: %s diff: %s canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty() == DIFFICULTY_NORMAL ? "normal" : "heroic", save->CanReset() ? "yes" : "no", timeleft.c_str());
6136 counter++;
6140 PSendSysMessage("group binds: %d", counter);
6142 return true;
6145 bool ChatHandler::HandleInstanceUnbindCommand(const char* args)
6147 if(!*args)
6148 return false;
6150 std::string cmd = args;
6151 if(cmd == "all")
6153 Player* player = getSelectedPlayer();
6154 if (!player) player = m_session->GetPlayer();
6155 uint32 counter = 0;
6156 for(uint8 i = 0; i < TOTAL_DIFFICULTIES; ++i)
6158 Player::BoundInstancesMap &binds = player->GetBoundInstances(i);
6159 for(Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end();)
6161 if(itr->first != player->GetMapId())
6163 InstanceSave *save = itr->second.save;
6164 std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
6165 PSendSysMessage("unbinding map: %d inst: %d perm: %s diff: %s canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty() == DIFFICULTY_NORMAL ? "normal" : "heroic", save->CanReset() ? "yes" : "no", timeleft.c_str());
6166 player->UnbindInstance(itr, i);
6167 counter++;
6169 else
6170 ++itr;
6173 PSendSysMessage("instances unbound: %d", counter);
6175 return true;
6178 bool ChatHandler::HandleInstanceStatsCommand(const char* /*args*/)
6180 PSendSysMessage("instances loaded: %d", MapManager::Instance().GetNumInstances());
6181 PSendSysMessage("players in instances: %d", MapManager::Instance().GetNumPlayersInInstances());
6182 PSendSysMessage("instance saves: %d", sInstanceSaveManager.GetNumInstanceSaves());
6183 PSendSysMessage("players bound: %d", sInstanceSaveManager.GetNumBoundPlayersTotal());
6184 PSendSysMessage("groups bound: %d", sInstanceSaveManager.GetNumBoundGroupsTotal());
6185 return true;
6188 bool ChatHandler::HandleInstanceSaveDataCommand(const char * /*args*/)
6190 Player* pl = m_session->GetPlayer();
6192 Map* map = pl->GetMap();
6193 if (!map->IsDungeon())
6195 PSendSysMessage("Map is not a dungeon.");
6196 SetSentErrorMessage(true);
6197 return false;
6200 if (!((InstanceMap*)map)->GetInstanceData())
6202 PSendSysMessage("Map has no instance data.");
6203 SetSentErrorMessage(true);
6204 return false;
6207 ((InstanceMap*)map)->GetInstanceData()->SaveToDB();
6208 return true;
6211 /// Display the list of GMs
6212 bool ChatHandler::HandleGMListFullCommand(const char* /*args*/)
6214 ///- Get the accounts with GM Level >0
6215 QueryResult *result = loginDatabase.Query( "SELECT username,gmlevel FROM account WHERE gmlevel > 0" );
6216 if(result)
6218 SendSysMessage(LANG_GMLIST);
6219 SendSysMessage("========================");
6220 SendSysMessage(LANG_GMLIST_HEADER);
6221 SendSysMessage("========================");
6223 ///- Circle through them. Display username and GM level
6226 Field *fields = result->Fetch();
6227 PSendSysMessage("|%15s|%6s|", fields[0].GetString(),fields[1].GetString());
6228 }while( result->NextRow() );
6230 PSendSysMessage("========================");
6231 delete result;
6233 else
6234 PSendSysMessage(LANG_GMLIST_EMPTY);
6235 return true;
6238 /// Define the 'Message of the day' for the realm
6239 bool ChatHandler::HandleServerSetMotdCommand(const char* args)
6241 sWorld.SetMotd(args);
6242 PSendSysMessage(LANG_MOTD_NEW, args);
6243 return true;
6246 /// Set/Unset the expansion level for an account
6247 bool ChatHandler::HandleAccountSetAddonCommand(const char* args)
6249 ///- Get the command line arguments
6250 char *szAcc = strtok((char*)args," ");
6251 char *szExp = strtok(NULL," ");
6253 if(!szAcc)
6254 return false;
6256 std::string account_name;
6257 uint32 account_id;
6259 if(!szExp)
6261 Player* player = getSelectedPlayer();
6262 if(!player)
6263 return false;
6265 account_id = player->GetSession()->GetAccountId();
6266 accmgr.GetName(account_id,account_name);
6267 szExp = szAcc;
6269 else
6271 ///- Convert Account name to Upper Format
6272 account_name = szAcc;
6273 if(!AccountMgr::normilizeString(account_name))
6275 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
6276 SetSentErrorMessage(true);
6277 return false;
6280 account_id = accmgr.GetId(account_name);
6281 if(!account_id)
6283 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
6284 SetSentErrorMessage(true);
6285 return false;
6290 // Let set addon state only for lesser (strong) security level
6291 // or to self account
6292 if (m_session && m_session->GetAccountId () != account_id &&
6293 HasLowerSecurityAccount (NULL,account_id,true))
6294 return false;
6296 int lev=atoi(szExp); //get int anyway (0 if error)
6297 if(lev < 0)
6298 return false;
6300 // No SQL injection
6301 loginDatabase.PExecute("UPDATE account SET expansion = '%d' WHERE id = '%u'",lev,account_id);
6302 PSendSysMessage(LANG_ACCOUNT_SETADDON,account_name.c_str(),account_id,lev);
6303 return true;
6306 //Send items by mail
6307 bool ChatHandler::HandleSendItemsCommand(const char* args)
6309 // format: name "subject text" "mail text" item1[:count1] item2[:count2] ... item12[:count12]
6310 Player* receiver;
6311 uint64 receiver_guid;
6312 std::string receiver_name;
6313 if(!extractPlayerTarget((char*)args,&receiver,&receiver_guid,&receiver_name))
6314 return false;
6316 char* tail1 = strtok(NULL, "");
6317 if(!tail1)
6318 return false;
6320 char* msgSubject = extractQuotedArg(tail1);
6321 if (!msgSubject)
6322 return false;
6324 char* tail2 = strtok(NULL, "");
6325 if(!tail2)
6326 return false;
6328 char* msgText = extractQuotedArg(tail2);
6329 if (!msgText)
6330 return false;
6332 // msgSubject, msgText isn't NUL after prev. check
6333 std::string subject = msgSubject;
6334 std::string text = msgText;
6336 // extract items
6337 typedef std::pair<uint32,uint32> ItemPair;
6338 typedef std::list< ItemPair > ItemPairs;
6339 ItemPairs items;
6341 // get all tail string
6342 char* tail = strtok(NULL, "");
6344 // get from tail next item str
6345 while(char* itemStr = strtok(tail, " "))
6347 // and get new tail
6348 tail = strtok(NULL, "");
6350 // parse item str
6351 char* itemIdStr = strtok(itemStr, ":");
6352 char* itemCountStr = strtok(NULL, " ");
6354 uint32 item_id = atoi(itemIdStr);
6355 if(!item_id)
6356 return false;
6358 ItemPrototype const* item_proto = objmgr.GetItemPrototype(item_id);
6359 if(!item_proto)
6361 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
6362 SetSentErrorMessage(true);
6363 return false;
6366 uint32 item_count = itemCountStr ? atoi(itemCountStr) : 1;
6367 if(item_count < 1 || item_proto->MaxCount > 0 && item_count > uint32(item_proto->MaxCount))
6369 PSendSysMessage(LANG_COMMAND_INVALID_ITEM_COUNT, item_count,item_id);
6370 SetSentErrorMessage(true);
6371 return false;
6374 while(item_count > item_proto->GetMaxStackSize())
6376 items.push_back(ItemPair(item_id,item_proto->GetMaxStackSize()));
6377 item_count -= item_proto->GetMaxStackSize();
6380 items.push_back(ItemPair(item_id,item_count));
6382 if(items.size() > MAX_MAIL_ITEMS)
6384 PSendSysMessage(LANG_COMMAND_MAIL_ITEMS_LIMIT, MAX_MAIL_ITEMS);
6385 SetSentErrorMessage(true);
6386 return false;
6390 // from console show not existed sender
6391 uint32 sender_guidlo = m_session ? m_session->GetPlayer()->GetGUIDLow() : 0;
6393 uint32 messagetype = MAIL_NORMAL;
6394 uint32 stationery = MAIL_STATIONERY_GM;
6395 uint32 itemTextId = !text.empty() ? objmgr.CreateItemText( text ) : 0;
6397 // fill mail
6398 MailItemsInfo mi; // item list preparing
6400 for(ItemPairs::const_iterator itr = items.begin(); itr != items.end(); ++itr)
6402 if(Item* item = Item::CreateItem(itr->first,itr->second,m_session ? m_session->GetPlayer() : 0))
6404 item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted
6405 mi.AddItem(item->GetGUIDLow(), item->GetEntry(), item);
6409 WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, &mi, 0, 0, MAIL_CHECK_MASK_NONE);
6411 std::string nameLink = playerLink(receiver_name);
6412 PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
6413 return true;
6416 ///Send money by mail
6417 bool ChatHandler::HandleSendMoneyCommand(const char* args)
6419 /// format: name "subject text" "mail text" money
6421 Player* receiver;
6422 uint64 receiver_guid;
6423 std::string receiver_name;
6424 if(!extractPlayerTarget((char*)args,&receiver,&receiver_guid,&receiver_name))
6425 return false;
6427 char* tail1 = strtok(NULL, "");
6428 if (!tail1)
6429 return false;
6431 char* msgSubject = extractQuotedArg(tail1);
6432 if (!msgSubject)
6433 return false;
6435 char* tail2 = strtok(NULL, "");
6436 if (!tail2)
6437 return false;
6439 char* msgText = extractQuotedArg(tail2);
6440 if (!msgText)
6441 return false;
6443 char* money_str = strtok(NULL, "");
6444 int32 money = money_str ? atoi(money_str) : 0;
6445 if (money <= 0)
6446 return false;
6448 // msgSubject, msgText isn't NUL after prev. check
6449 std::string subject = msgSubject;
6450 std::string text = msgText;
6452 // from console show not existed sender
6453 uint32 sender_guidlo = m_session ? m_session->GetPlayer()->GetGUIDLow() : 0;
6455 uint32 messagetype = MAIL_NORMAL;
6456 uint32 stationery = MAIL_STATIONERY_GM;
6457 uint32 itemTextId = !text.empty() ? objmgr.CreateItemText( text ) : 0;
6459 WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, NULL, money, 0, MAIL_CHECK_MASK_NONE);
6461 std::string nameLink = playerLink(receiver_name);
6462 PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
6463 return true;
6466 /// Send a message to a player in game
6467 bool ChatHandler::HandleSendMessageCommand(const char* args)
6469 ///- Find the player
6470 Player *rPlayer;
6471 if(!extractPlayerTarget((char*)args,&rPlayer))
6472 return false;
6474 char* msg_str = strtok(NULL, "");
6475 if(!msg_str)
6476 return false;
6478 ///- Check that he is not logging out.
6479 if(rPlayer->GetSession()->isLogingOut())
6481 SendSysMessage(LANG_PLAYER_NOT_FOUND);
6482 SetSentErrorMessage(true);
6483 return false;
6486 ///- Send the message
6487 //Use SendAreaTriggerMessage for fastest delivery.
6488 rPlayer->GetSession()->SendAreaTriggerMessage("%s", msg_str);
6489 rPlayer->GetSession()->SendAreaTriggerMessage("|cffff0000[Message from administrator]:|r");
6491 //Confirmation message
6492 std::string nameLink = GetNameLink(rPlayer);
6493 PSendSysMessage(LANG_SENDMESSAGE,nameLink.c_str(),msg_str);
6494 return true;
6497 bool ChatHandler::HandleFlushArenaPointsCommand(const char * /*args*/)
6499 sBattleGroundMgr.DistributeArenaPoints();
6500 return true;
6503 bool ChatHandler::HandleModifyGenderCommand(const char *args)
6505 if(!*args)
6506 return false;
6508 Player *player = getSelectedPlayer();
6510 if(!player)
6512 PSendSysMessage(LANG_PLAYER_NOT_FOUND);
6513 SetSentErrorMessage(true);
6514 return false;
6517 PlayerInfo const* info = objmgr.GetPlayerInfo(player->getRace(), player->getClass());
6518 if(!info)
6519 return false;
6521 char const* gender_str = (char*)args;
6522 int gender_len = strlen(gender_str);
6524 Gender gender;
6526 if(!strncmp(gender_str, "male", gender_len)) // MALE
6528 if(player->getGender() == GENDER_MALE)
6529 return true;
6531 gender = GENDER_MALE;
6533 else if (!strncmp(gender_str, "female", gender_len)) // FEMALE
6535 if(player->getGender() == GENDER_FEMALE)
6536 return true;
6538 gender = GENDER_FEMALE;
6540 else
6542 SendSysMessage(LANG_MUST_MALE_OR_FEMALE);
6543 SetSentErrorMessage(true);
6544 return false;
6547 // Set gender
6548 player->SetByteValue(UNIT_FIELD_BYTES_0, 2, gender);
6549 player->SetByteValue(PLAYER_BYTES_3, 0, gender);
6551 // Change display ID
6552 player->SetDisplayId(gender ? info->displayId_f : info->displayId_m);
6553 player->SetNativeDisplayId(gender ? info->displayId_f : info->displayId_m);
6555 char const* gender_full = gender ? "female" : "male";
6557 PSendSysMessage(LANG_YOU_CHANGE_GENDER, GetNameLink(player).c_str(), gender_full);
6559 if (needReportToTarget(player))
6560 ChatHandler(player).PSendSysMessage(LANG_YOUR_GENDER_CHANGED, gender_full, GetNameLink().c_str());
6562 return true;