[7160] Implement (un-)learning skill level dependent spells at skill level change.
[getmangos.git] / src / game / Level3.cpp
blob8ab22b392a2deff8c5c295a12b24f59ddfc7f7c9
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 "SpellAuras.h"
37 #include "ScriptCalls.h"
38 #include "Language.h"
39 #include "GridNotifiersImpl.h"
40 #include "CellImpl.h"
41 #include "Weather.h"
42 #include "PointMovementGenerator.h"
43 #include "TargetedMovementGenerator.h"
44 #include "SkillDiscovery.h"
45 #include "SkillExtraItems.h"
46 #include "SystemConfig.h"
47 #include "Config/ConfigEnv.h"
48 #include "Util.h"
49 #include "ItemEnchantmentMgr.h"
50 #include "BattleGroundMgr.h"
51 #include "InstanceSaveMgr.h"
52 #include "InstanceData.h"
54 //reload commands
55 bool ChatHandler::HandleReloadAllCommand(const char*)
57 HandleReloadSkillFishingBaseLevelCommand("");
59 HandleReloadAllAreaCommand("");
60 HandleReloadAllLootCommand("");
61 HandleReloadAllNpcCommand("");
62 HandleReloadAllQuestCommand("");
63 HandleReloadAllSpellCommand("");
64 HandleReloadAllItemCommand("");
65 HandleReloadAllLocalesCommand("");
67 HandleReloadCommandCommand("");
68 HandleReloadReservedNameCommand("");
69 HandleReloadMangosStringCommand("");
70 HandleReloadGameTeleCommand("");
71 return true;
74 bool ChatHandler::HandleReloadAllAreaCommand(const char*)
76 //HandleReloadQuestAreaTriggersCommand(""); -- reloaded in HandleReloadAllQuestCommand
77 HandleReloadAreaTriggerTeleportCommand("");
78 HandleReloadAreaTriggerTavernCommand("");
79 HandleReloadGameGraveyardZoneCommand("");
80 return true;
83 bool ChatHandler::HandleReloadAllLootCommand(const char*)
85 sLog.outString( "Re-Loading Loot Tables..." );
86 LoadLootTables();
87 SendGlobalSysMessage("DB tables `*_loot_template` reloaded.");
88 return true;
91 bool ChatHandler::HandleReloadAllNpcCommand(const char* /*args*/)
93 HandleReloadNpcGossipCommand("a");
94 HandleReloadNpcOptionCommand("a");
95 HandleReloadNpcTrainerCommand("a");
96 HandleReloadNpcVendorCommand("a");
97 return true;
100 bool ChatHandler::HandleReloadAllQuestCommand(const char* /*args*/)
102 HandleReloadQuestAreaTriggersCommand("a");
103 HandleReloadQuestTemplateCommand("a");
105 sLog.outString( "Re-Loading Quests Relations..." );
106 objmgr.LoadQuestRelations();
107 SendGlobalSysMessage("DB tables `*_questrelation` and `*_involvedrelation` reloaded.");
108 return true;
111 bool ChatHandler::HandleReloadAllScriptsCommand(const char*)
113 if(sWorld.IsScriptScheduled())
115 PSendSysMessage("DB scripts used currently, please attempt reload later.");
116 SetSentErrorMessage(true);
117 return false;
120 sLog.outString( "Re-Loading Scripts..." );
121 HandleReloadGameObjectScriptsCommand("a");
122 HandleReloadEventScriptsCommand("a");
123 HandleReloadQuestEndScriptsCommand("a");
124 HandleReloadQuestStartScriptsCommand("a");
125 HandleReloadSpellScriptsCommand("a");
126 SendGlobalSysMessage("DB tables `*_scripts` reloaded.");
127 HandleReloadDbScriptStringCommand("a");
128 return true;
131 bool ChatHandler::HandleReloadAllSpellCommand(const char*)
133 HandleReloadSkillDiscoveryTemplateCommand("a");
134 HandleReloadSkillExtraItemTemplateCommand("a");
135 HandleReloadSpellAffectCommand("a");
136 HandleReloadSpellChainCommand("a");
137 HandleReloadSpellElixirCommand("a");
138 HandleReloadSpellLearnSpellCommand("a");
139 HandleReloadSpellProcEventCommand("a");
140 HandleReloadSpellScriptTargetCommand("a");
141 HandleReloadSpellTargetPositionCommand("a");
142 HandleReloadSpellThreatsCommand("a");
143 HandleReloadSpellPetAurasCommand("a");
144 return true;
147 bool ChatHandler::HandleReloadAllItemCommand(const char*)
149 HandleReloadPageTextsCommand("a");
150 HandleReloadItemEnchantementsCommand("a");
151 return true;
154 bool ChatHandler::HandleReloadAllLocalesCommand(const char* /*args*/)
156 HandleReloadLocalesCreatureCommand("a");
157 HandleReloadLocalesGameobjectCommand("a");
158 HandleReloadLocalesItemCommand("a");
159 HandleReloadLocalesNpcTextCommand("a");
160 HandleReloadLocalesPageTextCommand("a");
161 HandleReloadLocalesQuestCommand("a");
162 return true;
165 bool ChatHandler::HandleReloadConfigCommand(const char* /*args*/)
167 sLog.outString( "Re-Loading config settings..." );
168 sWorld.LoadConfigSettings(true);
169 SendGlobalSysMessage("World config settings reloaded.");
170 return true;
173 bool ChatHandler::HandleReloadAreaTriggerTavernCommand(const char*)
175 sLog.outString( "Re-Loading Tavern Area Triggers..." );
176 objmgr.LoadTavernAreaTriggers();
177 SendGlobalSysMessage("DB table `areatrigger_tavern` reloaded.");
178 return true;
181 bool ChatHandler::HandleReloadAreaTriggerTeleportCommand(const char*)
183 sLog.outString( "Re-Loading AreaTrigger teleport definitions..." );
184 objmgr.LoadAreaTriggerTeleports();
185 SendGlobalSysMessage("DB table `areatrigger_teleport` reloaded.");
186 return true;
189 bool ChatHandler::HandleReloadCommandCommand(const char*)
191 load_command_table = true;
192 SendGlobalSysMessage("DB table `command` will be reloaded at next chat command use.");
193 return true;
196 bool ChatHandler::HandleReloadCreatureQuestRelationsCommand(const char*)
198 sLog.outString( "Loading Quests Relations... (`creature_questrelation`)" );
199 objmgr.LoadCreatureQuestRelations();
200 SendGlobalSysMessage("DB table `creature_questrelation` (creature quest givers) reloaded.");
201 return true;
204 bool ChatHandler::HandleReloadCreatureQuestInvRelationsCommand(const char*)
206 sLog.outString( "Loading Quests Relations... (`creature_involvedrelation`)" );
207 objmgr.LoadCreatureInvolvedRelations();
208 SendGlobalSysMessage("DB table `creature_involvedrelation` (creature quest takers) reloaded.");
209 return true;
212 bool ChatHandler::HandleReloadGOQuestRelationsCommand(const char*)
214 sLog.outString( "Loading Quests Relations... (`gameobject_questrelation`)" );
215 objmgr.LoadGameobjectQuestRelations();
216 SendGlobalSysMessage("DB table `gameobject_questrelation` (gameobject quest givers) reloaded.");
217 return true;
220 bool ChatHandler::HandleReloadGOQuestInvRelationsCommand(const char*)
222 sLog.outString( "Loading Quests Relations... (`gameobject_involvedrelation`)" );
223 objmgr.LoadGameobjectInvolvedRelations();
224 SendGlobalSysMessage("DB table `gameobject_involvedrelation` (gameobject quest takers) reloaded.");
225 return true;
228 bool ChatHandler::HandleReloadQuestAreaTriggersCommand(const char*)
230 sLog.outString( "Re-Loading Quest Area Triggers..." );
231 objmgr.LoadQuestAreaTriggers();
232 SendGlobalSysMessage("DB table `areatrigger_involvedrelation` (quest area triggers) reloaded.");
233 return true;
236 bool ChatHandler::HandleReloadQuestTemplateCommand(const char*)
238 sLog.outString( "Re-Loading Quest Templates..." );
239 objmgr.LoadQuests();
240 SendGlobalSysMessage("DB table `quest_template` (quest definitions) reloaded.");
241 return true;
244 bool ChatHandler::HandleReloadLootTemplatesCreatureCommand(const char*)
246 sLog.outString( "Re-Loading Loot Tables... (`creature_loot_template`)" );
247 LoadLootTemplates_Creature();
248 LootTemplates_Creature.CheckLootRefs();
249 SendGlobalSysMessage("DB table `creature_loot_template` reloaded.");
250 return true;
253 bool ChatHandler::HandleReloadLootTemplatesDisenchantCommand(const char*)
255 sLog.outString( "Re-Loading Loot Tables... (`disenchant_loot_template`)" );
256 LoadLootTemplates_Disenchant();
257 LootTemplates_Disenchant.CheckLootRefs();
258 SendGlobalSysMessage("DB table `disenchant_loot_template` reloaded.");
259 return true;
262 bool ChatHandler::HandleReloadLootTemplatesFishingCommand(const char*)
264 sLog.outString( "Re-Loading Loot Tables... (`fishing_loot_template`)" );
265 LoadLootTemplates_Fishing();
266 LootTemplates_Fishing.CheckLootRefs();
267 SendGlobalSysMessage("DB table `fishing_loot_template` reloaded.");
268 return true;
271 bool ChatHandler::HandleReloadLootTemplatesGameobjectCommand(const char*)
273 sLog.outString( "Re-Loading Loot Tables... (`gameobject_loot_template`)" );
274 LoadLootTemplates_Gameobject();
275 LootTemplates_Gameobject.CheckLootRefs();
276 SendGlobalSysMessage("DB table `gameobject_loot_template` reloaded.");
277 return true;
280 bool ChatHandler::HandleReloadLootTemplatesItemCommand(const char*)
282 sLog.outString( "Re-Loading Loot Tables... (`item_loot_template`)" );
283 LoadLootTemplates_Item();
284 LootTemplates_Item.CheckLootRefs();
285 SendGlobalSysMessage("DB table `item_loot_template` reloaded.");
286 return true;
289 bool ChatHandler::HandleReloadLootTemplatesMillingCommand(const char*)
291 sLog.outString( "Re-Loading Loot Tables... (`milling_loot_template`)" );
292 LoadLootTemplates_Milling();
293 LootTemplates_Milling.CheckLootRefs();
294 SendGlobalSysMessage("DB table `milling_loot_template` reloaded.");
295 return true;
298 bool ChatHandler::HandleReloadLootTemplatesPickpocketingCommand(const char*)
300 sLog.outString( "Re-Loading Loot Tables... (`pickpocketing_loot_template`)" );
301 LoadLootTemplates_Pickpocketing();
302 LootTemplates_Pickpocketing.CheckLootRefs();
303 SendGlobalSysMessage("DB table `pickpocketing_loot_template` reloaded.");
304 return true;
307 bool ChatHandler::HandleReloadLootTemplatesProspectingCommand(const char*)
309 sLog.outString( "Re-Loading Loot Tables... (`prospecting_loot_template`)" );
310 LoadLootTemplates_Prospecting();
311 LootTemplates_Prospecting.CheckLootRefs();
312 SendGlobalSysMessage("DB table `prospecting_loot_template` reloaded.");
313 return true;
316 bool ChatHandler::HandleReloadLootTemplatesQuestMailCommand(const char*)
318 sLog.outString( "Re-Loading Loot Tables... (`quest_mail_loot_template`)" );
319 LoadLootTemplates_QuestMail();
320 LootTemplates_QuestMail.CheckLootRefs();
321 SendGlobalSysMessage("DB table `quest_mail_loot_template` reloaded.");
322 return true;
325 bool ChatHandler::HandleReloadLootTemplatesReferenceCommand(const char*)
327 sLog.outString( "Re-Loading Loot Tables... (`reference_loot_template`)" );
328 LoadLootTemplates_Reference();
329 SendGlobalSysMessage("DB table `reference_loot_template` reloaded.");
330 return true;
333 bool ChatHandler::HandleReloadLootTemplatesSkinningCommand(const char*)
335 sLog.outString( "Re-Loading Loot Tables... (`skinning_loot_template`)" );
336 LoadLootTemplates_Skinning();
337 LootTemplates_Skinning.CheckLootRefs();
338 SendGlobalSysMessage("DB table `skinning_loot_template` reloaded.");
339 return true;
342 bool ChatHandler::HandleReloadLootTemplatesSpellCommand(const char*)
344 sLog.outString( "Re-Loading Loot Tables... (`spell_loot_template`)" );
345 LoadLootTemplates_Spell();
346 LootTemplates_Spell.CheckLootRefs();
347 SendGlobalSysMessage("DB table `spell_loot_template` reloaded.");
348 return true;
351 bool ChatHandler::HandleReloadMangosStringCommand(const char*)
353 sLog.outString( "Re-Loading mangos_string Table!" );
354 objmgr.LoadMangosStrings();
355 SendGlobalSysMessage("DB table `mangos_string` reloaded.");
356 return true;
359 bool ChatHandler::HandleReloadNpcOptionCommand(const char*)
361 sLog.outString( "Re-Loading `npc_option` Table!" );
362 objmgr.LoadNpcOptions();
363 SendGlobalSysMessage("DB table `npc_option` reloaded.");
364 return true;
367 bool ChatHandler::HandleReloadNpcGossipCommand(const char*)
369 sLog.outString( "Re-Loading `npc_gossip` Table!" );
370 objmgr.LoadNpcTextId();
371 SendGlobalSysMessage("DB table `npc_gossip` reloaded.");
372 return true;
375 bool ChatHandler::HandleReloadNpcTrainerCommand(const char*)
377 sLog.outString( "Re-Loading `npc_trainer` Table!" );
378 objmgr.LoadTrainerSpell();
379 SendGlobalSysMessage("DB table `npc_trainer` reloaded.");
380 return true;
383 bool ChatHandler::HandleReloadNpcVendorCommand(const char*)
385 sLog.outString( "Re-Loading `npc_vendor` Table!" );
386 objmgr.LoadVendors();
387 SendGlobalSysMessage("DB table `npc_vendor` reloaded.");
388 return true;
391 bool ChatHandler::HandleReloadReservedNameCommand(const char*)
393 sLog.outString( "Loading ReservedNames... (`reserved_name`)" );
394 objmgr.LoadReservedPlayersNames();
395 SendGlobalSysMessage("DB table `reserved_name` (player reserved names) reloaded.");
396 return true;
399 bool ChatHandler::HandleReloadSkillDiscoveryTemplateCommand(const char* /*args*/)
401 sLog.outString( "Re-Loading Skill Discovery Table..." );
402 LoadSkillDiscoveryTable();
403 SendGlobalSysMessage("DB table `skill_discovery_template` (recipes discovered at crafting) reloaded.");
404 return true;
407 bool ChatHandler::HandleReloadSkillExtraItemTemplateCommand(const char* /*args*/)
409 sLog.outString( "Re-Loading Skill Extra Item Table..." );
410 LoadSkillExtraItemTable();
411 SendGlobalSysMessage("DB table `skill_extra_item_template` (extra item creation when crafting) reloaded.");
412 return true;
415 bool ChatHandler::HandleReloadSkillFishingBaseLevelCommand(const char* /*args*/)
417 sLog.outString( "Re-Loading Skill Fishing base level requirements..." );
418 objmgr.LoadFishingBaseSkillLevel();
419 SendGlobalSysMessage("DB table `skill_fishing_base_level` (fishing base level for zone/subzone) reloaded.");
420 return true;
423 bool ChatHandler::HandleReloadSpellAffectCommand(const char*)
425 sLog.outString( "Re-Loading SpellAffect definitions..." );
426 spellmgr.LoadSpellAffects();
427 SendGlobalSysMessage("DB table `spell_affect` (spell mods apply requirements) reloaded.");
428 return true;
431 bool ChatHandler::HandleReloadSpellChainCommand(const char*)
433 sLog.outString( "Re-Loading Spell Chain Data... " );
434 spellmgr.LoadSpellChains();
435 SendGlobalSysMessage("DB table `spell_chain` (spell ranks) reloaded.");
436 return true;
439 bool ChatHandler::HandleReloadSpellElixirCommand(const char*)
441 sLog.outString( "Re-Loading Spell Elixir types..." );
442 spellmgr.LoadSpellElixirs();
443 SendGlobalSysMessage("DB table `spell_elixir` (spell elixir types) reloaded.");
444 return true;
447 bool ChatHandler::HandleReloadSpellLearnSpellCommand(const char*)
449 sLog.outString( "Re-Loading Spell Learn Spells..." );
450 spellmgr.LoadSpellLearnSpells();
451 SendGlobalSysMessage("DB table `spell_learn_spell` reloaded.");
452 return true;
455 bool ChatHandler::HandleReloadSpellProcEventCommand(const char*)
457 sLog.outString( "Re-Loading Spell Proc Event conditions..." );
458 spellmgr.LoadSpellProcEvents();
459 SendGlobalSysMessage("DB table `spell_proc_event` (spell proc trigger requirements) reloaded.");
460 return true;
463 bool ChatHandler::HandleReloadSpellScriptTargetCommand(const char*)
465 sLog.outString( "Re-Loading SpellsScriptTarget..." );
466 spellmgr.LoadSpellScriptTarget();
467 SendGlobalSysMessage("DB table `spell_script_target` (spell targets selection in case specific creature/GO requirements) reloaded.");
468 return true;
471 bool ChatHandler::HandleReloadSpellTargetPositionCommand(const char*)
473 sLog.outString( "Re-Loading Spell target coordinates..." );
474 spellmgr.LoadSpellTargetPositions();
475 SendGlobalSysMessage("DB table `spell_target_position` (destination coordinates for spell targets) reloaded.");
476 return true;
479 bool ChatHandler::HandleReloadSpellThreatsCommand(const char*)
481 sLog.outString( "Re-Loading Aggro Spells Definitions...");
482 spellmgr.LoadSpellThreats();
483 SendGlobalSysMessage("DB table `spell_threat` (spell aggro definitions) reloaded.");
484 return true;
487 bool ChatHandler::HandleReloadSpellPetAurasCommand(const char*)
489 sLog.outString( "Re-Loading Spell pet auras...");
490 spellmgr.LoadSpellPetAuras();
491 SendGlobalSysMessage("DB table `spell_pet_auras` reloaded.");
492 return true;
495 bool ChatHandler::HandleReloadPageTextsCommand(const char*)
497 sLog.outString( "Re-Loading Page Texts..." );
498 objmgr.LoadPageTexts();
499 SendGlobalSysMessage("DB table `page_texts` reloaded.");
500 return true;
503 bool ChatHandler::HandleReloadItemEnchantementsCommand(const char*)
505 sLog.outString( "Re-Loading Item Random Enchantments Table..." );
506 LoadRandomEnchantmentsTable();
507 SendGlobalSysMessage("DB table `item_enchantment_template` reloaded.");
508 return true;
511 bool ChatHandler::HandleReloadGameObjectScriptsCommand(const char* arg)
513 if(sWorld.IsScriptScheduled())
515 SendSysMessage("DB scripts used currently, please attempt reload later.");
516 SetSentErrorMessage(true);
517 return false;
520 if(*arg!='a')
521 sLog.outString( "Re-Loading Scripts from `gameobject_scripts`...");
523 objmgr.LoadGameObjectScripts();
525 if(*arg!='a')
526 SendGlobalSysMessage("DB table `gameobject_scripts` reloaded.");
528 return true;
531 bool ChatHandler::HandleReloadEventScriptsCommand(const char* arg)
533 if(sWorld.IsScriptScheduled())
535 SendSysMessage("DB scripts used currently, please attempt reload later.");
536 SetSentErrorMessage(true);
537 return false;
540 if(*arg!='a')
541 sLog.outString( "Re-Loading Scripts from `event_scripts`...");
543 objmgr.LoadEventScripts();
545 if(*arg!='a')
546 SendGlobalSysMessage("DB table `event_scripts` reloaded.");
548 return true;
551 bool ChatHandler::HandleReloadQuestEndScriptsCommand(const char* arg)
553 if(sWorld.IsScriptScheduled())
555 SendSysMessage("DB scripts used currently, please attempt reload later.");
556 SetSentErrorMessage(true);
557 return false;
560 if(*arg!='a')
561 sLog.outString( "Re-Loading Scripts from `quest_end_scripts`...");
563 objmgr.LoadQuestEndScripts();
565 if(*arg!='a')
566 SendGlobalSysMessage("DB table `quest_end_scripts` reloaded.");
568 return true;
571 bool ChatHandler::HandleReloadQuestStartScriptsCommand(const char* arg)
573 if(sWorld.IsScriptScheduled())
575 SendSysMessage("DB scripts used currently, please attempt reload later.");
576 SetSentErrorMessage(true);
577 return false;
580 if(*arg!='a')
581 sLog.outString( "Re-Loading Scripts from `quest_start_scripts`...");
583 objmgr.LoadQuestStartScripts();
585 if(*arg!='a')
586 SendGlobalSysMessage("DB table `quest_start_scripts` reloaded.");
588 return true;
591 bool ChatHandler::HandleReloadSpellScriptsCommand(const char* arg)
593 if(sWorld.IsScriptScheduled())
595 SendSysMessage("DB scripts used currently, please attempt reload later.");
596 SetSentErrorMessage(true);
597 return false;
600 if(*arg!='a')
601 sLog.outString( "Re-Loading Scripts from `spell_scripts`...");
603 objmgr.LoadSpellScripts();
605 if(*arg!='a')
606 SendGlobalSysMessage("DB table `spell_scripts` reloaded.");
608 return true;
611 bool ChatHandler::HandleReloadDbScriptStringCommand(const char* arg)
613 sLog.outString( "Re-Loading Script strings from `db_script_string`...");
614 objmgr.LoadDbScriptStrings();
615 SendGlobalSysMessage("DB table `db_script_string` reloaded.");
616 return true;
619 bool ChatHandler::HandleReloadGameGraveyardZoneCommand(const char* /*arg*/)
621 sLog.outString( "Re-Loading Graveyard-zone links...");
623 objmgr.LoadGraveyardZones();
625 SendGlobalSysMessage("DB table `game_graveyard_zone` reloaded.");
627 return true;
630 bool ChatHandler::HandleReloadGameTeleCommand(const char* /*arg*/)
632 sLog.outString( "Re-Loading Game Tele coordinates...");
634 objmgr.LoadGameTele();
636 SendGlobalSysMessage("DB table `game_tele` reloaded.");
638 return true;
641 bool ChatHandler::HandleReloadLocalesCreatureCommand(const char* /*arg*/)
643 sLog.outString( "Re-Loading Locales Creature ...");
644 objmgr.LoadCreatureLocales();
645 SendGlobalSysMessage("DB table `locales_creature` reloaded.");
646 return true;
649 bool ChatHandler::HandleReloadLocalesGameobjectCommand(const char* /*arg*/)
651 sLog.outString( "Re-Loading Locales Gameobject ... ");
652 objmgr.LoadGameObjectLocales();
653 SendGlobalSysMessage("DB table `locales_gameobject` reloaded.");
654 return true;
657 bool ChatHandler::HandleReloadLocalesItemCommand(const char* /*arg*/)
659 sLog.outString( "Re-Loading Locales Item ... ");
660 objmgr.LoadItemLocales();
661 SendGlobalSysMessage("DB table `locales_item` reloaded.");
662 return true;
665 bool ChatHandler::HandleReloadLocalesNpcTextCommand(const char* /*arg*/)
667 sLog.outString( "Re-Loading Locales NPC Text ... ");
668 objmgr.LoadNpcTextLocales();
669 SendGlobalSysMessage("DB table `locales_npc_text` reloaded.");
670 return true;
673 bool ChatHandler::HandleReloadLocalesPageTextCommand(const char* /*arg*/)
675 sLog.outString( "Re-Loading Locales Page Text ... ");
676 objmgr.LoadPageTextLocales();
677 SendGlobalSysMessage("DB table `locales_page_text` reloaded.");
678 return true;
681 bool ChatHandler::HandleReloadLocalesQuestCommand(const char* /*arg*/)
683 sLog.outString( "Re-Loading Locales Quest ... ");
684 objmgr.LoadQuestLocales();
685 SendGlobalSysMessage("DB table `locales_quest` reloaded.");
686 return true;
689 bool ChatHandler::HandleLoadScriptsCommand(const char* args)
691 if(!LoadScriptingModule(args)) return true;
693 sWorld.SendWorldText(LANG_SCRIPTS_RELOADED);
694 return true;
697 bool ChatHandler::HandleAccountSetGmLevelCommand(const char* args)
699 char* arg1 = strtok((char*)args, " ");
700 if( !arg1 )
701 return false;
703 /// must be NULL if targeted syntax and must be not nULL if not targeted
704 char* arg2 = strtok(NULL, " ");
706 std::string targetAccountName;
707 uint32 targetAccountId = 0;
709 /// only target player different from self allowed (if targetPlayer!=NULL then not console)
710 Player* targetPlayer = getSelectedPlayer();
711 if(targetPlayer && m_session->GetPlayer()!=targetPlayer)
713 /// wrong command syntax or unexpected targeting
714 if(arg2)
715 return false;
717 /// security level expected in arg2 after this if.
718 arg2 = arg1;
720 targetAccountId = targetPlayer->GetSession()->GetAccountId();
722 else
724 /// wrong command syntax (second arg expected)
725 if(!arg2)
726 return false;
728 targetAccountName = arg1;
729 if(!AccountMgr::normilizeString(targetAccountName))
731 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,targetAccountName.c_str());
732 SetSentErrorMessage(true);
733 return false;
736 targetAccountId = accmgr.GetId(targetAccountName);
737 if(!targetAccountId)
739 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,targetAccountName.c_str());
740 SetSentErrorMessage(true);
741 return false;
745 int32 gm = (int32)atoi(arg2);
746 if ( gm < SEC_PLAYER || gm > SEC_ADMINISTRATOR )
748 SendSysMessage(LANG_BAD_VALUE);
749 SetSentErrorMessage(true);
750 return false;
753 /// can set security level only for target with less security and to less security that we have
754 /// This is also reject self apply in fact
755 if(HasLowerSecurityAccount(NULL,targetAccountId,true))
756 return false;
758 /// account can't set security to same or grater level, need more power GM or console
759 uint32 plSecurity = m_session ? m_session->GetSecurity() : SEC_CONSOLE;
760 if (uint32(gm) >= plSecurity )
762 SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
763 SetSentErrorMessage(true);
764 return false;
767 if(targetPlayer)
769 ChatHandler(targetPlayer).PSendSysMessage(LANG_YOURS_SECURITY_CHANGED,GetName(), gm);
770 targetPlayer->GetSession()->SetSecurity(gm);
773 PSendSysMessage(LANG_YOU_CHANGE_SECURITY, targetAccountName.c_str(), gm);
774 loginDatabase.PExecute("UPDATE account SET gmlevel = '%i' WHERE id = '%u'", gm, targetAccountId);
776 return true;
779 /// Set password for account
780 bool ChatHandler::HandleAccountSetPasswordCommand(const char* args)
782 if(!*args)
783 return false;
785 ///- Get the command line arguments
786 char *szAccount = strtok ((char*)args," ");
787 char *szPassword1 = strtok (NULL," ");
788 char *szPassword2 = strtok (NULL," ");
790 if (!szAccount||!szPassword1 || !szPassword2)
791 return false;
793 std::string account_name = szAccount;
794 if(!AccountMgr::normilizeString(account_name))
796 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
797 SetSentErrorMessage(true);
798 return false;
801 uint32 targetAccountId = accmgr.GetId(account_name);
802 if (!targetAccountId)
804 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
805 SetSentErrorMessage(true);
806 return false;
809 /// can set password only for target with less security
810 /// This is also reject self apply in fact
811 if(HasLowerSecurityAccount (NULL,targetAccountId,true))
812 return false;
814 if (strcmp(szPassword1,szPassword2))
816 SendSysMessage (LANG_NEW_PASSWORDS_NOT_MATCH);
817 SetSentErrorMessage (true);
818 return false;
821 AccountOpResult result = accmgr.ChangePassword(targetAccountId, szPassword1);
823 switch(result)
825 case AOR_OK:
826 SendSysMessage(LANG_COMMAND_PASSWORD);
827 break;
828 case AOR_NAME_NOT_EXIST:
829 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
830 SetSentErrorMessage(true);
831 return false;
832 case AOR_PASS_TOO_LONG:
833 SendSysMessage(LANG_PASSWORD_TOO_LONG);
834 SetSentErrorMessage(true);
835 return false;
836 default:
837 SendSysMessage(LANG_COMMAND_NOTCHANGEPASSWORD);
838 SetSentErrorMessage(true);
839 return false;
842 return true;
845 bool ChatHandler::HandleAllowMovementCommand(const char* /*args*/)
847 if(sWorld.getAllowMovement())
849 sWorld.SetAllowMovement(false);
850 SendSysMessage(LANG_CREATURE_MOVE_DISABLED);
852 else
854 sWorld.SetAllowMovement(true);
855 SendSysMessage(LANG_CREATURE_MOVE_ENABLED);
857 return true;
860 bool ChatHandler::HandleMaxSkillCommand(const char* /*args*/)
862 Player* SelectedPlayer = getSelectedPlayer();
863 if(!SelectedPlayer)
865 SendSysMessage(LANG_NO_CHAR_SELECTED);
866 SetSentErrorMessage(true);
867 return false;
870 // each skills that have max skill value dependent from level seted to current level max skill value
871 SelectedPlayer->UpdateSkillsToMaxSkillsForLevel();
872 return true;
875 bool ChatHandler::HandleSetSkillCommand(const char* args)
877 // number or [name] Shift-click form |color|Hskill:skill_id|h[name]|h|r
878 char* skill_p = extractKeyFromLink((char*)args,"Hskill");
879 if(!skill_p)
880 return false;
882 char *level_p = strtok (NULL, " ");
884 if( !level_p)
885 return false;
887 char *max_p = strtok (NULL, " ");
889 int32 skill = atoi(skill_p);
891 if (skill <= 0)
893 PSendSysMessage(LANG_INVALID_SKILL_ID, skill);
894 SetSentErrorMessage(true);
895 return false;
898 int32 level = atol (level_p);
900 Player * target = getSelectedPlayer();
901 if(!target)
903 SendSysMessage(LANG_NO_CHAR_SELECTED);
904 SetSentErrorMessage(true);
905 return false;
908 SkillLineEntry const* sl = sSkillLineStore.LookupEntry(skill);
909 if(!sl)
911 PSendSysMessage(LANG_INVALID_SKILL_ID, skill);
912 SetSentErrorMessage(true);
913 return false;
916 if(!target->GetSkillValue(skill))
918 PSendSysMessage(LANG_SET_SKILL_ERROR, target->GetName(), skill, sl->name[0]);
919 SetSentErrorMessage(true);
920 return false;
923 int32 max = max_p ? atol (max_p) : target->GetPureMaxSkillValue(skill);
925 if( level <= 0 || level > max || max <= 0 )
926 return false;
928 target->SetSkill(skill, level, max);
929 PSendSysMessage(LANG_SET_SKILL, skill, sl->name[0], target->GetName(), level, max);
931 return true;
934 bool ChatHandler::HandleUnLearnCommand(const char* args)
936 if (!*args)
937 return false;
939 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
940 uint32 min_id = extractSpellIdFromLink((char*)args);
941 if(!min_id)
942 return false;
944 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
945 char* tail = strtok(NULL,"");
947 uint32 max_id = extractSpellIdFromLink(tail);
949 if (!max_id)
951 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
952 max_id = min_id+1;
954 else
956 if (max_id < min_id)
957 std::swap(min_id,max_id);
959 max_id=max_id+1;
962 Player* target = getSelectedPlayer();
963 if(!target)
965 SendSysMessage(LANG_NO_CHAR_SELECTED);
966 SetSentErrorMessage(true);
967 return false;
970 for(uint32 spell=min_id;spell<max_id;spell++)
972 if (target->HasSpell(spell))
973 target->removeSpell(spell);
974 else
975 SendSysMessage(LANG_FORGET_SPELL);
978 return true;
981 bool ChatHandler::HandleCooldownCommand(const char* args)
983 Player* target = getSelectedPlayer();
984 if(!target)
986 SendSysMessage(LANG_PLAYER_NOT_FOUND);
987 SetSentErrorMessage(true);
988 return false;
991 if (!*args)
993 target->RemoveAllSpellCooldown();
994 PSendSysMessage(LANG_REMOVEALL_COOLDOWN, target->GetName());
996 else
998 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
999 uint32 spell_id = extractSpellIdFromLink((char*)args);
1000 if(!spell_id)
1001 return false;
1003 if(!sSpellStore.LookupEntry(spell_id))
1005 PSendSysMessage(LANG_UNKNOWN_SPELL, target==m_session->GetPlayer() ? GetMangosString(LANG_YOU) : target->GetName());
1006 SetSentErrorMessage(true);
1007 return false;
1010 WorldPacket data( SMSG_CLEAR_COOLDOWN, (4+8) );
1011 data << uint32(spell_id);
1012 data << uint64(target->GetGUID());
1013 target->GetSession()->SendPacket(&data);
1014 target->RemoveSpellCooldown(spell_id);
1015 PSendSysMessage(LANG_REMOVE_COOLDOWN, spell_id, target==m_session->GetPlayer() ? GetMangosString(LANG_YOU) : target->GetName());
1017 return true;
1020 bool ChatHandler::HandleLearnAllCommand(const char* /*args*/)
1022 static const char *allSpellList[] =
1024 "3365",
1025 "6233",
1026 "6247",
1027 "6246",
1028 "6477",
1029 "6478",
1030 "22810",
1031 "8386",
1032 "21651",
1033 "21652",
1034 "522",
1035 "7266",
1036 "8597",
1037 "2479",
1038 "22027",
1039 "6603",
1040 "5019",
1041 "133",
1042 "168",
1043 "227",
1044 "5009",
1045 "9078",
1046 "668",
1047 "203",
1048 "20599",
1049 "20600",
1050 "81",
1051 "20597",
1052 "20598",
1053 "20864",
1054 "1459",
1055 "5504",
1056 "587",
1057 "5143",
1058 "118",
1059 "5505",
1060 "597",
1061 "604",
1062 "1449",
1063 "1460",
1064 "2855",
1065 "1008",
1066 "475",
1067 "5506",
1068 "1463",
1069 "12824",
1070 "8437",
1071 "990",
1072 "5145",
1073 "8450",
1074 "1461",
1075 "759",
1076 "8494",
1077 "8455",
1078 "8438",
1079 "6127",
1080 "8416",
1081 "6129",
1082 "8451",
1083 "8495",
1084 "8439",
1085 "3552",
1086 "8417",
1087 "10138",
1088 "12825",
1089 "10169",
1090 "10156",
1091 "10144",
1092 "10191",
1093 "10201",
1094 "10211",
1095 "10053",
1096 "10173",
1097 "10139",
1098 "10145",
1099 "10192",
1100 "10170",
1101 "10202",
1102 "10054",
1103 "10174",
1104 "10193",
1105 "12826",
1106 "2136",
1107 "143",
1108 "145",
1109 "2137",
1110 "2120",
1111 "3140",
1112 "543",
1113 "2138",
1114 "2948",
1115 "8400",
1116 "2121",
1117 "8444",
1118 "8412",
1119 "8457",
1120 "8401",
1121 "8422",
1122 "8445",
1123 "8402",
1124 "8413",
1125 "8458",
1126 "8423",
1127 "8446",
1128 "10148",
1129 "10197",
1130 "10205",
1131 "10149",
1132 "10215",
1133 "10223",
1134 "10206",
1135 "10199",
1136 "10150",
1137 "10216",
1138 "10207",
1139 "10225",
1140 "10151",
1141 "116",
1142 "205",
1143 "7300",
1144 "122",
1145 "837",
1146 "10",
1147 "7301",
1148 "7322",
1149 "6143",
1150 "120",
1151 "865",
1152 "8406",
1153 "6141",
1154 "7302",
1155 "8461",
1156 "8407",
1157 "8492",
1158 "8427",
1159 "8408",
1160 "6131",
1161 "7320",
1162 "10159",
1163 "8462",
1164 "10185",
1165 "10179",
1166 "10160",
1167 "10180",
1168 "10219",
1169 "10186",
1170 "10177",
1171 "10230",
1172 "10181",
1173 "10161",
1174 "10187",
1175 "10220",
1176 "2018",
1177 "2663",
1178 "12260",
1179 "2660",
1180 "3115",
1181 "3326",
1182 "2665",
1183 "3116",
1184 "2738",
1185 "3293",
1186 "2661",
1187 "3319",
1188 "2662",
1189 "9983",
1190 "8880",
1191 "2737",
1192 "2739",
1193 "7408",
1194 "3320",
1195 "2666",
1196 "3323",
1197 "3324",
1198 "3294",
1199 "22723",
1200 "23219",
1201 "23220",
1202 "23221",
1203 "23228",
1204 "23338",
1205 "10788",
1206 "10790",
1207 "5611",
1208 "5016",
1209 "5609",
1210 "2060",
1211 "10963",
1212 "10964",
1213 "10965",
1214 "22593",
1215 "22594",
1216 "596",
1217 "996",
1218 "499",
1219 "768",
1220 "17002",
1221 "1448",
1222 "1082",
1223 "16979",
1224 "1079",
1225 "5215",
1226 "20484",
1227 "5221",
1228 "15590",
1229 "17007",
1230 "6795",
1231 "6807",
1232 "5487",
1233 "1446",
1234 "1066",
1235 "5421",
1236 "3139",
1237 "779",
1238 "6811",
1239 "6808",
1240 "1445",
1241 "5216",
1242 "1737",
1243 "5222",
1244 "5217",
1245 "1432",
1246 "6812",
1247 "9492",
1248 "5210",
1249 "3030",
1250 "1441",
1251 "783",
1252 "6801",
1253 "20739",
1254 "8944",
1255 "9491",
1256 "22569",
1257 "5226",
1258 "6786",
1259 "1433",
1260 "8973",
1261 "1828",
1262 "9495",
1263 "9006",
1264 "6794",
1265 "8993",
1266 "5203",
1267 "16914",
1268 "6784",
1269 "9635",
1270 "22830",
1271 "20722",
1272 "9748",
1273 "6790",
1274 "9753",
1275 "9493",
1276 "9752",
1277 "9831",
1278 "9825",
1279 "9822",
1280 "5204",
1281 "5401",
1282 "22831",
1283 "6793",
1284 "9845",
1285 "17401",
1286 "9882",
1287 "9868",
1288 "20749",
1289 "9893",
1290 "9899",
1291 "9895",
1292 "9832",
1293 "9902",
1294 "9909",
1295 "22832",
1296 "9828",
1297 "9851",
1298 "9883",
1299 "9869",
1300 "17406",
1301 "17402",
1302 "9914",
1303 "20750",
1304 "9897",
1305 "9848",
1306 "3127",
1307 "107",
1308 "204",
1309 "9116",
1310 "2457",
1311 "78",
1312 "18848",
1313 "331",
1314 "403",
1315 "2098",
1316 "1752",
1317 "11278",
1318 "11288",
1319 "11284",
1320 "6461",
1321 "2344",
1322 "2345",
1323 "6463",
1324 "2346",
1325 "2352",
1326 "775",
1327 "1434",
1328 "1612",
1329 "71",
1330 "2468",
1331 "2458",
1332 "2467",
1333 "7164",
1334 "7178",
1335 "7367",
1336 "7376",
1337 "7381",
1338 "21156",
1339 "5209",
1340 "3029",
1341 "5201",
1342 "9849",
1343 "9850",
1344 "20719",
1345 "22568",
1346 "22827",
1347 "22828",
1348 "22829",
1349 "6809",
1350 "8972",
1351 "9005",
1352 "9823",
1353 "9827",
1354 "6783",
1355 "9913",
1356 "6785",
1357 "6787",
1358 "9866",
1359 "9867",
1360 "9894",
1361 "9896",
1362 "6800",
1363 "8992",
1364 "9829",
1365 "9830",
1366 "780",
1367 "769",
1368 "6749",
1369 "6750",
1370 "9755",
1371 "9754",
1372 "9908",
1373 "20745",
1374 "20742",
1375 "20747",
1376 "20748",
1377 "9746",
1378 "9745",
1379 "9880",
1380 "9881",
1381 "5391",
1382 "842",
1383 "3025",
1384 "3031",
1385 "3287",
1386 "3329",
1387 "1945",
1388 "3559",
1389 "4933",
1390 "4934",
1391 "4935",
1392 "4936",
1393 "5142",
1394 "5390",
1395 "5392",
1396 "5404",
1397 "5420",
1398 "6405",
1399 "7293",
1400 "7965",
1401 "8041",
1402 "8153",
1403 "9033",
1404 "9034",
1405 //"9036", problems with ghost state
1406 "16421",
1407 "21653",
1408 "22660",
1409 "5225",
1410 "9846",
1411 "2426",
1412 "5916",
1413 "6634",
1414 //"6718", phasing stealth, annoying for learn all case.
1415 "6719",
1416 "8822",
1417 "9591",
1418 "9590",
1419 "10032",
1420 "17746",
1421 "17747",
1422 "8203",
1423 "11392",
1424 "12495",
1425 "16380",
1426 "23452",
1427 "4079",
1428 "4996",
1429 "4997",
1430 "4998",
1431 "4999",
1432 "5000",
1433 "6348",
1434 "6349",
1435 "6481",
1436 "6482",
1437 "6483",
1438 "6484",
1439 "11362",
1440 "11410",
1441 "11409",
1442 "12510",
1443 "12509",
1444 "12885",
1445 "13142",
1446 "21463",
1447 "23460",
1448 "11421",
1449 "11416",
1450 "11418",
1451 "1851",
1452 "10059",
1453 "11423",
1454 "11417",
1455 "11422",
1456 "11419",
1457 "11424",
1458 "11420",
1459 "27",
1460 "31",
1461 "33",
1462 "34",
1463 "35",
1464 "15125",
1465 "21127",
1466 "22950",
1467 "1180",
1468 "201",
1469 "12593",
1470 "12842",
1471 "16770",
1472 "6057",
1473 "12051",
1474 "18468",
1475 "12606",
1476 "12605",
1477 "18466",
1478 "12502",
1479 "12043",
1480 "15060",
1481 "12042",
1482 "12341",
1483 "12848",
1484 "12344",
1485 "12353",
1486 "18460",
1487 "11366",
1488 "12350",
1489 "12352",
1490 "13043",
1491 "11368",
1492 "11113",
1493 "12400",
1494 "11129",
1495 "16766",
1496 "12573",
1497 "15053",
1498 "12580",
1499 "12475",
1500 "12472",
1501 "12953",
1502 "12488",
1503 "11189",
1504 "12985",
1505 "12519",
1506 "16758",
1507 "11958",
1508 "12490",
1509 "11426",
1510 "3565",
1511 "3562",
1512 "18960",
1513 "3567",
1514 "3561",
1515 "3566",
1516 "3563",
1517 "1953",
1518 "2139",
1519 "12505",
1520 "13018",
1521 "12522",
1522 "12523",
1523 "5146",
1524 "5144",
1525 "5148",
1526 "8419",
1527 "8418",
1528 "10213",
1529 "10212",
1530 "10157",
1531 "12524",
1532 "13019",
1533 "12525",
1534 "13020",
1535 "12526",
1536 "13021",
1537 "18809",
1538 "13031",
1539 "13032",
1540 "13033",
1541 "4036",
1542 "3920",
1543 "3919",
1544 "3918",
1545 "7430",
1546 "3922",
1547 "3923",
1548 "7411",
1549 "7418",
1550 "7421",
1551 "13262",
1552 "7412",
1553 "7415",
1554 "7413",
1555 "7416",
1556 "13920",
1557 "13921",
1558 "7745",
1559 "7779",
1560 "7428",
1561 "7457",
1562 "7857",
1563 "7748",
1564 "7426",
1565 "13421",
1566 "7454",
1567 "13378",
1568 "7788",
1569 "14807",
1570 "14293",
1571 "7795",
1572 "6296",
1573 "20608",
1574 "755",
1575 "444",
1576 "427",
1577 "428",
1578 "442",
1579 "447",
1580 "3578",
1581 "3581",
1582 "19027",
1583 "3580",
1584 "665",
1585 "3579",
1586 "3577",
1587 "6755",
1588 "3576",
1589 "2575",
1590 "2577",
1591 "2578",
1592 "2579",
1593 "2580",
1594 "2656",
1595 "2657",
1596 "2576",
1597 "3564",
1598 "10248",
1599 "8388",
1600 "2659",
1601 "14891",
1602 "3308",
1603 "3307",
1604 "10097",
1605 "2658",
1606 "3569",
1607 "16153",
1608 "3304",
1609 "10098",
1610 "4037",
1611 "3929",
1612 "3931",
1613 "3926",
1614 "3924",
1615 "3930",
1616 "3977",
1617 "3925",
1618 "136",
1619 "228",
1620 "5487",
1621 "43",
1622 "202",
1626 int loop = 0;
1627 while(strcmp(allSpellList[loop], "0"))
1629 uint32 spell = atol((char*)allSpellList[loop++]);
1631 if (m_session->GetPlayer()->HasSpell(spell))
1632 continue;
1634 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
1635 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
1637 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
1638 continue;
1641 m_session->GetPlayer()->learnSpell(spell,false);
1644 SendSysMessage(LANG_COMMAND_LEARN_MANY_SPELLS);
1646 return true;
1649 bool ChatHandler::HandleLearnAllGMCommand(const char* /*args*/)
1651 static const char *gmSpellList[] =
1653 "24347", // Become A Fish, No Breath Bar
1654 "35132", // Visual Boom
1655 "38488", // Attack 4000-8000 AOE
1656 "38795", // Attack 2000 AOE + Slow Down 90%
1657 "15712", // Attack 200
1658 "1852", // GM Spell Silence
1659 "31899", // Kill
1660 "31924", // Kill
1661 "29878", // Kill My Self
1662 "26644", // More Kill
1664 "28550", //Invisible 24
1665 "23452", //Invisible + Target
1669 uint16 gmSpellIter = 0;
1670 while( strcmp(gmSpellList[gmSpellIter], "0") )
1672 uint32 spell = atol((char*)gmSpellList[gmSpellIter++]);
1674 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
1675 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
1677 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
1678 continue;
1681 m_session->GetPlayer()->learnSpell(spell,false);
1684 SendSysMessage(LANG_LEARNING_GM_SKILLS);
1685 return true;
1688 bool ChatHandler::HandleLearnAllMyClassCommand(const char* /*args*/)
1690 HandleLearnAllMySpellsCommand("");
1691 HandleLearnAllMyTalentsCommand("");
1692 return true;
1695 bool ChatHandler::HandleLearnAllMySpellsCommand(const char* /*args*/)
1697 ChrClassesEntry const* clsEntry = sChrClassesStore.LookupEntry(m_session->GetPlayer()->getClass());
1698 if(!clsEntry)
1699 return true;
1700 uint32 family = clsEntry->spellfamily;
1702 for (uint32 i = 0; i < sSpellStore.GetNumRows(); i++)
1704 SpellEntry const *spellInfo = sSpellStore.LookupEntry(i);
1705 if(!spellInfo)
1706 continue;
1708 // skip server-side/triggered spells
1709 if(spellInfo->spellLevel==0)
1710 continue;
1712 // skip wrong class/race skills
1713 if(!m_session->GetPlayer()->IsSpellFitByClassAndRace(spellInfo->Id))
1714 continue;
1716 // skip other spell families
1717 if( spellInfo->SpellFamilyName != family)
1718 continue;
1720 // skip spells with first rank learned as talent (and all talents then also)
1721 uint32 first_rank = spellmgr.GetFirstSpellInChain(spellInfo->Id);
1722 if(GetTalentSpellCost(first_rank) > 0 )
1723 continue;
1725 // skip broken spells
1726 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
1727 continue;
1729 m_session->GetPlayer()->learnSpell(i,false);
1732 SendSysMessage(LANG_COMMAND_LEARN_CLASS_SPELLS);
1733 return true;
1736 static void learnAllHighRanks(Player* player, uint32 spellid)
1738 SpellChainMapNext const& nextMap = spellmgr.GetSpellChainNext();
1739 for(SpellChainMapNext::const_iterator itr = nextMap.lower_bound(spellid); itr != nextMap.upper_bound(spellid); ++itr)
1741 player->learnSpell(itr->second,false);
1742 learnAllHighRanks(player,itr->second);
1746 bool ChatHandler::HandleLearnAllMyTalentsCommand(const char* /*args*/)
1748 Player* player = m_session->GetPlayer();
1749 uint32 classMask = player->getClassMask();
1751 for (uint32 i = 0; i < sTalentStore.GetNumRows(); i++)
1753 TalentEntry const *talentInfo = sTalentStore.LookupEntry(i);
1754 if(!talentInfo)
1755 continue;
1757 TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab );
1758 if(!talentTabInfo)
1759 continue;
1761 if( (classMask & talentTabInfo->ClassMask) == 0 )
1762 continue;
1764 // search highest talent rank
1765 uint32 spellid = 0;
1766 int rank = 4;
1767 for(; rank >= 0; --rank)
1769 if(talentInfo->RankID[rank]!=0)
1771 spellid = talentInfo->RankID[rank];
1772 break;
1776 if(!spellid) // ??? none spells in talent
1777 continue;
1779 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid);
1780 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
1781 continue;
1783 // learn highest rank of talent
1784 player->learnSpell(spellid,false);
1786 // and learn all non-talent spell ranks (recursive by tree)
1787 learnAllHighRanks(player,spellid);
1790 SendSysMessage(LANG_COMMAND_LEARN_CLASS_TALENTS);
1791 return true;
1794 bool ChatHandler::HandleLearnAllLangCommand(const char* /*args*/)
1796 // skipping UNIVERSAL language (0)
1797 for(int i = 1; i < LANGUAGES_COUNT; ++i)
1798 m_session->GetPlayer()->learnSpell(lang_description[i].spell_id,false);
1800 SendSysMessage(LANG_COMMAND_LEARN_ALL_LANG);
1801 return true;
1804 bool ChatHandler::HandleLearnAllDefaultCommand(const char* args)
1806 char* pName = strtok((char*)args, "");
1807 Player *player = NULL;
1808 if (pName)
1810 std::string name = pName;
1812 if(!normalizePlayerName(name))
1814 SendSysMessage(LANG_PLAYER_NOT_FOUND);
1815 SetSentErrorMessage(true);
1816 return false;
1819 player = objmgr.GetPlayer(name.c_str());
1821 else
1822 player = getSelectedPlayer();
1824 if(!player)
1826 SendSysMessage(LANG_NO_CHAR_SELECTED);
1827 SetSentErrorMessage(true);
1828 return false;
1831 player->learnDefaultSpells();
1832 player->learnQuestRewardedSpells();
1834 PSendSysMessage(LANG_COMMAND_LEARN_ALL_DEFAULT_AND_QUEST,player->GetName());
1835 return true;
1838 bool ChatHandler::HandleLearnCommand(const char* args)
1840 Player* targetPlayer = getSelectedPlayer();
1842 if(!targetPlayer)
1844 SendSysMessage(LANG_PLAYER_NOT_FOUND);
1845 SetSentErrorMessage(true);
1846 return false;
1849 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
1850 uint32 spell = extractSpellIdFromLink((char*)args);
1851 if(!spell || !sSpellStore.LookupEntry(spell))
1852 return false;
1854 if (targetPlayer->HasSpell(spell))
1856 if(targetPlayer == m_session->GetPlayer())
1857 SendSysMessage(LANG_YOU_KNOWN_SPELL);
1858 else
1859 PSendSysMessage(LANG_TARGET_KNOWN_SPELL,targetPlayer->GetName());
1860 SetSentErrorMessage(true);
1861 return false;
1864 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
1865 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
1867 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
1868 SetSentErrorMessage(true);
1869 return false;
1872 targetPlayer->learnSpell(spell,false);
1874 return true;
1877 bool ChatHandler::HandleAddItemCommand(const char* args)
1879 if (!*args)
1880 return false;
1882 uint32 itemId = 0;
1884 if(args[0]=='[') // [name] manual form
1886 char* citemName = citemName = strtok((char*)args, "]");
1888 if(citemName && citemName[0])
1890 std::string itemName = citemName+1;
1891 WorldDatabase.escape_string(itemName);
1892 QueryResult *result = WorldDatabase.PQuery("SELECT entry FROM item_template WHERE name = '%s'", itemName.c_str());
1893 if (!result)
1895 PSendSysMessage(LANG_COMMAND_COULDNOTFIND, citemName+1);
1896 SetSentErrorMessage(true);
1897 return false;
1899 itemId = result->Fetch()->GetUInt16();
1900 delete result;
1902 else
1903 return false;
1905 else // item_id or [name] Shift-click form |color|Hitem:item_id:0:0:0|h[name]|h|r
1907 char* cId = extractKeyFromLink((char*)args,"Hitem");
1908 if(!cId)
1909 return false;
1910 itemId = atol(cId);
1913 char* ccount = strtok(NULL, " ");
1915 int32 count = 1;
1917 if (ccount)
1918 count = strtol(ccount, NULL, 10);
1920 if (count == 0)
1921 count = 1;
1923 Player* pl = m_session->GetPlayer();
1924 Player* plTarget = getSelectedPlayer();
1925 if(!plTarget)
1926 plTarget = pl;
1928 sLog.outDetail(GetMangosString(LANG_ADDITEM), itemId, count);
1930 ItemPrototype const *pProto = objmgr.GetItemPrototype(itemId);
1931 if(!pProto)
1933 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId);
1934 SetSentErrorMessage(true);
1935 return false;
1938 //Subtract
1939 if (count < 0)
1941 plTarget->DestroyItemCount(itemId, -count, true, false);
1942 PSendSysMessage(LANG_REMOVEITEM, itemId, -count, plTarget->GetName());
1943 return true;
1946 //Adding items
1947 uint32 noSpaceForCount = 0;
1949 // check space and find places
1950 ItemPosCountVec dest;
1951 uint8 msg = plTarget->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, itemId, count, &noSpaceForCount );
1952 if( msg != EQUIP_ERR_OK ) // convert to possible store amount
1953 count -= noSpaceForCount;
1955 if( count == 0 || dest.empty()) // can't add any
1957 PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount );
1958 SetSentErrorMessage(true);
1959 return false;
1962 Item* item = plTarget->StoreNewItem( dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId));
1964 // remove binding (let GM give it to another player later)
1965 if(pl==plTarget)
1966 for(ItemPosCountVec::const_iterator itr = dest.begin(); itr != dest.end(); ++itr)
1967 if(Item* item1 = pl->GetItemByPos(itr->pos))
1968 item1->SetBinding( false );
1970 if(count > 0 && item)
1972 pl->SendNewItem(item,count,false,true);
1973 if(pl!=plTarget)
1974 plTarget->SendNewItem(item,count,true,false);
1977 if(noSpaceForCount > 0)
1978 PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount);
1980 return true;
1983 bool ChatHandler::HandleAddItemSetCommand(const char* args)
1985 if (!*args)
1986 return false;
1988 char* cId = extractKeyFromLink((char*)args,"Hitemset"); // number or [name] Shift-click form |color|Hitemset:itemset_id|h[name]|h|r
1989 if (!cId)
1990 return false;
1992 uint32 itemsetId = atol(cId);
1994 // prevent generation all items with itemset field value '0'
1995 if (itemsetId == 0)
1997 PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND,itemsetId);
1998 SetSentErrorMessage(true);
1999 return false;
2002 Player* pl = m_session->GetPlayer();
2003 Player* plTarget = getSelectedPlayer();
2004 if(!plTarget)
2005 plTarget = pl;
2007 sLog.outDetail(GetMangosString(LANG_ADDITEMSET), itemsetId);
2009 bool found = false;
2010 for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
2012 ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype>(id);
2013 if (!pProto)
2014 continue;
2016 if (pProto->ItemSet == itemsetId)
2018 found = true;
2019 ItemPosCountVec dest;
2020 uint8 msg = plTarget->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, pProto->ItemId, 1 );
2021 if (msg == EQUIP_ERR_OK)
2023 Item* item = plTarget->StoreNewItem( dest, pProto->ItemId, true);
2025 // remove binding (let GM give it to another player later)
2026 if (pl==plTarget)
2027 item->SetBinding( false );
2029 pl->SendNewItem(item,1,false,true);
2030 if (pl!=plTarget)
2031 plTarget->SendNewItem(item,1,true,false);
2033 else
2035 pl->SendEquipError( msg, NULL, NULL );
2036 PSendSysMessage(LANG_ITEM_CANNOT_CREATE, pProto->ItemId, 1);
2041 if (!found)
2043 PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND,itemsetId);
2045 SetSentErrorMessage(true);
2046 return false;
2049 return true;
2052 bool ChatHandler::HandleListItemCommand(const char* args)
2054 if(!*args)
2055 return false;
2057 char* cId = extractKeyFromLink((char*)args,"Hitem");
2058 if(!cId)
2059 return false;
2061 uint32 item_id = atol(cId);
2062 if(!item_id)
2064 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
2065 SetSentErrorMessage(true);
2066 return false;
2069 ItemPrototype const* itemProto = objmgr.GetItemPrototype(item_id);
2070 if(!itemProto)
2072 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
2073 SetSentErrorMessage(true);
2074 return false;
2077 char* c_count = strtok(NULL, " ");
2078 int count = c_count ? atol(c_count) : 10;
2080 if(count < 0)
2081 return false;
2083 QueryResult *result;
2085 // inventory case
2086 uint32 inv_count = 0;
2087 result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM character_inventory WHERE item_template='%u'",item_id);
2088 if(result)
2090 inv_count = (*result)[0].GetUInt32();
2091 delete result;
2094 result=CharacterDatabase.PQuery(
2095 // 0 1 2 3 4 5
2096 "SELECT ci.item, cibag.slot AS bag, ci.slot, ci.guid, characters.account,characters.name "
2097 "FROM character_inventory AS ci LEFT JOIN character_inventory AS cibag ON (cibag.item=ci.bag),characters "
2098 "WHERE ci.item_template='%u' AND ci.guid = characters.guid LIMIT %u ",
2099 item_id,uint32(count));
2101 if(result)
2105 Field *fields = result->Fetch();
2106 uint32 item_guid = fields[0].GetUInt32();
2107 uint32 item_bag = fields[1].GetUInt32();
2108 uint32 item_slot = fields[2].GetUInt32();
2109 uint32 owner_guid = fields[3].GetUInt32();
2110 uint32 owner_acc = fields[4].GetUInt32();
2111 std::string owner_name = fields[5].GetCppString();
2113 char const* item_pos = 0;
2114 if(Player::IsEquipmentPos(item_bag,item_slot))
2115 item_pos = "[equipped]";
2116 else if(Player::IsInventoryPos(item_bag,item_slot))
2117 item_pos = "[in inventory]";
2118 else if(Player::IsBankPos(item_bag,item_slot))
2119 item_pos = "[in bank]";
2120 else
2121 item_pos = "";
2123 PSendSysMessage(LANG_ITEMLIST_SLOT,
2124 item_guid,owner_name.c_str(),owner_guid,owner_acc,item_pos);
2125 } while (result->NextRow());
2127 int64 res_count = result->GetRowCount();
2129 delete result;
2131 if(count > res_count)
2132 count-=res_count;
2133 else if(count)
2134 count = 0;
2137 // mail case
2138 uint32 mail_count = 0;
2139 result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM mail_items WHERE item_template='%u'", item_id);
2140 if(result)
2142 mail_count = (*result)[0].GetUInt32();
2143 delete result;
2146 if(count > 0)
2148 result=CharacterDatabase.PQuery(
2149 // 0 1 2 3 4 5 6
2150 "SELECT mail_items.item_guid, mail.sender, mail.receiver, char_s.account, char_s.name, char_r.account, char_r.name "
2151 "FROM mail,mail_items,characters as char_s,characters as char_r "
2152 "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",
2153 item_id,uint32(count));
2155 else
2156 result = NULL;
2158 if(result)
2162 Field *fields = result->Fetch();
2163 uint32 item_guid = fields[0].GetUInt32();
2164 uint32 item_s = fields[1].GetUInt32();
2165 uint32 item_r = fields[2].GetUInt32();
2166 uint32 item_s_acc = fields[3].GetUInt32();
2167 std::string item_s_name = fields[4].GetCppString();
2168 uint32 item_r_acc = fields[5].GetUInt32();
2169 std::string item_r_name = fields[6].GetCppString();
2171 char const* item_pos = "[in mail]";
2173 PSendSysMessage(LANG_ITEMLIST_MAIL,
2174 item_guid,item_s_name.c_str(),item_s,item_s_acc,item_r_name.c_str(),item_r,item_r_acc,item_pos);
2175 } while (result->NextRow());
2177 int64 res_count = result->GetRowCount();
2179 delete result;
2181 if(count > res_count)
2182 count-=res_count;
2183 else if(count)
2184 count = 0;
2187 // auction case
2188 uint32 auc_count = 0;
2189 result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM auctionhouse WHERE item_template='%u'",item_id);
2190 if(result)
2192 auc_count = (*result)[0].GetUInt32();
2193 delete result;
2196 if(count > 0)
2198 result=CharacterDatabase.PQuery(
2199 // 0 1 2 3
2200 "SELECT auctionhouse.itemguid, auctionhouse.itemowner, characters.account, characters.name "
2201 "FROM auctionhouse,characters WHERE auctionhouse.item_template='%u' AND characters.guid = auctionhouse.itemowner LIMIT %u",
2202 item_id,uint32(count));
2204 else
2205 result = NULL;
2207 if(result)
2211 Field *fields = result->Fetch();
2212 uint32 item_guid = fields[0].GetUInt32();
2213 uint32 owner = fields[1].GetUInt32();
2214 uint32 owner_acc = fields[2].GetUInt32();
2215 std::string owner_name = fields[3].GetCppString();
2217 char const* item_pos = "[in auction]";
2219 PSendSysMessage(LANG_ITEMLIST_AUCTION, item_guid, owner_name.c_str(), owner, owner_acc,item_pos);
2220 } while (result->NextRow());
2222 delete result;
2225 // guild bank case
2226 uint32 guild_count = 0;
2227 result=CharacterDatabase.PQuery("SELECT COUNT(item_entry) FROM guild_bank_item WHERE item_entry='%u'",item_id);
2228 if(result)
2230 guild_count = (*result)[0].GetUInt32();
2231 delete result;
2234 result=CharacterDatabase.PQuery(
2235 // 0 1 2
2236 "SELECT gi.item_guid, gi.guildid, guild.name "
2237 "FROM guild_bank_item AS gi, guild WHERE gi.item_entry='%u' AND gi.guildid = guild.guildid LIMIT %u ",
2238 item_id,uint32(count));
2240 if(result)
2244 Field *fields = result->Fetch();
2245 uint32 item_guid = fields[0].GetUInt32();
2246 uint32 guild_guid = fields[1].GetUInt32();
2247 std::string guild_name = fields[2].GetCppString();
2249 char const* item_pos = "[in guild bank]";
2251 PSendSysMessage(LANG_ITEMLIST_GUILD,item_guid,guild_name.c_str(),guild_guid,item_pos);
2252 } while (result->NextRow());
2254 int64 res_count = result->GetRowCount();
2256 delete result;
2258 if(count > res_count)
2259 count-=res_count;
2260 else if(count)
2261 count = 0;
2264 if(inv_count+mail_count+auc_count+guild_count == 0)
2266 SendSysMessage(LANG_COMMAND_NOITEMFOUND);
2267 SetSentErrorMessage(true);
2268 return false;
2271 PSendSysMessage(LANG_COMMAND_LISTITEMMESSAGE,item_id,inv_count+mail_count+auc_count+guild_count,inv_count,mail_count,auc_count,guild_count);
2273 return true;
2276 bool ChatHandler::HandleListObjectCommand(const char* args)
2278 if(!*args)
2279 return false;
2281 // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r
2282 char* cId = extractKeyFromLink((char*)args,"Hgameobject_entry");
2283 if(!cId)
2284 return false;
2286 uint32 go_id = atol(cId);
2287 if(!go_id)
2289 PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id);
2290 SetSentErrorMessage(true);
2291 return false;
2294 GameObjectInfo const * gInfo = objmgr.GetGameObjectInfo(go_id);
2295 if(!gInfo)
2297 PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id);
2298 SetSentErrorMessage(true);
2299 return false;
2302 char* c_count = strtok(NULL, " ");
2303 int count = c_count ? atol(c_count) : 10;
2305 if(count < 0)
2306 return false;
2308 QueryResult *result;
2310 uint32 obj_count = 0;
2311 result=WorldDatabase.PQuery("SELECT COUNT(guid) FROM gameobject WHERE id='%u'",go_id);
2312 if(result)
2314 obj_count = (*result)[0].GetUInt32();
2315 delete result;
2318 if(m_session)
2320 Player* pl = m_session->GetPlayer();
2321 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",
2322 pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),go_id,uint32(count));
2324 else
2325 result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map FROM gameobject WHERE id = '%u' LIMIT %u",
2326 go_id,uint32(count));
2328 if (result)
2332 Field *fields = result->Fetch();
2333 uint32 guid = fields[0].GetUInt32();
2334 float x = fields[1].GetFloat();
2335 float y = fields[2].GetFloat();
2336 float z = fields[3].GetFloat();
2337 int mapid = fields[4].GetUInt16();
2339 if (m_session)
2340 PSendSysMessage(LANG_GO_LIST_CHAT, guid, guid, gInfo->name, x, y, z, mapid);
2341 else
2342 PSendSysMessage(LANG_GO_LIST_CONSOLE, guid, gInfo->name, x, y, z, mapid);
2343 } while (result->NextRow());
2345 delete result;
2348 PSendSysMessage(LANG_COMMAND_LISTOBJMESSAGE,go_id,obj_count);
2349 return true;
2352 bool ChatHandler::HandleNearObjectCommand(const char* args)
2354 float distance = (!*args) ? 10 : atol(args);
2355 uint32 count = 0;
2357 Player* pl = m_session->GetPlayer();
2358 QueryResult *result = WorldDatabase.PQuery("SELECT guid, id, position_x, position_y, position_z, map, "
2359 "(POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ "
2360 "FROM gameobject WHERE map='%u' AND (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) <= '%f' ORDER BY order_",
2361 pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),
2362 pl->GetMapId(),pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),distance*distance);
2364 if (result)
2368 Field *fields = result->Fetch();
2369 uint32 guid = fields[0].GetUInt32();
2370 uint32 entry = fields[1].GetUInt32();
2371 float x = fields[2].GetFloat();
2372 float y = fields[3].GetFloat();
2373 float z = fields[4].GetFloat();
2374 int mapid = fields[5].GetUInt16();
2376 GameObjectInfo const * gInfo = objmgr.GetGameObjectInfo(entry);
2378 if(!gInfo)
2379 continue;
2381 PSendSysMessage(LANG_GO_LIST_CHAT, guid, guid, gInfo->name, x, y, z, mapid);
2383 ++count;
2384 } while (result->NextRow());
2386 delete result;
2389 PSendSysMessage(LANG_COMMAND_NEAROBJMESSAGE,distance,count);
2390 return true;
2393 bool ChatHandler::HandleListCreatureCommand(const char* args)
2395 if(!*args)
2396 return false;
2398 // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
2399 char* cId = extractKeyFromLink((char*)args,"Hcreature_entry");
2400 if(!cId)
2401 return false;
2403 uint32 cr_id = atol(cId);
2404 if(!cr_id)
2406 PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id);
2407 SetSentErrorMessage(true);
2408 return false;
2411 CreatureInfo const* cInfo = objmgr.GetCreatureTemplate(cr_id);
2412 if(!cInfo)
2414 PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id);
2415 SetSentErrorMessage(true);
2416 return false;
2419 char* c_count = strtok(NULL, " ");
2420 int count = c_count ? atol(c_count) : 10;
2422 if(count < 0)
2423 return false;
2425 QueryResult *result;
2427 uint32 cr_count = 0;
2428 result=WorldDatabase.PQuery("SELECT COUNT(guid) FROM creature WHERE id='%u'",cr_id);
2429 if(result)
2431 cr_count = (*result)[0].GetUInt32();
2432 delete result;
2435 if(m_session)
2437 Player* pl = m_session->GetPlayer();
2438 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",
2439 pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), cr_id,uint32(count));
2441 else
2442 result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map FROM creature WHERE id = '%u' LIMIT %u",
2443 cr_id,uint32(count));
2445 if (result)
2449 Field *fields = result->Fetch();
2450 uint32 guid = fields[0].GetUInt32();
2451 float x = fields[1].GetFloat();
2452 float y = fields[2].GetFloat();
2453 float z = fields[3].GetFloat();
2454 int mapid = fields[4].GetUInt16();
2456 if (m_session)
2457 PSendSysMessage(LANG_CREATURE_LIST_CHAT, guid, guid, cInfo->Name, x, y, z, mapid);
2458 else
2459 PSendSysMessage(LANG_CREATURE_LIST_CONSOLE, guid, cInfo->Name, x, y, z, mapid);
2460 } while (result->NextRow());
2462 delete result;
2465 PSendSysMessage(LANG_COMMAND_LISTCREATUREMESSAGE,cr_id,cr_count);
2466 return true;
2469 bool ChatHandler::HandleLookupItemCommand(const char* args)
2471 if(!*args)
2472 return false;
2474 std::string namepart = args;
2475 std::wstring wnamepart;
2477 // converting string that we try to find to lower case
2478 if(!Utf8toWStr(namepart,wnamepart))
2479 return false;
2481 wstrToLower(wnamepart);
2483 uint32 counter = 0;
2485 // Search in `item_template`
2486 for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
2488 ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype >(id);
2489 if(!pProto)
2490 continue;
2492 int loc_idx = m_session ? m_session->GetSessionDbLocaleIndex() : objmgr.GetDBCLocaleIndex();
2493 if ( loc_idx >= 0 )
2495 ItemLocale const *il = objmgr.GetItemLocale(pProto->ItemId);
2496 if (il)
2498 if (il->Name.size() > loc_idx && !il->Name[loc_idx].empty())
2500 std::string name = il->Name[loc_idx];
2502 if (Utf8FitTo(name, wnamepart))
2504 if (m_session)
2505 PSendSysMessage(LANG_ITEM_LIST_CHAT, id, id, name.c_str());
2506 else
2507 PSendSysMessage(LANG_ITEM_LIST_CONSOLE, id, name.c_str());
2508 ++counter;
2509 continue;
2515 std::string name = pProto->Name1;
2516 if(name.empty())
2517 continue;
2519 if (Utf8FitTo(name, wnamepart))
2521 if (m_session)
2522 PSendSysMessage(LANG_ITEM_LIST_CHAT, id, id, name.c_str());
2523 else
2524 PSendSysMessage(LANG_ITEM_LIST_CONSOLE, id, name.c_str());
2525 ++counter;
2529 if (counter==0)
2530 SendSysMessage(LANG_COMMAND_NOITEMFOUND);
2532 return true;
2535 bool ChatHandler::HandleLookupItemSetCommand(const char* args)
2537 if(!*args)
2538 return false;
2540 std::string namepart = args;
2541 std::wstring wnamepart;
2543 if(!Utf8toWStr(namepart,wnamepart))
2544 return false;
2546 // converting string that we try to find to lower case
2547 wstrToLower( wnamepart );
2549 uint32 counter = 0; // Counter for figure out that we found smth.
2551 // Search in ItemSet.dbc
2552 for (uint32 id = 0; id < sItemSetStore.GetNumRows(); id++)
2554 ItemSetEntry const *set = sItemSetStore.LookupEntry(id);
2555 if(set)
2557 int loc = m_session ? m_session->GetSessionDbcLocale() : sWorld.GetDefaultDbcLocale();
2558 std::string name = set->name[loc];
2559 if(name.empty())
2560 continue;
2562 if (!Utf8FitTo(name, wnamepart))
2564 loc = 0;
2565 for(; loc < MAX_LOCALE; ++loc)
2567 if(m_session && loc==m_session->GetSessionDbcLocale())
2568 continue;
2570 name = set->name[loc];
2571 if(name.empty())
2572 continue;
2574 if (Utf8FitTo(name, wnamepart))
2575 break;
2579 if(loc < MAX_LOCALE)
2581 // send item set in "id - [namedlink locale]" format
2582 if (m_session)
2583 PSendSysMessage(LANG_ITEMSET_LIST_CHAT,id,id,name.c_str(),localeNames[loc]);
2584 else
2585 PSendSysMessage(LANG_ITEMSET_LIST_CONSOLE,id,name.c_str(),localeNames[loc]);
2586 ++counter;
2590 if (counter == 0) // if counter == 0 then we found nth
2591 SendSysMessage(LANG_COMMAND_NOITEMSETFOUND);
2592 return true;
2595 bool ChatHandler::HandleLookupSkillCommand(const char* args)
2597 if(!*args)
2598 return false;
2600 // can be NULL in console call
2601 Player* target = getSelectedPlayer();
2603 std::string namepart = args;
2604 std::wstring wnamepart;
2606 if(!Utf8toWStr(namepart,wnamepart))
2607 return false;
2609 // converting string that we try to find to lower case
2610 wstrToLower( wnamepart );
2612 uint32 counter = 0; // Counter for figure out that we found smth.
2614 // Search in SkillLine.dbc
2615 for (uint32 id = 0; id < sSkillLineStore.GetNumRows(); id++)
2617 SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(id);
2618 if(skillInfo)
2620 int loc = m_session ? m_session->GetSessionDbcLocale() : sWorld.GetDefaultDbcLocale();
2621 std::string name = skillInfo->name[loc];
2622 if(name.empty())
2623 continue;
2625 if (!Utf8FitTo(name, wnamepart))
2627 loc = 0;
2628 for(; loc < MAX_LOCALE; ++loc)
2630 if(m_session && loc==m_session->GetSessionDbcLocale())
2631 continue;
2633 name = skillInfo->name[loc];
2634 if(name.empty())
2635 continue;
2637 if (Utf8FitTo(name, wnamepart))
2638 break;
2642 if(loc < MAX_LOCALE)
2644 char valStr[50] = "";
2645 char const* knownStr = "";
2646 if(target && target->HasSkill(id))
2648 knownStr = GetMangosString(LANG_KNOWN);
2649 uint32 curValue = target->GetPureSkillValue(id);
2650 uint32 maxValue = target->GetPureMaxSkillValue(id);
2651 uint32 permValue = target->GetSkillPermBonusValue(id);
2652 uint32 tempValue = target->GetSkillTempBonusValue(id);
2654 char const* valFormat = GetMangosString(LANG_SKILL_VALUES);
2655 snprintf(valStr,50,valFormat,curValue,maxValue,permValue,tempValue);
2658 // send skill in "id - [namedlink locale]" format
2659 if (m_session)
2660 PSendSysMessage(LANG_SKILL_LIST_CHAT,id,id,name.c_str(),localeNames[loc],knownStr,valStr);
2661 else
2662 PSendSysMessage(LANG_SKILL_LIST_CONSOLE,id,name.c_str(),localeNames[loc],knownStr,valStr);
2664 ++counter;
2668 if (counter == 0) // if counter == 0 then we found nth
2669 SendSysMessage(LANG_COMMAND_NOSKILLFOUND);
2670 return true;
2673 bool ChatHandler::HandleLookupSpellCommand(const char* args)
2675 if(!*args)
2676 return false;
2678 // can be NULL at console call
2679 Player* target = getSelectedPlayer();
2681 std::string namepart = args;
2682 std::wstring wnamepart;
2684 if(!Utf8toWStr(namepart,wnamepart))
2685 return false;
2687 // converting string that we try to find to lower case
2688 wstrToLower( wnamepart );
2690 uint32 counter = 0; // Counter for figure out that we found smth.
2692 // Search in Spell.dbc
2693 for (uint32 id = 0; id < sSpellStore.GetNumRows(); id++)
2695 SpellEntry const *spellInfo = sSpellStore.LookupEntry(id);
2696 if(spellInfo)
2698 int loc = m_session ? m_session->GetSessionDbcLocale() : sWorld.GetDefaultDbcLocale();
2699 std::string name = spellInfo->SpellName[loc];
2700 if(name.empty())
2701 continue;
2703 if (!Utf8FitTo(name, wnamepart))
2705 loc = 0;
2706 for(; loc < MAX_LOCALE; ++loc)
2708 if(m_session && loc==m_session->GetSessionDbcLocale())
2709 continue;
2711 name = spellInfo->SpellName[loc];
2712 if(name.empty())
2713 continue;
2715 if (Utf8FitTo(name, wnamepart))
2716 break;
2720 if(loc < MAX_LOCALE)
2722 bool known = target && target->HasSpell(id);
2723 bool learn = (spellInfo->Effect[0] == SPELL_EFFECT_LEARN_SPELL);
2725 uint32 talentCost = GetTalentSpellCost(id);
2727 bool talent = (talentCost > 0);
2728 bool passive = IsPassiveSpell(id);
2729 bool active = target && target->HasAura(id);
2731 // unit32 used to prevent interpreting uint8 as char at output
2732 // find rank of learned spell for learning spell, or talent rank
2733 uint32 rank = talentCost ? talentCost : spellmgr.GetSpellRank(learn ? spellInfo->EffectTriggerSpell[0] : id);
2735 // send spell in "id - [name, rank N] [talent] [passive] [learn] [known]" format
2736 std::ostringstream ss;
2737 if (m_session)
2738 ss << id << " - |cffffffff|Hspell:" << id << "|h[" << name;
2739 else
2740 ss << id << " - " << name;
2742 // include rank in link name
2743 if(rank)
2744 ss << GetMangosString(LANG_SPELL_RANK) << rank;
2746 if (m_session)
2747 ss << " " << localeNames[loc] << "]|h|r";
2748 else
2749 ss << " " << localeNames[loc];
2751 if(talent)
2752 ss << GetMangosString(LANG_TALENT);
2753 if(passive)
2754 ss << GetMangosString(LANG_PASSIVE);
2755 if(learn)
2756 ss << GetMangosString(LANG_LEARN);
2757 if(known)
2758 ss << GetMangosString(LANG_KNOWN);
2759 if(active)
2760 ss << GetMangosString(LANG_ACTIVE);
2762 SendSysMessage(ss.str().c_str());
2764 ++counter;
2768 if (counter == 0) // if counter == 0 then we found nth
2769 SendSysMessage(LANG_COMMAND_NOSPELLFOUND);
2770 return true;
2773 bool ChatHandler::HandleLookupQuestCommand(const char* args)
2775 if(!*args)
2776 return false;
2778 // can be NULL at console call
2779 Player* target = getSelectedPlayer();
2781 std::string namepart = args;
2782 std::wstring wnamepart;
2784 // converting string that we try to find to lower case
2785 if(!Utf8toWStr(namepart,wnamepart))
2786 return false;
2788 wstrToLower(wnamepart);
2790 uint32 counter = 0 ;
2792 ObjectMgr::QuestMap const& qTemplates = objmgr.GetQuestTemplates();
2793 for (ObjectMgr::QuestMap::const_iterator iter = qTemplates.begin(); iter != qTemplates.end(); ++iter)
2795 Quest * qinfo = iter->second;
2797 int loc_idx = m_session ? m_session->GetSessionDbLocaleIndex() : objmgr.GetDBCLocaleIndex();
2798 if ( loc_idx >= 0 )
2800 QuestLocale const *il = objmgr.GetQuestLocale(qinfo->GetQuestId());
2801 if (il)
2803 if (il->Title.size() > loc_idx && !il->Title[loc_idx].empty())
2805 std::string title = il->Title[loc_idx];
2807 if (Utf8FitTo(title, wnamepart))
2809 char const* statusStr = "";
2811 if(target)
2813 QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId());
2815 if(status == QUEST_STATUS_COMPLETE)
2817 if(target->GetQuestRewardStatus(qinfo->GetQuestId()))
2818 statusStr = GetMangosString(LANG_COMMAND_QUEST_REWARDED);
2819 else
2820 statusStr = GetMangosString(LANG_COMMAND_QUEST_COMPLETE);
2822 else if(status == QUEST_STATUS_INCOMPLETE)
2823 statusStr = GetMangosString(LANG_COMMAND_QUEST_ACTIVE);
2826 if (m_session)
2827 PSendSysMessage(LANG_QUEST_LIST_CHAT,qinfo->GetQuestId(),qinfo->GetQuestId(),title.c_str(),statusStr);
2828 else
2829 PSendSysMessage(LANG_QUEST_LIST_CONSOLE,qinfo->GetQuestId(),title.c_str(),statusStr);
2830 ++counter;
2831 continue;
2837 std::string title = qinfo->GetTitle();
2838 if(title.empty())
2839 continue;
2841 if (Utf8FitTo(title, wnamepart))
2843 char const* statusStr = "";
2845 if(target)
2847 QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId());
2849 if(status == QUEST_STATUS_COMPLETE)
2851 if(target->GetQuestRewardStatus(qinfo->GetQuestId()))
2852 statusStr = GetMangosString(LANG_COMMAND_QUEST_REWARDED);
2853 else
2854 statusStr = GetMangosString(LANG_COMMAND_QUEST_COMPLETE);
2856 else if(status == QUEST_STATUS_INCOMPLETE)
2857 statusStr = GetMangosString(LANG_COMMAND_QUEST_ACTIVE);
2860 if (m_session)
2861 PSendSysMessage(LANG_QUEST_LIST_CHAT,qinfo->GetQuestId(),qinfo->GetQuestId(),title.c_str(),statusStr);
2862 else
2863 PSendSysMessage(LANG_QUEST_LIST_CONSOLE,qinfo->GetQuestId(),title.c_str(),statusStr);
2865 ++counter;
2869 if (counter==0)
2870 SendSysMessage(LANG_COMMAND_NOQUESTFOUND);
2872 return true;
2875 bool ChatHandler::HandleLookupCreatureCommand(const char* args)
2877 if (!*args)
2878 return false;
2880 std::string namepart = args;
2881 std::wstring wnamepart;
2883 // converting string that we try to find to lower case
2884 if (!Utf8toWStr (namepart,wnamepart))
2885 return false;
2887 wstrToLower (wnamepart);
2889 uint32 counter = 0;
2891 for (uint32 id = 0; id< sCreatureStorage.MaxEntry; ++id)
2893 CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo> (id);
2894 if(!cInfo)
2895 continue;
2897 int loc_idx = m_session ? m_session->GetSessionDbLocaleIndex() : objmgr.GetDBCLocaleIndex();
2898 if (loc_idx >= 0)
2900 CreatureLocale const *cl = objmgr.GetCreatureLocale (id);
2901 if (cl)
2903 if (cl->Name.size() > loc_idx && !cl->Name[loc_idx].empty ())
2905 std::string name = cl->Name[loc_idx];
2907 if (Utf8FitTo (name, wnamepart))
2909 if (m_session)
2910 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CHAT, id, id, name.c_str ());
2911 else
2912 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CONSOLE, id, name.c_str ());
2913 ++counter;
2914 continue;
2920 std::string name = cInfo->Name;
2921 if (name.empty ())
2922 continue;
2924 if (Utf8FitTo(name, wnamepart))
2926 if (m_session)
2927 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CHAT, id, id, name.c_str ());
2928 else
2929 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CONSOLE, id, name.c_str ());
2930 ++counter;
2934 if (counter==0)
2935 SendSysMessage (LANG_COMMAND_NOCREATUREFOUND);
2937 return true;
2940 bool ChatHandler::HandleLookupObjectCommand(const char* args)
2942 if(!*args)
2943 return false;
2945 std::string namepart = args;
2946 std::wstring wnamepart;
2948 // converting string that we try to find to lower case
2949 if(!Utf8toWStr(namepart,wnamepart))
2950 return false;
2952 wstrToLower(wnamepart);
2954 uint32 counter = 0;
2956 for (uint32 id = 0; id< sGOStorage.MaxEntry; id++ )
2958 GameObjectInfo const* gInfo = sGOStorage.LookupEntry<GameObjectInfo>(id);
2959 if(!gInfo)
2960 continue;
2962 int loc_idx = m_session ? m_session->GetSessionDbLocaleIndex() : objmgr.GetDBCLocaleIndex();
2963 if ( loc_idx >= 0 )
2965 GameObjectLocale const *gl = objmgr.GetGameObjectLocale(id);
2966 if (gl)
2968 if (gl->Name.size() > loc_idx && !gl->Name[loc_idx].empty())
2970 std::string name = gl->Name[loc_idx];
2972 if (Utf8FitTo(name, wnamepart))
2974 if (m_session)
2975 PSendSysMessage(LANG_GO_ENTRY_LIST_CHAT, id, id, name.c_str());
2976 else
2977 PSendSysMessage(LANG_GO_ENTRY_LIST_CONSOLE, id, name.c_str());
2978 ++counter;
2979 continue;
2985 std::string name = gInfo->name;
2986 if(name.empty())
2987 continue;
2989 if(Utf8FitTo(name, wnamepart))
2991 if (m_session)
2992 PSendSysMessage(LANG_GO_ENTRY_LIST_CHAT, id, id, name.c_str());
2993 else
2994 PSendSysMessage(LANG_GO_ENTRY_LIST_CONSOLE, id, name.c_str());
2995 ++counter;
2999 if(counter==0)
3000 SendSysMessage(LANG_COMMAND_NOGAMEOBJECTFOUND);
3002 return true;
3005 /** \brief GM command level 3 - Create a guild.
3007 * This command allows a GM (level 3) to create a guild.
3009 * The "args" parameter contains the name of the guild leader
3010 * and then the name of the guild.
3013 bool ChatHandler::HandleGuildCreateCommand(const char* args)
3016 if (!*args)
3017 return false;
3019 char *lname = strtok ((char*)args, " ");
3020 char *gname = strtok (NULL, "");
3022 if (!lname)
3023 return false;
3025 if (!gname)
3027 SendSysMessage (LANG_INSERT_GUILD_NAME);
3028 SetSentErrorMessage (true);
3029 return false;
3032 std::string guildname = gname;
3034 Player* player = ObjectAccessor::Instance ().FindPlayerByName (lname);
3035 if (!player)
3037 SendSysMessage (LANG_PLAYER_NOT_FOUND);
3038 SetSentErrorMessage (true);
3039 return false;
3042 if (player->GetGuildId())
3044 SendSysMessage (LANG_PLAYER_IN_GUILD);
3045 return true;
3048 Guild *guild = new Guild;
3049 if (!guild->create (player->GetGUID (),guildname))
3051 delete guild;
3052 SendSysMessage (LANG_GUILD_NOT_CREATED);
3053 SetSentErrorMessage (true);
3054 return false;
3057 objmgr.AddGuild (guild);
3058 return true;
3061 bool ChatHandler::HandleGuildInviteCommand(const char *args)
3063 if (!*args)
3064 return false;
3066 char* par1 = strtok ((char*)args, " ");
3067 char* par2 = strtok (NULL, "");
3068 if(!par1 || !par2)
3069 return false;
3071 std::string glName = par2;
3072 Guild* targetGuild = objmgr.GetGuildByName (glName);
3073 if (!targetGuild)
3074 return false;
3076 std::string plName = par1;
3077 if (!normalizePlayerName (plName))
3079 SendSysMessage (LANG_PLAYER_NOT_FOUND);
3080 SetSentErrorMessage (true);
3081 return false;
3084 uint64 plGuid = 0;
3085 if (Player* targetPlayer = ObjectAccessor::Instance ().FindPlayerByName (plName.c_str ()))
3086 plGuid = targetPlayer->GetGUID ();
3087 else
3088 plGuid = objmgr.GetPlayerGUIDByName (plName.c_str ());
3090 if (!plGuid)
3091 false;
3093 // player's guild membership checked in AddMember before add
3094 if (!targetGuild->AddMember (plGuid,targetGuild->GetLowestRank ()))
3095 return false;
3097 return true;
3100 bool ChatHandler::HandleGuildUninviteCommand(const char *args)
3102 if (!*args)
3103 return false;
3105 char* par1 = strtok ((char*)args, " ");
3106 if(!par1)
3107 return false;
3109 std::string plName = par1;
3110 if (!normalizePlayerName (plName))
3112 SendSysMessage (LANG_PLAYER_NOT_FOUND);
3113 SetSentErrorMessage (true);
3114 return false;
3117 uint64 plGuid = 0;
3118 uint32 glId = 0;
3119 if (Player* targetPlayer = ObjectAccessor::Instance ().FindPlayerByName (plName.c_str ()))
3121 plGuid = targetPlayer->GetGUID ();
3122 glId = targetPlayer->GetGuildId ();
3124 else
3126 plGuid = objmgr.GetPlayerGUIDByName (plName.c_str ());
3127 glId = Player::GetGuildIdFromDB (plGuid);
3130 if (!plGuid || !glId)
3131 return false;
3133 Guild* targetGuild = objmgr.GetGuildById (glId);
3134 if (!targetGuild)
3135 return false;
3137 targetGuild->DelMember (plGuid);
3139 return true;
3142 bool ChatHandler::HandleGuildRankCommand(const char *args)
3144 if (!*args)
3145 return false;
3147 char* par1 = strtok ((char*)args, " ");
3148 char* par2 = strtok (NULL, " ");
3149 if (!par1 || !par2)
3150 return false;
3151 std::string plName = par1;
3152 if (!normalizePlayerName (plName))
3154 SendSysMessage (LANG_PLAYER_NOT_FOUND);
3155 SetSentErrorMessage (true);
3156 return false;
3159 uint64 plGuid = 0;
3160 uint32 glId = 0;
3161 if (Player* targetPlayer = ObjectAccessor::Instance ().FindPlayerByName (plName.c_str ()))
3163 plGuid = targetPlayer->GetGUID ();
3164 glId = targetPlayer->GetGuildId ();
3166 else
3168 plGuid = objmgr.GetPlayerGUIDByName (plName.c_str ());
3169 glId = Player::GetGuildIdFromDB (plGuid);
3172 if (!plGuid || !glId)
3173 return false;
3175 Guild* targetGuild = objmgr.GetGuildById (glId);
3176 if (!targetGuild)
3177 return false;
3179 uint32 newrank = uint32 (atoi (par2));
3180 if (newrank > targetGuild->GetLowestRank ())
3181 return false;
3183 targetGuild->ChangeRank (plGuid,newrank);
3185 return true;
3188 bool ChatHandler::HandleGuildDeleteCommand(const char* args)
3190 if (!*args)
3191 return false;
3193 char* par1 = strtok ((char*)args, " ");
3194 if (!par1)
3195 return false;
3197 std::string gld = par1;
3199 Guild* targetGuild = objmgr.GetGuildByName (gld);
3200 if (!targetGuild)
3201 return false;
3203 targetGuild->Disband ();
3205 return true;
3208 bool ChatHandler::HandleGetDistanceCommand(const char* /*args*/)
3210 Unit* pUnit = getSelectedUnit();
3212 if(!pUnit)
3214 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3215 SetSentErrorMessage(true);
3216 return false;
3219 PSendSysMessage(LANG_DISTANCE, m_session->GetPlayer()->GetDistance(pUnit),m_session->GetPlayer()->GetDistance2d(pUnit));
3221 return true;
3224 // FIX-ME!!!
3226 bool ChatHandler::HandleAddWeaponCommand(const char* /*args*/)
3228 /*if (!*args)
3229 return false;
3231 uint64 guid = m_session->GetPlayer()->GetSelection();
3232 if (guid == 0)
3234 SendSysMessage(LANG_NO_SELECTION);
3235 return true;
3238 Creature *pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
3240 if(!pCreature)
3242 SendSysMessage(LANG_SELECT_CREATURE);
3243 return true;
3246 char* pSlotID = strtok((char*)args, " ");
3247 if (!pSlotID)
3248 return false;
3250 char* pItemID = strtok(NULL, " ");
3251 if (!pItemID)
3252 return false;
3254 uint32 ItemID = atoi(pItemID);
3255 uint32 SlotID = atoi(pSlotID);
3257 ItemPrototype* tmpItem = objmgr.GetItemPrototype(ItemID);
3259 bool added = false;
3260 if(tmpItem)
3262 switch(SlotID)
3264 case 1:
3265 pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, ItemID);
3266 added = true;
3267 break;
3268 case 2:
3269 pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_01, ItemID);
3270 added = true;
3271 break;
3272 case 3:
3273 pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_02, ItemID);
3274 added = true;
3275 break;
3276 default:
3277 PSendSysMessage(LANG_ITEM_SLOT_NOT_EXIST,SlotID);
3278 added = false;
3279 break;
3281 if(added)
3283 PSendSysMessage(LANG_ITEM_ADDED_TO_SLOT,ItemID,tmpItem->Name1,SlotID);
3286 else
3288 PSendSysMessage(LANG_ITEM_NOT_FOUND,ItemID);
3289 return true;
3292 return true;
3295 bool ChatHandler::HandleDieCommand(const char* /*args*/)
3297 Unit* target = getSelectedUnit();
3299 if(!target || !m_session->GetPlayer()->GetSelection())
3301 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3302 SetSentErrorMessage(true);
3303 return false;
3306 if( target->isAlive() )
3308 m_session->GetPlayer()->DealDamage(target, target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
3311 return true;
3314 bool ChatHandler::HandleDamageCommand(const char * args)
3316 if (!*args)
3317 return false;
3319 Unit* target = getSelectedUnit();
3321 if(!target || !m_session->GetPlayer()->GetSelection())
3323 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3324 SetSentErrorMessage(true);
3325 return false;
3328 if( !target->isAlive() )
3329 return true;
3331 char* damageStr = strtok((char*)args, " ");
3332 if(!damageStr)
3333 return false;
3335 int32 damage = atoi((char*)damageStr);
3336 if(damage <=0)
3337 return true;
3339 char* schoolStr = strtok((char*)NULL, " ");
3341 // flat melee damage without resistence/etc reduction
3342 if(!schoolStr)
3344 m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
3345 m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, SPELL_SCHOOL_MASK_NORMAL, damage, 0, 0, VICTIMSTATE_NORMAL, 0);
3346 return true;
3349 uint32 school = schoolStr ? atoi((char*)schoolStr) : SPELL_SCHOOL_NORMAL;
3350 if(school >= MAX_SPELL_SCHOOL)
3351 return false;
3353 SpellSchoolMask schoolmask = SpellSchoolMask(1 << school);
3355 if ( schoolmask & SPELL_SCHOOL_MASK_NORMAL )
3356 damage = m_session->GetPlayer()->CalcArmorReducedDamage(target, damage);
3358 char* spellStr = strtok((char*)NULL, " ");
3360 // melee damage by specific school
3361 if(!spellStr)
3363 uint32 absorb = 0;
3364 uint32 resist = 0;
3366 m_session->GetPlayer()->CalcAbsorbResist(target,schoolmask, SPELL_DIRECT_DAMAGE, damage, &absorb, &resist);
3368 if (damage <= absorb + resist)
3369 return true;
3371 damage -= absorb + resist;
3373 m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, schoolmask, NULL, false);
3374 m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, schoolmask, damage, absorb, resist, VICTIMSTATE_NORMAL, 0);
3375 return true;
3378 // non-melee damage
3380 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
3381 uint32 spellid = extractSpellIdFromLink((char*)args);
3382 if(!spellid || !sSpellStore.LookupEntry(spellid))
3383 return false;
3385 m_session->GetPlayer()->SpellNonMeleeDamageLog(target, spellid, damage, false);
3386 return true;
3389 bool ChatHandler::HandleModifyArenaCommand(const char * args)
3391 if (!*args)
3392 return false;
3394 Player *target = getSelectedPlayer();
3395 if(!target)
3397 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3398 SetSentErrorMessage(true);
3399 return false;
3402 int32 amount = (uint32)atoi(args);
3404 target->ModifyArenaPoints(amount);
3406 PSendSysMessage(LANG_COMMAND_MODIFY_ARENA, target->GetName(), target->GetArenaPoints());
3408 return true;
3411 bool ChatHandler::HandleReviveCommand(const char* args)
3413 Player* SelectedPlayer = NULL;
3415 if (*args)
3417 std::string name = args;
3418 if(!normalizePlayerName(name))
3420 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3421 SetSentErrorMessage(true);
3422 return false;
3425 SelectedPlayer = objmgr.GetPlayer(name.c_str());
3427 else
3428 SelectedPlayer = getSelectedPlayer();
3430 if(!SelectedPlayer)
3432 SendSysMessage(LANG_NO_CHAR_SELECTED);
3433 SetSentErrorMessage(true);
3434 return false;
3437 SelectedPlayer->ResurrectPlayer(0.5f);
3438 SelectedPlayer->SpawnCorpseBones();
3439 SelectedPlayer->SaveToDB();
3440 return true;
3443 bool ChatHandler::HandleAuraCommand(const char* args)
3445 char* px = strtok((char*)args, " ");
3446 if (!px)
3447 return false;
3449 Unit *target = getSelectedUnit();
3450 if(!target)
3452 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3453 SetSentErrorMessage(true);
3454 return false;
3457 uint32 spellID = (uint32)atoi(px);
3458 SpellEntry const *spellInfo = sSpellStore.LookupEntry( spellID );
3459 if(spellInfo)
3461 for(uint32 i = 0;i<3;i++)
3463 uint8 eff = spellInfo->Effect[i];
3464 if (eff>=TOTAL_SPELL_EFFECTS)
3465 continue;
3466 if( IsAreaAuraEffect(eff) ||
3467 eff == SPELL_EFFECT_APPLY_AURA ||
3468 eff == SPELL_EFFECT_PERSISTENT_AREA_AURA )
3470 Aura *Aur = CreateAura(spellInfo, i, NULL, target);
3471 target->AddAura(Aur);
3476 return true;
3479 bool ChatHandler::HandleUnAuraCommand(const char* args)
3481 char* px = strtok((char*)args, " ");
3482 if (!px)
3483 return false;
3485 Unit *target = getSelectedUnit();
3486 if(!target)
3488 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3489 SetSentErrorMessage(true);
3490 return false;
3493 std::string argstr = args;
3494 if (argstr == "all")
3496 target->RemoveAllAuras();
3497 return true;
3500 uint32 spellID = (uint32)atoi(px);
3501 target->RemoveAurasDueToSpell(spellID);
3503 return true;
3506 bool ChatHandler::HandleLinkGraveCommand(const char* args)
3508 if(!*args)
3509 return false;
3511 char* px = strtok((char*)args, " ");
3512 if (!px)
3513 return false;
3515 uint32 g_id = (uint32)atoi(px);
3517 uint32 g_team;
3519 char* px2 = strtok(NULL, " ");
3521 if (!px2)
3522 g_team = 0;
3523 else if (strncmp(px2,"horde",6)==0)
3524 g_team = HORDE;
3525 else if (strncmp(px2,"alliance",9)==0)
3526 g_team = ALLIANCE;
3527 else
3528 return false;
3530 WorldSafeLocsEntry const* graveyard = sWorldSafeLocsStore.LookupEntry(g_id);
3532 if(!graveyard )
3534 PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST, g_id);
3535 SetSentErrorMessage(true);
3536 return false;
3539 Player* player = m_session->GetPlayer();
3541 uint32 zoneId = player->GetZoneId();
3543 AreaTableEntry const *areaEntry = GetAreaEntryByAreaID(zoneId);
3544 if(!areaEntry || areaEntry->zone !=0 )
3546 PSendSysMessage(LANG_COMMAND_GRAVEYARDWRONGZONE, g_id,zoneId);
3547 SetSentErrorMessage(true);
3548 return false;
3551 if(objmgr.AddGraveYardLink(g_id,player->GetZoneId(),g_team))
3552 PSendSysMessage(LANG_COMMAND_GRAVEYARDLINKED, g_id,zoneId);
3553 else
3554 PSendSysMessage(LANG_COMMAND_GRAVEYARDALRLINKED, g_id,zoneId);
3556 return true;
3559 bool ChatHandler::HandleNearGraveCommand(const char* args)
3561 uint32 g_team;
3563 size_t argslen = strlen(args);
3565 if(!*args)
3566 g_team = 0;
3567 else if (strncmp((char*)args,"horde",argslen)==0)
3568 g_team = HORDE;
3569 else if (strncmp((char*)args,"alliance",argslen)==0)
3570 g_team = ALLIANCE;
3571 else
3572 return false;
3574 Player* player = m_session->GetPlayer();
3576 WorldSafeLocsEntry const* graveyard = objmgr.GetClosestGraveYard(
3577 player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(),player->GetMapId(),g_team);
3579 if(graveyard)
3581 uint32 g_id = graveyard->ID;
3583 GraveYardData const* data = objmgr.FindGraveYardData(g_id,player->GetZoneId());
3584 if (!data)
3586 PSendSysMessage(LANG_COMMAND_GRAVEYARDERROR,g_id);
3587 SetSentErrorMessage(true);
3588 return false;
3591 g_team = data->team;
3593 std::string team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_NOTEAM);
3595 if(g_team == 0)
3596 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ANY);
3597 else if(g_team == HORDE)
3598 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_HORDE);
3599 else if(g_team == ALLIANCE)
3600 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ALLIANCE);
3602 PSendSysMessage(LANG_COMMAND_GRAVEYARDNEAREST, g_id,team_name.c_str(),player->GetZoneId());
3604 else
3606 std::string team_name;
3608 if(g_team == 0)
3609 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ANY);
3610 else if(g_team == HORDE)
3611 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_HORDE);
3612 else if(g_team == ALLIANCE)
3613 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ALLIANCE);
3615 if(g_team == ~uint32(0))
3616 PSendSysMessage(LANG_COMMAND_ZONENOGRAVEYARDS, player->GetZoneId());
3617 else
3618 PSendSysMessage(LANG_COMMAND_ZONENOGRAFACTION, player->GetZoneId(),team_name.c_str());
3621 return true;
3624 //play npc emote
3625 bool ChatHandler::HandleNpcPlayEmoteCommand(const char* args)
3627 uint32 emote = atoi((char*)args);
3629 Creature* target = getSelectedCreature();
3630 if(!target)
3632 SendSysMessage(LANG_SELECT_CREATURE);
3633 SetSentErrorMessage(true);
3634 return false;
3637 target->SetUInt32Value(UNIT_NPC_EMOTESTATE,emote);
3639 return true;
3642 bool ChatHandler::HandleNpcInfoCommand(const char* /*args*/)
3644 Creature* target = getSelectedCreature();
3646 if(!target)
3648 SendSysMessage(LANG_SELECT_CREATURE);
3649 SetSentErrorMessage(true);
3650 return false;
3653 uint32 faction = target->getFaction();
3654 uint32 npcflags = target->GetUInt32Value(UNIT_NPC_FLAGS);
3655 uint32 displayid = target->GetDisplayId();
3656 uint32 nativeid = target->GetNativeDisplayId();
3657 uint32 Entry = target->GetEntry();
3658 CreatureInfo const* cInfo = target->GetCreatureInfo();
3660 int32 curRespawnDelay = target->GetRespawnTimeEx()-time(NULL);
3661 if(curRespawnDelay < 0)
3662 curRespawnDelay = 0;
3663 std::string curRespawnDelayStr = secsToTimeString(curRespawnDelay,true);
3664 std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(),true);
3666 PSendSysMessage(LANG_NPCINFO_CHAR, target->GetDBTableGUIDLow(), faction, npcflags, Entry, displayid, nativeid);
3667 PSendSysMessage(LANG_NPCINFO_LEVEL, target->getLevel());
3668 PSendSysMessage(LANG_NPCINFO_HEALTH,target->GetCreateHealth(), target->GetMaxHealth(), target->GetHealth());
3669 PSendSysMessage(LANG_NPCINFO_FLAGS, target->GetUInt32Value(UNIT_FIELD_FLAGS), target->GetUInt32Value(UNIT_DYNAMIC_FLAGS), target->getFaction());
3670 PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES, defRespawnDelayStr.c_str(),curRespawnDelayStr.c_str());
3671 PSendSysMessage(LANG_NPCINFO_LOOT, cInfo->lootid,cInfo->pickpocketLootId,cInfo->SkinLootId);
3672 PSendSysMessage(LANG_NPCINFO_DUNGEON_ID, target->GetInstanceId());
3673 PSendSysMessage(LANG_NPCINFO_POSITION,float(target->GetPositionX()), float(target->GetPositionY()), float(target->GetPositionZ()));
3675 if ((npcflags & UNIT_NPC_FLAG_VENDOR) )
3677 SendSysMessage(LANG_NPCINFO_VENDOR);
3679 if ((npcflags & UNIT_NPC_FLAG_TRAINER) )
3681 SendSysMessage(LANG_NPCINFO_TRAINER);
3684 return true;
3687 bool ChatHandler::HandleExploreCheatCommand(const char* args)
3689 if (!*args)
3690 return false;
3692 int flag = atoi((char*)args);
3694 Player *chr = getSelectedPlayer();
3695 if (chr == NULL)
3697 SendSysMessage(LANG_NO_CHAR_SELECTED);
3698 SetSentErrorMessage(true);
3699 return false;
3702 if (flag != 0)
3704 PSendSysMessage(LANG_YOU_SET_EXPLORE_ALL, chr->GetName());
3705 if (needReportToTarget(chr))
3706 ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_ALL,GetName());
3708 else
3710 PSendSysMessage(LANG_YOU_SET_EXPLORE_NOTHING, chr->GetName());
3711 if (needReportToTarget(chr))
3712 ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_NOTHING,GetName());
3715 for (uint8 i=0; i<128; i++)
3717 if (flag != 0)
3719 m_session->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i,0xFFFFFFFF);
3721 else
3723 m_session->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i,0);
3727 return true;
3730 bool ChatHandler::HandleHoverCommand(const char* args)
3732 char* px = strtok((char*)args, " ");
3733 uint32 flag;
3734 if (!px)
3735 flag = 1;
3736 else
3737 flag = atoi(px);
3739 m_session->GetPlayer()->SetHover(flag);
3741 if (flag)
3742 SendSysMessage(LANG_HOVER_ENABLED);
3743 else
3744 SendSysMessage(LANG_HOVER_DISABLED);
3746 return true;
3749 bool ChatHandler::HandleLevelUpCommand(const char* args)
3751 char* px = strtok((char*)args, " ");
3752 char* py = strtok((char*)NULL, " ");
3754 // command format parsing
3755 char* pname = (char*)NULL;
3756 int addlevel = 1;
3758 if(px && py) // .levelup name level
3760 addlevel = atoi(py);
3761 pname = px;
3763 else if(px && !py) // .levelup name OR .levelup level
3765 if(isalpha(px[0])) // .levelup name
3766 pname = px;
3767 else // .levelup level
3768 addlevel = atoi(px);
3770 // else .levelup - nothing do for preparing
3772 // player
3773 Player *chr = NULL;
3774 uint64 chr_guid = 0;
3776 std::string name;
3778 if(pname) // player by name
3780 name = pname;
3781 if(!normalizePlayerName(name))
3783 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3784 SetSentErrorMessage(true);
3785 return false;
3788 chr = objmgr.GetPlayer(name.c_str());
3789 if(!chr) // not in game
3791 chr_guid = objmgr.GetPlayerGUIDByName(name);
3792 if (chr_guid == 0)
3794 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3795 SetSentErrorMessage(true);
3796 return false;
3800 else // player by selection
3802 chr = getSelectedPlayer();
3804 if (chr == NULL)
3806 SendSysMessage(LANG_NO_CHAR_SELECTED);
3807 SetSentErrorMessage(true);
3808 return false;
3811 name = chr->GetName();
3814 assert(chr || chr_guid);
3816 int32 oldlevel = chr ? chr->getLevel() : Player::GetUInt32ValueFromDB(UNIT_FIELD_LEVEL,chr_guid);
3817 int32 newlevel = oldlevel + addlevel;
3818 if(newlevel < 1)
3819 newlevel = 1;
3820 if(newlevel > STRONG_MAX_LEVEL) // hardcoded maximum level
3821 newlevel = STRONG_MAX_LEVEL;
3823 if(chr)
3825 chr->GiveLevel(newlevel);
3826 chr->InitTalentForLevel();
3827 chr->SetUInt32Value(PLAYER_XP,0);
3829 if(oldlevel == newlevel)
3830 ChatHandler(chr).SendSysMessage(LANG_YOURS_LEVEL_PROGRESS_RESET);
3831 else
3832 if(oldlevel < newlevel)
3833 ChatHandler(chr).PSendSysMessage(LANG_YOURS_LEVEL_UP,newlevel-oldlevel);
3834 else
3835 if(oldlevel > newlevel)
3836 ChatHandler(chr).PSendSysMessage(LANG_YOURS_LEVEL_DOWN,newlevel-oldlevel);
3838 else
3840 // update level and XP at level, all other will be updated at loading
3841 Tokens values;
3842 Player::LoadValuesArrayFromDB(values,chr_guid);
3843 Player::SetUInt32ValueInArray(values,UNIT_FIELD_LEVEL,newlevel);
3844 Player::SetUInt32ValueInArray(values,PLAYER_XP,0);
3845 Player::SaveValuesArrayInDB(values,chr_guid);
3848 if(m_session->GetPlayer() != chr) // including chr==NULL
3849 PSendSysMessage(LANG_YOU_CHANGE_LVL,name.c_str(),newlevel);
3850 return true;
3853 bool ChatHandler::HandleShowAreaCommand(const char* args)
3855 if (!*args)
3856 return false;
3858 Player *chr = getSelectedPlayer();
3859 if (chr == NULL)
3861 SendSysMessage(LANG_NO_CHAR_SELECTED);
3862 SetSentErrorMessage(true);
3863 return false;
3866 int area = GetAreaFlagByAreaID(atoi((char*)args));
3867 int offset = area / 32;
3868 uint32 val = (uint32)(1 << (area % 32));
3870 if(area<0 || offset >= 128)
3872 SendSysMessage(LANG_BAD_VALUE);
3873 SetSentErrorMessage(true);
3874 return false;
3877 uint32 currFields = chr->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset);
3878 chr->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields | val));
3880 SendSysMessage(LANG_EXPLORE_AREA);
3881 return true;
3884 bool ChatHandler::HandleHideAreaCommand(const char* args)
3886 if (!*args)
3887 return false;
3889 Player *chr = getSelectedPlayer();
3890 if (chr == NULL)
3892 SendSysMessage(LANG_NO_CHAR_SELECTED);
3893 SetSentErrorMessage(true);
3894 return false;
3897 int area = GetAreaFlagByAreaID(atoi((char*)args));
3898 int offset = area / 32;
3899 uint32 val = (uint32)(1 << (area % 32));
3901 if(area<0 || offset >= 128)
3903 SendSysMessage(LANG_BAD_VALUE);
3904 SetSentErrorMessage(true);
3905 return false;
3908 uint32 currFields = chr->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset);
3909 chr->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields ^ val));
3911 SendSysMessage(LANG_UNEXPLORE_AREA);
3912 return true;
3915 bool ChatHandler::HandleUpdate(const char* args)
3917 if(!*args)
3918 return false;
3920 uint32 updateIndex;
3921 uint32 value;
3923 char* pUpdateIndex = strtok((char*)args, " ");
3925 Unit* chr = getSelectedUnit();
3926 if (chr == NULL)
3928 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3929 SetSentErrorMessage(true);
3930 return false;
3933 if(!pUpdateIndex)
3935 return true;
3937 updateIndex = atoi(pUpdateIndex);
3938 //check updateIndex
3939 if(chr->GetTypeId() == TYPEID_PLAYER)
3941 if (updateIndex>=PLAYER_END) return true;
3943 else
3945 if (updateIndex>=UNIT_END) return true;
3948 char* pvalue = strtok(NULL, " ");
3949 if (!pvalue)
3951 value=chr->GetUInt32Value(updateIndex);
3953 PSendSysMessage(LANG_UPDATE, chr->GetGUIDLow(),updateIndex,value);
3954 return true;
3957 value=atoi(pvalue);
3959 PSendSysMessage(LANG_UPDATE_CHANGE, chr->GetGUIDLow(),updateIndex,value);
3961 chr->SetUInt32Value(updateIndex,value);
3963 return true;
3966 bool ChatHandler::HandleBankCommand(const char* /*args*/)
3968 m_session->SendShowBank( m_session->GetPlayer()->GetGUID() );
3970 return true;
3973 bool ChatHandler::HandleChangeWeather(const char* args)
3975 if(!*args)
3976 return false;
3978 //Weather is OFF
3979 if (!sWorld.getConfig(CONFIG_WEATHER))
3981 SendSysMessage(LANG_WEATHER_DISABLED);
3982 SetSentErrorMessage(true);
3983 return false;
3986 //*Change the weather of a cell
3987 char* px = strtok((char*)args, " ");
3988 char* py = strtok(NULL, " ");
3990 if (!px || !py)
3991 return false;
3993 uint32 type = (uint32)atoi(px); //0 to 3, 0: fine, 1: rain, 2: snow, 3: sand
3994 float grade = (float)atof(py); //0 to 1, sending -1 is instand good weather
3996 Player *player = m_session->GetPlayer();
3997 uint32 zoneid = player->GetZoneId();
3999 Weather* wth = sWorld.FindWeather(zoneid);
4001 if(!wth)
4002 wth = sWorld.AddWeather(zoneid);
4003 if(!wth)
4005 SendSysMessage(LANG_NO_WEATHER);
4006 SetSentErrorMessage(true);
4007 return false;
4010 wth->SetWeather(WeatherType(type), grade);
4012 return true;
4015 bool ChatHandler::HandleSetValue(const char* args)
4017 if(!*args)
4018 return false;
4020 char* px = strtok((char*)args, " ");
4021 char* py = strtok(NULL, " ");
4022 char* pz = strtok(NULL, " ");
4024 if (!px || !py)
4025 return false;
4027 Unit* target = getSelectedUnit();
4028 if(!target)
4030 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
4031 SetSentErrorMessage(true);
4032 return false;
4035 uint64 guid = target->GetGUID();
4037 uint32 Opcode = (uint32)atoi(px);
4038 if(Opcode >= target->GetValuesCount())
4040 PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, GUID_LOPART(guid), target->GetValuesCount());
4041 return false;
4043 uint32 iValue;
4044 float fValue;
4045 bool isint32 = true;
4046 if(pz)
4047 isint32 = (bool)atoi(pz);
4048 if(isint32)
4050 iValue = (uint32)atoi(py);
4051 sLog.outDebug(GetMangosString(LANG_SET_UINT), GUID_LOPART(guid), Opcode, iValue);
4052 target->SetUInt32Value( Opcode , iValue );
4053 PSendSysMessage(LANG_SET_UINT_FIELD, GUID_LOPART(guid), Opcode,iValue);
4055 else
4057 fValue = (float)atof(py);
4058 sLog.outDebug(GetMangosString(LANG_SET_FLOAT), GUID_LOPART(guid), Opcode, fValue);
4059 target->SetFloatValue( Opcode , fValue );
4060 PSendSysMessage(LANG_SET_FLOAT_FIELD, GUID_LOPART(guid), Opcode,fValue);
4063 return true;
4066 bool ChatHandler::HandleGetValue(const char* args)
4068 if(!*args)
4069 return false;
4071 char* px = strtok((char*)args, " ");
4072 char* pz = strtok(NULL, " ");
4074 if (!px)
4075 return false;
4077 Unit* target = getSelectedUnit();
4078 if(!target)
4080 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
4081 SetSentErrorMessage(true);
4082 return false;
4085 uint64 guid = target->GetGUID();
4087 uint32 Opcode = (uint32)atoi(px);
4088 if(Opcode >= target->GetValuesCount())
4090 PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, GUID_LOPART(guid), target->GetValuesCount());
4091 return false;
4093 uint32 iValue;
4094 float fValue;
4095 bool isint32 = true;
4096 if(pz)
4097 isint32 = (bool)atoi(pz);
4099 if(isint32)
4101 iValue = target->GetUInt32Value( Opcode );
4102 sLog.outDebug(GetMangosString(LANG_GET_UINT), GUID_LOPART(guid), Opcode, iValue);
4103 PSendSysMessage(LANG_GET_UINT_FIELD, GUID_LOPART(guid), Opcode, iValue);
4105 else
4107 fValue = target->GetFloatValue( Opcode );
4108 sLog.outDebug(GetMangosString(LANG_GET_FLOAT), GUID_LOPART(guid), Opcode, fValue);
4109 PSendSysMessage(LANG_GET_FLOAT_FIELD, GUID_LOPART(guid), Opcode, fValue);
4112 return true;
4115 bool ChatHandler::HandleSet32Bit(const char* args)
4117 if(!*args)
4118 return false;
4120 char* px = strtok((char*)args, " ");
4121 char* py = strtok(NULL, " ");
4123 if (!px || !py)
4124 return false;
4126 uint32 Opcode = (uint32)atoi(px);
4127 uint32 Value = (uint32)atoi(py);
4128 if (Value > 32) //uint32 = 32 bits
4129 return false;
4131 sLog.outDebug(GetMangosString(LANG_SET_32BIT), Opcode, Value);
4133 m_session->GetPlayer( )->SetUInt32Value( Opcode , 2^Value );
4135 PSendSysMessage(LANG_SET_32BIT_FIELD, Opcode,1);
4136 return true;
4139 bool ChatHandler::HandleMod32Value(const char* args)
4141 if(!*args)
4142 return false;
4144 char* px = strtok((char*)args, " ");
4145 char* py = strtok(NULL, " ");
4147 if (!px || !py)
4148 return false;
4150 uint32 Opcode = (uint32)atoi(px);
4151 int Value = atoi(py);
4153 if(Opcode >= m_session->GetPlayer()->GetValuesCount())
4155 PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, m_session->GetPlayer()->GetGUIDLow(), m_session->GetPlayer( )->GetValuesCount());
4156 return false;
4159 sLog.outDebug(GetMangosString(LANG_CHANGE_32BIT), Opcode, Value);
4161 int CurrentValue = (int)m_session->GetPlayer( )->GetUInt32Value( Opcode );
4163 CurrentValue += Value;
4164 m_session->GetPlayer( )->SetUInt32Value( Opcode , (uint32)CurrentValue );
4166 PSendSysMessage(LANG_CHANGE_32BIT_FIELD, Opcode,CurrentValue);
4168 return true;
4171 bool ChatHandler::HandleAddTeleCommand(const char * args)
4173 if(!*args)
4174 return false;
4176 Player *player=m_session->GetPlayer();
4177 if (!player)
4178 return false;
4180 std::string name = args;
4182 if(objmgr.GetGameTele(name))
4184 SendSysMessage(LANG_COMMAND_TP_ALREADYEXIST);
4185 SetSentErrorMessage(true);
4186 return false;
4189 GameTele tele;
4190 tele.position_x = player->GetPositionX();
4191 tele.position_y = player->GetPositionY();
4192 tele.position_z = player->GetPositionZ();
4193 tele.orientation = player->GetOrientation();
4194 tele.mapId = player->GetMapId();
4195 tele.name = name;
4197 if(objmgr.AddGameTele(tele))
4199 SendSysMessage(LANG_COMMAND_TP_ADDED);
4201 else
4203 SendSysMessage(LANG_COMMAND_TP_ADDEDERR);
4204 SetSentErrorMessage(true);
4205 return false;
4208 return true;
4211 bool ChatHandler::HandleDelTeleCommand(const char * args)
4213 if(!*args)
4214 return false;
4216 std::string name = args;
4218 if(!objmgr.DeleteGameTele(name))
4220 SendSysMessage(LANG_COMMAND_TELE_NOTFOUND);
4221 SetSentErrorMessage(true);
4222 return false;
4225 SendSysMessage(LANG_COMMAND_TP_DELETED);
4226 return true;
4229 bool ChatHandler::HandleListAurasCommand (const char * /*args*/)
4231 Unit *unit = getSelectedUnit();
4232 if(!unit)
4234 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
4235 SetSentErrorMessage(true);
4236 return false;
4239 char const* talentStr = GetMangosString(LANG_TALENT);
4240 char const* passiveStr = GetMangosString(LANG_PASSIVE);
4242 Unit::AuraMap const& uAuras = unit->GetAuras();
4243 PSendSysMessage(LANG_COMMAND_TARGET_LISTAURAS, uAuras.size());
4244 for (Unit::AuraMap::const_iterator itr = uAuras.begin(); itr != uAuras.end(); ++itr)
4246 bool talent = GetTalentSpellCost(itr->second->GetId()) > 0;
4247 PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffIndex(),
4248 itr->second->GetModifier()->m_auraname, itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(),
4249 itr->second->GetSpellProto()->SpellName[m_session->GetSessionDbcLocale()],
4250 (itr->second->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
4251 IS_PLAYER_GUID(itr->second->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(itr->second->GetCasterGUID()));
4253 for (int i = 0; i < TOTAL_AURAS; i++)
4255 Unit::AuraList const& uAuraList = unit->GetAurasByType(AuraType(i));
4256 if (uAuraList.empty()) continue;
4257 PSendSysMessage(LANG_COMMAND_TARGET_LISTAURATYPE, uAuraList.size(), i);
4258 for (Unit::AuraList::const_iterator itr = uAuraList.begin(); itr != uAuraList.end(); ++itr)
4260 bool talent = GetTalentSpellCost((*itr)->GetId()) > 0;
4261 PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(),
4262 (*itr)->GetSpellProto()->SpellName[m_session->GetSessionDbcLocale()],((*itr)->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
4263 IS_PLAYER_GUID((*itr)->GetCasterGUID()) ? "player" : "creature",GUID_LOPART((*itr)->GetCasterGUID()));
4266 return true;
4269 bool ChatHandler::HandleResetHonorCommand (const char * args)
4271 char* pName = strtok((char*)args, "");
4272 Player *player = NULL;
4273 if (pName)
4275 std::string name = pName;
4276 if(!normalizePlayerName(name))
4278 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4279 SetSentErrorMessage(true);
4280 return false;
4283 uint64 guid = objmgr.GetPlayerGUIDByName(name.c_str());
4284 player = objmgr.GetPlayer(guid);
4286 else
4287 player = getSelectedPlayer();
4289 if(!player)
4291 SendSysMessage(LANG_NO_CHAR_SELECTED);
4292 return true;
4295 player->SetUInt32Value(PLAYER_FIELD_KILLS, 0);
4296 player->SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORBALE_KILLS, 0);
4297 player->SetUInt32Value(PLAYER_FIELD_HONOR_CURRENCY, 0);
4298 player->SetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, 0);
4299 player->SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, 0);
4301 return true;
4304 static bool HandleResetStatsOrLevelHelper(Player* player)
4306 PlayerInfo const *info = objmgr.GetPlayerInfo(player->getRace(), player->getClass());
4307 if(!info) return false;
4309 ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(player->getClass());
4310 if(!cEntry)
4312 sLog.outError("Class %u not found in DBC (Wrong DBC files?)",player->getClass());
4313 return false;
4316 uint8 powertype = cEntry->powerType;
4318 uint32 unitfield;
4319 if(powertype == POWER_RAGE)
4320 unitfield = 0x1100EE00;
4321 else if(powertype == POWER_ENERGY)
4322 unitfield = 0x00000000;
4323 else if(powertype == POWER_MANA)
4324 unitfield = 0x0000EE00;
4325 else
4327 sLog.outError("Invalid default powertype %u for player (class %u)",powertype,player->getClass());
4328 return false;
4331 // reset m_form if no aura
4332 if(!player->HasAuraType(SPELL_AURA_MOD_SHAPESHIFT))
4333 player->m_form = FORM_NONE;
4335 player->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE );
4336 player->SetFloatValue(UNIT_FIELD_COMBATREACH, 1.5f );
4338 player->setFactionForRace(player->getRace());
4340 player->SetUInt32Value(UNIT_FIELD_BYTES_0, ( ( player->getRace() ) | ( player->getClass() << 8 ) | ( player->getGender() << 16 ) | ( powertype << 24 ) ) );
4342 // reset only if player not in some form;
4343 if(player->m_form==FORM_NONE)
4345 switch(player->getGender())
4347 case GENDER_FEMALE:
4348 player->SetDisplayId(info->displayId_f);
4349 player->SetNativeDisplayId(info->displayId_f);
4350 break;
4351 case GENDER_MALE:
4352 player->SetDisplayId(info->displayId_m);
4353 player->SetNativeDisplayId(info->displayId_m);
4354 break;
4355 default:
4356 break;
4360 // set UNIT_FIELD_BYTES_1 to init state but preserve m_form value
4361 player->SetUInt32Value(UNIT_FIELD_BYTES_1, unitfield);
4362 player->SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP );
4363 player->SetByteValue(UNIT_FIELD_BYTES_2, 3, player->m_form);
4365 player->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
4367 //-1 is default value
4368 player->SetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, uint32(-1));
4370 //player->SetUInt32Value(PLAYER_FIELD_BYTES, 0xEEE00000 );
4371 return true;
4374 bool ChatHandler::HandleResetLevelCommand(const char * args)
4376 char* pName = strtok((char*)args, "");
4377 Player *player = NULL;
4378 if (pName)
4380 std::string name = pName;
4381 if(!normalizePlayerName(name))
4383 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4384 SetSentErrorMessage(true);
4385 return false;
4388 uint64 guid = objmgr.GetPlayerGUIDByName(name.c_str());
4389 player = objmgr.GetPlayer(guid);
4391 else
4392 player = getSelectedPlayer();
4394 if(!player)
4396 SendSysMessage(LANG_NO_CHAR_SELECTED);
4397 SetSentErrorMessage(true);
4398 return false;
4401 if(!HandleResetStatsOrLevelHelper(player))
4402 return false;
4404 player->SetLevel(1);
4405 player->InitStatsForLevel(true);
4406 player->InitTaxiNodesForLevel();
4407 player->InitGlyphsForLevel();
4408 player->InitTalentForLevel();
4409 player->SetUInt32Value(PLAYER_XP,0);
4411 // reset level to summoned pet
4412 Pet* pet = player->GetPet();
4413 if(pet && pet->getPetType()==SUMMON_PET)
4415 pet->InitStatsForLevel(1);
4416 pet->InitTalentForLevel();
4418 return true;
4421 bool ChatHandler::HandleResetStatsCommand(const char * args)
4423 char* pName = strtok((char*)args, "");
4424 Player *player = NULL;
4425 if (pName)
4427 std::string name = pName;
4428 if(!normalizePlayerName(name))
4430 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4431 SetSentErrorMessage(true);
4432 return false;
4435 uint64 guid = objmgr.GetPlayerGUIDByName(name.c_str());
4436 player = objmgr.GetPlayer(guid);
4438 else
4439 player = getSelectedPlayer();
4441 if(!player)
4443 SendSysMessage(LANG_NO_CHAR_SELECTED);
4444 SetSentErrorMessage(true);
4445 return false;
4448 if(!HandleResetStatsOrLevelHelper(player))
4449 return false;
4451 player->InitStatsForLevel(true);
4452 player->InitTaxiNodesForLevel();
4453 player->InitGlyphsForLevel();
4454 player->InitTalentForLevel();
4456 return true;
4459 bool ChatHandler::HandleResetSpellsCommand(const char * args)
4461 char* pName = strtok((char*)args, "");
4462 Player *player = NULL;
4463 uint64 playerGUID = 0;
4464 if (pName)
4466 std::string name = pName;
4468 if(!normalizePlayerName(name))
4470 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4471 SetSentErrorMessage(true);
4472 return false;
4475 player = objmgr.GetPlayer(name.c_str());
4476 if(!player)
4477 playerGUID = objmgr.GetPlayerGUIDByName(name.c_str());
4479 else
4480 player = getSelectedPlayer();
4482 if(!player && !playerGUID)
4484 SendSysMessage(LANG_NO_CHAR_SELECTED);
4485 SetSentErrorMessage(true);
4486 return false;
4489 if(player)
4491 player->resetSpells();
4493 ChatHandler(player).SendSysMessage(LANG_RESET_SPELLS);
4495 if(m_session->GetPlayer()!=player)
4496 PSendSysMessage(LANG_RESET_SPELLS_ONLINE,player->GetName());
4498 else
4500 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",uint32(AT_LOGIN_RESET_SPELLS), GUID_LOPART(playerGUID));
4501 PSendSysMessage(LANG_RESET_SPELLS_OFFLINE,pName);
4504 return true;
4507 bool ChatHandler::HandleResetTalentsCommand(const char * args)
4509 char* pName = strtok((char*)args, "");
4510 Player *player = NULL;
4511 uint64 playerGUID = 0;
4512 if (pName)
4514 std::string name = pName;
4515 if(!normalizePlayerName(name))
4517 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4518 SetSentErrorMessage(true);
4519 return false;
4522 player = objmgr.GetPlayer(name.c_str());
4523 if(!player)
4524 playerGUID = objmgr.GetPlayerGUIDByName(name.c_str());
4526 else
4527 player = getSelectedPlayer();
4529 if(player)
4531 player->resetTalents(true);
4533 ChatHandler(player).SendSysMessage(LANG_RESET_TALENTS);
4535 if(m_session->GetPlayer()!=player)
4536 PSendSysMessage(LANG_RESET_TALENTS_ONLINE,player->GetName());
4537 return true;
4539 else if (playerGUID)
4541 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",uint32(AT_LOGIN_RESET_TALENTS), GUID_LOPART(playerGUID) );
4542 PSendSysMessage(LANG_RESET_TALENTS_OFFLINE,pName);
4543 return true;
4545 // Try reset talenents as Hunter Pet
4546 Creature* creature = getSelectedCreature();
4547 if (creature && creature->isPet() && ((Pet *)creature)->getPetType() == HUNTER_PET)
4549 ((Pet *)creature)->resetTalents(true);
4550 Unit *owner = creature->GetOwner();
4551 if (owner && owner->GetTypeId() == TYPEID_PLAYER)
4553 player = (Player *)owner;
4554 ChatHandler(player).SendSysMessage(LANG_RESET_TALENTS);
4555 if(m_session->GetPlayer()!=player)
4556 PSendSysMessage(LANG_RESET_TALENTS_ONLINE,player->GetName());
4558 return true;
4561 SendSysMessage(LANG_NO_CHAR_SELECTED);
4562 SetSentErrorMessage(true);
4563 return false;
4566 bool ChatHandler::HandleResetAllCommand(const char * args)
4568 if(!*args)
4569 return false;
4571 std::string casename = args;
4573 AtLoginFlags atLogin;
4575 // Command specially created as single command to prevent using short case names
4576 if(casename=="spells")
4578 atLogin = AT_LOGIN_RESET_SPELLS;
4579 sWorld.SendWorldText(LANG_RESETALL_SPELLS);
4581 else if(casename=="talents")
4583 atLogin = AT_LOGIN_RESET_TALENTS;
4584 sWorld.SendWorldText(LANG_RESETALL_TALENTS);
4586 else
4588 PSendSysMessage(LANG_RESETALL_UNKNOWN_CASE,args);
4589 SetSentErrorMessage(true);
4590 return false;
4593 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE (at_login & '%u') = '0'",atLogin,atLogin);
4594 HashMapHolder<Player>::MapType const& plist = ObjectAccessor::Instance().GetPlayers();
4595 for(HashMapHolder<Player>::MapType::const_iterator itr = plist.begin(); itr != plist.end(); ++itr)
4596 itr->second->SetAtLoginFlag(atLogin);
4598 return true;
4601 bool ChatHandler::HandleServerShutDownCancelCommand(const char* args)
4603 sWorld.ShutdownCancel();
4604 return true;
4607 bool ChatHandler::HandleServerShutDownCommand(const char* args)
4609 if(!*args)
4610 return false;
4612 char* time_str = strtok ((char*) args, " ");
4613 char* exitcode_str = strtok (NULL, "");
4615 int32 time = atoi (time_str);
4617 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4618 if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0)
4619 return false;
4621 if (exitcode_str)
4623 int32 exitcode = atoi (exitcode_str);
4625 // Handle atoi() errors
4626 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4627 return false;
4629 // Exit code should be in range of 0-125, 126-255 is used
4630 // in many shells for their own return codes and code > 255
4631 // is not supported in many others
4632 if (exitcode < 0 || exitcode > 125)
4633 return false;
4635 sWorld.ShutdownServ (time, 0, exitcode);
4637 else
4638 sWorld.ShutdownServ(time,0,SHUTDOWN_EXIT_CODE);
4639 return true;
4642 bool ChatHandler::HandleServerRestartCommand(const char* args)
4644 if(!*args)
4645 return false;
4647 char* time_str = strtok ((char*) args, " ");
4648 char* exitcode_str = strtok (NULL, "");
4650 int32 time = atoi (time_str);
4652 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4653 if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0)
4654 return false;
4656 if (exitcode_str)
4658 int32 exitcode = atoi (exitcode_str);
4660 // Handle atoi() errors
4661 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4662 return false;
4664 // Exit code should be in range of 0-125, 126-255 is used
4665 // in many shells for their own return codes and code > 255
4666 // is not supported in many others
4667 if (exitcode < 0 || exitcode > 125)
4668 return false;
4670 sWorld.ShutdownServ (time, SHUTDOWN_MASK_RESTART, exitcode);
4672 else
4673 sWorld.ShutdownServ(time, SHUTDOWN_MASK_RESTART, RESTART_EXIT_CODE);
4674 return true;
4677 bool ChatHandler::HandleServerIdleRestartCommand(const char* args)
4679 if(!*args)
4680 return false;
4682 char* time_str = strtok ((char*) args, " ");
4683 char* exitcode_str = strtok (NULL, "");
4685 int32 time = atoi (time_str);
4687 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4688 if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0)
4689 return false;
4691 if (exitcode_str)
4693 int32 exitcode = atoi (exitcode_str);
4695 // Handle atoi() errors
4696 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4697 return false;
4699 // Exit code should be in range of 0-125, 126-255 is used
4700 // in many shells for their own return codes and code > 255
4701 // is not supported in many others
4702 if (exitcode < 0 || exitcode > 125)
4703 return false;
4705 sWorld.ShutdownServ (time, SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE, exitcode);
4707 else
4708 sWorld.ShutdownServ(time,SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE,RESTART_EXIT_CODE);
4709 return true;
4712 bool ChatHandler::HandleServerIdleShutDownCommand(const char* args)
4714 if(!*args)
4715 return false;
4717 char* time_str = strtok ((char*) args, " ");
4718 char* exitcode_str = strtok (NULL, "");
4720 int32 time = atoi (time_str);
4722 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4723 if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0)
4724 return false;
4726 if (exitcode_str)
4728 int32 exitcode = atoi (exitcode_str);
4730 // Handle atoi() errors
4731 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4732 return false;
4734 // Exit code should be in range of 0-125, 126-255 is used
4735 // in many shells for their own return codes and code > 255
4736 // is not supported in many others
4737 if (exitcode < 0 || exitcode > 125)
4738 return false;
4740 sWorld.ShutdownServ (time, SHUTDOWN_MASK_IDLE, exitcode);
4742 else
4743 sWorld.ShutdownServ(time,SHUTDOWN_MASK_IDLE,SHUTDOWN_EXIT_CODE);
4744 return true;
4747 bool ChatHandler::HandleAddQuest(const char* args)
4749 Player* player = getSelectedPlayer();
4750 if(!player)
4752 SendSysMessage(LANG_NO_CHAR_SELECTED);
4753 SetSentErrorMessage(true);
4754 return false;
4757 // .addquest #entry'
4758 // number or [name] Shift-click form |color|Hquest:quest_id|h[name]|h|r
4759 char* cId = extractKeyFromLink((char*)args,"Hquest");
4760 if(!cId)
4761 return false;
4763 uint32 entry = atol(cId);
4765 Quest const* pQuest = objmgr.GetQuestTemplate(entry);
4767 if(!pQuest)
4769 PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND,entry);
4770 SetSentErrorMessage(true);
4771 return false;
4774 // check item starting quest (it can work incorrectly if added without item in inventory)
4775 for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
4777 ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype>(id);
4778 if (!pProto)
4779 continue;
4781 if (pProto->StartQuest == entry)
4783 PSendSysMessage(LANG_COMMAND_QUEST_STARTFROMITEM, entry, pProto->ItemId);
4784 SetSentErrorMessage(true);
4785 return false;
4789 // ok, normal (creature/GO starting) quest
4790 if( player->CanAddQuest( pQuest, true ) )
4792 player->AddQuest( pQuest, NULL );
4794 if ( player->CanCompleteQuest( entry ) )
4795 player->CompleteQuest( entry );
4798 return true;
4801 bool ChatHandler::HandleRemoveQuest(const char* args)
4803 Player* player = getSelectedPlayer();
4804 if(!player)
4806 SendSysMessage(LANG_NO_CHAR_SELECTED);
4807 SetSentErrorMessage(true);
4808 return false;
4811 // .removequest #entry'
4812 // number or [name] Shift-click form |color|Hquest:quest_id|h[name]|h|r
4813 char* cId = extractKeyFromLink((char*)args,"Hquest");
4814 if(!cId)
4815 return false;
4817 uint32 entry = atol(cId);
4819 Quest const* pQuest = objmgr.GetQuestTemplate(entry);
4821 if(!pQuest)
4823 PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry);
4824 SetSentErrorMessage(true);
4825 return false;
4828 // remove all quest entries for 'entry' from quest log
4829 for(uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot )
4831 uint32 quest = player->GetQuestSlotQuestId(slot);
4832 if(quest==entry)
4834 player->SetQuestSlot(slot,0);
4836 // we ignore unequippable quest items in this case, its' still be equipped
4837 player->TakeQuestSourceItem( quest, false );
4841 // set quest status to not started (will updated in DB at next save)
4842 player->SetQuestStatus( entry, QUEST_STATUS_NONE);
4844 // reset rewarded for restart repeatable quest
4845 player->getQuestStatusMap()[entry].m_rewarded = false;
4847 SendSysMessage(LANG_COMMAND_QUEST_REMOVED);
4848 return true;
4851 bool ChatHandler::HandleCompleteQuest(const char* args)
4853 Player* player = getSelectedPlayer();
4854 if(!player)
4856 SendSysMessage(LANG_NO_CHAR_SELECTED);
4857 SetSentErrorMessage(true);
4858 return false;
4861 // .quest complete #entry
4862 // number or [name] Shift-click form |color|Hquest:quest_id|h[name]|h|r
4863 char* cId = extractKeyFromLink((char*)args,"Hquest");
4864 if(!cId)
4865 return false;
4867 uint32 entry = atol(cId);
4869 Quest const* pQuest = objmgr.GetQuestTemplate(entry);
4871 // If player doesn't have the quest
4872 if(!pQuest || player->GetQuestStatus(entry) == QUEST_STATUS_NONE)
4874 PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry);
4875 SetSentErrorMessage(true);
4876 return false;
4879 // Add quest items for quests that require items
4880 for(uint8 x = 0; x < QUEST_OBJECTIVES_COUNT; ++x)
4882 uint32 id = pQuest->ReqItemId[x];
4883 uint32 count = pQuest->ReqItemCount[x];
4884 if(!id || !count)
4885 continue;
4887 uint32 curItemCount = player->GetItemCount(id,true);
4889 ItemPosCountVec dest;
4890 uint8 msg = player->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, id, count-curItemCount );
4891 if( msg == EQUIP_ERR_OK )
4893 Item* item = player->StoreNewItem( dest, id, true);
4894 player->SendNewItem(item,count-curItemCount,true,false);
4898 // All creature/GO slain/casted (not required, but otherwise it will display "Creature slain 0/10")
4899 for(uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; i++)
4901 uint32 creature = pQuest->ReqCreatureOrGOId[i];
4902 uint32 creaturecount = pQuest->ReqCreatureOrGOCount[i];
4904 if(uint32 spell_id = pQuest->ReqSpell[i])
4906 for(uint16 z = 0; z < creaturecount; ++z)
4907 player->CastedCreatureOrGO(creature,0,spell_id);
4909 else if(creature > 0)
4911 for(uint16 z = 0; z < creaturecount; ++z)
4912 player->KilledMonster(creature,0);
4914 else if(creature < 0)
4916 for(uint16 z = 0; z < creaturecount; ++z)
4917 player->CastedCreatureOrGO(creature,0,0);
4921 // If the quest requires reputation to complete
4922 if(uint32 repFaction = pQuest->GetRepObjectiveFaction())
4924 uint32 repValue = pQuest->GetRepObjectiveValue();
4925 uint32 curRep = player->GetReputation(repFaction);
4926 if(curRep < repValue)
4928 FactionEntry const *factionEntry = sFactionStore.LookupEntry(repFaction);
4929 player->SetFactionReputation(factionEntry,repValue);
4933 // If the quest requires money
4934 int32 ReqOrRewMoney = pQuest->GetRewOrReqMoney();
4935 if(ReqOrRewMoney < 0)
4936 player->ModifyMoney(-ReqOrRewMoney);
4938 player->CompleteQuest(entry);
4939 return true;
4942 bool ChatHandler::HandleBanAccountCommand(const char* args)
4944 return HandleBanHelper(BAN_ACCOUNT,args);
4947 bool ChatHandler::HandleBanCharacterCommand(const char* args)
4949 return HandleBanHelper(BAN_CHARACTER,args);
4952 bool ChatHandler::HandleBanIPCommand(const char* args)
4954 return HandleBanHelper(BAN_IP,args);
4957 bool ChatHandler::HandleBanHelper(BanMode mode, const char* args)
4959 if(!args)
4960 return false;
4962 char* cnameOrIP = strtok ((char*)args, " ");
4963 if (!cnameOrIP)
4964 return false;
4966 std::string nameOrIP = cnameOrIP;
4968 char* duration = strtok (NULL," ");
4969 if(!duration || !atoi(duration))
4970 return false;
4972 char* reason = strtok (NULL,"");
4973 if(!reason)
4974 return false;
4976 switch(mode)
4978 case BAN_ACCOUNT:
4979 if(!AccountMgr::normilizeString(nameOrIP))
4981 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,nameOrIP.c_str());
4982 SetSentErrorMessage(true);
4983 return false;
4985 break;
4986 case BAN_CHARACTER:
4987 if(!normalizePlayerName(nameOrIP))
4989 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4990 SetSentErrorMessage(true);
4991 return false;
4993 break;
4994 case BAN_IP:
4995 if(!IsIPAddress(nameOrIP.c_str()))
4996 return false;
4997 break;
5000 switch(sWorld.BanAccount(mode, nameOrIP, duration, reason,m_session ? m_session->GetPlayerName() : ""))
5002 case BAN_SUCCESS:
5003 if(atoi(duration)>0)
5004 PSendSysMessage(LANG_BAN_YOUBANNED,nameOrIP.c_str(),secsToTimeString(TimeStringToSecs(duration),true).c_str(),reason);
5005 else
5006 PSendSysMessage(LANG_BAN_YOUPERMBANNED,nameOrIP.c_str(),reason);
5007 break;
5008 case BAN_SYNTAX_ERROR:
5009 return false;
5010 case BAN_NOTFOUND:
5011 switch(mode)
5013 default:
5014 PSendSysMessage(LANG_BAN_NOTFOUND,"account",nameOrIP.c_str());
5015 break;
5016 case BAN_CHARACTER:
5017 PSendSysMessage(LANG_BAN_NOTFOUND,"character",nameOrIP.c_str());
5018 break;
5019 case BAN_IP:
5020 PSendSysMessage(LANG_BAN_NOTFOUND,"ip",nameOrIP.c_str());
5021 break;
5023 SetSentErrorMessage(true);
5024 return false;
5027 return true;
5030 bool ChatHandler::HandleUnBanAccountCommand(const char* args)
5032 return HandleUnBanHelper(BAN_ACCOUNT,args);
5035 bool ChatHandler::HandleUnBanCharacterCommand(const char* args)
5037 return HandleUnBanHelper(BAN_CHARACTER,args);
5040 bool ChatHandler::HandleUnBanIPCommand(const char* args)
5042 return HandleUnBanHelper(BAN_IP,args);
5045 bool ChatHandler::HandleUnBanHelper(BanMode mode, const char* args)
5047 if(!args)
5048 return false;
5050 char* cnameOrIP = strtok ((char*)args, " ");
5051 if(!cnameOrIP)
5052 return false;
5054 std::string nameOrIP = cnameOrIP;
5056 switch(mode)
5058 case BAN_ACCOUNT:
5059 if(!AccountMgr::normilizeString(nameOrIP))
5061 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,nameOrIP.c_str());
5062 SetSentErrorMessage(true);
5063 return false;
5065 break;
5066 case BAN_CHARACTER:
5067 if(!normalizePlayerName(nameOrIP))
5069 SendSysMessage(LANG_PLAYER_NOT_FOUND);
5070 SetSentErrorMessage(true);
5071 return false;
5073 break;
5074 case BAN_IP:
5075 if(!IsIPAddress(nameOrIP.c_str()))
5076 return false;
5077 break;
5080 if(sWorld.RemoveBanAccount(mode,nameOrIP))
5081 PSendSysMessage(LANG_UNBAN_UNBANNED,nameOrIP.c_str());
5082 else
5083 PSendSysMessage(LANG_UNBAN_ERROR,nameOrIP.c_str());
5085 return true;
5088 bool ChatHandler::HandleBanInfoAccountCommand(const char* args)
5090 if(!args)
5091 return false;
5093 char* cname = strtok((char*)args, "");
5094 if(!cname)
5095 return false;
5097 std::string account_name = cname;
5098 if(!AccountMgr::normilizeString(account_name))
5100 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5101 SetSentErrorMessage(true);
5102 return false;
5105 uint32 accountid = accmgr.GetId(account_name);
5106 if(!accountid)
5108 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5109 return true;
5112 return HandleBanInfoHelper(accountid,account_name.c_str());
5115 bool ChatHandler::HandleBanInfoCharacterCommand(const char* args)
5117 if(!args)
5118 return false;
5120 char* cname = strtok ((char*)args, "");
5121 if(!cname)
5122 return false;
5124 std::string name = cname;
5125 if(!normalizePlayerName(name))
5127 SendSysMessage(LANG_PLAYER_NOT_FOUND);
5128 SetSentErrorMessage(true);
5129 return false;
5132 uint32 accountid = objmgr.GetPlayerAccountIdByPlayerName(name);
5133 if(!accountid)
5135 SendSysMessage(LANG_PLAYER_NOT_FOUND);
5136 SetSentErrorMessage(true);
5137 return false;
5140 std::string accountname;
5141 if(!accmgr.GetName(accountid,accountname))
5143 PSendSysMessage(LANG_BANINFO_NOCHARACTER);
5144 return true;
5147 return HandleBanInfoHelper(accountid,accountname.c_str());
5150 bool ChatHandler::HandleBanInfoHelper(uint32 accountid, char const* accountname)
5152 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);
5153 if(!result)
5155 PSendSysMessage(LANG_BANINFO_NOACCOUNTBAN, accountname);
5156 return true;
5159 PSendSysMessage(LANG_BANINFO_BANHISTORY,accountname);
5162 Field* fields = result->Fetch();
5164 time_t unbandate = time_t(fields[3].GetUInt64());
5165 bool active = false;
5166 if(fields[2].GetBool() && (fields[1].GetUInt64() == (uint64)0 ||unbandate >= time(NULL)) )
5167 active = true;
5168 bool permanent = (fields[1].GetUInt64() == (uint64)0);
5169 std::string bantime = permanent?GetMangosString(LANG_BANINFO_INFINITE):secsToTimeString(fields[1].GetUInt64(), true);
5170 PSendSysMessage(LANG_BANINFO_HISTORYENTRY,
5171 fields[0].GetString(), bantime.c_str(), active ? GetMangosString(LANG_BANINFO_YES):GetMangosString(LANG_BANINFO_NO), fields[4].GetString(), fields[5].GetString());
5172 }while (result->NextRow());
5174 delete result;
5175 return true;
5178 bool ChatHandler::HandleBanInfoIPCommand(const char* args)
5180 if(!args)
5181 return false;
5183 char* cIP = strtok ((char*)args, "");
5184 if(!cIP)
5185 return false;
5187 if (!IsIPAddress(cIP))
5188 return false;
5190 std::string IP = cIP;
5192 loginDatabase.escape_string(IP);
5193 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());
5194 if(!result)
5196 PSendSysMessage(LANG_BANINFO_NOIP);
5197 return true;
5200 Field *fields = result->Fetch();
5201 bool permanent = !fields[6].GetUInt64();
5202 PSendSysMessage(LANG_BANINFO_IPENTRY,
5203 fields[0].GetString(), fields[1].GetString(), permanent ? GetMangosString(LANG_BANINFO_NEVER):fields[2].GetString(),
5204 permanent ? GetMangosString(LANG_BANINFO_INFINITE):secsToTimeString(fields[3].GetUInt64(), true).c_str(), fields[4].GetString(), fields[5].GetString());
5205 delete result;
5206 return true;
5209 bool ChatHandler::HandleBanListCharacterCommand(const char* args)
5211 loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
5213 char* cFilter = strtok ((char*)args, " ");
5214 if(!cFilter)
5215 return false;
5217 std::string filter = cFilter;
5218 loginDatabase.escape_string(filter);
5219 QueryResult* result = CharacterDatabase.PQuery("SELECT account FROM characters WHERE name "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'"),filter.c_str());
5220 if (!result)
5222 PSendSysMessage(LANG_BANLIST_NOCHARACTER);
5223 return true;
5226 return HandleBanListHelper(result);
5229 bool ChatHandler::HandleBanListAccountCommand(const char* args)
5231 loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
5233 char* cFilter = strtok((char*)args, " ");
5234 std::string filter = cFilter ? cFilter : "";
5235 loginDatabase.escape_string(filter);
5237 QueryResult* result;
5239 if(filter.empty())
5241 result = loginDatabase.Query("SELECT account.id, username FROM account, account_banned"
5242 " WHERE account.id = account_banned.id AND active = 1 GROUP BY account.id");
5244 else
5246 result = loginDatabase.PQuery("SELECT account.id, username FROM account, account_banned"
5247 " WHERE account.id = account_banned.id AND active = 1 AND username "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")" GROUP BY account.id",
5248 filter.c_str());
5251 if (!result)
5253 PSendSysMessage(LANG_BANLIST_NOACCOUNT);
5254 return true;
5257 return HandleBanListHelper(result);
5260 bool ChatHandler::HandleBanListHelper(QueryResult* result)
5262 PSendSysMessage(LANG_BANLIST_MATCHINGACCOUNT);
5264 // Chat short output
5265 if(m_session)
5269 Field* fields = result->Fetch();
5270 uint32 accountid = fields[0].GetUInt32();
5272 QueryResult* banresult = loginDatabase.PQuery("SELECT account.username FROM account,account_banned WHERE account_banned.id='%u' AND account_banned.id=account.id",accountid);
5273 if(banresult)
5275 Field* fields2 = banresult->Fetch();
5276 PSendSysMessage("%s",fields2[0].GetString());
5277 delete banresult;
5279 } while (result->NextRow());
5281 // Console wide output
5282 else
5284 SendSysMessage(LANG_BANLIST_ACCOUNTS);
5285 SendSysMessage("===============================================================================");
5286 SendSysMessage(LANG_BANLIST_ACCOUNTS_HEADER);
5289 SendSysMessage("-------------------------------------------------------------------------------");
5290 Field *fields = result->Fetch();
5291 uint32 account_id = fields[0].GetUInt32 ();
5293 std::string account_name;
5295 // "account" case, name can be get in same query
5296 if(result->GetFieldCount() > 1)
5297 account_name = fields[1].GetCppString();
5298 // "character" case, name need extract from another DB
5299 else
5300 accmgr.GetName (account_id,account_name);
5302 // No SQL injection. id is uint32.
5303 QueryResult *banInfo = loginDatabase.PQuery("SELECT bandate,unbandate,bannedby,banreason FROM account_banned WHERE id = %u ORDER BY unbandate", account_id);
5304 if (banInfo)
5306 Field *fields2 = banInfo->Fetch();
5309 time_t t_ban = fields2[0].GetUInt64();
5310 tm* aTm_ban = localtime(&t_ban);
5312 if (fields2[0].GetUInt64() == fields2[1].GetUInt64())
5314 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|",
5315 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,
5316 fields2[2].GetString(),fields2[3].GetString());
5318 else
5320 time_t t_unban = fields2[1].GetUInt64();
5321 tm* aTm_unban = localtime(&t_unban);
5322 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|",
5323 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,
5324 aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min,
5325 fields2[2].GetString(),fields2[3].GetString());
5327 }while ( banInfo->NextRow() );
5328 delete banInfo;
5330 }while( result->NextRow() );
5331 SendSysMessage("===============================================================================");
5334 delete result;
5335 return true;
5338 bool ChatHandler::HandleBanListIPCommand(const char* args)
5340 loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
5342 char* cFilter = strtok((char*)args, " ");
5343 std::string filter = cFilter ? cFilter : "";
5344 loginDatabase.escape_string(filter);
5346 QueryResult* result;
5348 if(filter.empty())
5350 result = loginDatabase.Query ("SELECT ip,bandate,unbandate,bannedby,banreason FROM ip_banned"
5351 " WHERE (bandate=unbandate OR unbandate>UNIX_TIMESTAMP())"
5352 " ORDER BY unbandate" );
5354 else
5356 result = loginDatabase.PQuery( "SELECT ip,bandate,unbandate,bannedby,banreason FROM ip_banned"
5357 " WHERE (bandate=unbandate OR unbandate>UNIX_TIMESTAMP()) AND ip "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")
5358 " ORDER BY unbandate",filter.c_str() );
5361 if(!result)
5363 PSendSysMessage(LANG_BANLIST_NOIP);
5364 return true;
5367 PSendSysMessage(LANG_BANLIST_MATCHINGIP);
5368 // Chat short output
5369 if(m_session)
5373 Field* fields = result->Fetch();
5374 PSendSysMessage("%s",fields[0].GetString());
5375 } while (result->NextRow());
5377 // Console wide output
5378 else
5380 SendSysMessage(LANG_BANLIST_IPS);
5381 SendSysMessage("===============================================================================");
5382 SendSysMessage(LANG_BANLIST_IPS_HEADER);
5385 SendSysMessage("-------------------------------------------------------------------------------");
5386 Field *fields = result->Fetch();
5387 time_t t_ban = fields[1].GetUInt64();
5388 tm* aTm_ban = localtime(&t_ban);
5389 if ( fields[1].GetUInt64() == fields[2].GetUInt64() )
5391 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|",
5392 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,
5393 fields[3].GetString(), fields[4].GetString());
5395 else
5397 time_t t_unban = fields[2].GetUInt64();
5398 tm* aTm_unban = localtime(&t_unban);
5399 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|",
5400 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,
5401 aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min,
5402 fields[3].GetString(), fields[4].GetString());
5404 }while( result->NextRow() );
5405 SendSysMessage("===============================================================================");
5408 delete result;
5409 return true;
5412 bool ChatHandler::HandleRespawnCommand(const char* /*args*/)
5414 Player* pl = m_session->GetPlayer();
5416 // accept only explicitly selected target (not implicitly self targeting case)
5417 Unit* target = getSelectedUnit();
5418 if(pl->GetSelection() && target)
5420 if(target->GetTypeId()!=TYPEID_UNIT)
5422 SendSysMessage(LANG_SELECT_CREATURE);
5423 SetSentErrorMessage(true);
5424 return false;
5427 if(target->isDead())
5428 ((Creature*)target)->Respawn();
5429 return true;
5432 CellPair p(MaNGOS::ComputeCellPair(pl->GetPositionX(), pl->GetPositionY()));
5433 Cell cell(p);
5434 cell.data.Part.reserved = ALL_DISTRICT;
5435 cell.SetNoCreate();
5437 MaNGOS::RespawnDo u_do;
5438 MaNGOS::WorldObjectWorker<MaNGOS::RespawnDo> worker(u_do);
5440 TypeContainerVisitor<MaNGOS::WorldObjectWorker<MaNGOS::RespawnDo>, GridTypeMapContainer > obj_worker(worker);
5441 CellLock<GridReadGuard> cell_lock(cell, p);
5442 cell_lock->Visit(cell_lock, obj_worker, *pl->GetMap());
5444 return true;
5447 bool ChatHandler::HandleFlyModeCommand(const char* args)
5449 if(!args)
5450 return false;
5452 Unit *unit = getSelectedUnit();
5453 if (!unit || (unit->GetTypeId() != TYPEID_PLAYER))
5454 unit = m_session->GetPlayer();
5456 WorldPacket data(12);
5457 if (strncmp(args, "on", 3) == 0)
5458 data.SetOpcode(SMSG_MOVE_SET_CAN_FLY);
5459 else if (strncmp(args, "off", 4) == 0)
5460 data.SetOpcode(SMSG_MOVE_UNSET_CAN_FLY);
5461 else
5463 SendSysMessage(LANG_USE_BOL);
5464 return false;
5466 data.append(unit->GetPackGUID());
5467 data << uint32(0); // unknown
5468 unit->SendMessageToSet(&data, true);
5469 PSendSysMessage(LANG_COMMAND_FLYMODE_STATUS, unit->GetName(), args);
5470 return true;
5473 bool ChatHandler::HandleLoadPDumpCommand(const char *args)
5475 if(!args)
5476 return false;
5478 char * file = strtok((char*)args, " ");
5479 if(!file)
5480 return false;
5482 char * account = strtok(NULL, " ");
5483 if(!account)
5484 return false;
5486 std::string account_name = account;
5487 if(!AccountMgr::normilizeString(account_name))
5489 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5490 SetSentErrorMessage(true);
5491 return false;
5494 uint32 account_id = accmgr.GetId(account_name);
5495 if(!account_id)
5497 account_id = atoi(account); // use original string
5498 if(!account_id)
5500 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5501 SetSentErrorMessage(true);
5502 return false;
5506 if(!accmgr.GetName(account_id,account_name))
5508 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5509 SetSentErrorMessage(true);
5510 return false;
5513 char* guid_str = NULL;
5514 char* name_str = strtok(NULL, " ");
5516 std::string name;
5517 if(name_str)
5519 name = name_str;
5520 // normalize the name if specified and check if it exists
5521 if(!normalizePlayerName(name))
5523 PSendSysMessage(LANG_INVALID_CHARACTER_NAME);
5524 SetSentErrorMessage(true);
5525 return false;
5528 if(!ObjectMgr::IsValidName(name,true))
5530 PSendSysMessage(LANG_INVALID_CHARACTER_NAME);
5531 SetSentErrorMessage(true);
5532 return false;
5535 guid_str = strtok(NULL, " ");
5538 uint32 guid = 0;
5540 if(guid_str)
5542 guid = atoi(guid_str);
5543 if(!guid)
5545 PSendSysMessage(LANG_INVALID_CHARACTER_GUID);
5546 SetSentErrorMessage(true);
5547 return false;
5550 if(objmgr.GetPlayerAccountIdByGUID(guid))
5552 PSendSysMessage(LANG_CHARACTER_GUID_IN_USE,guid);
5553 SetSentErrorMessage(true);
5554 return false;
5558 switch(PlayerDumpReader().LoadDump(file, account_id, name, guid))
5560 case DUMP_SUCCESS:
5561 PSendSysMessage(LANG_COMMAND_IMPORT_SUCCESS);
5562 break;
5563 case DUMP_FILE_OPEN_ERROR:
5564 PSendSysMessage(LANG_FILE_OPEN_FAIL,file);
5565 SetSentErrorMessage(true);
5566 return false;
5567 case DUMP_FILE_BROKEN:
5568 PSendSysMessage(LANG_DUMP_BROKEN,file);
5569 SetSentErrorMessage(true);
5570 return false;
5571 case DUMP_TOO_MANY_CHARS:
5572 PSendSysMessage(LANG_ACCOUNT_CHARACTER_LIST_FULL,account_name.c_str(),account_id);
5573 SetSentErrorMessage(true);
5574 return false;
5575 default:
5576 PSendSysMessage(LANG_COMMAND_IMPORT_FAILED);
5577 SetSentErrorMessage(true);
5578 return false;
5581 return true;
5584 bool ChatHandler::HandleNpcChangeEntryCommand(const char *args)
5586 if(!args)
5587 return false;
5589 uint32 newEntryNum = atoi(args);
5590 if(!newEntryNum)
5591 return false;
5593 Unit* unit = getSelectedUnit();
5594 if(!unit || unit->GetTypeId() != TYPEID_UNIT)
5596 SendSysMessage(LANG_SELECT_CREATURE);
5597 SetSentErrorMessage(true);
5598 return false;
5600 Creature* creature = (Creature*)unit;
5601 if(creature->UpdateEntry(newEntryNum))
5602 SendSysMessage(LANG_DONE);
5603 else
5604 SendSysMessage(LANG_ERROR);
5605 return true;
5608 bool ChatHandler::HandleWritePDumpCommand(const char *args)
5610 if(!args)
5611 return false;
5613 char* file = strtok((char*)args, " ");
5614 char* p2 = strtok(NULL, " ");
5616 if(!file || !p2)
5617 return false;
5619 uint32 guid;
5620 // character name can't start from number
5621 if (isNumeric(p2[0]))
5622 guid = atoi(p2);
5623 else
5625 std::string name = p2;
5627 if (!normalizePlayerName (name))
5629 SendSysMessage (LANG_PLAYER_NOT_FOUND);
5630 SetSentErrorMessage (true);
5631 return false;
5634 guid = objmgr.GetPlayerGUIDByName(name);
5637 if(!objmgr.GetPlayerAccountIdByGUID(guid))
5639 PSendSysMessage(LANG_PLAYER_NOT_FOUND);
5640 SetSentErrorMessage(true);
5641 return false;
5644 switch(PlayerDumpWriter().WriteDump(file, guid))
5646 case DUMP_SUCCESS:
5647 PSendSysMessage(LANG_COMMAND_EXPORT_SUCCESS);
5648 break;
5649 case DUMP_FILE_OPEN_ERROR:
5650 PSendSysMessage(LANG_FILE_OPEN_FAIL,file);
5651 SetSentErrorMessage(true);
5652 return false;
5653 default:
5654 PSendSysMessage(LANG_COMMAND_EXPORT_FAILED);
5655 SetSentErrorMessage(true);
5656 return false;
5659 return true;
5662 bool ChatHandler::HandleMovegensCommand(const char* /*args*/)
5664 Unit* unit = getSelectedUnit();
5665 if(!unit)
5667 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5668 SetSentErrorMessage(true);
5669 return false;
5672 PSendSysMessage(LANG_MOVEGENS_LIST,(unit->GetTypeId()==TYPEID_PLAYER ? "Player" : "Creature" ),unit->GetGUIDLow());
5674 MotionMaster* mm = unit->GetMotionMaster();
5675 for(MotionMaster::const_iterator itr = mm->begin(); itr != mm->end(); ++itr)
5677 switch((*itr)->GetMovementGeneratorType())
5679 case IDLE_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_IDLE); break;
5680 case RANDOM_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_RANDOM); break;
5681 case WAYPOINT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_WAYPOINT); break;
5682 case ANIMAL_RANDOM_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_ANIMAL_RANDOM); break;
5683 case CONFUSED_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_CONFUSED); break;
5684 case TARGETED_MOTION_TYPE:
5686 if(unit->GetTypeId()==TYPEID_PLAYER)
5688 TargetedMovementGenerator<Player> const* mgen = static_cast<TargetedMovementGenerator<Player> const*>(*itr);
5689 Unit* target = mgen->GetTarget();
5690 if(target)
5691 PSendSysMessage(LANG_MOVEGENS_TARGETED_PLAYER,target->GetName(),target->GetGUIDLow());
5692 else
5693 SendSysMessage(LANG_MOVEGENS_TARGETED_NULL);
5695 else
5697 TargetedMovementGenerator<Creature> const* mgen = static_cast<TargetedMovementGenerator<Creature> const*>(*itr);
5698 Unit* target = mgen->GetTarget();
5699 if(target)
5700 PSendSysMessage(LANG_MOVEGENS_TARGETED_CREATURE,target->GetName(),target->GetGUIDLow());
5701 else
5702 SendSysMessage(LANG_MOVEGENS_TARGETED_NULL);
5704 break;
5706 case HOME_MOTION_TYPE:
5707 if(unit->GetTypeId()==TYPEID_UNIT)
5709 float x,y,z;
5710 (*itr)->GetDestination(x,y,z);
5711 PSendSysMessage(LANG_MOVEGENS_HOME_CREATURE,x,y,z);
5713 else
5714 SendSysMessage(LANG_MOVEGENS_HOME_PLAYER);
5715 break;
5716 case FLIGHT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_FLIGHT); break;
5717 case POINT_MOTION_TYPE:
5719 float x,y,z;
5720 (*itr)->GetDestination(x,y,z);
5721 PSendSysMessage(LANG_MOVEGENS_POINT,x,y,z);
5722 break;
5724 case FLEEING_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_FEAR); break;
5725 case DISTRACT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_DISTRACT); break;
5726 default:
5727 PSendSysMessage(LANG_MOVEGENS_UNKNOWN,(*itr)->GetMovementGeneratorType());
5728 break;
5731 return true;
5734 bool ChatHandler::HandlePLimitCommand(const char *args)
5736 if(*args)
5738 char* param = strtok((char*)args, " ");
5739 if(!param)
5740 return false;
5742 int l = strlen(param);
5744 if( strncmp(param,"player",l) == 0 )
5745 sWorld.SetPlayerLimit(-SEC_PLAYER);
5746 else if(strncmp(param,"moderator",l) == 0 )
5747 sWorld.SetPlayerLimit(-SEC_MODERATOR);
5748 else if(strncmp(param,"gamemaster",l) == 0 )
5749 sWorld.SetPlayerLimit(-SEC_GAMEMASTER);
5750 else if(strncmp(param,"administrator",l) == 0 )
5751 sWorld.SetPlayerLimit(-SEC_ADMINISTRATOR);
5752 else if(strncmp(param,"reset",l) == 0 )
5753 sWorld.SetPlayerLimit( sConfig.GetIntDefault("PlayerLimit", DEFAULT_PLAYER_LIMIT) );
5754 else
5756 int val = atoi(param);
5757 if(val < -SEC_ADMINISTRATOR) val = -SEC_ADMINISTRATOR;
5759 sWorld.SetPlayerLimit(val);
5762 // kick all low security level players
5763 if(sWorld.GetPlayerAmountLimit() > SEC_PLAYER)
5764 sWorld.KickAllLess(sWorld.GetPlayerSecurityLimit());
5767 uint32 pLimit = sWorld.GetPlayerAmountLimit();
5768 AccountTypes allowedAccountType = sWorld.GetPlayerSecurityLimit();
5769 char const* secName = "";
5770 switch(allowedAccountType)
5772 case SEC_PLAYER: secName = "Player"; break;
5773 case SEC_MODERATOR: secName = "Moderator"; break;
5774 case SEC_GAMEMASTER: secName = "Gamemaster"; break;
5775 case SEC_ADMINISTRATOR: secName = "Administrator"; break;
5776 default: secName = "<unknown>"; break;
5779 PSendSysMessage("Player limits: amount %u, min. security level %s.",pLimit,secName);
5781 return true;
5784 bool ChatHandler::HandleCastCommand(const char* args)
5786 if(!*args)
5787 return false;
5789 Unit* target = getSelectedUnit();
5791 if(!target)
5793 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5794 SetSentErrorMessage(true);
5795 return false;
5798 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5799 uint32 spell = extractSpellIdFromLink((char*)args);
5800 if(!spell)
5801 return false;
5803 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
5804 if(!spellInfo)
5805 return false;
5807 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
5809 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
5810 SetSentErrorMessage(true);
5811 return false;
5814 char* trig_str = strtok(NULL, " ");
5815 if(trig_str)
5817 int l = strlen(trig_str);
5818 if(strncmp(trig_str,"triggered",l) != 0 )
5819 return false;
5822 bool triggered = (trig_str != NULL);
5824 m_session->GetPlayer()->CastSpell(target,spell,triggered);
5826 return true;
5829 bool ChatHandler::HandleCastBackCommand(const char* args)
5831 Creature* caster = getSelectedCreature();
5833 if(!caster)
5835 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5836 SetSentErrorMessage(true);
5837 return false;
5840 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
5841 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5842 uint32 spell = extractSpellIdFromLink((char*)args);
5843 if(!spell || !sSpellStore.LookupEntry(spell))
5844 return false;
5846 char* trig_str = strtok(NULL, " ");
5847 if(trig_str)
5849 int l = strlen(trig_str);
5850 if(strncmp(trig_str,"triggered",l) != 0 )
5851 return false;
5854 bool triggered = (trig_str != NULL);
5856 // update orientation at server
5857 caster->SetOrientation(caster->GetAngle(m_session->GetPlayer()));
5859 // and client
5860 WorldPacket data;
5861 caster->BuildHeartBeatMsg(&data);
5862 caster->SendMessageToSet(&data,true);
5864 caster->CastSpell(m_session->GetPlayer(),spell,triggered);
5866 return true;
5869 bool ChatHandler::HandleCastDistCommand(const char* args)
5871 if(!*args)
5872 return false;
5874 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5875 uint32 spell = extractSpellIdFromLink((char*)args);
5876 if(!spell)
5877 return false;
5879 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
5880 if(!spellInfo)
5881 return false;
5883 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
5885 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
5886 SetSentErrorMessage(true);
5887 return false;
5890 char *distStr = strtok(NULL, " ");
5892 float dist = 0;
5894 if(distStr)
5895 sscanf(distStr, "%f", &dist);
5897 char* trig_str = strtok(NULL, " ");
5898 if(trig_str)
5900 int l = strlen(trig_str);
5901 if(strncmp(trig_str,"triggered",l) != 0 )
5902 return false;
5905 bool triggered = (trig_str != NULL);
5907 float x,y,z;
5908 m_session->GetPlayer()->GetClosePoint(x,y,z,dist);
5910 m_session->GetPlayer()->CastSpell(x,y,z,spell,triggered);
5911 return true;
5914 bool ChatHandler::HandleCastTargetCommand(const char* args)
5916 Creature* caster = getSelectedCreature();
5918 if(!caster)
5920 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5921 SetSentErrorMessage(true);
5922 return false;
5925 if(!caster->getVictim())
5927 SendSysMessage(LANG_SELECTED_TARGET_NOT_HAVE_VICTIM);
5928 SetSentErrorMessage(true);
5929 return false;
5932 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5933 uint32 spell = extractSpellIdFromLink((char*)args);
5934 if(!spell || !sSpellStore.LookupEntry(spell))
5935 return false;
5937 char* trig_str = strtok(NULL, " ");
5938 if(trig_str)
5940 int l = strlen(trig_str);
5941 if(strncmp(trig_str,"triggered",l) != 0 )
5942 return false;
5945 bool triggered = (trig_str != NULL);
5947 // update orientation at server
5948 caster->SetOrientation(caster->GetAngle(m_session->GetPlayer()));
5950 // and client
5951 WorldPacket data;
5952 caster->BuildHeartBeatMsg(&data);
5953 caster->SendMessageToSet(&data,true);
5955 caster->CastSpell(caster->getVictim(),spell,triggered);
5957 return true;
5961 ComeToMe command REQUIRED for 3rd party scripting library to have access to PointMovementGenerator
5962 Without this function 3rd party scripting library will get linking errors (unresolved external)
5963 when attempting to use the PointMovementGenerator
5965 bool ChatHandler::HandleComeToMeCommand(const char *args)
5967 Creature* caster = getSelectedCreature();
5969 if(!caster)
5971 SendSysMessage(LANG_SELECT_CREATURE);
5972 SetSentErrorMessage(true);
5973 return false;
5976 char* newFlagStr = strtok((char*)args, " ");
5978 if(!newFlagStr)
5979 return false;
5981 uint32 newFlags = atoi(newFlagStr);
5983 caster->SetUnitMovementFlags(newFlags);
5985 Player* pl = m_session->GetPlayer();
5987 caster->GetMotionMaster()->MovePoint(0, pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ());
5988 return true;
5991 bool ChatHandler::HandleCastSelfCommand(const char* args)
5993 if(!*args)
5994 return false;
5996 Unit* target = getSelectedUnit();
5998 if(!target)
6000 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
6001 SetSentErrorMessage(true);
6002 return false;
6005 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
6006 uint32 spell = extractSpellIdFromLink((char*)args);
6007 if(!spell)
6008 return false;
6010 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
6011 if(!spellInfo)
6012 return false;
6014 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
6016 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
6017 SetSentErrorMessage(true);
6018 return false;
6021 target->CastSpell(target,spell,false);
6023 return true;
6026 std::string GetTimeString(uint32 time)
6028 uint16 days = time / DAY, hours = (time % DAY) / HOUR, minute = (time % HOUR) / MINUTE;
6029 std::ostringstream ss;
6030 if(days) ss << days << "d ";
6031 if(hours) ss << hours << "h ";
6032 ss << minute << "m";
6033 return ss.str();
6036 bool ChatHandler::HandleInstanceListBindsCommand(const char* /*args*/)
6038 Player* player = getSelectedPlayer();
6039 if (!player) player = m_session->GetPlayer();
6040 uint32 counter = 0;
6041 for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++)
6043 Player::BoundInstancesMap &binds = player->GetBoundInstances(i);
6044 for(Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end(); ++itr)
6046 InstanceSave *save = itr->second.save;
6047 std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
6048 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());
6049 counter++;
6052 PSendSysMessage("player binds: %d", counter);
6053 counter = 0;
6054 Group *group = player->GetGroup();
6055 if(group)
6057 for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++)
6059 Group::BoundInstancesMap &binds = group->GetBoundInstances(i);
6060 for(Group::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end(); ++itr)
6062 InstanceSave *save = itr->second.save;
6063 std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
6064 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());
6065 counter++;
6069 PSendSysMessage("group binds: %d", counter);
6071 return true;
6074 bool ChatHandler::HandleInstanceUnbindCommand(const char* args)
6076 if(!*args)
6077 return false;
6079 std::string cmd = args;
6080 if(cmd == "all")
6082 Player* player = getSelectedPlayer();
6083 if (!player) player = m_session->GetPlayer();
6084 uint32 counter = 0;
6085 for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++)
6087 Player::BoundInstancesMap &binds = player->GetBoundInstances(i);
6088 for(Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end();)
6090 if(itr->first != player->GetMapId())
6092 InstanceSave *save = itr->second.save;
6093 std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
6094 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());
6095 player->UnbindInstance(itr, i);
6096 counter++;
6098 else
6099 ++itr;
6102 PSendSysMessage("instances unbound: %d", counter);
6104 return true;
6107 bool ChatHandler::HandleInstanceStatsCommand(const char* /*args*/)
6109 PSendSysMessage("instances loaded: %d", MapManager::Instance().GetNumInstances());
6110 PSendSysMessage("players in instances: %d", MapManager::Instance().GetNumPlayersInInstances());
6111 PSendSysMessage("instance saves: %d", sInstanceSaveManager.GetNumInstanceSaves());
6112 PSendSysMessage("players bound: %d", sInstanceSaveManager.GetNumBoundPlayersTotal());
6113 PSendSysMessage("groups bound: %d", sInstanceSaveManager.GetNumBoundGroupsTotal());
6114 return true;
6117 bool ChatHandler::HandleInstanceSaveDataCommand(const char * /*args*/)
6119 Player* pl = m_session->GetPlayer();
6121 Map* map = pl->GetMap();
6122 if (!map->IsDungeon())
6124 PSendSysMessage("Map is not a dungeon.");
6125 SetSentErrorMessage(true);
6126 return false;
6129 if (!((InstanceMap*)map)->GetInstanceData())
6131 PSendSysMessage("Map has no instance data.");
6132 SetSentErrorMessage(true);
6133 return false;
6136 ((InstanceMap*)map)->GetInstanceData()->SaveToDB();
6137 return true;
6140 /// Display the list of GMs
6141 bool ChatHandler::HandleGMListFullCommand(const char* /*args*/)
6143 ///- Get the accounts with GM Level >0
6144 QueryResult *result = loginDatabase.Query( "SELECT username,gmlevel FROM account WHERE gmlevel > 0" );
6145 if(result)
6147 SendSysMessage(LANG_GMLIST);
6148 SendSysMessage("========================");
6149 SendSysMessage(LANG_GMLIST_HEADER);
6150 SendSysMessage("========================");
6152 ///- Circle through them. Display username and GM level
6155 Field *fields = result->Fetch();
6156 PSendSysMessage("|%15s|%6s|", fields[0].GetString(),fields[1].GetString());
6157 }while( result->NextRow() );
6159 PSendSysMessage("========================");
6160 delete result;
6162 else
6163 PSendSysMessage(LANG_GMLIST_EMPTY);
6164 return true;
6167 /// Define the 'Message of the day' for the realm
6168 bool ChatHandler::HandleServerSetMotdCommand(const char* args)
6170 sWorld.SetMotd(args);
6171 PSendSysMessage(LANG_MOTD_NEW, args);
6172 return true;
6175 /// Set/Unset the expansion level for an account
6176 bool ChatHandler::HandleAccountSetAddonCommand(const char* args)
6178 ///- Get the command line arguments
6179 char *szAcc = strtok((char*)args," ");
6180 char *szExp = strtok(NULL," ");
6182 if(!szAcc)
6183 return false;
6185 std::string account_name;
6186 uint32 account_id;
6188 if(!szExp)
6190 Player* player = getSelectedPlayer();
6191 if(!player)
6192 return false;
6194 account_id = player->GetSession()->GetAccountId();
6195 accmgr.GetName(account_id,account_name);
6196 szExp = szAcc;
6198 else
6200 ///- Convert Account name to Upper Format
6201 account_name = szAcc;
6202 if(!AccountMgr::normilizeString(account_name))
6204 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
6205 SetSentErrorMessage(true);
6206 return false;
6209 account_id = accmgr.GetId(account_name);
6210 if(!account_id)
6212 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
6213 SetSentErrorMessage(true);
6214 return false;
6219 // Let set addon state only for lesser (strong) security level
6220 // or to self account
6221 if (m_session && m_session->GetAccountId () != account_id &&
6222 HasLowerSecurityAccount (NULL,account_id,true))
6223 return false;
6225 int lev=atoi(szExp); //get int anyway (0 if error)
6226 if(lev < 0)
6227 return false;
6229 // No SQL injection
6230 loginDatabase.PExecute("UPDATE account SET expansion = '%d' WHERE id = '%u'",lev,account_id);
6231 PSendSysMessage(LANG_ACCOUNT_SETADDON,account_name.c_str(),account_id,lev);
6232 return true;
6235 //Send items by mail
6236 bool ChatHandler::HandleSendItemsCommand(const char* args)
6238 if(!*args)
6239 return false;
6241 // format: name "subject text" "mail text" item1[:count1] item2[:count2] ... item12[:count12]
6243 char* pName = strtok((char*)args, " ");
6244 if(!pName)
6245 return false;
6247 char* tail1 = strtok(NULL, "");
6248 if(!tail1)
6249 return false;
6251 char* msgSubject;
6252 if(*tail1=='"')
6253 msgSubject = strtok(tail1+1, "\"");
6254 else
6256 char* space = strtok(tail1, "\"");
6257 if(!space)
6258 return false;
6259 msgSubject = strtok(NULL, "\"");
6262 if (!msgSubject)
6263 return false;
6265 char* tail2 = strtok(NULL, "");
6266 if(!tail2)
6267 return false;
6269 char* msgText;
6270 if(*tail2=='"')
6271 msgText = strtok(tail2+1, "\"");
6272 else
6274 char* space = strtok(tail2, "\"");
6275 if(!space)
6276 return false;
6277 msgText = strtok(NULL, "\"");
6280 if (!msgText)
6281 return false;
6283 // pName, msgSubject, msgText isn't NUL after prev. check
6284 std::string name = pName;
6285 std::string subject = msgSubject;
6286 std::string text = msgText;
6288 // extract items
6289 typedef std::pair<uint32,uint32> ItemPair;
6290 typedef std::list< ItemPair > ItemPairs;
6291 ItemPairs items;
6293 // get all tail string
6294 char* tail = strtok(NULL, "");
6296 // get from tail next item str
6297 while(char* itemStr = strtok(tail, " "))
6299 // and get new tail
6300 tail = strtok(NULL, "");
6302 // parse item str
6303 char* itemIdStr = strtok(itemStr, ":");
6304 char* itemCountStr = strtok(NULL, " ");
6306 uint32 item_id = atoi(itemIdStr);
6307 if(!item_id)
6308 return false;
6310 ItemPrototype const* item_proto = objmgr.GetItemPrototype(item_id);
6311 if(!item_proto)
6313 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
6314 SetSentErrorMessage(true);
6315 return false;
6318 uint32 item_count = itemCountStr ? atoi(itemCountStr) : 1;
6319 if(item_count < 1 || item_proto->MaxCount > 0 && item_count > uint32(item_proto->MaxCount))
6321 PSendSysMessage(LANG_COMMAND_INVALID_ITEM_COUNT, item_count,item_id);
6322 SetSentErrorMessage(true);
6323 return false;
6326 while(item_count > item_proto->GetMaxStackSize())
6328 items.push_back(ItemPair(item_id,item_proto->GetMaxStackSize()));
6329 item_count -= item_proto->GetMaxStackSize();
6332 items.push_back(ItemPair(item_id,item_count));
6334 if(items.size() > MAX_MAIL_ITEMS)
6336 PSendSysMessage(LANG_COMMAND_MAIL_ITEMS_LIMIT, MAX_MAIL_ITEMS);
6337 SetSentErrorMessage(true);
6338 return false;
6342 if(!normalizePlayerName(name))
6344 SendSysMessage(LANG_PLAYER_NOT_FOUND);
6345 SetSentErrorMessage(true);
6346 return false;
6349 uint64 receiver_guid = objmgr.GetPlayerGUIDByName(name);
6350 if(!receiver_guid)
6352 SendSysMessage(LANG_PLAYER_NOT_FOUND);
6353 SetSentErrorMessage(true);
6354 return false;
6357 // from console show not existed sender
6358 uint32 sender_guidlo = m_session ? m_session->GetPlayer()->GetGUIDLow() : 0;
6360 uint32 messagetype = MAIL_NORMAL;
6361 uint32 stationery = MAIL_STATIONERY_GM;
6362 uint32 itemTextId = !text.empty() ? objmgr.CreateItemText( text ) : 0;
6364 Player *receiver = objmgr.GetPlayer(receiver_guid);
6366 // fill mail
6367 MailItemsInfo mi; // item list preparing
6369 for(ItemPairs::const_iterator itr = items.begin(); itr != items.end(); ++itr)
6371 if(Item* item = Item::CreateItem(itr->first,itr->second,m_session ? m_session->GetPlayer() : 0))
6373 item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted
6374 mi.AddItem(item->GetGUIDLow(), item->GetEntry(), item);
6378 WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, &mi, 0, 0, MAIL_CHECK_MASK_NONE);
6380 PSendSysMessage(LANG_MAIL_SENT, name.c_str());
6381 return true;
6384 ///Send money by mail
6385 bool ChatHandler::HandleSendMoneyCommand(const char* args)
6387 if (!*args)
6388 return false;
6390 /// format: name "subject text" "mail text" money
6392 char* pName = strtok((char*)args, " ");
6393 if (!pName)
6394 return false;
6396 char* tail1 = strtok(NULL, "");
6397 if (!tail1)
6398 return false;
6400 char* msgSubject;
6401 if (*tail1=='"')
6402 msgSubject = strtok(tail1+1, "\"");
6403 else
6405 char* space = strtok(tail1, "\"");
6406 if (!space)
6407 return false;
6408 msgSubject = strtok(NULL, "\"");
6411 if (!msgSubject)
6412 return false;
6414 char* tail2 = strtok(NULL, "");
6415 if (!tail2)
6416 return false;
6418 char* msgText;
6419 if (*tail2=='"')
6420 msgText = strtok(tail2+1, "\"");
6421 else
6423 char* space = strtok(tail2, "\"");
6424 if (!space)
6425 return false;
6426 msgText = strtok(NULL, "\"");
6429 if (!msgText)
6430 return false;
6432 char* money_str = strtok(NULL, "");
6433 int32 money = money_str ? atoi(money_str) : 0;
6434 if (money <= 0)
6435 return false;
6437 // pName, msgSubject, msgText isn't NUL after prev. check
6438 std::string name = pName;
6439 std::string subject = msgSubject;
6440 std::string text = msgText;
6442 if (!normalizePlayerName(name))
6444 SendSysMessage(LANG_PLAYER_NOT_FOUND);
6445 SetSentErrorMessage(true);
6446 return false;
6449 uint64 receiver_guid = objmgr.GetPlayerGUIDByName(name);
6450 if (!receiver_guid)
6452 SendSysMessage(LANG_PLAYER_NOT_FOUND);
6453 SetSentErrorMessage(true);
6454 return false;
6457 uint32 mailId = objmgr.GenerateMailID();
6459 // from console show not existed sender
6460 uint32 sender_guidlo = m_session ? m_session->GetPlayer()->GetGUIDLow() : 0;
6462 uint32 messagetype = MAIL_NORMAL;
6463 uint32 stationery = MAIL_STATIONERY_GM;
6464 uint32 itemTextId = !text.empty() ? objmgr.CreateItemText( text ) : 0;
6466 Player *receiver = objmgr.GetPlayer(receiver_guid);
6468 WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, NULL, money, 0, MAIL_CHECK_MASK_NONE);
6470 PSendSysMessage(LANG_MAIL_SENT, name.c_str());
6471 return true;
6474 /// Send a message to a player in game
6475 bool ChatHandler::HandleSendMessageCommand(const char* args)
6477 ///- Get the command line arguments
6478 char* name_str = strtok((char*)args, " ");
6479 char* msg_str = strtok(NULL, "");
6481 if(!name_str || !msg_str)
6482 return false;
6484 std::string name = name_str;
6486 if(!normalizePlayerName(name))
6487 return false;
6489 ///- Find the player and check that he is not logging out.
6490 Player *rPlayer = objmgr.GetPlayer(name.c_str());
6491 if(!rPlayer)
6493 SendSysMessage(LANG_PLAYER_NOT_FOUND);
6494 SetSentErrorMessage(true);
6495 return false;
6498 if(rPlayer->GetSession()->isLogingOut())
6500 SendSysMessage(LANG_PLAYER_NOT_FOUND);
6501 SetSentErrorMessage(true);
6502 return false;
6505 ///- Send the message
6506 //Use SendAreaTriggerMessage for fastest delivery.
6507 rPlayer->GetSession()->SendAreaTriggerMessage("%s", msg_str);
6508 rPlayer->GetSession()->SendAreaTriggerMessage("|cffff0000[Message from administrator]:|r");
6510 //Confirmation message
6511 PSendSysMessage(LANG_SENDMESSAGE,name.c_str(),msg_str);
6512 return true;
6515 bool ChatHandler::HandleFlushArenaPointsCommand(const char * /*args*/)
6517 sBattleGroundMgr.DistributeArenaPoints();
6518 return true;
6521 bool ChatHandler::HandleModifyGenderCommand(const char *args)
6523 if(!*args)
6524 return false;
6526 Player *player = getSelectedPlayer();
6528 if(!player)
6530 PSendSysMessage(LANG_NO_PLAYER);
6531 SetSentErrorMessage(true);
6532 return false;
6535 PlayerInfo const* info = objmgr.GetPlayerInfo(player->getRace(), player->getClass());
6536 if(!info)
6537 return false;
6539 char const* gender_str = (char*)args;
6540 int gender_len = strlen(gender_str);
6542 Gender gender;
6544 if(!strncmp(gender_str, "male", gender_len)) // MALE
6546 if(player->getGender() == GENDER_MALE)
6547 return true;
6549 gender = GENDER_MALE;
6551 else if (!strncmp(gender_str, "female", gender_len)) // FEMALE
6553 if(player->getGender() == GENDER_FEMALE)
6554 return true;
6556 gender = GENDER_FEMALE;
6558 else
6560 SendSysMessage(LANG_MUST_MALE_OR_FEMALE);
6561 SetSentErrorMessage(true);
6562 return false;
6565 // Set gender
6566 player->SetByteValue(UNIT_FIELD_BYTES_0, 2, gender);
6567 player->SetByteValue(PLAYER_BYTES_3, 0, gender);
6569 // Change display ID
6570 player->SetDisplayId(gender ? info->displayId_f : info->displayId_m);
6571 player->SetNativeDisplayId(gender ? info->displayId_f : info->displayId_m);
6573 char const* gender_full = gender ? "female" : "male";
6575 PSendSysMessage(LANG_YOU_CHANGE_GENDER, player->GetName(), gender_full);
6577 if (needReportToTarget(player))
6578 ChatHandler(player).PSendSysMessage(LANG_YOUR_GENDER_CHANGED, gender_full, GetName());
6580 return true;