Merge branch 'master' into 303
[getmangos.git] / src / game / Level3.cpp
blob09af98247a808fc2a4fd0423191f77a061bd5363
1 /*
2 * Copyright (C) 2005-2008 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::HandleReloadCommand(const char* arg)
57 // this is error catcher for wrong table name in .reload commands
58 PSendSysMessage("Db table with name starting from '%s' not found and can't be reloaded.",arg);
59 SetSentErrorMessage(true);
60 return false;
63 bool ChatHandler::HandleReloadAllCommand(const char*)
65 HandleReloadAreaTriggerTeleportCommand("");
66 HandleReloadSkillFishingBaseLevelCommand("");
68 HandleReloadAllAreaCommand("");
69 HandleReloadAllLootCommand("");
70 HandleReloadAllNpcCommand("");
71 HandleReloadAllQuestCommand("");
72 HandleReloadAllSpellCommand("");
73 HandleReloadAllItemCommand("");
74 HandleReloadAllLocalesCommand("");
76 HandleReloadCommandCommand("");
77 HandleReloadReservedNameCommand("");
78 HandleReloadMangosStringCommand("");
79 HandleReloadGameTeleCommand("");
80 return true;
83 bool ChatHandler::HandleReloadAllAreaCommand(const char*)
85 //HandleReloadQuestAreaTriggersCommand(""); -- reloaded in HandleReloadAllQuestCommand
86 HandleReloadAreaTriggerTeleportCommand("");
87 HandleReloadAreaTriggerTavernCommand("");
88 HandleReloadGameGraveyardZoneCommand("");
89 return true;
92 bool ChatHandler::HandleReloadAllLootCommand(const char*)
94 sLog.outString( "Re-Loading Loot Tables..." );
95 LoadLootTables();
96 SendGlobalSysMessage("DB tables `*_loot_template` reloaded.");
97 return true;
100 bool ChatHandler::HandleReloadAllNpcCommand(const char* /*args*/)
102 HandleReloadNpcGossipCommand("a");
103 HandleReloadNpcOptionCommand("a");
104 HandleReloadNpcTrainerCommand("a");
105 HandleReloadNpcVendorCommand("a");
106 return true;
109 bool ChatHandler::HandleReloadAllQuestCommand(const char* /*args*/)
111 HandleReloadQuestAreaTriggersCommand("a");
112 HandleReloadQuestTemplateCommand("a");
114 sLog.outString( "Re-Loading Quests Relations..." );
115 objmgr.LoadQuestRelations();
116 SendGlobalSysMessage("DB tables `*_questrelation` and `*_involvedrelation` reloaded.");
117 return true;
120 bool ChatHandler::HandleReloadAllScriptsCommand(const char*)
122 if(sWorld.IsScriptScheduled())
124 PSendSysMessage("DB scripts used currently, please attempt reload later.");
125 SetSentErrorMessage(true);
126 return false;
129 sLog.outString( "Re-Loading Scripts..." );
130 HandleReloadGameObjectScriptsCommand("a");
131 HandleReloadEventScriptsCommand("a");
132 HandleReloadQuestEndScriptsCommand("a");
133 HandleReloadQuestStartScriptsCommand("a");
134 HandleReloadSpellScriptsCommand("a");
135 SendGlobalSysMessage("DB tables `*_scripts` reloaded.");
136 HandleReloadDbScriptStringCommand("a");
137 return true;
140 bool ChatHandler::HandleReloadAllSpellCommand(const char*)
142 HandleReloadSkillDiscoveryTemplateCommand("a");
143 HandleReloadSkillExtraItemTemplateCommand("a");
144 HandleReloadSpellAffectCommand("a");
145 HandleReloadSpellChainCommand("a");
146 HandleReloadSpellElixirCommand("a");
147 HandleReloadSpellLearnSpellCommand("a");
148 HandleReloadSpellProcEventCommand("a");
149 HandleReloadSpellScriptTargetCommand("a");
150 HandleReloadSpellTargetPositionCommand("a");
151 HandleReloadSpellThreatsCommand("a");
152 HandleReloadSpellPetAurasCommand("a");
153 return true;
156 bool ChatHandler::HandleReloadAllItemCommand(const char*)
158 HandleReloadPageTextsCommand("a");
159 HandleReloadItemEnchantementsCommand("a");
160 return true;
163 bool ChatHandler::HandleReloadAllLocalesCommand(const char* /*args*/)
165 HandleReloadLocalesCreatureCommand("a");
166 HandleReloadLocalesGameobjectCommand("a");
167 HandleReloadLocalesItemCommand("a");
168 HandleReloadLocalesNpcTextCommand("a");
169 HandleReloadLocalesPageTextCommand("a");
170 HandleReloadLocalesQuestCommand("a");
171 return true;
174 bool ChatHandler::HandleReloadConfigCommand(const char* /*args*/)
176 sLog.outString( "Re-Loading config settings..." );
177 sWorld.LoadConfigSettings(true);
178 SendGlobalSysMessage("World config settings reloaded.");
179 return true;
182 bool ChatHandler::HandleReloadAreaTriggerTavernCommand(const char*)
184 sLog.outString( "Re-Loading Tavern Area Triggers..." );
185 objmgr.LoadTavernAreaTriggers();
186 SendGlobalSysMessage("DB table `areatrigger_tavern` reloaded.");
187 return true;
190 bool ChatHandler::HandleReloadAreaTriggerTeleportCommand(const char*)
192 sLog.outString( "Re-Loading AreaTrigger teleport definitions..." );
193 objmgr.LoadAreaTriggerTeleports();
194 SendGlobalSysMessage("DB table `areatrigger_teleport` reloaded.");
195 return true;
198 bool ChatHandler::HandleReloadCommandCommand(const char*)
200 load_command_table = true;
201 SendGlobalSysMessage("DB table `command` will be reloaded at next chat command use.");
202 return true;
205 bool ChatHandler::HandleReloadCreatureQuestRelationsCommand(const char*)
207 sLog.outString( "Loading Quests Relations... (`creature_questrelation`)" );
208 objmgr.LoadCreatureQuestRelations();
209 SendGlobalSysMessage("DB table `creature_questrelation` (creature quest givers) reloaded.");
210 return true;
213 bool ChatHandler::HandleReloadCreatureQuestInvRelationsCommand(const char*)
215 sLog.outString( "Loading Quests Relations... (`creature_involvedrelation`)" );
216 objmgr.LoadCreatureInvolvedRelations();
217 SendGlobalSysMessage("DB table `creature_involvedrelation` (creature quest takers) reloaded.");
218 return true;
221 bool ChatHandler::HandleReloadGOQuestRelationsCommand(const char*)
223 sLog.outString( "Loading Quests Relations... (`gameobject_questrelation`)" );
224 objmgr.LoadGameobjectQuestRelations();
225 SendGlobalSysMessage("DB table `gameobject_questrelation` (gameobject quest givers) reloaded.");
226 return true;
229 bool ChatHandler::HandleReloadGOQuestInvRelationsCommand(const char*)
231 sLog.outString( "Loading Quests Relations... (`gameobject_involvedrelation`)" );
232 objmgr.LoadGameobjectInvolvedRelations();
233 SendGlobalSysMessage("DB table `gameobject_involvedrelation` (gameobject quest takers) reloaded.");
234 return true;
237 bool ChatHandler::HandleReloadQuestAreaTriggersCommand(const char*)
239 sLog.outString( "Re-Loading Quest Area Triggers..." );
240 objmgr.LoadQuestAreaTriggers();
241 SendGlobalSysMessage("DB table `areatrigger_involvedrelation` (quest area triggers) reloaded.");
242 return true;
245 bool ChatHandler::HandleReloadQuestTemplateCommand(const char*)
247 sLog.outString( "Re-Loading Quest Templates..." );
248 objmgr.LoadQuests();
249 SendGlobalSysMessage("DB table `quest_template` (quest definitions) reloaded.");
250 return true;
253 bool ChatHandler::HandleReloadLootTemplatesCreatureCommand(const char*)
255 sLog.outString( "Re-Loading Loot Tables... (`creature_loot_template`)" );
256 LoadLootTemplates_Creature();
257 LootTemplates_Creature.CheckLootRefs();
258 SendGlobalSysMessage("DB table `creature_loot_template` reloaded.");
259 return true;
262 bool ChatHandler::HandleReloadLootTemplatesDisenchantCommand(const char*)
264 sLog.outString( "Re-Loading Loot Tables... (`disenchant_loot_template`)" );
265 LoadLootTemplates_Disenchant();
266 LootTemplates_Disenchant.CheckLootRefs();
267 SendGlobalSysMessage("DB table `disenchant_loot_template` reloaded.");
268 return true;
271 bool ChatHandler::HandleReloadLootTemplatesFishingCommand(const char*)
273 sLog.outString( "Re-Loading Loot Tables... (`fishing_loot_template`)" );
274 LoadLootTemplates_Fishing();
275 LootTemplates_Fishing.CheckLootRefs();
276 SendGlobalSysMessage("DB table `fishing_loot_template` reloaded.");
277 return true;
280 bool ChatHandler::HandleReloadLootTemplatesGameobjectCommand(const char*)
282 sLog.outString( "Re-Loading Loot Tables... (`gameobject_loot_template`)" );
283 LoadLootTemplates_Gameobject();
284 LootTemplates_Gameobject.CheckLootRefs();
285 SendGlobalSysMessage("DB table `gameobject_loot_template` reloaded.");
286 return true;
289 bool ChatHandler::HandleReloadLootTemplatesItemCommand(const char*)
291 sLog.outString( "Re-Loading Loot Tables... (`item_loot_template`)" );
292 LoadLootTemplates_Item();
293 LootTemplates_Item.CheckLootRefs();
294 SendGlobalSysMessage("DB table `item_loot_template` reloaded.");
295 return true;
298 bool ChatHandler::HandleReloadLootTemplatesMillingCommand(const char*)
300 sLog.outString( "Re-Loading Loot Tables... (`milling_loot_template`)" );
301 LoadLootTemplates_Milling();
302 LootTemplates_Milling.CheckLootRefs();
303 SendGlobalSysMessage("DB table `milling_loot_template` reloaded.");
304 return true;
307 bool ChatHandler::HandleReloadLootTemplatesPickpocketingCommand(const char*)
309 sLog.outString( "Re-Loading Loot Tables... (`pickpocketing_loot_template`)" );
310 LoadLootTemplates_Pickpocketing();
311 LootTemplates_Pickpocketing.CheckLootRefs();
312 SendGlobalSysMessage("DB table `pickpocketing_loot_template` reloaded.");
313 return true;
316 bool ChatHandler::HandleReloadLootTemplatesProspectingCommand(const char*)
318 sLog.outString( "Re-Loading Loot Tables... (`prospecting_loot_template`)" );
319 LoadLootTemplates_Prospecting();
320 LootTemplates_Prospecting.CheckLootRefs();
321 SendGlobalSysMessage("DB table `prospecting_loot_template` reloaded.");
322 return true;
325 bool ChatHandler::HandleReloadLootTemplatesQuestMailCommand(const char*)
327 sLog.outString( "Re-Loading Loot Tables... (`quest_mail_loot_template`)" );
328 LoadLootTemplates_QuestMail();
329 LootTemplates_QuestMail.CheckLootRefs();
330 SendGlobalSysMessage("DB table `quest_mail_loot_template` reloaded.");
331 return true;
334 bool ChatHandler::HandleReloadLootTemplatesReferenceCommand(const char*)
336 sLog.outString( "Re-Loading Loot Tables... (`reference_loot_template`)" );
337 LoadLootTemplates_Reference();
338 SendGlobalSysMessage("DB table `reference_loot_template` reloaded.");
339 return true;
342 bool ChatHandler::HandleReloadLootTemplatesSkinningCommand(const char*)
344 sLog.outString( "Re-Loading Loot Tables... (`skinning_loot_template`)" );
345 LoadLootTemplates_Skinning();
346 LootTemplates_Skinning.CheckLootRefs();
347 SendGlobalSysMessage("DB table `skinning_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;
708 uint32 targetSecurity = 0;
710 /// only target player different from self allowed (if targetPlayer!=NULL then not console)
711 Player* targetPlayer = getSelectedPlayer();
712 if(targetPlayer && m_session->GetPlayer()!=targetPlayer)
714 /// wrong command syntax or unexpected targeting
715 if(arg2)
716 return false;
718 /// security level expected in arg2 after this if.
719 arg2 = arg1;
721 targetAccountId = targetPlayer->GetSession()->GetAccountId();
722 targetSecurity = targetPlayer->GetSession()->GetSecurity();
723 if(!accmgr.GetName(targetAccountId,targetAccountName))
725 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,targetAccountName.c_str());
726 SetSentErrorMessage(true);
727 return false;
730 else
732 /// wrong command syntax (second arg expected)
733 if(!arg2)
734 return false;
736 targetAccountName = arg1;
737 if(!AccountMgr::normilizeString(targetAccountName))
739 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,targetAccountName.c_str());
740 SetSentErrorMessage(true);
741 return false;
744 targetAccountId = accmgr.GetId(targetAccountName);
745 targetSecurity = accmgr.GetSecurity(targetAccountId);
748 int32 gm = (int32)atoi(arg2);
749 if ( gm < SEC_PLAYER || gm > SEC_ADMINISTRATOR )
751 SendSysMessage(LANG_BAD_VALUE);
752 SetSentErrorMessage(true);
753 return false;
756 /// m_session==NULL only for console
757 uint32 plSecurity = m_session ? m_session->GetSecurity() : SEC_CONSOLE;
759 /// can set security level only for target with less security and to less security that we have
760 /// This is also reject self apply in fact
761 if(targetSecurity >= plSecurity || uint32(gm) >= plSecurity )
763 SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
764 SetSentErrorMessage(true);
765 return false;
768 if(targetPlayer)
770 ChatHandler(targetPlayer).PSendSysMessage(LANG_YOURS_SECURITY_CHANGED,GetName(), gm);
771 targetPlayer->GetSession()->SetSecurity(gm);
774 PSendSysMessage(LANG_YOU_CHANGE_SECURITY, targetAccountName.c_str(), gm);
775 loginDatabase.PExecute("UPDATE account SET gmlevel = '%i' WHERE id = '%u'", gm, targetAccountId);
777 return true;
780 /// Set password for account
781 bool ChatHandler::HandleAccountSetPasswordCommand(const char* args)
783 if(!*args)
784 return false;
786 ///- Get the command line arguments
787 char *szAccount = strtok ((char*)args," ");
788 char *szPassword1 = strtok (NULL," ");
789 char *szPassword2 = strtok (NULL," ");
791 if (!szAccount||!szPassword1 || !szPassword2)
792 return false;
794 std::string account_name = szAccount;
795 if(!AccountMgr::normilizeString(account_name))
797 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
798 SetSentErrorMessage(true);
799 return false;
802 uint32 targetAccountId = accmgr.GetId(account_name);
803 if (!targetAccountId)
805 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
806 SetSentErrorMessage(true);
807 return false;
810 uint32 targetSecurity = accmgr.GetSecurity(targetAccountId);
812 /// m_session==NULL only for console
813 uint32 plSecurity = m_session ? m_session->GetSecurity() : SEC_CONSOLE;
815 /// can set password only for target with less security
816 /// This is also reject self apply in fact
817 if (targetSecurity >= plSecurity)
819 SendSysMessage (LANG_YOURS_SECURITY_IS_LOW);
820 SetSentErrorMessage (true);
821 return false;
824 if (strcmp(szPassword1,szPassword2))
826 SendSysMessage (LANG_NEW_PASSWORDS_NOT_MATCH);
827 SetSentErrorMessage (true);
828 return false;
831 AccountOpResult result = accmgr.ChangePassword(targetAccountId, szPassword1);
833 switch(result)
835 case AOR_OK:
836 SendSysMessage(LANG_COMMAND_PASSWORD);
837 break;
838 case AOR_NAME_NOT_EXIST:
839 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
840 SetSentErrorMessage(true);
841 return false;
842 case AOR_PASS_TOO_LONG:
843 SendSysMessage(LANG_PASSWORD_TOO_LONG);
844 SetSentErrorMessage(true);
845 return false;
846 default:
847 SendSysMessage(LANG_COMMAND_NOTCHANGEPASSWORD);
848 SetSentErrorMessage(true);
849 return false;
852 return true;
855 bool ChatHandler::HandleAllowMovementCommand(const char* /*args*/)
857 if(sWorld.getAllowMovement())
859 sWorld.SetAllowMovement(false);
860 SendSysMessage(LANG_CREATURE_MOVE_DISABLED);
862 else
864 sWorld.SetAllowMovement(true);
865 SendSysMessage(LANG_CREATURE_MOVE_ENABLED);
867 return true;
870 bool ChatHandler::HandleMaxSkillCommand(const char* /*args*/)
872 Player* SelectedPlayer = getSelectedPlayer();
873 if(!SelectedPlayer)
875 SendSysMessage(LANG_NO_CHAR_SELECTED);
876 SetSentErrorMessage(true);
877 return false;
880 // each skills that have max skill value dependent from level seted to current level max skill value
881 SelectedPlayer->UpdateSkillsToMaxSkillsForLevel();
882 return true;
885 bool ChatHandler::HandleSetSkillCommand(const char* args)
887 // number or [name] Shift-click form |color|Hskill:skill_id|h[name]|h|r
888 char* skill_p = extractKeyFromLink((char*)args,"Hskill");
889 if(!skill_p)
890 return false;
892 char *level_p = strtok (NULL, " ");
894 if( !level_p)
895 return false;
897 char *max_p = strtok (NULL, " ");
899 int32 skill = atoi(skill_p);
901 if (skill <= 0)
903 PSendSysMessage(LANG_INVALID_SKILL_ID, skill);
904 SetSentErrorMessage(true);
905 return false;
908 int32 level = atol (level_p);
910 Player * target = getSelectedPlayer();
911 if(!target)
913 SendSysMessage(LANG_NO_CHAR_SELECTED);
914 SetSentErrorMessage(true);
915 return false;
918 SkillLineEntry const* sl = sSkillLineStore.LookupEntry(skill);
919 if(!sl)
921 PSendSysMessage(LANG_INVALID_SKILL_ID, skill);
922 SetSentErrorMessage(true);
923 return false;
926 if(!target->GetSkillValue(skill))
928 PSendSysMessage(LANG_SET_SKILL_ERROR, target->GetName(), skill, sl->name[0]);
929 SetSentErrorMessage(true);
930 return false;
933 int32 max = max_p ? atol (max_p) : target->GetPureMaxSkillValue(skill);
935 if( level <= 0 || level > max || max <= 0 )
936 return false;
938 target->SetSkill(skill, level, max);
939 PSendSysMessage(LANG_SET_SKILL, skill, sl->name[0], target->GetName(), level, max);
941 return true;
944 bool ChatHandler::HandleUnLearnCommand(const char* args)
946 if (!*args)
947 return false;
949 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
950 uint32 min_id = extractSpellIdFromLink((char*)args);
951 if(!min_id)
952 return false;
954 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
955 char* tail = strtok(NULL,"");
957 uint32 max_id = extractSpellIdFromLink(tail);
959 if (!max_id)
961 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
962 max_id = min_id+1;
964 else
966 if (max_id < min_id)
967 std::swap(min_id,max_id);
969 max_id=max_id+1;
972 Player* target = getSelectedPlayer();
973 if(!target)
975 SendSysMessage(LANG_NO_CHAR_SELECTED);
976 SetSentErrorMessage(true);
977 return false;
980 for(uint32 spell=min_id;spell<max_id;spell++)
982 if (target->HasSpell(spell))
983 target->removeSpell(spell);
984 else
985 SendSysMessage(LANG_FORGET_SPELL);
988 return true;
991 bool ChatHandler::HandleCooldownCommand(const char* args)
993 Player* target = getSelectedPlayer();
994 if(!target)
996 SendSysMessage(LANG_PLAYER_NOT_FOUND);
997 SetSentErrorMessage(true);
998 return false;
1001 if (!*args)
1003 target->RemoveAllSpellCooldown();
1004 PSendSysMessage(LANG_REMOVEALL_COOLDOWN, target->GetName());
1006 else
1008 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
1009 uint32 spell_id = extractSpellIdFromLink((char*)args);
1010 if(!spell_id)
1011 return false;
1013 if(!sSpellStore.LookupEntry(spell_id))
1015 PSendSysMessage(LANG_UNKNOWN_SPELL, target==m_session->GetPlayer() ? GetMangosString(LANG_YOU) : target->GetName());
1016 SetSentErrorMessage(true);
1017 return false;
1020 WorldPacket data( SMSG_CLEAR_COOLDOWN, (4+8) );
1021 data << uint32(spell_id);
1022 data << uint64(target->GetGUID());
1023 target->GetSession()->SendPacket(&data);
1024 target->RemoveSpellCooldown(spell_id);
1025 PSendSysMessage(LANG_REMOVE_COOLDOWN, spell_id, target==m_session->GetPlayer() ? GetMangosString(LANG_YOU) : target->GetName());
1027 return true;
1030 bool ChatHandler::HandleLearnAllCommand(const char* /*args*/)
1032 static const char *allSpellList[] =
1034 "3365",
1035 "6233",
1036 "6247",
1037 "6246",
1038 "6477",
1039 "6478",
1040 "22810",
1041 "8386",
1042 "21651",
1043 "21652",
1044 "522",
1045 "7266",
1046 "8597",
1047 "2479",
1048 "22027",
1049 "6603",
1050 "5019",
1051 "133",
1052 "168",
1053 "227",
1054 "5009",
1055 "9078",
1056 "668",
1057 "203",
1058 "20599",
1059 "20600",
1060 "81",
1061 "20597",
1062 "20598",
1063 "20864",
1064 "1459",
1065 "5504",
1066 "587",
1067 "5143",
1068 "118",
1069 "5505",
1070 "597",
1071 "604",
1072 "1449",
1073 "1460",
1074 "2855",
1075 "1008",
1076 "475",
1077 "5506",
1078 "1463",
1079 "12824",
1080 "8437",
1081 "990",
1082 "5145",
1083 "8450",
1084 "1461",
1085 "759",
1086 "8494",
1087 "8455",
1088 "8438",
1089 "6127",
1090 "8416",
1091 "6129",
1092 "8451",
1093 "8495",
1094 "8439",
1095 "3552",
1096 "8417",
1097 "10138",
1098 "12825",
1099 "10169",
1100 "10156",
1101 "10144",
1102 "10191",
1103 "10201",
1104 "10211",
1105 "10053",
1106 "10173",
1107 "10139",
1108 "10145",
1109 "10192",
1110 "10170",
1111 "10202",
1112 "10054",
1113 "10174",
1114 "10193",
1115 "12826",
1116 "2136",
1117 "143",
1118 "145",
1119 "2137",
1120 "2120",
1121 "3140",
1122 "543",
1123 "2138",
1124 "2948",
1125 "8400",
1126 "2121",
1127 "8444",
1128 "8412",
1129 "8457",
1130 "8401",
1131 "8422",
1132 "8445",
1133 "8402",
1134 "8413",
1135 "8458",
1136 "8423",
1137 "8446",
1138 "10148",
1139 "10197",
1140 "10205",
1141 "10149",
1142 "10215",
1143 "10223",
1144 "10206",
1145 "10199",
1146 "10150",
1147 "10216",
1148 "10207",
1149 "10225",
1150 "10151",
1151 "116",
1152 "205",
1153 "7300",
1154 "122",
1155 "837",
1156 "10",
1157 "7301",
1158 "7322",
1159 "6143",
1160 "120",
1161 "865",
1162 "8406",
1163 "6141",
1164 "7302",
1165 "8461",
1166 "8407",
1167 "8492",
1168 "8427",
1169 "8408",
1170 "6131",
1171 "7320",
1172 "10159",
1173 "8462",
1174 "10185",
1175 "10179",
1176 "10160",
1177 "10180",
1178 "10219",
1179 "10186",
1180 "10177",
1181 "10230",
1182 "10181",
1183 "10161",
1184 "10187",
1185 "10220",
1186 "2018",
1187 "2663",
1188 "12260",
1189 "2660",
1190 "3115",
1191 "3326",
1192 "2665",
1193 "3116",
1194 "2738",
1195 "3293",
1196 "2661",
1197 "3319",
1198 "2662",
1199 "9983",
1200 "8880",
1201 "2737",
1202 "2739",
1203 "7408",
1204 "3320",
1205 "2666",
1206 "3323",
1207 "3324",
1208 "3294",
1209 "22723",
1210 "23219",
1211 "23220",
1212 "23221",
1213 "23228",
1214 "23338",
1215 "10788",
1216 "10790",
1217 "5611",
1218 "5016",
1219 "5609",
1220 "2060",
1221 "10963",
1222 "10964",
1223 "10965",
1224 "22593",
1225 "22594",
1226 "596",
1227 "996",
1228 "499",
1229 "768",
1230 "17002",
1231 "1448",
1232 "1082",
1233 "16979",
1234 "1079",
1235 "5215",
1236 "20484",
1237 "5221",
1238 "15590",
1239 "17007",
1240 "6795",
1241 "6807",
1242 "5487",
1243 "1446",
1244 "1066",
1245 "5421",
1246 "3139",
1247 "779",
1248 "6811",
1249 "6808",
1250 "1445",
1251 "5216",
1252 "1737",
1253 "5222",
1254 "5217",
1255 "1432",
1256 "6812",
1257 "9492",
1258 "5210",
1259 "3030",
1260 "1441",
1261 "783",
1262 "6801",
1263 "20739",
1264 "8944",
1265 "9491",
1266 "22569",
1267 "5226",
1268 "6786",
1269 "1433",
1270 "8973",
1271 "1828",
1272 "9495",
1273 "9006",
1274 "6794",
1275 "8993",
1276 "5203",
1277 "16914",
1278 "6784",
1279 "9635",
1280 "22830",
1281 "20722",
1282 "9748",
1283 "6790",
1284 "9753",
1285 "9493",
1286 "9752",
1287 "9831",
1288 "9825",
1289 "9822",
1290 "5204",
1291 "5401",
1292 "22831",
1293 "6793",
1294 "9845",
1295 "17401",
1296 "9882",
1297 "9868",
1298 "20749",
1299 "9893",
1300 "9899",
1301 "9895",
1302 "9832",
1303 "9902",
1304 "9909",
1305 "22832",
1306 "9828",
1307 "9851",
1308 "9883",
1309 "9869",
1310 "17406",
1311 "17402",
1312 "9914",
1313 "20750",
1314 "9897",
1315 "9848",
1316 "3127",
1317 "107",
1318 "204",
1319 "9116",
1320 "2457",
1321 "78",
1322 "18848",
1323 "331",
1324 "403",
1325 "2098",
1326 "1752",
1327 "11278",
1328 "11288",
1329 "11284",
1330 "6461",
1331 "2344",
1332 "2345",
1333 "6463",
1334 "2346",
1335 "2352",
1336 "775",
1337 "1434",
1338 "1612",
1339 "71",
1340 "2468",
1341 "2458",
1342 "2467",
1343 "7164",
1344 "7178",
1345 "7367",
1346 "7376",
1347 "7381",
1348 "21156",
1349 "5209",
1350 "3029",
1351 "5201",
1352 "9849",
1353 "9850",
1354 "20719",
1355 "22568",
1356 "22827",
1357 "22828",
1358 "22829",
1359 "6809",
1360 "8972",
1361 "9005",
1362 "9823",
1363 "9827",
1364 "6783",
1365 "9913",
1366 "6785",
1367 "6787",
1368 "9866",
1369 "9867",
1370 "9894",
1371 "9896",
1372 "6800",
1373 "8992",
1374 "9829",
1375 "9830",
1376 "780",
1377 "769",
1378 "6749",
1379 "6750",
1380 "9755",
1381 "9754",
1382 "9908",
1383 "20745",
1384 "20742",
1385 "20747",
1386 "20748",
1387 "9746",
1388 "9745",
1389 "9880",
1390 "9881",
1391 "5391",
1392 "842",
1393 "3025",
1394 "3031",
1395 "3287",
1396 "3329",
1397 "1945",
1398 "3559",
1399 "4933",
1400 "4934",
1401 "4935",
1402 "4936",
1403 "5142",
1404 "5390",
1405 "5392",
1406 "5404",
1407 "5420",
1408 "6405",
1409 "7293",
1410 "7965",
1411 "8041",
1412 "8153",
1413 "9033",
1414 "9034",
1415 //"9036", problems with ghost state
1416 "16421",
1417 "21653",
1418 "22660",
1419 "5225",
1420 "9846",
1421 "2426",
1422 "5916",
1423 "6634",
1424 //"6718", phasing stealth, annoying for learn all case.
1425 "6719",
1426 "8822",
1427 "9591",
1428 "9590",
1429 "10032",
1430 "17746",
1431 "17747",
1432 "8203",
1433 "11392",
1434 "12495",
1435 "16380",
1436 "23452",
1437 "4079",
1438 "4996",
1439 "4997",
1440 "4998",
1441 "4999",
1442 "5000",
1443 "6348",
1444 "6349",
1445 "6481",
1446 "6482",
1447 "6483",
1448 "6484",
1449 "11362",
1450 "11410",
1451 "11409",
1452 "12510",
1453 "12509",
1454 "12885",
1455 "13142",
1456 "21463",
1457 "23460",
1458 "11421",
1459 "11416",
1460 "11418",
1461 "1851",
1462 "10059",
1463 "11423",
1464 "11417",
1465 "11422",
1466 "11419",
1467 "11424",
1468 "11420",
1469 "27",
1470 "31",
1471 "33",
1472 "34",
1473 "35",
1474 "15125",
1475 "21127",
1476 "22950",
1477 "1180",
1478 "201",
1479 "12593",
1480 "12842",
1481 "16770",
1482 "6057",
1483 "12051",
1484 "18468",
1485 "12606",
1486 "12605",
1487 "18466",
1488 "12502",
1489 "12043",
1490 "15060",
1491 "12042",
1492 "12341",
1493 "12848",
1494 "12344",
1495 "12353",
1496 "18460",
1497 "11366",
1498 "12350",
1499 "12352",
1500 "13043",
1501 "11368",
1502 "11113",
1503 "12400",
1504 "11129",
1505 "16766",
1506 "12573",
1507 "15053",
1508 "12580",
1509 "12475",
1510 "12472",
1511 "12953",
1512 "12488",
1513 "11189",
1514 "12985",
1515 "12519",
1516 "16758",
1517 "11958",
1518 "12490",
1519 "11426",
1520 "3565",
1521 "3562",
1522 "18960",
1523 "3567",
1524 "3561",
1525 "3566",
1526 "3563",
1527 "1953",
1528 "2139",
1529 "12505",
1530 "13018",
1531 "12522",
1532 "12523",
1533 "5146",
1534 "5144",
1535 "5148",
1536 "8419",
1537 "8418",
1538 "10213",
1539 "10212",
1540 "10157",
1541 "12524",
1542 "13019",
1543 "12525",
1544 "13020",
1545 "12526",
1546 "13021",
1547 "18809",
1548 "13031",
1549 "13032",
1550 "13033",
1551 "4036",
1552 "3920",
1553 "3919",
1554 "3918",
1555 "7430",
1556 "3922",
1557 "3923",
1558 "7411",
1559 "7418",
1560 "7421",
1561 "13262",
1562 "7412",
1563 "7415",
1564 "7413",
1565 "7416",
1566 "13920",
1567 "13921",
1568 "7745",
1569 "7779",
1570 "7428",
1571 "7457",
1572 "7857",
1573 "7748",
1574 "7426",
1575 "13421",
1576 "7454",
1577 "13378",
1578 "7788",
1579 "14807",
1580 "14293",
1581 "7795",
1582 "6296",
1583 "20608",
1584 "755",
1585 "444",
1586 "427",
1587 "428",
1588 "442",
1589 "447",
1590 "3578",
1591 "3581",
1592 "19027",
1593 "3580",
1594 "665",
1595 "3579",
1596 "3577",
1597 "6755",
1598 "3576",
1599 "2575",
1600 "2577",
1601 "2578",
1602 "2579",
1603 "2580",
1604 "2656",
1605 "2657",
1606 "2576",
1607 "3564",
1608 "10248",
1609 "8388",
1610 "2659",
1611 "14891",
1612 "3308",
1613 "3307",
1614 "10097",
1615 "2658",
1616 "3569",
1617 "16153",
1618 "3304",
1619 "10098",
1620 "4037",
1621 "3929",
1622 "3931",
1623 "3926",
1624 "3924",
1625 "3930",
1626 "3977",
1627 "3925",
1628 "136",
1629 "228",
1630 "5487",
1631 "43",
1632 "202",
1636 int loop = 0;
1637 while(strcmp(allSpellList[loop], "0"))
1639 uint32 spell = atol((char*)allSpellList[loop++]);
1641 if (m_session->GetPlayer()->HasSpell(spell))
1642 continue;
1644 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
1645 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
1647 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
1648 continue;
1651 m_session->GetPlayer()->learnSpell(spell);
1654 SendSysMessage(LANG_COMMAND_LEARN_MANY_SPELLS);
1656 return true;
1659 bool ChatHandler::HandleLearnAllGMCommand(const char* /*args*/)
1661 static const char *gmSpellList[] =
1663 "24347", // Become A Fish, No Breath Bar
1664 "35132", // Visual Boom
1665 "38488", // Attack 4000-8000 AOE
1666 "38795", // Attack 2000 AOE + Slow Down 90%
1667 "15712", // Attack 200
1668 "1852", // GM Spell Silence
1669 "31899", // Kill
1670 "31924", // Kill
1671 "29878", // Kill My Self
1672 "26644", // More Kill
1674 "28550", //Invisible 24
1675 "23452", //Invisible + Target
1679 uint16 gmSpellIter = 0;
1680 while( strcmp(gmSpellList[gmSpellIter], "0") )
1682 uint32 spell = atol((char*)gmSpellList[gmSpellIter++]);
1684 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
1685 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
1687 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
1688 continue;
1691 m_session->GetPlayer()->learnSpell(spell);
1694 SendSysMessage(LANG_LEARNING_GM_SKILLS);
1695 return true;
1698 bool ChatHandler::HandleLearnAllMyClassCommand(const char* /*args*/)
1700 HandleLearnAllMySpellsCommand("");
1701 HandleLearnAllMyTalentsCommand("");
1702 return true;
1705 bool ChatHandler::HandleLearnAllMySpellsCommand(const char* /*args*/)
1707 ChrClassesEntry const* clsEntry = sChrClassesStore.LookupEntry(m_session->GetPlayer()->getClass());
1708 if(!clsEntry)
1709 return true;
1710 uint32 family = clsEntry->spellfamily;
1712 for (uint32 i = 0; i < sSpellStore.GetNumRows(); i++)
1714 SpellEntry const *spellInfo = sSpellStore.LookupEntry(i);
1715 if(!spellInfo)
1716 continue;
1718 // skip wrong class/race skills
1719 if(!m_session->GetPlayer()->IsSpellFitByClassAndRace(spellInfo->Id))
1720 continue;
1722 // skip other spell families
1723 if( spellInfo->SpellFamilyName != family)
1724 continue;
1726 //TODO: skip triggered spells
1728 // skip spells with first rank learned as talent (and all talents then also)
1729 uint32 first_rank = spellmgr.GetFirstSpellInChain(spellInfo->Id);
1730 if(GetTalentSpellCost(first_rank) > 0 )
1731 continue;
1733 // skip broken spells
1734 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
1735 continue;
1737 m_session->GetPlayer()->learnSpell(i);
1740 SendSysMessage(LANG_COMMAND_LEARN_CLASS_SPELLS);
1741 return true;
1744 static void learnAllHighRanks(Player* player, uint32 spellid)
1746 SpellChainMapNext const& nextMap = spellmgr.GetSpellChainNext();
1747 for(SpellChainMapNext::const_iterator itr = nextMap.lower_bound(spellid); itr != nextMap.upper_bound(spellid); ++itr)
1749 player->learnSpell(itr->second);
1750 learnAllHighRanks(player,itr->second);
1754 bool ChatHandler::HandleLearnAllMyTalentsCommand(const char* /*args*/)
1756 Player* player = m_session->GetPlayer();
1757 uint32 classMask = player->getClassMask();
1759 for (uint32 i = 0; i < sTalentStore.GetNumRows(); i++)
1761 TalentEntry const *talentInfo = sTalentStore.LookupEntry(i);
1762 if(!talentInfo)
1763 continue;
1765 TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab );
1766 if(!talentTabInfo)
1767 continue;
1769 if( (classMask & talentTabInfo->ClassMask) == 0 )
1770 continue;
1772 // search highest talent rank
1773 uint32 spellid = 0;
1774 int rank = 4;
1775 for(; rank >= 0; --rank)
1777 if(talentInfo->RankID[rank]!=0)
1779 spellid = talentInfo->RankID[rank];
1780 break;
1784 if(!spellid) // ??? none spells in talent
1785 continue;
1787 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid);
1788 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
1789 continue;
1791 // learn highest rank of talent
1792 player->learnSpell(spellid);
1794 // and learn all non-talent spell ranks (recursive by tree)
1795 learnAllHighRanks(player,spellid);
1798 SendSysMessage(LANG_COMMAND_LEARN_CLASS_TALENTS);
1799 return true;
1802 bool ChatHandler::HandleLearnAllLangCommand(const char* /*args*/)
1804 // skipping UNIVERSAL language (0)
1805 for(int i = 1; i < LANGUAGES_COUNT; ++i)
1806 m_session->GetPlayer()->learnSpell(lang_description[i].spell_id);
1808 SendSysMessage(LANG_COMMAND_LEARN_ALL_LANG);
1809 return true;
1812 bool ChatHandler::HandleLearnAllDefaultCommand(const char* args)
1814 char* pName = strtok((char*)args, "");
1815 Player *player = NULL;
1816 if (pName)
1818 std::string name = pName;
1820 if(!normalizePlayerName(name))
1822 SendSysMessage(LANG_PLAYER_NOT_FOUND);
1823 SetSentErrorMessage(true);
1824 return false;
1827 player = objmgr.GetPlayer(name.c_str());
1829 else
1830 player = getSelectedPlayer();
1832 if(!player)
1834 SendSysMessage(LANG_NO_CHAR_SELECTED);
1835 SetSentErrorMessage(true);
1836 return false;
1839 player->learnDefaultSpells();
1840 player->learnQuestRewardedSpells();
1842 PSendSysMessage(LANG_COMMAND_LEARN_ALL_DEFAULT_AND_QUEST,player->GetName());
1843 return true;
1846 bool ChatHandler::HandleLearnCommand(const char* args)
1848 Player* targetPlayer = getSelectedPlayer();
1850 if(!targetPlayer)
1852 SendSysMessage(LANG_PLAYER_NOT_FOUND);
1853 SetSentErrorMessage(true);
1854 return false;
1857 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
1858 uint32 spell = extractSpellIdFromLink((char*)args);
1859 if(!spell || !sSpellStore.LookupEntry(spell))
1860 return false;
1862 if (targetPlayer->HasSpell(spell))
1864 if(targetPlayer == m_session->GetPlayer())
1865 SendSysMessage(LANG_YOU_KNOWN_SPELL);
1866 else
1867 PSendSysMessage(LANG_TARGET_KNOWN_SPELL,targetPlayer->GetName());
1868 SetSentErrorMessage(true);
1869 return false;
1872 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
1873 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
1875 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
1876 SetSentErrorMessage(true);
1877 return false;
1880 targetPlayer->learnSpell(spell);
1882 return true;
1885 bool ChatHandler::HandleAddItemCommand(const char* args)
1887 if (!*args)
1888 return false;
1890 uint32 itemId = 0;
1892 if(args[0]=='[') // [name] manual form
1894 char* citemName = citemName = strtok((char*)args, "]");
1896 if(citemName && citemName[0])
1898 std::string itemName = citemName+1;
1899 WorldDatabase.escape_string(itemName);
1900 QueryResult *result = WorldDatabase.PQuery("SELECT entry FROM item_template WHERE name = '%s'", itemName.c_str());
1901 if (!result)
1903 PSendSysMessage(LANG_COMMAND_COULDNOTFIND, citemName+1);
1904 SetSentErrorMessage(true);
1905 return false;
1907 itemId = result->Fetch()->GetUInt16();
1908 delete result;
1910 else
1911 return false;
1913 else // item_id or [name] Shift-click form |color|Hitem:item_id:0:0:0|h[name]|h|r
1915 char* cId = extractKeyFromLink((char*)args,"Hitem");
1916 if(!cId)
1917 return false;
1918 itemId = atol(cId);
1921 char* ccount = strtok(NULL, " ");
1923 int32 count = 1;
1925 if (ccount)
1926 count = strtol(ccount, NULL, 10);
1928 if (count == 0)
1929 count = 1;
1931 Player* pl = m_session->GetPlayer();
1932 Player* plTarget = getSelectedPlayer();
1933 if(!plTarget)
1934 plTarget = pl;
1936 sLog.outDetail(GetMangosString(LANG_ADDITEM), itemId, count);
1938 ItemPrototype const *pProto = objmgr.GetItemPrototype(itemId);
1939 if(!pProto)
1941 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId);
1942 SetSentErrorMessage(true);
1943 return false;
1946 //Subtract
1947 if (count < 0)
1949 plTarget->DestroyItemCount(itemId, -count, true, false);
1950 PSendSysMessage(LANG_REMOVEITEM, itemId, -count, plTarget->GetName());
1951 return true;
1954 //Adding items
1955 uint32 noSpaceForCount = 0;
1957 // check space and find places
1958 ItemPosCountVec dest;
1959 uint8 msg = plTarget->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, itemId, count, &noSpaceForCount );
1960 if( msg != EQUIP_ERR_OK ) // convert to possible store amount
1961 count -= noSpaceForCount;
1963 if( count == 0 || dest.empty()) // can't add any
1965 PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount );
1966 SetSentErrorMessage(true);
1967 return false;
1970 Item* item = plTarget->StoreNewItem( dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId));
1972 // remove binding (let GM give it to another player later)
1973 if(pl==plTarget)
1974 for(ItemPosCountVec::const_iterator itr = dest.begin(); itr != dest.end(); ++itr)
1975 if(Item* item1 = pl->GetItemByPos(itr->pos))
1976 item1->SetBinding( false );
1978 if(count > 0 && item)
1980 pl->SendNewItem(item,count,false,true);
1981 if(pl!=plTarget)
1982 plTarget->SendNewItem(item,count,true,false);
1985 if(noSpaceForCount > 0)
1986 PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount);
1988 return true;
1991 bool ChatHandler::HandleAddItemSetCommand(const char* args)
1993 if (!*args)
1994 return false;
1996 char* cId = extractKeyFromLink((char*)args,"Hitemset"); // number or [name] Shift-click form |color|Hitemset:itemset_id|h[name]|h|r
1997 if (!cId)
1998 return false;
2000 uint32 itemsetId = atol(cId);
2002 // prevent generation all items with itemset field value '0'
2003 if (itemsetId == 0)
2005 PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND,itemsetId);
2006 SetSentErrorMessage(true);
2007 return false;
2010 Player* pl = m_session->GetPlayer();
2011 Player* plTarget = getSelectedPlayer();
2012 if(!plTarget)
2013 plTarget = pl;
2015 sLog.outDetail(GetMangosString(LANG_ADDITEMSET), itemsetId);
2017 bool found = false;
2018 for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
2020 ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype>(id);
2021 if (!pProto)
2022 continue;
2024 if (pProto->ItemSet == itemsetId)
2026 found = true;
2027 ItemPosCountVec dest;
2028 uint8 msg = plTarget->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, pProto->ItemId, 1 );
2029 if (msg == EQUIP_ERR_OK)
2031 Item* item = plTarget->StoreNewItem( dest, pProto->ItemId, true);
2033 // remove binding (let GM give it to another player later)
2034 if (pl==plTarget)
2035 item->SetBinding( false );
2037 pl->SendNewItem(item,1,false,true);
2038 if (pl!=plTarget)
2039 plTarget->SendNewItem(item,1,true,false);
2041 else
2043 pl->SendEquipError( msg, NULL, NULL );
2044 PSendSysMessage(LANG_ITEM_CANNOT_CREATE, pProto->ItemId, 1);
2049 if (!found)
2051 PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND,itemsetId);
2053 SetSentErrorMessage(true);
2054 return false;
2057 return true;
2060 bool ChatHandler::HandleListItemCommand(const char* args)
2062 if(!*args)
2063 return false;
2065 char* cId = extractKeyFromLink((char*)args,"Hitem");
2066 if(!cId)
2067 return false;
2069 uint32 item_id = atol(cId);
2070 if(!item_id)
2072 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
2073 SetSentErrorMessage(true);
2074 return false;
2077 ItemPrototype const* itemProto = objmgr.GetItemPrototype(item_id);
2078 if(!itemProto)
2080 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
2081 SetSentErrorMessage(true);
2082 return false;
2085 char* c_count = strtok(NULL, " ");
2086 int count = c_count ? atol(c_count) : 10;
2088 if(count < 0)
2089 return false;
2091 QueryResult *result;
2093 // inventory case
2094 uint32 inv_count = 0;
2095 result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM character_inventory WHERE item_template='%u'",item_id);
2096 if(result)
2098 inv_count = (*result)[0].GetUInt32();
2099 delete result;
2102 result=CharacterDatabase.PQuery(
2103 // 0 1 2 3 4 5
2104 "SELECT ci.item, cibag.slot AS bag, ci.slot, ci.guid, characters.account,characters.name "
2105 "FROM character_inventory AS ci LEFT JOIN character_inventory AS cibag ON (cibag.item=ci.bag),characters "
2106 "WHERE ci.item_template='%u' AND ci.guid = characters.guid LIMIT %u ",
2107 item_id,uint32(count));
2109 if(result)
2113 Field *fields = result->Fetch();
2114 uint32 item_guid = fields[0].GetUInt32();
2115 uint32 item_bag = fields[1].GetUInt32();
2116 uint32 item_slot = fields[2].GetUInt32();
2117 uint32 owner_guid = fields[3].GetUInt32();
2118 uint32 owner_acc = fields[4].GetUInt32();
2119 std::string owner_name = fields[5].GetCppString();
2121 char const* item_pos = 0;
2122 if(Player::IsEquipmentPos(item_bag,item_slot))
2123 item_pos = "[equipped]";
2124 else if(Player::IsInventoryPos(item_bag,item_slot))
2125 item_pos = "[in inventory]";
2126 else if(Player::IsBankPos(item_bag,item_slot))
2127 item_pos = "[in bank]";
2128 else
2129 item_pos = "";
2131 PSendSysMessage(LANG_ITEMLIST_SLOT,
2132 item_guid,owner_name.c_str(),owner_guid,owner_acc,item_pos);
2133 } while (result->NextRow());
2135 int64 res_count = result->GetRowCount();
2137 delete result;
2139 if(count > res_count)
2140 count-=res_count;
2141 else if(count)
2142 count = 0;
2145 // mail case
2146 uint32 mail_count = 0;
2147 result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM mail_items WHERE item_template='%u'", item_id);
2148 if(result)
2150 mail_count = (*result)[0].GetUInt32();
2151 delete result;
2154 if(count > 0)
2156 result=CharacterDatabase.PQuery(
2157 // 0 1 2 3 4 5 6
2158 "SELECT mail_items.item_guid, mail.sender, mail.receiver, char_s.account, char_s.name, char_r.account, char_r.name "
2159 "FROM mail,mail_items,characters as char_s,characters as char_r "
2160 "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",
2161 item_id,uint32(count));
2163 else
2164 result = NULL;
2166 if(result)
2170 Field *fields = result->Fetch();
2171 uint32 item_guid = fields[0].GetUInt32();
2172 uint32 item_s = fields[1].GetUInt32();
2173 uint32 item_r = fields[2].GetUInt32();
2174 uint32 item_s_acc = fields[3].GetUInt32();
2175 std::string item_s_name = fields[4].GetCppString();
2176 uint32 item_r_acc = fields[5].GetUInt32();
2177 std::string item_r_name = fields[6].GetCppString();
2179 char const* item_pos = "[in mail]";
2181 PSendSysMessage(LANG_ITEMLIST_MAIL,
2182 item_guid,item_s_name.c_str(),item_s,item_s_acc,item_r_name.c_str(),item_r,item_r_acc,item_pos);
2183 } while (result->NextRow());
2185 int64 res_count = result->GetRowCount();
2187 delete result;
2189 if(count > res_count)
2190 count-=res_count;
2191 else if(count)
2192 count = 0;
2195 // auction case
2196 uint32 auc_count = 0;
2197 result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM auctionhouse WHERE item_template='%u'",item_id);
2198 if(result)
2200 auc_count = (*result)[0].GetUInt32();
2201 delete result;
2204 if(count > 0)
2206 result=CharacterDatabase.PQuery(
2207 // 0 1 2 3
2208 "SELECT auctionhouse.itemguid, auctionhouse.itemowner, characters.account, characters.name "
2209 "FROM auctionhouse,characters WHERE auctionhouse.item_template='%u' AND characters.guid = auctionhouse.itemowner LIMIT %u",
2210 item_id,uint32(count));
2212 else
2213 result = NULL;
2215 if(result)
2219 Field *fields = result->Fetch();
2220 uint32 item_guid = fields[0].GetUInt32();
2221 uint32 owner = fields[1].GetUInt32();
2222 uint32 owner_acc = fields[2].GetUInt32();
2223 std::string owner_name = fields[3].GetCppString();
2225 char const* item_pos = "[in auction]";
2227 PSendSysMessage(LANG_ITEMLIST_AUCTION, item_guid, owner_name.c_str(), owner, owner_acc,item_pos);
2228 } while (result->NextRow());
2230 delete result;
2233 // guild bank case
2234 uint32 guild_count = 0;
2235 result=CharacterDatabase.PQuery("SELECT COUNT(item_entry) FROM guild_bank_item WHERE item_entry='%u'",item_id);
2236 if(result)
2238 guild_count = (*result)[0].GetUInt32();
2239 delete result;
2242 result=CharacterDatabase.PQuery(
2243 // 0 1 2
2244 "SELECT gi.item_guid, gi.guildid, guild.name "
2245 "FROM guild_bank_item AS gi, guild WHERE gi.item_entry='%u' AND gi.guildid = guild.guildid LIMIT %u ",
2246 item_id,uint32(count));
2248 if(result)
2252 Field *fields = result->Fetch();
2253 uint32 item_guid = fields[0].GetUInt32();
2254 uint32 guild_guid = fields[1].GetUInt32();
2255 std::string guild_name = fields[2].GetCppString();
2257 char const* item_pos = "[in guild bank]";
2259 PSendSysMessage(LANG_ITEMLIST_GUILD,item_guid,guild_name.c_str(),guild_guid,item_pos);
2260 } while (result->NextRow());
2262 int64 res_count = result->GetRowCount();
2264 delete result;
2266 if(count > res_count)
2267 count-=res_count;
2268 else if(count)
2269 count = 0;
2272 if(inv_count+mail_count+auc_count+guild_count == 0)
2274 SendSysMessage(LANG_COMMAND_NOITEMFOUND);
2275 SetSentErrorMessage(true);
2276 return false;
2279 PSendSysMessage(LANG_COMMAND_LISTITEMMESSAGE,item_id,inv_count+mail_count+auc_count+guild_count,inv_count,mail_count,auc_count,guild_count);
2281 return true;
2284 bool ChatHandler::HandleListObjectCommand(const char* args)
2286 if(!*args)
2287 return false;
2289 // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r
2290 char* cId = extractKeyFromLink((char*)args,"Hgameobject_entry");
2291 if(!cId)
2292 return false;
2294 uint32 go_id = atol(cId);
2295 if(!go_id)
2297 PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id);
2298 SetSentErrorMessage(true);
2299 return false;
2302 GameObjectInfo const * gInfo = objmgr.GetGameObjectInfo(go_id);
2303 if(!gInfo)
2305 PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id);
2306 SetSentErrorMessage(true);
2307 return false;
2310 char* c_count = strtok(NULL, " ");
2311 int count = c_count ? atol(c_count) : 10;
2313 if(count < 0)
2314 return false;
2316 QueryResult *result;
2318 uint32 obj_count = 0;
2319 result=WorldDatabase.PQuery("SELECT COUNT(guid) FROM gameobject WHERE id='%u'",go_id);
2320 if(result)
2322 obj_count = (*result)[0].GetUInt32();
2323 delete result;
2326 if(m_session)
2328 Player* pl = m_session->GetPlayer();
2329 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",
2330 pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),go_id,uint32(count));
2332 else
2333 result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map FROM gameobject WHERE id = '%u' LIMIT %u",
2334 go_id,uint32(count));
2336 if (result)
2340 Field *fields = result->Fetch();
2341 uint32 guid = fields[0].GetUInt32();
2342 float x = fields[1].GetFloat();
2343 float y = fields[2].GetFloat();
2344 float z = fields[3].GetFloat();
2345 int mapid = fields[4].GetUInt16();
2347 if (m_session)
2348 PSendSysMessage(LANG_GO_LIST_CHAT, guid, guid, gInfo->name, x, y, z, mapid);
2349 else
2350 PSendSysMessage(LANG_GO_LIST_CONSOLE, guid, gInfo->name, x, y, z, mapid);
2351 } while (result->NextRow());
2353 delete result;
2356 PSendSysMessage(LANG_COMMAND_LISTOBJMESSAGE,go_id,obj_count);
2357 return true;
2360 bool ChatHandler::HandleNearObjectCommand(const char* args)
2362 float distance = (!*args) ? 10 : atol(args);
2363 uint32 count = 0;
2365 Player* pl = m_session->GetPlayer();
2366 QueryResult *result = WorldDatabase.PQuery("SELECT guid, id, position_x, position_y, position_z, map, "
2367 "(POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ "
2368 "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_",
2369 pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),
2370 pl->GetMapId(),pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),distance*distance);
2372 if (result)
2376 Field *fields = result->Fetch();
2377 uint32 guid = fields[0].GetUInt32();
2378 uint32 entry = fields[1].GetUInt32();
2379 float x = fields[2].GetFloat();
2380 float y = fields[3].GetFloat();
2381 float z = fields[4].GetFloat();
2382 int mapid = fields[5].GetUInt16();
2384 GameObjectInfo const * gInfo = objmgr.GetGameObjectInfo(entry);
2386 if(!gInfo)
2387 continue;
2389 PSendSysMessage(LANG_GO_LIST_CHAT, guid, guid, gInfo->name, x, y, z, mapid);
2391 ++count;
2392 } while (result->NextRow());
2394 delete result;
2397 PSendSysMessage(LANG_COMMAND_NEAROBJMESSAGE,distance,count);
2398 return true;
2401 bool ChatHandler::HandleListCreatureCommand(const char* args)
2403 if(!*args)
2404 return false;
2406 // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
2407 char* cId = extractKeyFromLink((char*)args,"Hcreature_entry");
2408 if(!cId)
2409 return false;
2411 uint32 cr_id = atol(cId);
2412 if(!cr_id)
2414 PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id);
2415 SetSentErrorMessage(true);
2416 return false;
2419 CreatureInfo const* cInfo = objmgr.GetCreatureTemplate(cr_id);
2420 if(!cInfo)
2422 PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id);
2423 SetSentErrorMessage(true);
2424 return false;
2427 char* c_count = strtok(NULL, " ");
2428 int count = c_count ? atol(c_count) : 10;
2430 if(count < 0)
2431 return false;
2433 QueryResult *result;
2435 uint32 cr_count = 0;
2436 result=WorldDatabase.PQuery("SELECT COUNT(guid) FROM creature WHERE id='%u'",cr_id);
2437 if(result)
2439 cr_count = (*result)[0].GetUInt32();
2440 delete result;
2443 if(m_session)
2445 Player* pl = m_session->GetPlayer();
2446 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",
2447 pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), cr_id,uint32(count));
2449 else
2450 result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map FROM creature WHERE id = '%u' LIMIT %u",
2451 cr_id,uint32(count));
2453 if (result)
2457 Field *fields = result->Fetch();
2458 uint32 guid = fields[0].GetUInt32();
2459 float x = fields[1].GetFloat();
2460 float y = fields[2].GetFloat();
2461 float z = fields[3].GetFloat();
2462 int mapid = fields[4].GetUInt16();
2464 if (m_session)
2465 PSendSysMessage(LANG_CREATURE_LIST_CHAT, guid, guid, cInfo->Name, x, y, z, mapid);
2466 else
2467 PSendSysMessage(LANG_CREATURE_LIST_CONSOLE, guid, cInfo->Name, x, y, z, mapid);
2468 } while (result->NextRow());
2470 delete result;
2473 PSendSysMessage(LANG_COMMAND_LISTCREATUREMESSAGE,cr_id,cr_count);
2474 return true;
2477 bool ChatHandler::HandleLookupItemCommand(const char* args)
2479 if(!*args)
2480 return false;
2482 std::string namepart = args;
2483 std::wstring wnamepart;
2485 // converting string that we try to find to lower case
2486 if(!Utf8toWStr(namepart,wnamepart))
2487 return false;
2489 wstrToLower(wnamepart);
2491 uint32 counter = 0;
2493 // Search in `item_template`
2494 for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
2496 ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype >(id);
2497 if(!pProto)
2498 continue;
2500 int loc_idx = m_session ? m_session->GetSessionDbLocaleIndex() : objmgr.GetDBCLocaleIndex();
2501 if ( loc_idx >= 0 )
2503 ItemLocale const *il = objmgr.GetItemLocale(pProto->ItemId);
2504 if (il)
2506 if (il->Name.size() > loc_idx && !il->Name[loc_idx].empty())
2508 std::string name = il->Name[loc_idx];
2510 if (Utf8FitTo(name, wnamepart))
2512 if (m_session)
2513 PSendSysMessage(LANG_ITEM_LIST_CHAT, id, id, name.c_str());
2514 else
2515 PSendSysMessage(LANG_ITEM_LIST_CONSOLE, id, name.c_str());
2516 ++counter;
2517 continue;
2523 std::string name = pProto->Name1;
2524 if(name.empty())
2525 continue;
2527 if (Utf8FitTo(name, wnamepart))
2529 if (m_session)
2530 PSendSysMessage(LANG_ITEM_LIST_CHAT, id, id, name.c_str());
2531 else
2532 PSendSysMessage(LANG_ITEM_LIST_CONSOLE, id, name.c_str());
2533 ++counter;
2537 if (counter==0)
2538 SendSysMessage(LANG_COMMAND_NOITEMFOUND);
2540 return true;
2543 bool ChatHandler::HandleLookupItemSetCommand(const char* args)
2545 if(!*args)
2546 return false;
2548 std::string namepart = args;
2549 std::wstring wnamepart;
2551 if(!Utf8toWStr(namepart,wnamepart))
2552 return false;
2554 // converting string that we try to find to lower case
2555 wstrToLower( wnamepart );
2557 uint32 counter = 0; // Counter for figure out that we found smth.
2559 // Search in ItemSet.dbc
2560 for (uint32 id = 0; id < sItemSetStore.GetNumRows(); id++)
2562 ItemSetEntry const *set = sItemSetStore.LookupEntry(id);
2563 if(set)
2565 int loc = m_session ? m_session->GetSessionDbcLocale() : sWorld.GetDefaultDbcLocale();
2566 std::string name = set->name[loc];
2567 if(name.empty())
2568 continue;
2570 if (!Utf8FitTo(name, wnamepart))
2572 loc = 0;
2573 for(; loc < MAX_LOCALE; ++loc)
2575 if(m_session && loc==m_session->GetSessionDbcLocale())
2576 continue;
2578 name = set->name[loc];
2579 if(name.empty())
2580 continue;
2582 if (Utf8FitTo(name, wnamepart))
2583 break;
2587 if(loc < MAX_LOCALE)
2589 // send item set in "id - [namedlink locale]" format
2590 if (m_session)
2591 PSendSysMessage(LANG_ITEMSET_LIST_CHAT,id,id,name.c_str(),localeNames[loc]);
2592 else
2593 PSendSysMessage(LANG_ITEMSET_LIST_CONSOLE,id,name.c_str(),localeNames[loc]);
2594 ++counter;
2598 if (counter == 0) // if counter == 0 then we found nth
2599 SendSysMessage(LANG_COMMAND_NOITEMSETFOUND);
2600 return true;
2603 bool ChatHandler::HandleLookupSkillCommand(const char* args)
2605 if(!*args)
2606 return false;
2608 // can be NULL in console call
2609 Player* target = getSelectedPlayer();
2611 std::string namepart = args;
2612 std::wstring wnamepart;
2614 if(!Utf8toWStr(namepart,wnamepart))
2615 return false;
2617 // converting string that we try to find to lower case
2618 wstrToLower( wnamepart );
2620 uint32 counter = 0; // Counter for figure out that we found smth.
2622 // Search in SkillLine.dbc
2623 for (uint32 id = 0; id < sSkillLineStore.GetNumRows(); id++)
2625 SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(id);
2626 if(skillInfo)
2628 int loc = m_session ? m_session->GetSessionDbcLocale() : sWorld.GetDefaultDbcLocale();
2629 std::string name = skillInfo->name[loc];
2630 if(name.empty())
2631 continue;
2633 if (!Utf8FitTo(name, wnamepart))
2635 loc = 0;
2636 for(; loc < MAX_LOCALE; ++loc)
2638 if(m_session && loc==m_session->GetSessionDbcLocale())
2639 continue;
2641 name = skillInfo->name[loc];
2642 if(name.empty())
2643 continue;
2645 if (Utf8FitTo(name, wnamepart))
2646 break;
2650 if(loc < MAX_LOCALE)
2652 char const* knownStr = "";
2653 if(target && target->HasSkill(id))
2654 knownStr = GetMangosString(LANG_KNOWN);
2656 // send skill in "id - [namedlink locale]" format
2657 if (m_session)
2658 PSendSysMessage(LANG_SKILL_LIST_CHAT,id,id,name.c_str(),localeNames[loc],knownStr);
2659 else
2660 PSendSysMessage(LANG_SKILL_LIST_CONSOLE,id,name.c_str(),localeNames[loc],knownStr);
2662 ++counter;
2666 if (counter == 0) // if counter == 0 then we found nth
2667 SendSysMessage(LANG_COMMAND_NOSKILLFOUND);
2668 return true;
2671 bool ChatHandler::HandleLookupSpellCommand(const char* args)
2673 if(!*args)
2674 return false;
2676 // can be NULL at console call
2677 Player* target = getSelectedPlayer();
2679 std::string namepart = args;
2680 std::wstring wnamepart;
2682 if(!Utf8toWStr(namepart,wnamepart))
2683 return false;
2685 // converting string that we try to find to lower case
2686 wstrToLower( wnamepart );
2688 uint32 counter = 0; // Counter for figure out that we found smth.
2690 // Search in Spell.dbc
2691 for (uint32 id = 0; id < sSpellStore.GetNumRows(); id++)
2693 SpellEntry const *spellInfo = sSpellStore.LookupEntry(id);
2694 if(spellInfo)
2696 int loc = m_session ? m_session->GetSessionDbcLocale() : sWorld.GetDefaultDbcLocale();
2697 std::string name = spellInfo->SpellName[loc];
2698 if(name.empty())
2699 continue;
2701 if (!Utf8FitTo(name, wnamepart))
2703 loc = 0;
2704 for(; loc < MAX_LOCALE; ++loc)
2706 if(m_session && loc==m_session->GetSessionDbcLocale())
2707 continue;
2709 name = spellInfo->SpellName[loc];
2710 if(name.empty())
2711 continue;
2713 if (Utf8FitTo(name, wnamepart))
2714 break;
2718 if(loc < MAX_LOCALE)
2720 bool known = target && target->HasSpell(id);
2721 bool learn = (spellInfo->Effect[0] == SPELL_EFFECT_LEARN_SPELL);
2723 uint32 talentCost = GetTalentSpellCost(id);
2725 bool talent = (talentCost > 0);
2726 bool passive = IsPassiveSpell(id);
2727 bool active = target && (target->HasAura(id,0) || target->HasAura(id,1) || target->HasAura(id,2));
2729 // unit32 used to prevent interpreting uint8 as char at output
2730 // find rank of learned spell for learning spell, or talent rank
2731 uint32 rank = talentCost ? talentCost : spellmgr.GetSpellRank(learn ? spellInfo->EffectTriggerSpell[0] : id);
2733 // send spell in "id - [name, rank N] [talent] [passive] [learn] [known]" format
2734 std::ostringstream ss;
2735 if (m_session)
2736 ss << id << " - |cffffffff|Hspell:" << id << "|h[" << name;
2737 else
2738 ss << id << " - " << name;
2740 // include rank in link name
2741 if(rank)
2742 ss << GetMangosString(LANG_SPELL_RANK) << rank;
2744 if (m_session)
2745 ss << " " << localeNames[loc] << "]|h|r";
2746 else
2747 ss << " " << localeNames[loc];
2749 if(talent)
2750 ss << GetMangosString(LANG_TALENT);
2751 if(passive)
2752 ss << GetMangosString(LANG_PASSIVE);
2753 if(learn)
2754 ss << GetMangosString(LANG_LEARN);
2755 if(known)
2756 ss << GetMangosString(LANG_KNOWN);
2757 if(active)
2758 ss << GetMangosString(LANG_ACTIVE);
2760 SendSysMessage(ss.str().c_str());
2762 ++counter;
2766 if (counter == 0) // if counter == 0 then we found nth
2767 SendSysMessage(LANG_COMMAND_NOSPELLFOUND);
2768 return true;
2771 bool ChatHandler::HandleLookupQuestCommand(const char* args)
2773 if(!*args)
2774 return false;
2776 // can be NULL at console call
2777 Player* target = getSelectedPlayer();
2779 std::string namepart = args;
2780 std::wstring wnamepart;
2782 // converting string that we try to find to lower case
2783 if(!Utf8toWStr(namepart,wnamepart))
2784 return false;
2786 wstrToLower(wnamepart);
2788 uint32 counter = 0 ;
2790 ObjectMgr::QuestMap const& qTemplates = objmgr.GetQuestTemplates();
2791 for (ObjectMgr::QuestMap::const_iterator iter = qTemplates.begin(); iter != qTemplates.end(); ++iter)
2793 Quest * qinfo = iter->second;
2795 int loc_idx = m_session ? m_session->GetSessionDbLocaleIndex() : objmgr.GetDBCLocaleIndex();
2796 if ( loc_idx >= 0 )
2798 QuestLocale const *il = objmgr.GetQuestLocale(qinfo->GetQuestId());
2799 if (il)
2801 if (il->Title.size() > loc_idx && !il->Title[loc_idx].empty())
2803 std::string title = il->Title[loc_idx];
2805 if (Utf8FitTo(title, wnamepart))
2807 char const* statusStr = "";
2809 if(target)
2811 QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId());
2813 if(status == QUEST_STATUS_COMPLETE)
2815 if(target->GetQuestRewardStatus(qinfo->GetQuestId()))
2816 statusStr = GetMangosString(LANG_COMMAND_QUEST_REWARDED);
2817 else
2818 statusStr = GetMangosString(LANG_COMMAND_QUEST_COMPLETE);
2820 else if(status == QUEST_STATUS_INCOMPLETE)
2821 statusStr = GetMangosString(LANG_COMMAND_QUEST_ACTIVE);
2824 if (m_session)
2825 PSendSysMessage(LANG_QUEST_LIST_CHAT,qinfo->GetQuestId(),qinfo->GetQuestId(),title.c_str(),statusStr);
2826 else
2827 PSendSysMessage(LANG_QUEST_LIST_CONSOLE,qinfo->GetQuestId(),title.c_str(),statusStr);
2828 ++counter;
2829 continue;
2835 std::string title = qinfo->GetTitle();
2836 if(title.empty())
2837 continue;
2839 if (Utf8FitTo(title, wnamepart))
2841 char const* statusStr = "";
2843 if(target)
2845 QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId());
2847 if(status == QUEST_STATUS_COMPLETE)
2849 if(target->GetQuestRewardStatus(qinfo->GetQuestId()))
2850 statusStr = GetMangosString(LANG_COMMAND_QUEST_REWARDED);
2851 else
2852 statusStr = GetMangosString(LANG_COMMAND_QUEST_COMPLETE);
2854 else if(status == QUEST_STATUS_INCOMPLETE)
2855 statusStr = GetMangosString(LANG_COMMAND_QUEST_ACTIVE);
2858 if (m_session)
2859 PSendSysMessage(LANG_QUEST_LIST_CHAT,qinfo->GetQuestId(),qinfo->GetQuestId(),title.c_str(),statusStr);
2860 else
2861 PSendSysMessage(LANG_QUEST_LIST_CONSOLE,qinfo->GetQuestId(),title.c_str(),statusStr);
2863 ++counter;
2867 if (counter==0)
2868 SendSysMessage(LANG_COMMAND_NOQUESTFOUND);
2870 return true;
2873 bool ChatHandler::HandleLookupCreatureCommand(const char* args)
2875 if (!*args)
2876 return false;
2878 std::string namepart = args;
2879 std::wstring wnamepart;
2881 // converting string that we try to find to lower case
2882 if (!Utf8toWStr (namepart,wnamepart))
2883 return false;
2885 wstrToLower (wnamepart);
2887 uint32 counter = 0;
2889 for (uint32 id = 0; id< sCreatureStorage.MaxEntry; ++id)
2891 CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo> (id);
2892 if(!cInfo)
2893 continue;
2895 int loc_idx = m_session ? m_session->GetSessionDbLocaleIndex() : objmgr.GetDBCLocaleIndex();
2896 if (loc_idx >= 0)
2898 CreatureLocale const *cl = objmgr.GetCreatureLocale (id);
2899 if (cl)
2901 if (cl->Name.size() > loc_idx && !cl->Name[loc_idx].empty ())
2903 std::string name = cl->Name[loc_idx];
2905 if (Utf8FitTo (name, wnamepart))
2907 if (m_session)
2908 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CHAT, id, id, name.c_str ());
2909 else
2910 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CONSOLE, id, name.c_str ());
2911 ++counter;
2912 continue;
2918 std::string name = cInfo->Name;
2919 if (name.empty ())
2920 continue;
2922 if (Utf8FitTo(name, wnamepart))
2924 if (m_session)
2925 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CHAT, id, id, name.c_str ());
2926 else
2927 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CONSOLE, id, name.c_str ());
2928 ++counter;
2932 if (counter==0)
2933 SendSysMessage (LANG_COMMAND_NOCREATUREFOUND);
2935 return true;
2938 bool ChatHandler::HandleLookupObjectCommand(const char* args)
2940 if(!*args)
2941 return false;
2943 std::string namepart = args;
2944 std::wstring wnamepart;
2946 // converting string that we try to find to lower case
2947 if(!Utf8toWStr(namepart,wnamepart))
2948 return false;
2950 wstrToLower(wnamepart);
2952 uint32 counter = 0;
2954 for (uint32 id = 0; id< sGOStorage.MaxEntry; id++ )
2956 GameObjectInfo const* gInfo = sGOStorage.LookupEntry<GameObjectInfo>(id);
2957 if(!gInfo)
2958 continue;
2960 int loc_idx = m_session ? m_session->GetSessionDbLocaleIndex() : objmgr.GetDBCLocaleIndex();
2961 if ( loc_idx >= 0 )
2963 GameObjectLocale const *gl = objmgr.GetGameObjectLocale(id);
2964 if (gl)
2966 if (gl->Name.size() > loc_idx && !gl->Name[loc_idx].empty())
2968 std::string name = gl->Name[loc_idx];
2970 if (Utf8FitTo(name, wnamepart))
2972 if (m_session)
2973 PSendSysMessage(LANG_GO_ENTRY_LIST_CHAT, id, id, name.c_str());
2974 else
2975 PSendSysMessage(LANG_GO_ENTRY_LIST_CONSOLE, id, name.c_str());
2976 ++counter;
2977 continue;
2983 std::string name = gInfo->name;
2984 if(name.empty())
2985 continue;
2987 if(Utf8FitTo(name, wnamepart))
2989 if (m_session)
2990 PSendSysMessage(LANG_GO_ENTRY_LIST_CHAT, id, id, name.c_str());
2991 else
2992 PSendSysMessage(LANG_GO_ENTRY_LIST_CONSOLE, id, name.c_str());
2993 ++counter;
2997 if(counter==0)
2998 SendSysMessage(LANG_COMMAND_NOGAMEOBJECTFOUND);
3000 return true;
3003 /** \brief GM command level 3 - Create a guild.
3005 * This command allows a GM (level 3) to create a guild.
3007 * The "args" parameter contains the name of the guild leader
3008 * and then the name of the guild.
3011 bool ChatHandler::HandleGuildCreateCommand(const char* args)
3014 if (!*args)
3015 return false;
3017 char *lname = strtok ((char*)args, " ");
3018 char *gname = strtok (NULL, "");
3020 if (!lname)
3021 return false;
3023 if (!gname)
3025 SendSysMessage (LANG_INSERT_GUILD_NAME);
3026 SetSentErrorMessage (true);
3027 return false;
3030 std::string guildname = gname;
3032 Player* player = ObjectAccessor::Instance ().FindPlayerByName (lname);
3033 if (!player)
3035 SendSysMessage (LANG_PLAYER_NOT_FOUND);
3036 SetSentErrorMessage (true);
3037 return false;
3040 if (player->GetGuildId())
3042 SendSysMessage (LANG_PLAYER_IN_GUILD);
3043 return true;
3046 Guild *guild = new Guild;
3047 if (!guild->create (player->GetGUID (),guildname))
3049 delete guild;
3050 SendSysMessage (LANG_GUILD_NOT_CREATED);
3051 SetSentErrorMessage (true);
3052 return false;
3055 objmgr.AddGuild (guild);
3056 return true;
3059 bool ChatHandler::HandleGuildInviteCommand(const char *args)
3061 if (!*args)
3062 return false;
3064 char* par1 = strtok ((char*)args, " ");
3065 char* par2 = strtok (NULL, "");
3066 if(!par1 || !par2)
3067 return false;
3069 std::string glName = par2;
3070 Guild* targetGuild = objmgr.GetGuildByName (glName);
3071 if (!targetGuild)
3072 return false;
3074 std::string plName = par1;
3075 if (!normalizePlayerName (plName))
3077 SendSysMessage (LANG_PLAYER_NOT_FOUND);
3078 SetSentErrorMessage (true);
3079 return false;
3082 uint64 plGuid = 0;
3083 if (Player* targetPlayer = ObjectAccessor::Instance ().FindPlayerByName (plName.c_str ()))
3084 plGuid = targetPlayer->GetGUID ();
3085 else
3086 plGuid = objmgr.GetPlayerGUIDByName (plName.c_str ());
3088 if (!plGuid)
3089 false;
3091 // player's guild membership checked in AddMember before add
3092 if (!targetGuild->AddMember (plGuid,targetGuild->GetLowestRank ()))
3093 return false;
3095 return true;
3098 bool ChatHandler::HandleGuildUninviteCommand(const char *args)
3100 if (!*args)
3101 return false;
3103 char* par1 = strtok ((char*)args, " ");
3104 if(!par1)
3105 return false;
3107 std::string plName = par1;
3108 if (!normalizePlayerName (plName))
3110 SendSysMessage (LANG_PLAYER_NOT_FOUND);
3111 SetSentErrorMessage (true);
3112 return false;
3115 uint64 plGuid = 0;
3116 uint32 glId = 0;
3117 if (Player* targetPlayer = ObjectAccessor::Instance ().FindPlayerByName (plName.c_str ()))
3119 plGuid = targetPlayer->GetGUID ();
3120 glId = targetPlayer->GetGuildId ();
3122 else
3124 plGuid = objmgr.GetPlayerGUIDByName (plName.c_str ());
3125 glId = Player::GetGuildIdFromDB (plGuid);
3128 if (!plGuid || !glId)
3129 return false;
3131 Guild* targetGuild = objmgr.GetGuildById (glId);
3132 if (!targetGuild)
3133 return false;
3135 targetGuild->DelMember (plGuid);
3137 return true;
3140 bool ChatHandler::HandleGuildRankCommand(const char *args)
3142 if (!*args)
3143 return false;
3145 char* par1 = strtok ((char*)args, " ");
3146 char* par2 = strtok (NULL, " ");
3147 if (!par1 || !par2)
3148 return false;
3149 std::string plName = par1;
3150 if (!normalizePlayerName (plName))
3152 SendSysMessage (LANG_PLAYER_NOT_FOUND);
3153 SetSentErrorMessage (true);
3154 return false;
3157 uint64 plGuid = 0;
3158 uint32 glId = 0;
3159 if (Player* targetPlayer = ObjectAccessor::Instance ().FindPlayerByName (plName.c_str ()))
3161 plGuid = targetPlayer->GetGUID ();
3162 glId = targetPlayer->GetGuildId ();
3164 else
3166 plGuid = objmgr.GetPlayerGUIDByName (plName.c_str ());
3167 glId = Player::GetGuildIdFromDB (plGuid);
3170 if (!plGuid || !glId)
3171 return false;
3173 Guild* targetGuild = objmgr.GetGuildById (glId);
3174 if (!targetGuild)
3175 return false;
3177 uint32 newrank = uint32 (atoi (par2));
3178 if (newrank > targetGuild->GetLowestRank ())
3179 return false;
3181 targetGuild->ChangeRank (plGuid,newrank);
3183 return true;
3186 bool ChatHandler::HandleGuildDeleteCommand(const char* args)
3188 if (!*args)
3189 return false;
3191 char* par1 = strtok ((char*)args, " ");
3192 if (!par1)
3193 return false;
3195 std::string gld = par1;
3197 Guild* targetGuild = objmgr.GetGuildByName (gld);
3198 if (!targetGuild)
3199 return false;
3201 targetGuild->Disband ();
3203 return true;
3206 bool ChatHandler::HandleGetDistanceCommand(const char* /*args*/)
3208 Unit* pUnit = getSelectedUnit();
3210 if(!pUnit)
3212 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3213 SetSentErrorMessage(true);
3214 return false;
3217 PSendSysMessage(LANG_DISTANCE, m_session->GetPlayer()->GetDistance(pUnit),m_session->GetPlayer()->GetDistance2d(pUnit));
3219 return true;
3222 // FIX-ME!!!
3224 bool ChatHandler::HandleAddWeaponCommand(const char* /*args*/)
3226 /*if (!*args)
3227 return false;
3229 uint64 guid = m_session->GetPlayer()->GetSelection();
3230 if (guid == 0)
3232 SendSysMessage(LANG_NO_SELECTION);
3233 return true;
3236 Creature *pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
3238 if(!pCreature)
3240 SendSysMessage(LANG_SELECT_CREATURE);
3241 return true;
3244 char* pSlotID = strtok((char*)args, " ");
3245 if (!pSlotID)
3246 return false;
3248 char* pItemID = strtok(NULL, " ");
3249 if (!pItemID)
3250 return false;
3252 uint32 ItemID = atoi(pItemID);
3253 uint32 SlotID = atoi(pSlotID);
3255 ItemPrototype* tmpItem = objmgr.GetItemPrototype(ItemID);
3257 bool added = false;
3258 if(tmpItem)
3260 switch(SlotID)
3262 case 1:
3263 pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, ItemID);
3264 added = true;
3265 break;
3266 case 2:
3267 pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_01, ItemID);
3268 added = true;
3269 break;
3270 case 3:
3271 pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_02, ItemID);
3272 added = true;
3273 break;
3274 default:
3275 PSendSysMessage(LANG_ITEM_SLOT_NOT_EXIST,SlotID);
3276 added = false;
3277 break;
3279 if(added)
3281 PSendSysMessage(LANG_ITEM_ADDED_TO_SLOT,ItemID,tmpItem->Name1,SlotID);
3284 else
3286 PSendSysMessage(LANG_ITEM_NOT_FOUND,ItemID);
3287 return true;
3290 return true;
3293 bool ChatHandler::HandleDieCommand(const char* /*args*/)
3295 Unit* target = getSelectedUnit();
3297 if(!target || !m_session->GetPlayer()->GetSelection())
3299 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3300 SetSentErrorMessage(true);
3301 return false;
3304 if( target->isAlive() )
3306 m_session->GetPlayer()->DealDamage(target, target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
3309 return true;
3312 bool ChatHandler::HandleDamageCommand(const char * args)
3314 if (!*args)
3315 return false;
3317 Unit* target = getSelectedUnit();
3319 if(!target || !m_session->GetPlayer()->GetSelection())
3321 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3322 SetSentErrorMessage(true);
3323 return false;
3326 if( !target->isAlive() )
3327 return true;
3329 char* damageStr = strtok((char*)args, " ");
3330 if(!damageStr)
3331 return false;
3333 int32 damage = atoi((char*)damageStr);
3334 if(damage <=0)
3335 return true;
3337 char* schoolStr = strtok((char*)NULL, " ");
3339 // flat melee damage without resistence/etc reduction
3340 if(!schoolStr)
3342 m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
3343 m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, SPELL_SCHOOL_MASK_NORMAL, damage, 0, 0, VICTIMSTATE_NORMAL, 0);
3344 return true;
3347 uint32 school = schoolStr ? atoi((char*)schoolStr) : SPELL_SCHOOL_NORMAL;
3348 if(school >= MAX_SPELL_SCHOOL)
3349 return false;
3351 SpellSchoolMask schoolmask = SpellSchoolMask(1 << school);
3353 if ( schoolmask & SPELL_SCHOOL_MASK_NORMAL )
3354 damage = m_session->GetPlayer()->CalcArmorReducedDamage(target, damage);
3356 char* spellStr = strtok((char*)NULL, " ");
3358 // melee damage by specific school
3359 if(!spellStr)
3361 uint32 absorb = 0;
3362 uint32 resist = 0;
3364 m_session->GetPlayer()->CalcAbsorbResist(target,schoolmask, SPELL_DIRECT_DAMAGE, damage, &absorb, &resist);
3366 if (damage <= absorb + resist)
3367 return true;
3369 damage -= absorb + resist;
3371 m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, schoolmask, NULL, false);
3372 m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, schoolmask, damage, absorb, resist, VICTIMSTATE_NORMAL, 0);
3373 return true;
3376 // non-melee damage
3378 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
3379 uint32 spellid = extractSpellIdFromLink((char*)args);
3380 if(!spellid || !sSpellStore.LookupEntry(spellid))
3381 return false;
3383 m_session->GetPlayer()->SpellNonMeleeDamageLog(target, spellid, damage, false);
3384 return true;
3387 bool ChatHandler::HandleModifyArenaCommand(const char * args)
3389 if (!*args)
3390 return false;
3392 Player *target = getSelectedPlayer();
3393 if(!target)
3395 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3396 SetSentErrorMessage(true);
3397 return false;
3400 int32 amount = (uint32)atoi(args);
3402 target->ModifyArenaPoints(amount);
3404 PSendSysMessage(LANG_COMMAND_MODIFY_ARENA, target->GetName(), target->GetArenaPoints());
3406 return true;
3409 bool ChatHandler::HandleReviveCommand(const char* args)
3411 Player* SelectedPlayer = NULL;
3413 if (*args)
3415 std::string name = args;
3416 if(!normalizePlayerName(name))
3418 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3419 SetSentErrorMessage(true);
3420 return false;
3423 SelectedPlayer = objmgr.GetPlayer(name.c_str());
3425 else
3426 SelectedPlayer = getSelectedPlayer();
3428 if(!SelectedPlayer)
3430 SendSysMessage(LANG_NO_CHAR_SELECTED);
3431 SetSentErrorMessage(true);
3432 return false;
3435 SelectedPlayer->ResurrectPlayer(0.5f);
3436 SelectedPlayer->SpawnCorpseBones();
3437 SelectedPlayer->SaveToDB();
3438 return true;
3441 bool ChatHandler::HandleAuraCommand(const char* args)
3443 char* px = strtok((char*)args, " ");
3444 if (!px)
3445 return false;
3447 Unit *target = getSelectedUnit();
3448 if(!target)
3450 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3451 SetSentErrorMessage(true);
3452 return false;
3455 uint32 spellID = (uint32)atoi(px);
3456 SpellEntry const *spellInfo = sSpellStore.LookupEntry( spellID );
3457 if(spellInfo)
3459 for(uint32 i = 0;i<3;i++)
3461 uint8 eff = spellInfo->Effect[i];
3462 if (eff>=TOTAL_SPELL_EFFECTS)
3463 continue;
3464 if( IsAreaAuraEffect(eff) ||
3465 eff == SPELL_EFFECT_APPLY_AURA ||
3466 eff == SPELL_EFFECT_PERSISTENT_AREA_AURA )
3468 Aura *Aur = CreateAura(spellInfo, i, NULL, target);
3469 target->AddAura(Aur);
3474 return true;
3477 bool ChatHandler::HandleUnAuraCommand(const char* args)
3479 char* px = strtok((char*)args, " ");
3480 if (!px)
3481 return false;
3483 Unit *target = getSelectedUnit();
3484 if(!target)
3486 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3487 SetSentErrorMessage(true);
3488 return false;
3491 std::string argstr = args;
3492 if (argstr == "all")
3494 target->RemoveAllAuras();
3495 return true;
3498 uint32 spellID = (uint32)atoi(px);
3499 target->RemoveAurasDueToSpell(spellID);
3501 return true;
3504 bool ChatHandler::HandleLinkGraveCommand(const char* args)
3506 if(!*args)
3507 return false;
3509 char* px = strtok((char*)args, " ");
3510 if (!px)
3511 return false;
3513 uint32 g_id = (uint32)atoi(px);
3515 uint32 g_team;
3517 char* px2 = strtok(NULL, " ");
3519 if (!px2)
3520 g_team = 0;
3521 else if (strncmp(px2,"horde",6)==0)
3522 g_team = HORDE;
3523 else if (strncmp(px2,"alliance",9)==0)
3524 g_team = ALLIANCE;
3525 else
3526 return false;
3528 WorldSafeLocsEntry const* graveyard = sWorldSafeLocsStore.LookupEntry(g_id);
3530 if(!graveyard )
3532 PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST, g_id);
3533 SetSentErrorMessage(true);
3534 return false;
3537 Player* player = m_session->GetPlayer();
3539 uint32 zoneId = player->GetZoneId();
3541 AreaTableEntry const *areaEntry = GetAreaEntryByAreaID(zoneId);
3542 if(!areaEntry || areaEntry->zone !=0 )
3544 PSendSysMessage(LANG_COMMAND_GRAVEYARDWRONGZONE, g_id,zoneId);
3545 SetSentErrorMessage(true);
3546 return false;
3549 if(objmgr.AddGraveYardLink(g_id,player->GetZoneId(),g_team))
3550 PSendSysMessage(LANG_COMMAND_GRAVEYARDLINKED, g_id,zoneId);
3551 else
3552 PSendSysMessage(LANG_COMMAND_GRAVEYARDALRLINKED, g_id,zoneId);
3554 return true;
3557 bool ChatHandler::HandleNearGraveCommand(const char* args)
3559 uint32 g_team;
3561 size_t argslen = strlen(args);
3563 if(!*args)
3564 g_team = 0;
3565 else if (strncmp((char*)args,"horde",argslen)==0)
3566 g_team = HORDE;
3567 else if (strncmp((char*)args,"alliance",argslen)==0)
3568 g_team = ALLIANCE;
3569 else
3570 return false;
3572 Player* player = m_session->GetPlayer();
3574 WorldSafeLocsEntry const* graveyard = objmgr.GetClosestGraveYard(
3575 player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(),player->GetMapId(),g_team);
3577 if(graveyard)
3579 uint32 g_id = graveyard->ID;
3581 GraveYardData const* data = objmgr.FindGraveYardData(g_id,player->GetZoneId());
3582 if (!data)
3584 PSendSysMessage(LANG_COMMAND_GRAVEYARDERROR,g_id);
3585 SetSentErrorMessage(true);
3586 return false;
3589 g_team = data->team;
3591 std::string team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_NOTEAM);
3593 if(g_team == 0)
3594 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ANY);
3595 else if(g_team == HORDE)
3596 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_HORDE);
3597 else if(g_team == ALLIANCE)
3598 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ALLIANCE);
3600 PSendSysMessage(LANG_COMMAND_GRAVEYARDNEAREST, g_id,team_name.c_str(),player->GetZoneId());
3602 else
3604 std::string team_name;
3606 if(g_team == 0)
3607 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ANY);
3608 else if(g_team == HORDE)
3609 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_HORDE);
3610 else if(g_team == ALLIANCE)
3611 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ALLIANCE);
3613 if(g_team == ~uint32(0))
3614 PSendSysMessage(LANG_COMMAND_ZONENOGRAVEYARDS, player->GetZoneId());
3615 else
3616 PSendSysMessage(LANG_COMMAND_ZONENOGRAFACTION, player->GetZoneId(),team_name.c_str());
3619 return true;
3622 //play npc emote
3623 bool ChatHandler::HandleNpcPlayEmoteCommand(const char* args)
3625 uint32 emote = atoi((char*)args);
3627 Creature* target = getSelectedCreature();
3628 if(!target)
3630 SendSysMessage(LANG_SELECT_CREATURE);
3631 SetSentErrorMessage(true);
3632 return false;
3635 target->SetUInt32Value(UNIT_NPC_EMOTESTATE,emote);
3637 return true;
3640 bool ChatHandler::HandleNpcInfoCommand(const char* /*args*/)
3642 Creature* target = getSelectedCreature();
3644 if(!target)
3646 SendSysMessage(LANG_SELECT_CREATURE);
3647 SetSentErrorMessage(true);
3648 return false;
3651 uint32 faction = target->getFaction();
3652 uint32 npcflags = target->GetUInt32Value(UNIT_NPC_FLAGS);
3653 uint32 displayid = target->GetDisplayId();
3654 uint32 nativeid = target->GetNativeDisplayId();
3655 uint32 Entry = target->GetEntry();
3656 CreatureInfo const* cInfo = target->GetCreatureInfo();
3658 int32 curRespawnDelay = target->GetRespawnTimeEx()-time(NULL);
3659 if(curRespawnDelay < 0)
3660 curRespawnDelay = 0;
3661 std::string curRespawnDelayStr = secsToTimeString(curRespawnDelay,true);
3662 std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(),true);
3664 PSendSysMessage(LANG_NPCINFO_CHAR, target->GetDBTableGUIDLow(), faction, npcflags, Entry, displayid, nativeid);
3665 PSendSysMessage(LANG_NPCINFO_LEVEL, target->getLevel());
3666 PSendSysMessage(LANG_NPCINFO_HEALTH,target->GetCreateHealth(), target->GetMaxHealth(), target->GetHealth());
3667 PSendSysMessage(LANG_NPCINFO_FLAGS, target->GetUInt32Value(UNIT_FIELD_FLAGS), target->GetUInt32Value(UNIT_DYNAMIC_FLAGS), target->getFaction());
3668 PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES, defRespawnDelayStr.c_str(),curRespawnDelayStr.c_str());
3669 PSendSysMessage(LANG_NPCINFO_LOOT, cInfo->lootid,cInfo->pickpocketLootId,cInfo->SkinLootId);
3670 PSendSysMessage(LANG_NPCINFO_DUNGEON_ID, target->GetInstanceId());
3671 PSendSysMessage(LANG_NPCINFO_POSITION,float(target->GetPositionX()), float(target->GetPositionY()), float(target->GetPositionZ()));
3673 if ((npcflags & UNIT_NPC_FLAG_VENDOR) )
3675 SendSysMessage(LANG_NPCINFO_VENDOR);
3677 if ((npcflags & UNIT_NPC_FLAG_TRAINER) )
3679 SendSysMessage(LANG_NPCINFO_TRAINER);
3682 return true;
3685 bool ChatHandler::HandleExploreCheatCommand(const char* args)
3687 if (!*args)
3688 return false;
3690 int flag = atoi((char*)args);
3692 Player *chr = getSelectedPlayer();
3693 if (chr == NULL)
3695 SendSysMessage(LANG_NO_CHAR_SELECTED);
3696 SetSentErrorMessage(true);
3697 return false;
3700 if (flag != 0)
3702 PSendSysMessage(LANG_YOU_SET_EXPLORE_ALL, chr->GetName());
3703 if (needReportToTarget(chr))
3704 ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_ALL,GetName());
3706 else
3708 PSendSysMessage(LANG_YOU_SET_EXPLORE_NOTHING, chr->GetName());
3709 if (needReportToTarget(chr))
3710 ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_NOTHING,GetName());
3713 for (uint8 i=0; i<128; i++)
3715 if (flag != 0)
3717 m_session->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i,0xFFFFFFFF);
3719 else
3721 m_session->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i,0);
3725 return true;
3728 bool ChatHandler::HandleHoverCommand(const char* args)
3730 char* px = strtok((char*)args, " ");
3731 uint32 flag;
3732 if (!px)
3733 flag = 1;
3734 else
3735 flag = atoi(px);
3737 m_session->GetPlayer()->SetHover(flag);
3739 if (flag)
3740 SendSysMessage(LANG_HOVER_ENABLED);
3741 else
3742 SendSysMessage(LANG_HOVER_DISABLED);
3744 return true;
3747 bool ChatHandler::HandleLevelUpCommand(const char* args)
3749 char* px = strtok((char*)args, " ");
3750 char* py = strtok((char*)NULL, " ");
3752 // command format parsing
3753 char* pname = (char*)NULL;
3754 int addlevel = 1;
3756 if(px && py) // .levelup name level
3758 addlevel = atoi(py);
3759 pname = px;
3761 else if(px && !py) // .levelup name OR .levelup level
3763 if(isalpha(px[0])) // .levelup name
3764 pname = px;
3765 else // .levelup level
3766 addlevel = atoi(px);
3768 // else .levelup - nothing do for preparing
3770 // player
3771 Player *chr = NULL;
3772 uint64 chr_guid = 0;
3774 std::string name;
3776 if(pname) // player by name
3778 name = pname;
3779 if(!normalizePlayerName(name))
3781 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3782 SetSentErrorMessage(true);
3783 return false;
3786 chr = objmgr.GetPlayer(name.c_str());
3787 if(!chr) // not in game
3789 chr_guid = objmgr.GetPlayerGUIDByName(name);
3790 if (chr_guid == 0)
3792 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3793 SetSentErrorMessage(true);
3794 return false;
3798 else // player by selection
3800 chr = getSelectedPlayer();
3802 if (chr == NULL)
3804 SendSysMessage(LANG_NO_CHAR_SELECTED);
3805 SetSentErrorMessage(true);
3806 return false;
3809 name = chr->GetName();
3812 assert(chr || chr_guid);
3814 int32 oldlevel = chr ? chr->getLevel() : Player::GetUInt32ValueFromDB(UNIT_FIELD_LEVEL,chr_guid);
3815 int32 newlevel = oldlevel + addlevel;
3816 if(newlevel < 1)
3817 newlevel = 1;
3818 if(newlevel > STRONG_MAX_LEVEL) // hardcoded maximum level
3819 newlevel = STRONG_MAX_LEVEL;
3821 if(chr)
3823 chr->GiveLevel(newlevel);
3824 chr->InitTalentForLevel();
3825 chr->SetUInt32Value(PLAYER_XP,0);
3827 if(oldlevel == newlevel)
3828 ChatHandler(chr).SendSysMessage(LANG_YOURS_LEVEL_PROGRESS_RESET);
3829 else
3830 if(oldlevel < newlevel)
3831 ChatHandler(chr).PSendSysMessage(LANG_YOURS_LEVEL_UP,newlevel-oldlevel);
3832 else
3833 if(oldlevel > newlevel)
3834 ChatHandler(chr).PSendSysMessage(LANG_YOURS_LEVEL_DOWN,newlevel-oldlevel);
3836 else
3838 // update level and XP at level, all other will be updated at loading
3839 Tokens values;
3840 Player::LoadValuesArrayFromDB(values,chr_guid);
3841 Player::SetUInt32ValueInArray(values,UNIT_FIELD_LEVEL,newlevel);
3842 Player::SetUInt32ValueInArray(values,PLAYER_XP,0);
3843 Player::SaveValuesArrayInDB(values,chr_guid);
3846 if(m_session->GetPlayer() != chr) // including chr==NULL
3847 PSendSysMessage(LANG_YOU_CHANGE_LVL,name.c_str(),newlevel);
3848 return true;
3851 bool ChatHandler::HandleShowAreaCommand(const char* args)
3853 if (!*args)
3854 return false;
3856 int area = atoi((char*)args);
3858 Player *chr = getSelectedPlayer();
3859 if (chr == NULL)
3861 SendSysMessage(LANG_NO_CHAR_SELECTED);
3862 SetSentErrorMessage(true);
3863 return false;
3866 int offset = area / 32;
3867 uint32 val = (uint32)(1 << (area % 32));
3869 if(offset >= 128)
3871 SendSysMessage(LANG_BAD_VALUE);
3872 SetSentErrorMessage(true);
3873 return false;
3876 uint32 currFields = chr->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset);
3877 chr->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields | val));
3879 SendSysMessage(LANG_EXPLORE_AREA);
3880 return true;
3883 bool ChatHandler::HandleHideAreaCommand(const char* args)
3885 if (!*args)
3886 return false;
3888 int area = atoi((char*)args);
3890 Player *chr = getSelectedPlayer();
3891 if (chr == NULL)
3893 SendSysMessage(LANG_NO_CHAR_SELECTED);
3894 SetSentErrorMessage(true);
3895 return false;
3898 int offset = area / 32;
3899 uint32 val = (uint32)(1 << (area % 32));
3901 if(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)
4414 pet->InitStatsForLevel(1);
4416 return true;
4419 bool ChatHandler::HandleResetStatsCommand(const char * args)
4421 char* pName = strtok((char*)args, "");
4422 Player *player = NULL;
4423 if (pName)
4425 std::string name = pName;
4426 if(!normalizePlayerName(name))
4428 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4429 SetSentErrorMessage(true);
4430 return false;
4433 uint64 guid = objmgr.GetPlayerGUIDByName(name.c_str());
4434 player = objmgr.GetPlayer(guid);
4436 else
4437 player = getSelectedPlayer();
4439 if(!player)
4441 SendSysMessage(LANG_NO_CHAR_SELECTED);
4442 SetSentErrorMessage(true);
4443 return false;
4446 if(!HandleResetStatsOrLevelHelper(player))
4447 return false;
4449 player->InitStatsForLevel(true);
4450 player->InitTaxiNodesForLevel();
4451 player->InitGlyphsForLevel();
4452 player->InitTalentForLevel();
4454 return true;
4457 bool ChatHandler::HandleResetSpellsCommand(const char * args)
4459 char* pName = strtok((char*)args, "");
4460 Player *player = NULL;
4461 uint64 playerGUID = 0;
4462 if (pName)
4464 std::string name = pName;
4466 if(!normalizePlayerName(name))
4468 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4469 SetSentErrorMessage(true);
4470 return false;
4473 player = objmgr.GetPlayer(name.c_str());
4474 if(!player)
4475 playerGUID = objmgr.GetPlayerGUIDByName(name.c_str());
4477 else
4478 player = getSelectedPlayer();
4480 if(!player && !playerGUID)
4482 SendSysMessage(LANG_NO_CHAR_SELECTED);
4483 SetSentErrorMessage(true);
4484 return false;
4487 if(player)
4489 player->resetSpells();
4491 ChatHandler(player).SendSysMessage(LANG_RESET_SPELLS);
4493 if(m_session->GetPlayer()!=player)
4494 PSendSysMessage(LANG_RESET_SPELLS_ONLINE,player->GetName());
4496 else
4498 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",uint32(AT_LOGIN_RESET_SPELLS), GUID_LOPART(playerGUID));
4499 PSendSysMessage(LANG_RESET_SPELLS_OFFLINE,pName);
4502 return true;
4505 bool ChatHandler::HandleResetTalentsCommand(const char * args)
4507 char* pName = strtok((char*)args, "");
4508 Player *player = NULL;
4509 uint64 playerGUID = 0;
4510 if (pName)
4512 std::string name = pName;
4513 if(!normalizePlayerName(name))
4515 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4516 SetSentErrorMessage(true);
4517 return false;
4520 player = objmgr.GetPlayer(name.c_str());
4521 if(!player)
4522 playerGUID = objmgr.GetPlayerGUIDByName(name.c_str());
4524 else
4525 player = getSelectedPlayer();
4527 if(!player && !playerGUID)
4529 SendSysMessage(LANG_NO_CHAR_SELECTED);
4530 SetSentErrorMessage(true);
4531 return false;
4534 if(player)
4536 player->resetTalents(true);
4538 ChatHandler(player).SendSysMessage(LANG_RESET_TALENTS);
4540 if(m_session->GetPlayer()!=player)
4541 PSendSysMessage(LANG_RESET_TALENTS_ONLINE,player->GetName());
4543 else
4545 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",uint32(AT_LOGIN_RESET_TALENTS), GUID_LOPART(playerGUID) );
4546 PSendSysMessage(LANG_RESET_TALENTS_OFFLINE,pName);
4549 return true;
4552 bool ChatHandler::HandleResetAllCommand(const char * args)
4554 if(!*args)
4555 return false;
4557 std::string casename = args;
4559 AtLoginFlags atLogin;
4561 // Command specially created as single command to prevent using short case names
4562 if(casename=="spells")
4564 atLogin = AT_LOGIN_RESET_SPELLS;
4565 sWorld.SendWorldText(LANG_RESETALL_SPELLS);
4567 else if(casename=="talents")
4569 atLogin = AT_LOGIN_RESET_TALENTS;
4570 sWorld.SendWorldText(LANG_RESETALL_TALENTS);
4572 else
4574 PSendSysMessage(LANG_RESETALL_UNKNOWN_CASE,args);
4575 SetSentErrorMessage(true);
4576 return false;
4579 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE (at_login & '%u') = '0'",atLogin,atLogin);
4580 HashMapHolder<Player>::MapType const& plist = ObjectAccessor::Instance().GetPlayers();
4581 for(HashMapHolder<Player>::MapType::const_iterator itr = plist.begin(); itr != plist.end(); ++itr)
4582 itr->second->SetAtLoginFlag(atLogin);
4584 return true;
4587 bool ChatHandler::HandleServerShutDownCancelCommand(const char* args)
4589 sWorld.ShutdownCancel();
4590 return true;
4593 bool ChatHandler::HandleServerShutDownCommand(const char* args)
4595 if(!*args)
4596 return false;
4598 char* time_str = strtok ((char*) args, " ");
4599 char* exitcode_str = strtok (NULL, "");
4601 int32 time = atoi (time_str);
4603 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4604 if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0)
4605 return false;
4607 if (exitcode_str)
4609 int32 exitcode = atoi (exitcode_str);
4611 // Handle atoi() errors
4612 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4613 return false;
4615 // Exit code should be in range of 0-125, 126-255 is used
4616 // in many shells for their own return codes and code > 255
4617 // is not supported in many others
4618 if (exitcode < 0 || exitcode > 125)
4619 return false;
4621 sWorld.ShutdownServ (time, 0, exitcode);
4623 else
4624 sWorld.ShutdownServ(time,0,SHUTDOWN_EXIT_CODE);
4625 return true;
4628 bool ChatHandler::HandleServerRestartCommand(const char* args)
4630 if(!*args)
4631 return false;
4633 char* time_str = strtok ((char*) args, " ");
4634 char* exitcode_str = strtok (NULL, "");
4636 int32 time = atoi (time_str);
4638 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4639 if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0)
4640 return false;
4642 if (exitcode_str)
4644 int32 exitcode = atoi (exitcode_str);
4646 // Handle atoi() errors
4647 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4648 return false;
4650 // Exit code should be in range of 0-125, 126-255 is used
4651 // in many shells for their own return codes and code > 255
4652 // is not supported in many others
4653 if (exitcode < 0 || exitcode > 125)
4654 return false;
4656 sWorld.ShutdownServ (time, SHUTDOWN_MASK_RESTART, exitcode);
4658 else
4659 sWorld.ShutdownServ(time, SHUTDOWN_MASK_RESTART, RESTART_EXIT_CODE);
4660 return true;
4663 bool ChatHandler::HandleServerIdleRestartCommand(const char* args)
4665 if(!*args)
4666 return false;
4668 char* time_str = strtok ((char*) args, " ");
4669 char* exitcode_str = strtok (NULL, "");
4671 int32 time = atoi (time_str);
4673 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4674 if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0)
4675 return false;
4677 if (exitcode_str)
4679 int32 exitcode = atoi (exitcode_str);
4681 // Handle atoi() errors
4682 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4683 return false;
4685 // Exit code should be in range of 0-125, 126-255 is used
4686 // in many shells for their own return codes and code > 255
4687 // is not supported in many others
4688 if (exitcode < 0 || exitcode > 125)
4689 return false;
4691 sWorld.ShutdownServ (time, SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE, exitcode);
4693 else
4694 sWorld.ShutdownServ(time,SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE,RESTART_EXIT_CODE);
4695 return true;
4698 bool ChatHandler::HandleServerIdleShutDownCommand(const char* args)
4700 if(!*args)
4701 return false;
4703 char* time_str = strtok ((char*) args, " ");
4704 char* exitcode_str = strtok (NULL, "");
4706 int32 time = atoi (time_str);
4708 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4709 if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0)
4710 return false;
4712 if (exitcode_str)
4714 int32 exitcode = atoi (exitcode_str);
4716 // Handle atoi() errors
4717 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4718 return false;
4720 // Exit code should be in range of 0-125, 126-255 is used
4721 // in many shells for their own return codes and code > 255
4722 // is not supported in many others
4723 if (exitcode < 0 || exitcode > 125)
4724 return false;
4726 sWorld.ShutdownServ (time, SHUTDOWN_MASK_IDLE, exitcode);
4728 else
4729 sWorld.ShutdownServ(time,SHUTDOWN_MASK_IDLE,SHUTDOWN_EXIT_CODE);
4730 return true;
4733 bool ChatHandler::HandleAddQuest(const char* args)
4735 Player* player = getSelectedPlayer();
4736 if(!player)
4738 SendSysMessage(LANG_NO_CHAR_SELECTED);
4739 SetSentErrorMessage(true);
4740 return false;
4743 // .addquest #entry'
4744 // number or [name] Shift-click form |color|Hquest:quest_id|h[name]|h|r
4745 char* cId = extractKeyFromLink((char*)args,"Hquest");
4746 if(!cId)
4747 return false;
4749 uint32 entry = atol(cId);
4751 Quest const* pQuest = objmgr.GetQuestTemplate(entry);
4753 if(!pQuest)
4755 PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND,entry);
4756 SetSentErrorMessage(true);
4757 return false;
4760 // check item starting quest (it can work incorrectly if added without item in inventory)
4761 for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
4763 ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype>(id);
4764 if (!pProto)
4765 continue;
4767 if (pProto->StartQuest == entry)
4769 PSendSysMessage(LANG_COMMAND_QUEST_STARTFROMITEM, entry, pProto->ItemId);
4770 SetSentErrorMessage(true);
4771 return false;
4775 // ok, normal (creature/GO starting) quest
4776 if( player->CanAddQuest( pQuest, true ) )
4778 player->AddQuest( pQuest, NULL );
4780 if ( player->CanCompleteQuest( entry ) )
4781 player->CompleteQuest( entry );
4784 return true;
4787 bool ChatHandler::HandleRemoveQuest(const char* args)
4789 Player* player = getSelectedPlayer();
4790 if(!player)
4792 SendSysMessage(LANG_NO_CHAR_SELECTED);
4793 SetSentErrorMessage(true);
4794 return false;
4797 // .removequest #entry'
4798 // number or [name] Shift-click form |color|Hquest:quest_id|h[name]|h|r
4799 char* cId = extractKeyFromLink((char*)args,"Hquest");
4800 if(!cId)
4801 return false;
4803 uint32 entry = atol(cId);
4805 Quest const* pQuest = objmgr.GetQuestTemplate(entry);
4807 if(!pQuest)
4809 PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry);
4810 SetSentErrorMessage(true);
4811 return false;
4814 // remove all quest entries for 'entry' from quest log
4815 for(uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot )
4817 uint32 quest = player->GetQuestSlotQuestId(slot);
4818 if(quest==entry)
4820 player->SetQuestSlot(slot,0);
4822 // we ignore unequippable quest items in this case, its' still be equipped
4823 player->TakeQuestSourceItem( quest, false );
4827 // set quest status to not started (will updated in DB at next save)
4828 player->SetQuestStatus( entry, QUEST_STATUS_NONE);
4830 // reset rewarded for restart repeatable quest
4831 player->getQuestStatusMap()[entry].m_rewarded = false;
4833 SendSysMessage(LANG_COMMAND_QUEST_REMOVED);
4834 return true;
4837 bool ChatHandler::HandleCompleteQuest(const char* args)
4839 Player* player = getSelectedPlayer();
4840 if(!player)
4842 SendSysMessage(LANG_NO_CHAR_SELECTED);
4843 SetSentErrorMessage(true);
4844 return false;
4847 // .quest complete #entry
4848 // number or [name] Shift-click form |color|Hquest:quest_id|h[name]|h|r
4849 char* cId = extractKeyFromLink((char*)args,"Hquest");
4850 if(!cId)
4851 return false;
4853 uint32 entry = atol(cId);
4855 Quest const* pQuest = objmgr.GetQuestTemplate(entry);
4857 // If player doesn't have the quest
4858 if(!pQuest || player->GetQuestStatus(entry) == QUEST_STATUS_NONE)
4860 PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry);
4861 SetSentErrorMessage(true);
4862 return false;
4865 // Add quest items for quests that require items
4866 for(uint8 x = 0; x < QUEST_OBJECTIVES_COUNT; ++x)
4868 uint32 id = pQuest->ReqItemId[x];
4869 uint32 count = pQuest->ReqItemCount[x];
4870 if(!id || !count)
4871 continue;
4873 uint32 curItemCount = player->GetItemCount(id,true);
4875 ItemPosCountVec dest;
4876 uint8 msg = player->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, id, count-curItemCount );
4877 if( msg == EQUIP_ERR_OK )
4879 Item* item = player->StoreNewItem( dest, id, true);
4880 player->SendNewItem(item,count-curItemCount,true,false);
4884 // All creature/GO slain/casted (not required, but otherwise it will display "Creature slain 0/10")
4885 for(uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; i++)
4887 uint32 creature = pQuest->ReqCreatureOrGOId[i];
4888 uint32 creaturecount = pQuest->ReqCreatureOrGOCount[i];
4890 if(uint32 spell_id = pQuest->ReqSpell[i])
4892 for(uint16 z = 0; z < creaturecount; ++z)
4893 player->CastedCreatureOrGO(creature,0,spell_id);
4895 else if(creature > 0)
4897 for(uint16 z = 0; z < creaturecount; ++z)
4898 player->KilledMonster(creature,0);
4900 else if(creature < 0)
4902 for(uint16 z = 0; z < creaturecount; ++z)
4903 player->CastedCreatureOrGO(creature,0,0);
4907 // If the quest requires reputation to complete
4908 if(uint32 repFaction = pQuest->GetRepObjectiveFaction())
4910 uint32 repValue = pQuest->GetRepObjectiveValue();
4911 uint32 curRep = player->GetReputation(repFaction);
4912 if(curRep < repValue)
4914 FactionEntry const *factionEntry = sFactionStore.LookupEntry(repFaction);
4915 player->SetFactionReputation(factionEntry,repValue);
4919 // If the quest requires money
4920 int32 ReqOrRewMoney = pQuest->GetRewOrReqMoney();
4921 if(ReqOrRewMoney < 0)
4922 player->ModifyMoney(-ReqOrRewMoney);
4924 player->CompleteQuest(entry);
4925 return true;
4928 bool ChatHandler::HandleBanAccountCommand(const char* args)
4930 return HandleBanHelper(BAN_ACCOUNT,args);
4933 bool ChatHandler::HandleBanCharacterCommand(const char* args)
4935 return HandleBanHelper(BAN_CHARACTER,args);
4938 bool ChatHandler::HandleBanIPCommand(const char* args)
4940 return HandleBanHelper(BAN_IP,args);
4943 bool ChatHandler::HandleBanHelper(BanMode mode, const char* args)
4945 if(!args)
4946 return false;
4948 char* cnameOrIP = strtok ((char*)args, " ");
4949 if (!cnameOrIP)
4950 return false;
4952 std::string nameOrIP = cnameOrIP;
4954 char* duration = strtok (NULL," ");
4955 if(!duration || !atoi(duration))
4956 return false;
4958 char* reason = strtok (NULL,"");
4959 if(!reason)
4960 return false;
4962 switch(mode)
4964 case BAN_ACCOUNT:
4965 if(!AccountMgr::normilizeString(nameOrIP))
4967 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,nameOrIP.c_str());
4968 SetSentErrorMessage(true);
4969 return false;
4971 break;
4972 case BAN_CHARACTER:
4973 if(!normalizePlayerName(nameOrIP))
4975 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4976 SetSentErrorMessage(true);
4977 return false;
4979 break;
4980 case BAN_IP:
4981 if(!IsIPAddress(nameOrIP.c_str()))
4982 return false;
4983 break;
4986 switch(sWorld.BanAccount(mode, nameOrIP, duration, reason,m_session ? m_session->GetPlayerName() : ""))
4988 case BAN_SUCCESS:
4989 if(atoi(duration)>0)
4990 PSendSysMessage(LANG_BAN_YOUBANNED,nameOrIP.c_str(),secsToTimeString(TimeStringToSecs(duration),true).c_str(),reason);
4991 else
4992 PSendSysMessage(LANG_BAN_YOUPERMBANNED,nameOrIP.c_str(),reason);
4993 break;
4994 case BAN_SYNTAX_ERROR:
4995 return false;
4996 case BAN_NOTFOUND:
4997 switch(mode)
4999 default:
5000 PSendSysMessage(LANG_BAN_NOTFOUND,"account",nameOrIP.c_str());
5001 break;
5002 case BAN_CHARACTER:
5003 PSendSysMessage(LANG_BAN_NOTFOUND,"character",nameOrIP.c_str());
5004 break;
5005 case BAN_IP:
5006 PSendSysMessage(LANG_BAN_NOTFOUND,"ip",nameOrIP.c_str());
5007 break;
5009 SetSentErrorMessage(true);
5010 return false;
5013 return true;
5016 bool ChatHandler::HandleUnBanAccountCommand(const char* args)
5018 return HandleUnBanHelper(BAN_ACCOUNT,args);
5021 bool ChatHandler::HandleUnBanCharacterCommand(const char* args)
5023 return HandleUnBanHelper(BAN_CHARACTER,args);
5026 bool ChatHandler::HandleUnBanIPCommand(const char* args)
5028 return HandleUnBanHelper(BAN_IP,args);
5031 bool ChatHandler::HandleUnBanHelper(BanMode mode, const char* args)
5033 if(!args)
5034 return false;
5036 char* cnameOrIP = strtok ((char*)args, " ");
5037 if(!cnameOrIP)
5038 return false;
5040 std::string nameOrIP = cnameOrIP;
5042 switch(mode)
5044 case BAN_ACCOUNT:
5045 if(!AccountMgr::normilizeString(nameOrIP))
5047 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,nameOrIP.c_str());
5048 SetSentErrorMessage(true);
5049 return false;
5051 break;
5052 case BAN_CHARACTER:
5053 if(!normalizePlayerName(nameOrIP))
5055 SendSysMessage(LANG_PLAYER_NOT_FOUND);
5056 SetSentErrorMessage(true);
5057 return false;
5059 break;
5060 case BAN_IP:
5061 if(!IsIPAddress(nameOrIP.c_str()))
5062 return false;
5063 break;
5066 if(sWorld.RemoveBanAccount(mode,nameOrIP))
5067 PSendSysMessage(LANG_UNBAN_UNBANNED,nameOrIP.c_str());
5068 else
5069 PSendSysMessage(LANG_UNBAN_ERROR,nameOrIP.c_str());
5071 return true;
5074 bool ChatHandler::HandleBanInfoAccountCommand(const char* args)
5076 if(!args)
5077 return false;
5079 char* cname = strtok((char*)args, "");
5080 if(!cname)
5081 return false;
5083 std::string account_name = cname;
5084 if(!AccountMgr::normilizeString(account_name))
5086 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5087 SetSentErrorMessage(true);
5088 return false;
5091 uint32 accountid = accmgr.GetId(account_name);
5092 if(!accountid)
5094 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5095 return true;
5098 return HandleBanInfoHelper(accountid,account_name.c_str());
5101 bool ChatHandler::HandleBanInfoCharacterCommand(const char* args)
5103 if(!args)
5104 return false;
5106 char* cname = strtok ((char*)args, "");
5107 if(!cname)
5108 return false;
5110 std::string name = cname;
5111 if(!normalizePlayerName(name))
5113 SendSysMessage(LANG_PLAYER_NOT_FOUND);
5114 SetSentErrorMessage(true);
5115 return false;
5118 uint32 accountid = objmgr.GetPlayerAccountIdByPlayerName(name);
5119 if(!accountid)
5121 SendSysMessage(LANG_PLAYER_NOT_FOUND);
5122 SetSentErrorMessage(true);
5123 return false;
5126 std::string accountname;
5127 if(!accmgr.GetName(accountid,accountname))
5129 PSendSysMessage(LANG_BANINFO_NOCHARACTER);
5130 return true;
5133 return HandleBanInfoHelper(accountid,accountname.c_str());
5136 bool ChatHandler::HandleBanInfoHelper(uint32 accountid, char const* accountname)
5138 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);
5139 if(!result)
5141 PSendSysMessage(LANG_BANINFO_NOACCOUNTBAN, accountname);
5142 return true;
5145 PSendSysMessage(LANG_BANINFO_BANHISTORY,accountname);
5148 Field* fields = result->Fetch();
5150 time_t unbandate = time_t(fields[3].GetUInt64());
5151 bool active = false;
5152 if(fields[2].GetBool() && (fields[1].GetUInt64() == (uint64)0 ||unbandate >= time(NULL)) )
5153 active = true;
5154 bool permanent = (fields[1].GetUInt64() == (uint64)0);
5155 std::string bantime = permanent?GetMangosString(LANG_BANINFO_INFINITE):secsToTimeString(fields[1].GetUInt64(), true);
5156 PSendSysMessage(LANG_BANINFO_HISTORYENTRY,
5157 fields[0].GetString(), bantime.c_str(), active ? GetMangosString(LANG_BANINFO_YES):GetMangosString(LANG_BANINFO_NO), fields[4].GetString(), fields[5].GetString());
5158 }while (result->NextRow());
5160 delete result;
5161 return true;
5164 bool ChatHandler::HandleBanInfoIPCommand(const char* args)
5166 if(!args)
5167 return false;
5169 char* cIP = strtok ((char*)args, "");
5170 if(!cIP)
5171 return false;
5173 if (!IsIPAddress(cIP))
5174 return false;
5176 std::string IP = cIP;
5178 loginDatabase.escape_string(IP);
5179 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());
5180 if(!result)
5182 PSendSysMessage(LANG_BANINFO_NOIP);
5183 return true;
5186 Field *fields = result->Fetch();
5187 bool permanent = !fields[6].GetUInt64();
5188 PSendSysMessage(LANG_BANINFO_IPENTRY,
5189 fields[0].GetString(), fields[1].GetString(), permanent ? GetMangosString(LANG_BANINFO_NEVER):fields[2].GetString(),
5190 permanent ? GetMangosString(LANG_BANINFO_INFINITE):secsToTimeString(fields[3].GetUInt64(), true).c_str(), fields[4].GetString(), fields[5].GetString());
5191 delete result;
5192 return true;
5195 bool ChatHandler::HandleBanListCharacterCommand(const char* args)
5197 loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
5199 char* cFilter = strtok ((char*)args, " ");
5200 if(!cFilter)
5201 return false;
5203 std::string filter = cFilter;
5204 loginDatabase.escape_string(filter);
5205 QueryResult* result = CharacterDatabase.PQuery("SELECT account FROM characters WHERE name "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'"),filter.c_str());
5206 if (!result)
5208 PSendSysMessage(LANG_BANLIST_NOCHARACTER);
5209 return true;
5212 return HandleBanListHelper(result);
5215 bool ChatHandler::HandleBanListAccountCommand(const char* args)
5217 loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
5219 char* cFilter = strtok((char*)args, " ");
5220 std::string filter = cFilter ? cFilter : "";
5221 loginDatabase.escape_string(filter);
5223 QueryResult* result;
5225 if(filter.empty())
5227 result = loginDatabase.Query("SELECT account.id, username FROM account, account_banned"
5228 " WHERE account.id = account_banned.id AND active = 1 GROUP BY account.id");
5230 else
5232 result = loginDatabase.PQuery("SELECT account.id, username FROM account, account_banned"
5233 " WHERE account.id = account_banned.id AND active = 1 AND username "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")" GROUP BY account.id",
5234 filter.c_str());
5237 if (!result)
5239 PSendSysMessage(LANG_BANLIST_NOACCOUNT);
5240 return true;
5243 return HandleBanListHelper(result);
5246 bool ChatHandler::HandleBanListHelper(QueryResult* result)
5248 PSendSysMessage(LANG_BANLIST_MATCHINGACCOUNT);
5250 // Chat short output
5251 if(m_session)
5255 Field* fields = result->Fetch();
5256 uint32 accountid = fields[0].GetUInt32();
5258 QueryResult* banresult = loginDatabase.PQuery("SELECT account.username FROM account,account_banned WHERE account_banned.id='%u' AND account_banned.id=account.id",accountid);
5259 if(banresult)
5261 Field* fields2 = banresult->Fetch();
5262 PSendSysMessage("%s",fields2[0].GetString());
5263 delete banresult;
5265 } while (result->NextRow());
5267 // Console wide output
5268 else
5270 SendSysMessage(LANG_BANLIST_ACCOUNTS);
5271 SendSysMessage("===============================================================================");
5272 SendSysMessage(LANG_BANLIST_ACCOUNTS_HEADER);
5275 SendSysMessage("-------------------------------------------------------------------------------");
5276 Field *fields = result->Fetch();
5277 uint32 account_id = fields[0].GetUInt32 ();
5279 std::string account_name;
5281 // "account" case, name can be get in same query
5282 if(result->GetFieldCount() > 1)
5283 account_name = fields[1].GetCppString();
5284 // "character" case, name need extract from another DB
5285 else
5286 accmgr.GetName (account_id,account_name);
5288 // No SQL injection. id is uint32.
5289 QueryResult *banInfo = loginDatabase.PQuery("SELECT bandate,unbandate,bannedby,banreason FROM account_banned WHERE id = %u ORDER BY unbandate", account_id);
5290 if (banInfo)
5292 Field *fields2 = banInfo->Fetch();
5295 time_t t_ban = fields2[0].GetUInt64();
5296 tm* aTm_ban = localtime(&t_ban);
5298 if (fields2[0].GetUInt64() == fields2[1].GetUInt64())
5300 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|",
5301 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,
5302 fields2[2].GetString(),fields2[3].GetString());
5304 else
5306 time_t t_unban = fields2[1].GetUInt64();
5307 tm* aTm_unban = localtime(&t_unban);
5308 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|",
5309 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,
5310 aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min,
5311 fields2[2].GetString(),fields2[3].GetString());
5313 }while ( banInfo->NextRow() );
5314 delete banInfo;
5316 }while( result->NextRow() );
5317 SendSysMessage("===============================================================================");
5320 delete result;
5321 return true;
5324 bool ChatHandler::HandleBanListIPCommand(const char* args)
5326 loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
5328 char* cFilter = strtok((char*)args, " ");
5329 std::string filter = cFilter ? cFilter : "";
5330 loginDatabase.escape_string(filter);
5332 QueryResult* result;
5334 if(filter.empty())
5336 result = loginDatabase.Query ("SELECT ip,bandate,unbandate,bannedby,banreason FROM ip_banned"
5337 " WHERE (bandate=unbandate OR unbandate>UNIX_TIMESTAMP())"
5338 " ORDER BY unbandate" );
5340 else
5342 result = loginDatabase.PQuery( "SELECT ip,bandate,unbandate,bannedby,banreason FROM ip_banned"
5343 " WHERE (bandate=unbandate OR unbandate>UNIX_TIMESTAMP()) AND ip "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")
5344 " ORDER BY unbandate",filter.c_str() );
5347 if(!result)
5349 PSendSysMessage(LANG_BANLIST_NOIP);
5350 return true;
5353 PSendSysMessage(LANG_BANLIST_MATCHINGIP);
5354 // Chat short output
5355 if(m_session)
5359 Field* fields = result->Fetch();
5360 PSendSysMessage("%s",fields[0].GetString());
5361 } while (result->NextRow());
5363 // Console wide output
5364 else
5366 SendSysMessage(LANG_BANLIST_IPS);
5367 SendSysMessage("===============================================================================");
5368 SendSysMessage(LANG_BANLIST_IPS_HEADER);
5371 SendSysMessage("-------------------------------------------------------------------------------");
5372 Field *fields = result->Fetch();
5373 time_t t_ban = fields[1].GetUInt64();
5374 tm* aTm_ban = localtime(&t_ban);
5375 if ( fields[1].GetUInt64() == fields[2].GetUInt64() )
5377 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|",
5378 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,
5379 fields[3].GetString(), fields[4].GetString());
5381 else
5383 time_t t_unban = fields[2].GetUInt64();
5384 tm* aTm_unban = localtime(&t_unban);
5385 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|",
5386 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,
5387 aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min,
5388 fields[3].GetString(), fields[4].GetString());
5390 }while( result->NextRow() );
5391 SendSysMessage("===============================================================================");
5394 delete result;
5395 return true;
5398 bool ChatHandler::HandleRespawnCommand(const char* /*args*/)
5400 Player* pl = m_session->GetPlayer();
5402 // accept only explicitly selected target (not implicitly self targeting case)
5403 Unit* target = getSelectedUnit();
5404 if(pl->GetSelection() && target)
5406 if(target->GetTypeId()!=TYPEID_UNIT)
5408 SendSysMessage(LANG_SELECT_CREATURE);
5409 SetSentErrorMessage(true);
5410 return false;
5413 if(target->isDead())
5414 ((Creature*)target)->Respawn();
5415 return true;
5418 CellPair p(MaNGOS::ComputeCellPair(pl->GetPositionX(), pl->GetPositionY()));
5419 Cell cell(p);
5420 cell.data.Part.reserved = ALL_DISTRICT;
5421 cell.SetNoCreate();
5423 MaNGOS::RespawnDo u_do;
5424 MaNGOS::WorldObjectWorker<MaNGOS::RespawnDo> worker(u_do);
5426 TypeContainerVisitor<MaNGOS::WorldObjectWorker<MaNGOS::RespawnDo>, GridTypeMapContainer > obj_worker(worker);
5427 CellLock<GridReadGuard> cell_lock(cell, p);
5428 cell_lock->Visit(cell_lock, obj_worker, *pl->GetMap());
5430 return true;
5433 bool ChatHandler::HandleFlyModeCommand(const char* args)
5435 if(!args)
5436 return false;
5438 Unit *unit = getSelectedUnit();
5439 if (!unit || (unit->GetTypeId() != TYPEID_PLAYER))
5440 unit = m_session->GetPlayer();
5442 WorldPacket data(12);
5443 if (strncmp(args, "on", 3) == 0)
5444 data.SetOpcode(SMSG_MOVE_SET_CAN_FLY);
5445 else if (strncmp(args, "off", 4) == 0)
5446 data.SetOpcode(SMSG_MOVE_UNSET_CAN_FLY);
5447 else
5449 SendSysMessage(LANG_USE_BOL);
5450 return false;
5452 data.append(unit->GetPackGUID());
5453 data << uint32(0); // unknown
5454 unit->SendMessageToSet(&data, true);
5455 PSendSysMessage(LANG_COMMAND_FLYMODE_STATUS, unit->GetName(), args);
5456 return true;
5459 bool ChatHandler::HandleLoadPDumpCommand(const char *args)
5461 if(!args)
5462 return false;
5464 char * file = strtok((char*)args, " ");
5465 if(!file)
5466 return false;
5468 char * account = strtok(NULL, " ");
5469 if(!account)
5470 return false;
5472 std::string account_name = account;
5473 if(!AccountMgr::normilizeString(account_name))
5475 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5476 SetSentErrorMessage(true);
5477 return false;
5480 uint32 account_id = accmgr.GetId(account_name);
5481 if(!account_id)
5483 account_id = atoi(account); // use original string
5484 if(!account_id)
5486 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5487 SetSentErrorMessage(true);
5488 return false;
5492 if(!accmgr.GetName(account_id,account_name))
5494 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5495 SetSentErrorMessage(true);
5496 return false;
5499 char* guid_str = NULL;
5500 char* name_str = strtok(NULL, " ");
5502 std::string name;
5503 if(name_str)
5505 name = name_str;
5506 // normalize the name if specified and check if it exists
5507 if(!normalizePlayerName(name))
5509 PSendSysMessage(LANG_INVALID_CHARACTER_NAME);
5510 SetSentErrorMessage(true);
5511 return false;
5514 if(!ObjectMgr::IsValidName(name,true))
5516 PSendSysMessage(LANG_INVALID_CHARACTER_NAME);
5517 SetSentErrorMessage(true);
5518 return false;
5521 guid_str = strtok(NULL, " ");
5524 uint32 guid = 0;
5526 if(guid_str)
5528 guid = atoi(guid_str);
5529 if(!guid)
5531 PSendSysMessage(LANG_INVALID_CHARACTER_GUID);
5532 SetSentErrorMessage(true);
5533 return false;
5536 if(objmgr.GetPlayerAccountIdByGUID(guid))
5538 PSendSysMessage(LANG_CHARACTER_GUID_IN_USE,guid);
5539 SetSentErrorMessage(true);
5540 return false;
5544 switch(PlayerDumpReader().LoadDump(file, account_id, name, guid))
5546 case DUMP_SUCCESS:
5547 PSendSysMessage(LANG_COMMAND_IMPORT_SUCCESS);
5548 break;
5549 case DUMP_FILE_OPEN_ERROR:
5550 PSendSysMessage(LANG_FILE_OPEN_FAIL,file);
5551 SetSentErrorMessage(true);
5552 return false;
5553 case DUMP_FILE_BROKEN:
5554 PSendSysMessage(LANG_DUMP_BROKEN,file);
5555 SetSentErrorMessage(true);
5556 return false;
5557 case DUMP_TOO_MANY_CHARS:
5558 PSendSysMessage(LANG_ACCOUNT_CHARACTER_LIST_FULL,account_name.c_str(),account_id);
5559 SetSentErrorMessage(true);
5560 return false;
5561 default:
5562 PSendSysMessage(LANG_COMMAND_IMPORT_FAILED);
5563 SetSentErrorMessage(true);
5564 return false;
5567 return true;
5570 bool ChatHandler::HandleNpcChangeEntryCommand(const char *args)
5572 if(!args)
5573 return false;
5575 uint32 newEntryNum = atoi(args);
5576 if(!newEntryNum)
5577 return false;
5579 Unit* unit = getSelectedUnit();
5580 if(!unit || unit->GetTypeId() != TYPEID_UNIT)
5582 SendSysMessage(LANG_SELECT_CREATURE);
5583 SetSentErrorMessage(true);
5584 return false;
5586 Creature* creature = (Creature*)unit;
5587 if(creature->UpdateEntry(newEntryNum))
5588 SendSysMessage(LANG_DONE);
5589 else
5590 SendSysMessage(LANG_ERROR);
5591 return true;
5594 bool ChatHandler::HandleWritePDumpCommand(const char *args)
5596 if(!args)
5597 return false;
5599 char* file = strtok((char*)args, " ");
5600 char* p2 = strtok(NULL, " ");
5602 if(!file || !p2)
5603 return false;
5605 uint32 guid;
5606 // character name can't start from number
5607 if (isNumeric(p2[0]))
5608 guid = atoi(p2);
5609 else
5611 std::string name = p2;
5613 if (!normalizePlayerName (name))
5615 SendSysMessage (LANG_PLAYER_NOT_FOUND);
5616 SetSentErrorMessage (true);
5617 return false;
5620 guid = objmgr.GetPlayerGUIDByName(name);
5623 if(!objmgr.GetPlayerAccountIdByGUID(guid))
5625 PSendSysMessage(LANG_PLAYER_NOT_FOUND);
5626 SetSentErrorMessage(true);
5627 return false;
5630 switch(PlayerDumpWriter().WriteDump(file, guid))
5632 case DUMP_SUCCESS:
5633 PSendSysMessage(LANG_COMMAND_EXPORT_SUCCESS);
5634 break;
5635 case DUMP_FILE_OPEN_ERROR:
5636 PSendSysMessage(LANG_FILE_OPEN_FAIL,file);
5637 SetSentErrorMessage(true);
5638 return false;
5639 default:
5640 PSendSysMessage(LANG_COMMAND_EXPORT_FAILED);
5641 SetSentErrorMessage(true);
5642 return false;
5645 return true;
5648 bool ChatHandler::HandleMovegensCommand(const char* /*args*/)
5650 Unit* unit = getSelectedUnit();
5651 if(!unit)
5653 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5654 SetSentErrorMessage(true);
5655 return false;
5658 PSendSysMessage(LANG_MOVEGENS_LIST,(unit->GetTypeId()==TYPEID_PLAYER ? "Player" : "Creature" ),unit->GetGUIDLow());
5660 MotionMaster* mm = unit->GetMotionMaster();
5661 for(MotionMaster::const_iterator itr = mm->begin(); itr != mm->end(); ++itr)
5663 switch((*itr)->GetMovementGeneratorType())
5665 case IDLE_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_IDLE); break;
5666 case RANDOM_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_RANDOM); break;
5667 case WAYPOINT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_WAYPOINT); break;
5668 case ANIMAL_RANDOM_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_ANIMAL_RANDOM); break;
5669 case CONFUSED_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_CONFUSED); break;
5670 case TARGETED_MOTION_TYPE:
5672 if(unit->GetTypeId()==TYPEID_PLAYER)
5674 TargetedMovementGenerator<Player> const* mgen = static_cast<TargetedMovementGenerator<Player> const*>(*itr);
5675 Unit* target = mgen->GetTarget();
5676 if(target)
5677 PSendSysMessage(LANG_MOVEGENS_TARGETED_PLAYER,target->GetName(),target->GetGUIDLow());
5678 else
5679 SendSysMessage(LANG_MOVEGENS_TARGETED_NULL);
5681 else
5683 TargetedMovementGenerator<Creature> const* mgen = static_cast<TargetedMovementGenerator<Creature> const*>(*itr);
5684 Unit* target = mgen->GetTarget();
5685 if(target)
5686 PSendSysMessage(LANG_MOVEGENS_TARGETED_CREATURE,target->GetName(),target->GetGUIDLow());
5687 else
5688 SendSysMessage(LANG_MOVEGENS_TARGETED_NULL);
5690 break;
5692 case HOME_MOTION_TYPE:
5693 if(unit->GetTypeId()==TYPEID_UNIT)
5695 float x,y,z;
5696 (*itr)->GetDestination(x,y,z);
5697 PSendSysMessage(LANG_MOVEGENS_HOME_CREATURE,x,y,z);
5699 else
5700 SendSysMessage(LANG_MOVEGENS_HOME_PLAYER);
5701 break;
5702 case FLIGHT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_FLIGHT); break;
5703 case POINT_MOTION_TYPE:
5705 float x,y,z;
5706 (*itr)->GetDestination(x,y,z);
5707 PSendSysMessage(LANG_MOVEGENS_POINT,x,y,z);
5708 break;
5710 case FLEEING_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_FEAR); break;
5711 case DISTRACT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_DISTRACT); break;
5712 default:
5713 PSendSysMessage(LANG_MOVEGENS_UNKNOWN,(*itr)->GetMovementGeneratorType());
5714 break;
5717 return true;
5720 bool ChatHandler::HandlePLimitCommand(const char *args)
5722 if(*args)
5724 char* param = strtok((char*)args, " ");
5725 if(!param)
5726 return false;
5728 int l = strlen(param);
5730 if( strncmp(param,"player",l) == 0 )
5731 sWorld.SetPlayerLimit(-SEC_PLAYER);
5732 else if(strncmp(param,"moderator",l) == 0 )
5733 sWorld.SetPlayerLimit(-SEC_MODERATOR);
5734 else if(strncmp(param,"gamemaster",l) == 0 )
5735 sWorld.SetPlayerLimit(-SEC_GAMEMASTER);
5736 else if(strncmp(param,"administrator",l) == 0 )
5737 sWorld.SetPlayerLimit(-SEC_ADMINISTRATOR);
5738 else if(strncmp(param,"reset",l) == 0 )
5739 sWorld.SetPlayerLimit( sConfig.GetIntDefault("PlayerLimit", DEFAULT_PLAYER_LIMIT) );
5740 else
5742 int val = atoi(param);
5743 if(val < -SEC_ADMINISTRATOR) val = -SEC_ADMINISTRATOR;
5745 sWorld.SetPlayerLimit(val);
5748 // kick all low security level players
5749 if(sWorld.GetPlayerAmountLimit() > SEC_PLAYER)
5750 sWorld.KickAllLess(sWorld.GetPlayerSecurityLimit());
5753 uint32 pLimit = sWorld.GetPlayerAmountLimit();
5754 AccountTypes allowedAccountType = sWorld.GetPlayerSecurityLimit();
5755 char const* secName = "";
5756 switch(allowedAccountType)
5758 case SEC_PLAYER: secName = "Player"; break;
5759 case SEC_MODERATOR: secName = "Moderator"; break;
5760 case SEC_GAMEMASTER: secName = "Gamemaster"; break;
5761 case SEC_ADMINISTRATOR: secName = "Administrator"; break;
5762 default: secName = "<unknown>"; break;
5765 PSendSysMessage("Player limits: amount %u, min. security level %s.",pLimit,secName);
5767 return true;
5770 bool ChatHandler::HandleCastCommand(const char* args)
5772 if(!*args)
5773 return false;
5775 Unit* target = getSelectedUnit();
5777 if(!target)
5779 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5780 SetSentErrorMessage(true);
5781 return false;
5784 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5785 uint32 spell = extractSpellIdFromLink((char*)args);
5786 if(!spell)
5787 return false;
5789 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
5790 if(!spellInfo)
5791 return false;
5793 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
5795 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
5796 SetSentErrorMessage(true);
5797 return false;
5800 char* trig_str = strtok(NULL, " ");
5801 if(trig_str)
5803 int l = strlen(trig_str);
5804 if(strncmp(trig_str,"triggered",l) != 0 )
5805 return false;
5808 bool triggered = (trig_str != NULL);
5810 m_session->GetPlayer()->CastSpell(target,spell,triggered);
5812 return true;
5815 bool ChatHandler::HandleCastBackCommand(const char* args)
5817 Creature* caster = getSelectedCreature();
5819 if(!caster)
5821 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5822 SetSentErrorMessage(true);
5823 return false;
5826 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
5827 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5828 uint32 spell = extractSpellIdFromLink((char*)args);
5829 if(!spell || !sSpellStore.LookupEntry(spell))
5830 return false;
5832 char* trig_str = strtok(NULL, " ");
5833 if(trig_str)
5835 int l = strlen(trig_str);
5836 if(strncmp(trig_str,"triggered",l) != 0 )
5837 return false;
5840 bool triggered = (trig_str != NULL);
5842 // update orientation at server
5843 caster->SetOrientation(caster->GetAngle(m_session->GetPlayer()));
5845 // and client
5846 WorldPacket data;
5847 caster->BuildHeartBeatMsg(&data);
5848 caster->SendMessageToSet(&data,true);
5850 caster->CastSpell(m_session->GetPlayer(),spell,triggered);
5852 return true;
5855 bool ChatHandler::HandleCastDistCommand(const char* args)
5857 if(!*args)
5858 return false;
5860 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5861 uint32 spell = extractSpellIdFromLink((char*)args);
5862 if(!spell)
5863 return false;
5865 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
5866 if(!spellInfo)
5867 return false;
5869 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
5871 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
5872 SetSentErrorMessage(true);
5873 return false;
5876 char *distStr = strtok(NULL, " ");
5878 float dist = 0;
5880 if(distStr)
5881 sscanf(distStr, "%f", &dist);
5883 char* trig_str = strtok(NULL, " ");
5884 if(trig_str)
5886 int l = strlen(trig_str);
5887 if(strncmp(trig_str,"triggered",l) != 0 )
5888 return false;
5891 bool triggered = (trig_str != NULL);
5893 float x,y,z;
5894 m_session->GetPlayer()->GetClosePoint(x,y,z,dist);
5896 m_session->GetPlayer()->CastSpell(x,y,z,spell,triggered);
5897 return true;
5900 bool ChatHandler::HandleCastTargetCommand(const char* args)
5902 Creature* caster = getSelectedCreature();
5904 if(!caster)
5906 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5907 SetSentErrorMessage(true);
5908 return false;
5911 if(!caster->getVictim())
5913 SendSysMessage(LANG_SELECTED_TARGET_NOT_HAVE_VICTIM);
5914 SetSentErrorMessage(true);
5915 return false;
5918 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5919 uint32 spell = extractSpellIdFromLink((char*)args);
5920 if(!spell || !sSpellStore.LookupEntry(spell))
5921 return false;
5923 char* trig_str = strtok(NULL, " ");
5924 if(trig_str)
5926 int l = strlen(trig_str);
5927 if(strncmp(trig_str,"triggered",l) != 0 )
5928 return false;
5931 bool triggered = (trig_str != NULL);
5933 // update orientation at server
5934 caster->SetOrientation(caster->GetAngle(m_session->GetPlayer()));
5936 // and client
5937 WorldPacket data;
5938 caster->BuildHeartBeatMsg(&data);
5939 caster->SendMessageToSet(&data,true);
5941 caster->CastSpell(caster->getVictim(),spell,triggered);
5943 return true;
5947 ComeToMe command REQUIRED for 3rd party scripting library to have access to PointMovementGenerator
5948 Without this function 3rd party scripting library will get linking errors (unresolved external)
5949 when attempting to use the PointMovementGenerator
5951 bool ChatHandler::HandleComeToMeCommand(const char *args)
5953 Creature* caster = getSelectedCreature();
5955 if(!caster)
5957 SendSysMessage(LANG_SELECT_CREATURE);
5958 SetSentErrorMessage(true);
5959 return false;
5962 char* newFlagStr = strtok((char*)args, " ");
5964 if(!newFlagStr)
5965 return false;
5967 uint32 newFlags = atoi(newFlagStr);
5969 caster->SetUnitMovementFlags(newFlags);
5971 Player* pl = m_session->GetPlayer();
5973 caster->GetMotionMaster()->MovePoint(0, pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ());
5974 return true;
5977 bool ChatHandler::HandleCastSelfCommand(const char* args)
5979 if(!*args)
5980 return false;
5982 Unit* target = getSelectedUnit();
5984 if(!target)
5986 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5987 SetSentErrorMessage(true);
5988 return false;
5991 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5992 uint32 spell = extractSpellIdFromLink((char*)args);
5993 if(!spell)
5994 return false;
5996 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
5997 if(!spellInfo)
5998 return false;
6000 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
6002 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
6003 SetSentErrorMessage(true);
6004 return false;
6007 target->CastSpell(target,spell,false);
6009 return true;
6012 std::string GetTimeString(uint32 time)
6014 uint16 days = time / DAY, hours = (time % DAY) / HOUR, minute = (time % HOUR) / MINUTE;
6015 std::ostringstream ss;
6016 if(days) ss << days << "d ";
6017 if(hours) ss << hours << "h ";
6018 ss << minute << "m";
6019 return ss.str();
6022 bool ChatHandler::HandleInstanceListBindsCommand(const char* /*args*/)
6024 Player* player = getSelectedPlayer();
6025 if (!player) player = m_session->GetPlayer();
6026 uint32 counter = 0;
6027 for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++)
6029 Player::BoundInstancesMap &binds = player->GetBoundInstances(i);
6030 for(Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end(); ++itr)
6032 InstanceSave *save = itr->second.save;
6033 std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
6034 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());
6035 counter++;
6038 PSendSysMessage("player binds: %d", counter);
6039 counter = 0;
6040 Group *group = player->GetGroup();
6041 if(group)
6043 for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++)
6045 Group::BoundInstancesMap &binds = group->GetBoundInstances(i);
6046 for(Group::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end(); ++itr)
6048 InstanceSave *save = itr->second.save;
6049 std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
6050 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());
6051 counter++;
6055 PSendSysMessage("group binds: %d", counter);
6057 return true;
6060 bool ChatHandler::HandleInstanceUnbindCommand(const char* args)
6062 if(!*args)
6063 return false;
6065 std::string cmd = args;
6066 if(cmd == "all")
6068 Player* player = getSelectedPlayer();
6069 if (!player) player = m_session->GetPlayer();
6070 uint32 counter = 0;
6071 for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++)
6073 Player::BoundInstancesMap &binds = player->GetBoundInstances(i);
6074 for(Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end();)
6076 if(itr->first != player->GetMapId())
6078 InstanceSave *save = itr->second.save;
6079 std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
6080 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());
6081 player->UnbindInstance(itr, i);
6082 counter++;
6084 else
6085 ++itr;
6088 PSendSysMessage("instances unbound: %d", counter);
6090 return true;
6093 bool ChatHandler::HandleInstanceStatsCommand(const char* /*args*/)
6095 PSendSysMessage("instances loaded: %d", MapManager::Instance().GetNumInstances());
6096 PSendSysMessage("players in instances: %d", MapManager::Instance().GetNumPlayersInInstances());
6097 PSendSysMessage("instance saves: %d", sInstanceSaveManager.GetNumInstanceSaves());
6098 PSendSysMessage("players bound: %d", sInstanceSaveManager.GetNumBoundPlayersTotal());
6099 PSendSysMessage("groups bound: %d", sInstanceSaveManager.GetNumBoundGroupsTotal());
6100 return true;
6103 bool ChatHandler::HandleInstanceSaveDataCommand(const char * /*args*/)
6105 Player* pl = m_session->GetPlayer();
6107 Map* map = pl->GetMap();
6108 if (!map->IsDungeon())
6110 PSendSysMessage("Map is not a dungeon.");
6111 SetSentErrorMessage(true);
6112 return false;
6115 if (!((InstanceMap*)map)->GetInstanceData())
6117 PSendSysMessage("Map has no instance data.");
6118 SetSentErrorMessage(true);
6119 return false;
6122 ((InstanceMap*)map)->GetInstanceData()->SaveToDB();
6123 return true;
6126 /// Display the list of GMs
6127 bool ChatHandler::HandleGMListFullCommand(const char* /*args*/)
6129 ///- Get the accounts with GM Level >0
6130 QueryResult *result = loginDatabase.Query( "SELECT username,gmlevel FROM account WHERE gmlevel > 0" );
6131 if(result)
6133 SendSysMessage(LANG_GMLIST);
6134 SendSysMessage("========================");
6135 SendSysMessage(LANG_GMLIST_HEADER);
6136 SendSysMessage("========================");
6138 ///- Circle through them. Display username and GM level
6141 Field *fields = result->Fetch();
6142 PSendSysMessage("|%15s|%6s|", fields[0].GetString(),fields[1].GetString());
6143 }while( result->NextRow() );
6145 PSendSysMessage("========================");
6146 delete result;
6148 else
6149 PSendSysMessage(LANG_GMLIST_EMPTY);
6150 return true;
6153 /// Define the 'Message of the day' for the realm
6154 bool ChatHandler::HandleServerSetMotdCommand(const char* args)
6156 sWorld.SetMotd(args);
6157 PSendSysMessage(LANG_MOTD_NEW, args);
6158 return true;
6161 /// Set/Unset the expansion level for an account
6162 bool ChatHandler::HandleAccountSetAddonCommand(const char* args)
6164 ///- Get the command line arguments
6165 char *szAcc = strtok((char*)args," ");
6166 char *szExp = strtok(NULL," ");
6168 if(!szAcc)
6169 return false;
6171 std::string account_name;
6172 uint32 account_id;
6174 if(!szExp)
6176 Player* player = getSelectedPlayer();
6177 if(!player)
6178 return false;
6180 account_id = player->GetSession()->GetAccountId();
6181 accmgr.GetName(account_id,account_name);
6182 szExp = szAcc;
6184 else
6186 ///- Convert Account name to Upper Format
6187 account_name = szAcc;
6188 if(!AccountMgr::normilizeString(account_name))
6190 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
6191 SetSentErrorMessage(true);
6192 return false;
6195 account_id = accmgr.GetId(account_name);
6196 if(!account_id)
6198 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
6199 SetSentErrorMessage(true);
6200 return false;
6204 int lev=atoi(szExp); //get int anyway (0 if error)
6205 if(lev < 0)
6206 return false;
6208 // No SQL injection
6209 loginDatabase.PExecute("UPDATE account SET expansion = '%d' WHERE id = '%u'",lev,account_id);
6210 PSendSysMessage(LANG_ACCOUNT_SETADDON,account_name.c_str(),account_id,lev);
6211 return true;
6214 //Send items by mail
6215 bool ChatHandler::HandleSendItemsCommand(const char* args)
6217 if(!*args)
6218 return false;
6220 // format: name "subject text" "mail text" item1[:count1] item2[:count2] ... item12[:count12]
6222 char* pName = strtok((char*)args, " ");
6223 if(!pName)
6224 return false;
6226 char* tail1 = strtok(NULL, "");
6227 if(!tail1)
6228 return false;
6230 char* msgSubject;
6231 if(*tail1=='"')
6232 msgSubject = strtok(tail1+1, "\"");
6233 else
6235 char* space = strtok(tail1, "\"");
6236 if(!space)
6237 return false;
6238 msgSubject = strtok(NULL, "\"");
6241 if (!msgSubject)
6242 return false;
6244 char* tail2 = strtok(NULL, "");
6245 if(!tail2)
6246 return false;
6248 char* msgText;
6249 if(*tail2=='"')
6250 msgText = strtok(tail2+1, "\"");
6251 else
6253 char* space = strtok(tail2, "\"");
6254 if(!space)
6255 return false;
6256 msgText = strtok(NULL, "\"");
6259 if (!msgText)
6260 return false;
6262 // pName, msgSubject, msgText isn't NUL after prev. check
6263 std::string name = pName;
6264 std::string subject = msgSubject;
6265 std::string text = msgText;
6267 // extract items
6268 typedef std::pair<uint32,uint32> ItemPair;
6269 typedef std::list< ItemPair > ItemPairs;
6270 ItemPairs items;
6272 // get all tail string
6273 char* tail = strtok(NULL, "");
6275 // get from tail next item str
6276 while(char* itemStr = strtok(tail, " "))
6278 // and get new tail
6279 tail = strtok(NULL, "");
6281 // parse item str
6282 char* itemIdStr = strtok(itemStr, ":");
6283 char* itemCountStr = strtok(NULL, " ");
6285 uint32 item_id = atoi(itemIdStr);
6286 if(!item_id)
6287 return false;
6289 ItemPrototype const* item_proto = objmgr.GetItemPrototype(item_id);
6290 if(!item_proto)
6292 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
6293 SetSentErrorMessage(true);
6294 return false;
6297 uint32 item_count = itemCountStr ? atoi(itemCountStr) : 1;
6298 if(item_count < 1 || item_proto->MaxCount && item_count > item_proto->MaxCount)
6300 PSendSysMessage(LANG_COMMAND_INVALID_ITEM_COUNT, item_count,item_id);
6301 SetSentErrorMessage(true);
6302 return false;
6305 while(item_count > item_proto->Stackable)
6307 items.push_back(ItemPair(item_id,item_proto->Stackable));
6308 item_count -= item_proto->Stackable;
6311 items.push_back(ItemPair(item_id,item_count));
6313 if(items.size() > MAX_MAIL_ITEMS)
6315 PSendSysMessage(LANG_COMMAND_MAIL_ITEMS_LIMIT, MAX_MAIL_ITEMS);
6316 SetSentErrorMessage(true);
6317 return false;
6321 if(!normalizePlayerName(name))
6323 SendSysMessage(LANG_PLAYER_NOT_FOUND);
6324 SetSentErrorMessage(true);
6325 return false;
6328 uint64 receiver_guid = objmgr.GetPlayerGUIDByName(name);
6329 if(!receiver_guid)
6331 SendSysMessage(LANG_PLAYER_NOT_FOUND);
6332 SetSentErrorMessage(true);
6333 return false;
6336 // from console show not existed sender
6337 uint32 sender_guidlo = m_session ? m_session->GetPlayer()->GetGUIDLow() : 0;
6339 uint32 messagetype = MAIL_NORMAL;
6340 uint32 stationery = MAIL_STATIONERY_GM;
6341 uint32 itemTextId = !text.empty() ? objmgr.CreateItemText( text ) : 0;
6343 Player *receiver = objmgr.GetPlayer(receiver_guid);
6345 // fill mail
6346 MailItemsInfo mi; // item list preparing
6348 for(ItemPairs::const_iterator itr = items.begin(); itr != items.end(); ++itr)
6350 if(Item* item = Item::CreateItem(itr->first,itr->second,m_session ? m_session->GetPlayer() : 0))
6352 item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted
6353 mi.AddItem(item->GetGUIDLow(), item->GetEntry(), item);
6357 WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, &mi, 0, 0, MAIL_CHECK_MASK_NONE);
6359 PSendSysMessage(LANG_MAIL_SENT, name.c_str());
6360 return true;
6363 ///Send money by mail
6364 bool ChatHandler::HandleSendMoneyCommand(const char* args)
6366 if (!*args)
6367 return false;
6369 /// format: name "subject text" "mail text" money
6371 char* pName = strtok((char*)args, " ");
6372 if (!pName)
6373 return false;
6375 char* tail1 = strtok(NULL, "");
6376 if (!tail1)
6377 return false;
6379 char* msgSubject;
6380 if (*tail1=='"')
6381 msgSubject = strtok(tail1+1, "\"");
6382 else
6384 char* space = strtok(tail1, "\"");
6385 if (!space)
6386 return false;
6387 msgSubject = strtok(NULL, "\"");
6390 if (!msgSubject)
6391 return false;
6393 char* tail2 = strtok(NULL, "");
6394 if (!tail2)
6395 return false;
6397 char* msgText;
6398 if (*tail2=='"')
6399 msgText = strtok(tail2+1, "\"");
6400 else
6402 char* space = strtok(tail2, "\"");
6403 if (!space)
6404 return false;
6405 msgText = strtok(NULL, "\"");
6408 if (!msgText)
6409 return false;
6411 char* money_str = strtok(NULL, "");
6412 int32 money = money_str ? atoi(money_str) : 0;
6413 if (money <= 0)
6414 return false;
6416 // pName, msgSubject, msgText isn't NUL after prev. check
6417 std::string name = pName;
6418 std::string subject = msgSubject;
6419 std::string text = msgText;
6421 if (!normalizePlayerName(name))
6423 SendSysMessage(LANG_PLAYER_NOT_FOUND);
6424 SetSentErrorMessage(true);
6425 return false;
6428 uint64 receiver_guid = objmgr.GetPlayerGUIDByName(name);
6429 if (!receiver_guid)
6431 SendSysMessage(LANG_PLAYER_NOT_FOUND);
6432 SetSentErrorMessage(true);
6433 return false;
6436 uint32 mailId = objmgr.GenerateMailID();
6438 // from console show not existed sender
6439 uint32 sender_guidlo = m_session ? m_session->GetPlayer()->GetGUIDLow() : 0;
6441 uint32 messagetype = MAIL_NORMAL;
6442 uint32 stationery = MAIL_STATIONERY_GM;
6443 uint32 itemTextId = !text.empty() ? objmgr.CreateItemText( text ) : 0;
6445 Player *receiver = objmgr.GetPlayer(receiver_guid);
6447 WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, NULL, money, 0, MAIL_CHECK_MASK_NONE);
6449 PSendSysMessage(LANG_MAIL_SENT, name.c_str());
6450 return true;
6453 /// Send a message to a player in game
6454 bool ChatHandler::HandleSendMessageCommand(const char* args)
6456 ///- Get the command line arguments
6457 char* name_str = strtok((char*)args, " ");
6458 char* msg_str = strtok(NULL, "");
6460 if(!name_str || !msg_str)
6461 return false;
6463 std::string name = name_str;
6465 if(!normalizePlayerName(name))
6466 return false;
6468 ///- Find the player and check that he is not logging out.
6469 Player *rPlayer = objmgr.GetPlayer(name.c_str());
6470 if(!rPlayer)
6472 SendSysMessage(LANG_PLAYER_NOT_FOUND);
6473 SetSentErrorMessage(true);
6474 return false;
6477 if(rPlayer->GetSession()->isLogingOut())
6479 SendSysMessage(LANG_PLAYER_NOT_FOUND);
6480 SetSentErrorMessage(true);
6481 return false;
6484 ///- Send the message
6485 //Use SendAreaTriggerMessage for fastest delivery.
6486 rPlayer->GetSession()->SendAreaTriggerMessage("%s", msg_str);
6487 rPlayer->GetSession()->SendAreaTriggerMessage("|cffff0000[Message from administrator]:|r");
6489 //Confirmation message
6490 PSendSysMessage(LANG_SENDMESSAGE,name.c_str(),msg_str);
6491 return true;
6494 bool ChatHandler::HandleFlushArenaPointsCommand(const char * /*args*/)
6496 sBattleGroundMgr.DistributeArenaPoints();
6497 return true;
6500 bool ChatHandler::HandleModifyGenderCommand(const char *args)
6502 if(!*args)
6503 return false;
6505 Player *player = getSelectedPlayer();
6507 if(!player)
6509 PSendSysMessage(LANG_NO_PLAYER);
6510 SetSentErrorMessage(true);
6511 return false;
6514 PlayerInfo const* info = objmgr.GetPlayerInfo(player->getRace(), player->getClass());
6515 if(!info)
6516 return false;
6518 char const* gender_str = (char*)args;
6519 int gender_len = strlen(gender_str);
6521 Gender gender;
6523 if(!strncmp(gender_str, "male", gender_len)) // MALE
6525 if(player->getGender() == GENDER_MALE)
6526 return true;
6528 gender = GENDER_MALE;
6530 else if (!strncmp(gender_str, "female", gender_len)) // FEMALE
6532 if(player->getGender() == GENDER_FEMALE)
6533 return true;
6535 gender = GENDER_FEMALE;
6537 else
6539 SendSysMessage(LANG_MUST_MALE_OR_FEMALE);
6540 SetSentErrorMessage(true);
6541 return false;
6544 // Set gender
6545 player->SetByteValue(UNIT_FIELD_BYTES_0, 2, gender);
6546 player->SetByteValue(PLAYER_BYTES_3, 0, gender);
6548 // Change display ID
6549 player->SetDisplayId(gender ? info->displayId_f : info->displayId_m);
6550 player->SetNativeDisplayId(gender ? info->displayId_f : info->displayId_m);
6552 char const* gender_full = gender ? "female" : "male";
6554 PSendSysMessage(LANG_YOU_CHANGE_GENDER, player->GetName(), gender_full);
6556 if (needReportToTarget(player))
6557 ChatHandler(player).PSendSysMessage(LANG_YOUR_GENDER_CHANGED, gender_full, GetName());
6559 return true;