[7102] Fixed .showarea/,hodearea commands.
[getmangos.git] / src / game / Level3.cpp
blob0323b09af3b639241e5a124f2a875a095ce1bea1
1 /*
2 * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include "Common.h"
20 #include "Database/DatabaseEnv.h"
21 #include "WorldPacket.h"
22 #include "WorldSession.h"
23 #include "World.h"
24 #include "ObjectMgr.h"
25 #include "AccountMgr.h"
26 #include "PlayerDump.h"
27 #include "SpellMgr.h"
28 #include "Player.h"
29 #include "Opcodes.h"
30 #include "GameObject.h"
31 #include "Chat.h"
32 #include "Log.h"
33 #include "Guild.h"
34 #include "ObjectAccessor.h"
35 #include "MapManager.h"
36 #include "SpellAuras.h"
37 #include "ScriptCalls.h"
38 #include "Language.h"
39 #include "GridNotifiersImpl.h"
40 #include "CellImpl.h"
41 #include "Weather.h"
42 #include "PointMovementGenerator.h"
43 #include "TargetedMovementGenerator.h"
44 #include "SkillDiscovery.h"
45 #include "SkillExtraItems.h"
46 #include "SystemConfig.h"
47 #include "Config/ConfigEnv.h"
48 #include "Util.h"
49 #include "ItemEnchantmentMgr.h"
50 #include "BattleGroundMgr.h"
51 #include "InstanceSaveMgr.h"
52 #include "InstanceData.h"
54 //reload commands
55 bool ChatHandler::HandleReloadAllCommand(const char*)
57 HandleReloadSkillFishingBaseLevelCommand("");
59 HandleReloadAllAreaCommand("");
60 HandleReloadAllLootCommand("");
61 HandleReloadAllNpcCommand("");
62 HandleReloadAllQuestCommand("");
63 HandleReloadAllSpellCommand("");
64 HandleReloadAllItemCommand("");
65 HandleReloadAllLocalesCommand("");
67 HandleReloadCommandCommand("");
68 HandleReloadReservedNameCommand("");
69 HandleReloadMangosStringCommand("");
70 HandleReloadGameTeleCommand("");
71 return true;
74 bool ChatHandler::HandleReloadAllAreaCommand(const char*)
76 //HandleReloadQuestAreaTriggersCommand(""); -- reloaded in HandleReloadAllQuestCommand
77 HandleReloadAreaTriggerTeleportCommand("");
78 HandleReloadAreaTriggerTavernCommand("");
79 HandleReloadGameGraveyardZoneCommand("");
80 return true;
83 bool ChatHandler::HandleReloadAllLootCommand(const char*)
85 sLog.outString( "Re-Loading Loot Tables..." );
86 LoadLootTables();
87 SendGlobalSysMessage("DB tables `*_loot_template` reloaded.");
88 return true;
91 bool ChatHandler::HandleReloadAllNpcCommand(const char* /*args*/)
93 HandleReloadNpcGossipCommand("a");
94 HandleReloadNpcOptionCommand("a");
95 HandleReloadNpcTrainerCommand("a");
96 HandleReloadNpcVendorCommand("a");
97 return true;
100 bool ChatHandler::HandleReloadAllQuestCommand(const char* /*args*/)
102 HandleReloadQuestAreaTriggersCommand("a");
103 HandleReloadQuestTemplateCommand("a");
105 sLog.outString( "Re-Loading Quests Relations..." );
106 objmgr.LoadQuestRelations();
107 SendGlobalSysMessage("DB tables `*_questrelation` and `*_involvedrelation` reloaded.");
108 return true;
111 bool ChatHandler::HandleReloadAllScriptsCommand(const char*)
113 if(sWorld.IsScriptScheduled())
115 PSendSysMessage("DB scripts used currently, please attempt reload later.");
116 SetSentErrorMessage(true);
117 return false;
120 sLog.outString( "Re-Loading Scripts..." );
121 HandleReloadGameObjectScriptsCommand("a");
122 HandleReloadEventScriptsCommand("a");
123 HandleReloadQuestEndScriptsCommand("a");
124 HandleReloadQuestStartScriptsCommand("a");
125 HandleReloadSpellScriptsCommand("a");
126 SendGlobalSysMessage("DB tables `*_scripts` reloaded.");
127 HandleReloadDbScriptStringCommand("a");
128 return true;
131 bool ChatHandler::HandleReloadAllSpellCommand(const char*)
133 HandleReloadSkillDiscoveryTemplateCommand("a");
134 HandleReloadSkillExtraItemTemplateCommand("a");
135 HandleReloadSpellAffectCommand("a");
136 HandleReloadSpellChainCommand("a");
137 HandleReloadSpellElixirCommand("a");
138 HandleReloadSpellLearnSpellCommand("a");
139 HandleReloadSpellProcEventCommand("a");
140 HandleReloadSpellScriptTargetCommand("a");
141 HandleReloadSpellTargetPositionCommand("a");
142 HandleReloadSpellThreatsCommand("a");
143 HandleReloadSpellPetAurasCommand("a");
144 return true;
147 bool ChatHandler::HandleReloadAllItemCommand(const char*)
149 HandleReloadPageTextsCommand("a");
150 HandleReloadItemEnchantementsCommand("a");
151 return true;
154 bool ChatHandler::HandleReloadAllLocalesCommand(const char* /*args*/)
156 HandleReloadLocalesCreatureCommand("a");
157 HandleReloadLocalesGameobjectCommand("a");
158 HandleReloadLocalesItemCommand("a");
159 HandleReloadLocalesNpcTextCommand("a");
160 HandleReloadLocalesPageTextCommand("a");
161 HandleReloadLocalesQuestCommand("a");
162 return true;
165 bool ChatHandler::HandleReloadConfigCommand(const char* /*args*/)
167 sLog.outString( "Re-Loading config settings..." );
168 sWorld.LoadConfigSettings(true);
169 SendGlobalSysMessage("World config settings reloaded.");
170 return true;
173 bool ChatHandler::HandleReloadAreaTriggerTavernCommand(const char*)
175 sLog.outString( "Re-Loading Tavern Area Triggers..." );
176 objmgr.LoadTavernAreaTriggers();
177 SendGlobalSysMessage("DB table `areatrigger_tavern` reloaded.");
178 return true;
181 bool ChatHandler::HandleReloadAreaTriggerTeleportCommand(const char*)
183 sLog.outString( "Re-Loading AreaTrigger teleport definitions..." );
184 objmgr.LoadAreaTriggerTeleports();
185 SendGlobalSysMessage("DB table `areatrigger_teleport` reloaded.");
186 return true;
189 bool ChatHandler::HandleReloadCommandCommand(const char*)
191 load_command_table = true;
192 SendGlobalSysMessage("DB table `command` will be reloaded at next chat command use.");
193 return true;
196 bool ChatHandler::HandleReloadCreatureQuestRelationsCommand(const char*)
198 sLog.outString( "Loading Quests Relations... (`creature_questrelation`)" );
199 objmgr.LoadCreatureQuestRelations();
200 SendGlobalSysMessage("DB table `creature_questrelation` (creature quest givers) reloaded.");
201 return true;
204 bool ChatHandler::HandleReloadCreatureQuestInvRelationsCommand(const char*)
206 sLog.outString( "Loading Quests Relations... (`creature_involvedrelation`)" );
207 objmgr.LoadCreatureInvolvedRelations();
208 SendGlobalSysMessage("DB table `creature_involvedrelation` (creature quest takers) reloaded.");
209 return true;
212 bool ChatHandler::HandleReloadGOQuestRelationsCommand(const char*)
214 sLog.outString( "Loading Quests Relations... (`gameobject_questrelation`)" );
215 objmgr.LoadGameobjectQuestRelations();
216 SendGlobalSysMessage("DB table `gameobject_questrelation` (gameobject quest givers) reloaded.");
217 return true;
220 bool ChatHandler::HandleReloadGOQuestInvRelationsCommand(const char*)
222 sLog.outString( "Loading Quests Relations... (`gameobject_involvedrelation`)" );
223 objmgr.LoadGameobjectInvolvedRelations();
224 SendGlobalSysMessage("DB table `gameobject_involvedrelation` (gameobject quest takers) reloaded.");
225 return true;
228 bool ChatHandler::HandleReloadQuestAreaTriggersCommand(const char*)
230 sLog.outString( "Re-Loading Quest Area Triggers..." );
231 objmgr.LoadQuestAreaTriggers();
232 SendGlobalSysMessage("DB table `areatrigger_involvedrelation` (quest area triggers) reloaded.");
233 return true;
236 bool ChatHandler::HandleReloadQuestTemplateCommand(const char*)
238 sLog.outString( "Re-Loading Quest Templates..." );
239 objmgr.LoadQuests();
240 SendGlobalSysMessage("DB table `quest_template` (quest definitions) reloaded.");
241 return true;
244 bool ChatHandler::HandleReloadLootTemplatesCreatureCommand(const char*)
246 sLog.outString( "Re-Loading Loot Tables... (`creature_loot_template`)" );
247 LoadLootTemplates_Creature();
248 LootTemplates_Creature.CheckLootRefs();
249 SendGlobalSysMessage("DB table `creature_loot_template` reloaded.");
250 return true;
253 bool ChatHandler::HandleReloadLootTemplatesDisenchantCommand(const char*)
255 sLog.outString( "Re-Loading Loot Tables... (`disenchant_loot_template`)" );
256 LoadLootTemplates_Disenchant();
257 LootTemplates_Disenchant.CheckLootRefs();
258 SendGlobalSysMessage("DB table `disenchant_loot_template` reloaded.");
259 return true;
262 bool ChatHandler::HandleReloadLootTemplatesFishingCommand(const char*)
264 sLog.outString( "Re-Loading Loot Tables... (`fishing_loot_template`)" );
265 LoadLootTemplates_Fishing();
266 LootTemplates_Fishing.CheckLootRefs();
267 SendGlobalSysMessage("DB table `fishing_loot_template` reloaded.");
268 return true;
271 bool ChatHandler::HandleReloadLootTemplatesGameobjectCommand(const char*)
273 sLog.outString( "Re-Loading Loot Tables... (`gameobject_loot_template`)" );
274 LoadLootTemplates_Gameobject();
275 LootTemplates_Gameobject.CheckLootRefs();
276 SendGlobalSysMessage("DB table `gameobject_loot_template` reloaded.");
277 return true;
280 bool ChatHandler::HandleReloadLootTemplatesItemCommand(const char*)
282 sLog.outString( "Re-Loading Loot Tables... (`item_loot_template`)" );
283 LoadLootTemplates_Item();
284 LootTemplates_Item.CheckLootRefs();
285 SendGlobalSysMessage("DB table `item_loot_template` reloaded.");
286 return true;
289 bool ChatHandler::HandleReloadLootTemplatesMillingCommand(const char*)
291 sLog.outString( "Re-Loading Loot Tables... (`milling_loot_template`)" );
292 LoadLootTemplates_Milling();
293 LootTemplates_Milling.CheckLootRefs();
294 SendGlobalSysMessage("DB table `milling_loot_template` reloaded.");
295 return true;
298 bool ChatHandler::HandleReloadLootTemplatesPickpocketingCommand(const char*)
300 sLog.outString( "Re-Loading Loot Tables... (`pickpocketing_loot_template`)" );
301 LoadLootTemplates_Pickpocketing();
302 LootTemplates_Pickpocketing.CheckLootRefs();
303 SendGlobalSysMessage("DB table `pickpocketing_loot_template` reloaded.");
304 return true;
307 bool ChatHandler::HandleReloadLootTemplatesProspectingCommand(const char*)
309 sLog.outString( "Re-Loading Loot Tables... (`prospecting_loot_template`)" );
310 LoadLootTemplates_Prospecting();
311 LootTemplates_Prospecting.CheckLootRefs();
312 SendGlobalSysMessage("DB table `prospecting_loot_template` reloaded.");
313 return true;
316 bool ChatHandler::HandleReloadLootTemplatesQuestMailCommand(const char*)
318 sLog.outString( "Re-Loading Loot Tables... (`quest_mail_loot_template`)" );
319 LoadLootTemplates_QuestMail();
320 LootTemplates_QuestMail.CheckLootRefs();
321 SendGlobalSysMessage("DB table `quest_mail_loot_template` reloaded.");
322 return true;
325 bool ChatHandler::HandleReloadLootTemplatesReferenceCommand(const char*)
327 sLog.outString( "Re-Loading Loot Tables... (`reference_loot_template`)" );
328 LoadLootTemplates_Reference();
329 SendGlobalSysMessage("DB table `reference_loot_template` reloaded.");
330 return true;
333 bool ChatHandler::HandleReloadLootTemplatesSkinningCommand(const char*)
335 sLog.outString( "Re-Loading Loot Tables... (`skinning_loot_template`)" );
336 LoadLootTemplates_Skinning();
337 LootTemplates_Skinning.CheckLootRefs();
338 SendGlobalSysMessage("DB table `skinning_loot_template` reloaded.");
339 return true;
342 bool ChatHandler::HandleReloadMangosStringCommand(const char*)
344 sLog.outString( "Re-Loading mangos_string Table!" );
345 objmgr.LoadMangosStrings();
346 SendGlobalSysMessage("DB table `mangos_string` reloaded.");
347 return true;
350 bool ChatHandler::HandleReloadNpcOptionCommand(const char*)
352 sLog.outString( "Re-Loading `npc_option` Table!" );
353 objmgr.LoadNpcOptions();
354 SendGlobalSysMessage("DB table `npc_option` reloaded.");
355 return true;
358 bool ChatHandler::HandleReloadNpcGossipCommand(const char*)
360 sLog.outString( "Re-Loading `npc_gossip` Table!" );
361 objmgr.LoadNpcTextId();
362 SendGlobalSysMessage("DB table `npc_gossip` reloaded.");
363 return true;
366 bool ChatHandler::HandleReloadNpcTrainerCommand(const char*)
368 sLog.outString( "Re-Loading `npc_trainer` Table!" );
369 objmgr.LoadTrainerSpell();
370 SendGlobalSysMessage("DB table `npc_trainer` reloaded.");
371 return true;
374 bool ChatHandler::HandleReloadNpcVendorCommand(const char*)
376 sLog.outString( "Re-Loading `npc_vendor` Table!" );
377 objmgr.LoadVendors();
378 SendGlobalSysMessage("DB table `npc_vendor` reloaded.");
379 return true;
382 bool ChatHandler::HandleReloadReservedNameCommand(const char*)
384 sLog.outString( "Loading ReservedNames... (`reserved_name`)" );
385 objmgr.LoadReservedPlayersNames();
386 SendGlobalSysMessage("DB table `reserved_name` (player reserved names) reloaded.");
387 return true;
390 bool ChatHandler::HandleReloadSkillDiscoveryTemplateCommand(const char* /*args*/)
392 sLog.outString( "Re-Loading Skill Discovery Table..." );
393 LoadSkillDiscoveryTable();
394 SendGlobalSysMessage("DB table `skill_discovery_template` (recipes discovered at crafting) reloaded.");
395 return true;
398 bool ChatHandler::HandleReloadSkillExtraItemTemplateCommand(const char* /*args*/)
400 sLog.outString( "Re-Loading Skill Extra Item Table..." );
401 LoadSkillExtraItemTable();
402 SendGlobalSysMessage("DB table `skill_extra_item_template` (extra item creation when crafting) reloaded.");
403 return true;
406 bool ChatHandler::HandleReloadSkillFishingBaseLevelCommand(const char* /*args*/)
408 sLog.outString( "Re-Loading Skill Fishing base level requirements..." );
409 objmgr.LoadFishingBaseSkillLevel();
410 SendGlobalSysMessage("DB table `skill_fishing_base_level` (fishing base level for zone/subzone) reloaded.");
411 return true;
414 bool ChatHandler::HandleReloadSpellAffectCommand(const char*)
416 sLog.outString( "Re-Loading SpellAffect definitions..." );
417 spellmgr.LoadSpellAffects();
418 SendGlobalSysMessage("DB table `spell_affect` (spell mods apply requirements) reloaded.");
419 return true;
422 bool ChatHandler::HandleReloadSpellChainCommand(const char*)
424 sLog.outString( "Re-Loading Spell Chain Data... " );
425 spellmgr.LoadSpellChains();
426 SendGlobalSysMessage("DB table `spell_chain` (spell ranks) reloaded.");
427 return true;
430 bool ChatHandler::HandleReloadSpellElixirCommand(const char*)
432 sLog.outString( "Re-Loading Spell Elixir types..." );
433 spellmgr.LoadSpellElixirs();
434 SendGlobalSysMessage("DB table `spell_elixir` (spell elixir types) reloaded.");
435 return true;
438 bool ChatHandler::HandleReloadSpellLearnSpellCommand(const char*)
440 sLog.outString( "Re-Loading Spell Learn Spells..." );
441 spellmgr.LoadSpellLearnSpells();
442 SendGlobalSysMessage("DB table `spell_learn_spell` reloaded.");
443 return true;
446 bool ChatHandler::HandleReloadSpellProcEventCommand(const char*)
448 sLog.outString( "Re-Loading Spell Proc Event conditions..." );
449 spellmgr.LoadSpellProcEvents();
450 SendGlobalSysMessage("DB table `spell_proc_event` (spell proc trigger requirements) reloaded.");
451 return true;
454 bool ChatHandler::HandleReloadSpellScriptTargetCommand(const char*)
456 sLog.outString( "Re-Loading SpellsScriptTarget..." );
457 spellmgr.LoadSpellScriptTarget();
458 SendGlobalSysMessage("DB table `spell_script_target` (spell targets selection in case specific creature/GO requirements) reloaded.");
459 return true;
462 bool ChatHandler::HandleReloadSpellTargetPositionCommand(const char*)
464 sLog.outString( "Re-Loading Spell target coordinates..." );
465 spellmgr.LoadSpellTargetPositions();
466 SendGlobalSysMessage("DB table `spell_target_position` (destination coordinates for spell targets) reloaded.");
467 return true;
470 bool ChatHandler::HandleReloadSpellThreatsCommand(const char*)
472 sLog.outString( "Re-Loading Aggro Spells Definitions...");
473 spellmgr.LoadSpellThreats();
474 SendGlobalSysMessage("DB table `spell_threat` (spell aggro definitions) reloaded.");
475 return true;
478 bool ChatHandler::HandleReloadSpellPetAurasCommand(const char*)
480 sLog.outString( "Re-Loading Spell pet auras...");
481 spellmgr.LoadSpellPetAuras();
482 SendGlobalSysMessage("DB table `spell_pet_auras` reloaded.");
483 return true;
486 bool ChatHandler::HandleReloadPageTextsCommand(const char*)
488 sLog.outString( "Re-Loading Page Texts..." );
489 objmgr.LoadPageTexts();
490 SendGlobalSysMessage("DB table `page_texts` reloaded.");
491 return true;
494 bool ChatHandler::HandleReloadItemEnchantementsCommand(const char*)
496 sLog.outString( "Re-Loading Item Random Enchantments Table..." );
497 LoadRandomEnchantmentsTable();
498 SendGlobalSysMessage("DB table `item_enchantment_template` reloaded.");
499 return true;
502 bool ChatHandler::HandleReloadGameObjectScriptsCommand(const char* arg)
504 if(sWorld.IsScriptScheduled())
506 SendSysMessage("DB scripts used currently, please attempt reload later.");
507 SetSentErrorMessage(true);
508 return false;
511 if(*arg!='a')
512 sLog.outString( "Re-Loading Scripts from `gameobject_scripts`...");
514 objmgr.LoadGameObjectScripts();
516 if(*arg!='a')
517 SendGlobalSysMessage("DB table `gameobject_scripts` reloaded.");
519 return true;
522 bool ChatHandler::HandleReloadEventScriptsCommand(const char* arg)
524 if(sWorld.IsScriptScheduled())
526 SendSysMessage("DB scripts used currently, please attempt reload later.");
527 SetSentErrorMessage(true);
528 return false;
531 if(*arg!='a')
532 sLog.outString( "Re-Loading Scripts from `event_scripts`...");
534 objmgr.LoadEventScripts();
536 if(*arg!='a')
537 SendGlobalSysMessage("DB table `event_scripts` reloaded.");
539 return true;
542 bool ChatHandler::HandleReloadQuestEndScriptsCommand(const char* arg)
544 if(sWorld.IsScriptScheduled())
546 SendSysMessage("DB scripts used currently, please attempt reload later.");
547 SetSentErrorMessage(true);
548 return false;
551 if(*arg!='a')
552 sLog.outString( "Re-Loading Scripts from `quest_end_scripts`...");
554 objmgr.LoadQuestEndScripts();
556 if(*arg!='a')
557 SendGlobalSysMessage("DB table `quest_end_scripts` reloaded.");
559 return true;
562 bool ChatHandler::HandleReloadQuestStartScriptsCommand(const char* arg)
564 if(sWorld.IsScriptScheduled())
566 SendSysMessage("DB scripts used currently, please attempt reload later.");
567 SetSentErrorMessage(true);
568 return false;
571 if(*arg!='a')
572 sLog.outString( "Re-Loading Scripts from `quest_start_scripts`...");
574 objmgr.LoadQuestStartScripts();
576 if(*arg!='a')
577 SendGlobalSysMessage("DB table `quest_start_scripts` reloaded.");
579 return true;
582 bool ChatHandler::HandleReloadSpellScriptsCommand(const char* arg)
584 if(sWorld.IsScriptScheduled())
586 SendSysMessage("DB scripts used currently, please attempt reload later.");
587 SetSentErrorMessage(true);
588 return false;
591 if(*arg!='a')
592 sLog.outString( "Re-Loading Scripts from `spell_scripts`...");
594 objmgr.LoadSpellScripts();
596 if(*arg!='a')
597 SendGlobalSysMessage("DB table `spell_scripts` reloaded.");
599 return true;
602 bool ChatHandler::HandleReloadDbScriptStringCommand(const char* arg)
604 sLog.outString( "Re-Loading Script strings from `db_script_string`...");
605 objmgr.LoadDbScriptStrings();
606 SendGlobalSysMessage("DB table `db_script_string` reloaded.");
607 return true;
610 bool ChatHandler::HandleReloadGameGraveyardZoneCommand(const char* /*arg*/)
612 sLog.outString( "Re-Loading Graveyard-zone links...");
614 objmgr.LoadGraveyardZones();
616 SendGlobalSysMessage("DB table `game_graveyard_zone` reloaded.");
618 return true;
621 bool ChatHandler::HandleReloadGameTeleCommand(const char* /*arg*/)
623 sLog.outString( "Re-Loading Game Tele coordinates...");
625 objmgr.LoadGameTele();
627 SendGlobalSysMessage("DB table `game_tele` reloaded.");
629 return true;
632 bool ChatHandler::HandleReloadLocalesCreatureCommand(const char* /*arg*/)
634 sLog.outString( "Re-Loading Locales Creature ...");
635 objmgr.LoadCreatureLocales();
636 SendGlobalSysMessage("DB table `locales_creature` reloaded.");
637 return true;
640 bool ChatHandler::HandleReloadLocalesGameobjectCommand(const char* /*arg*/)
642 sLog.outString( "Re-Loading Locales Gameobject ... ");
643 objmgr.LoadGameObjectLocales();
644 SendGlobalSysMessage("DB table `locales_gameobject` reloaded.");
645 return true;
648 bool ChatHandler::HandleReloadLocalesItemCommand(const char* /*arg*/)
650 sLog.outString( "Re-Loading Locales Item ... ");
651 objmgr.LoadItemLocales();
652 SendGlobalSysMessage("DB table `locales_item` reloaded.");
653 return true;
656 bool ChatHandler::HandleReloadLocalesNpcTextCommand(const char* /*arg*/)
658 sLog.outString( "Re-Loading Locales NPC Text ... ");
659 objmgr.LoadNpcTextLocales();
660 SendGlobalSysMessage("DB table `locales_npc_text` reloaded.");
661 return true;
664 bool ChatHandler::HandleReloadLocalesPageTextCommand(const char* /*arg*/)
666 sLog.outString( "Re-Loading Locales Page Text ... ");
667 objmgr.LoadPageTextLocales();
668 SendGlobalSysMessage("DB table `locales_page_text` reloaded.");
669 return true;
672 bool ChatHandler::HandleReloadLocalesQuestCommand(const char* /*arg*/)
674 sLog.outString( "Re-Loading Locales Quest ... ");
675 objmgr.LoadQuestLocales();
676 SendGlobalSysMessage("DB table `locales_quest` reloaded.");
677 return true;
680 bool ChatHandler::HandleLoadScriptsCommand(const char* args)
682 if(!LoadScriptingModule(args)) return true;
684 sWorld.SendWorldText(LANG_SCRIPTS_RELOADED);
685 return true;
688 bool ChatHandler::HandleAccountSetGmLevelCommand(const char* args)
690 char* arg1 = strtok((char*)args, " ");
691 if( !arg1 )
692 return false;
694 /// must be NULL if targeted syntax and must be not nULL if not targeted
695 char* arg2 = strtok(NULL, " ");
697 std::string targetAccountName;
698 uint32 targetAccountId = 0;
700 /// only target player different from self allowed (if targetPlayer!=NULL then not console)
701 Player* targetPlayer = getSelectedPlayer();
702 if(targetPlayer && m_session->GetPlayer()!=targetPlayer)
704 /// wrong command syntax or unexpected targeting
705 if(arg2)
706 return false;
708 /// security level expected in arg2 after this if.
709 arg2 = arg1;
711 targetAccountId = targetPlayer->GetSession()->GetAccountId();
713 else
715 /// wrong command syntax (second arg expected)
716 if(!arg2)
717 return false;
719 targetAccountName = arg1;
720 if(!AccountMgr::normilizeString(targetAccountName))
722 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,targetAccountName.c_str());
723 SetSentErrorMessage(true);
724 return false;
727 targetAccountId = accmgr.GetId(targetAccountName);
728 if(!targetAccountId)
730 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,targetAccountName.c_str());
731 SetSentErrorMessage(true);
732 return false;
736 int32 gm = (int32)atoi(arg2);
737 if ( gm < SEC_PLAYER || gm > SEC_ADMINISTRATOR )
739 SendSysMessage(LANG_BAD_VALUE);
740 SetSentErrorMessage(true);
741 return false;
744 /// can set security level only for target with less security and to less security that we have
745 /// This is also reject self apply in fact
746 if(HasLowerSecurityAccount(NULL,targetAccountId,true))
747 return false;
749 /// account can't set security to same or grater level, need more power GM or console
750 uint32 plSecurity = m_session ? m_session->GetSecurity() : SEC_CONSOLE;
751 if (uint32(gm) >= plSecurity )
753 SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
754 SetSentErrorMessage(true);
755 return false;
758 if(targetPlayer)
760 ChatHandler(targetPlayer).PSendSysMessage(LANG_YOURS_SECURITY_CHANGED,GetName(), gm);
761 targetPlayer->GetSession()->SetSecurity(gm);
764 PSendSysMessage(LANG_YOU_CHANGE_SECURITY, targetAccountName.c_str(), gm);
765 loginDatabase.PExecute("UPDATE account SET gmlevel = '%i' WHERE id = '%u'", gm, targetAccountId);
767 return true;
770 /// Set password for account
771 bool ChatHandler::HandleAccountSetPasswordCommand(const char* args)
773 if(!*args)
774 return false;
776 ///- Get the command line arguments
777 char *szAccount = strtok ((char*)args," ");
778 char *szPassword1 = strtok (NULL," ");
779 char *szPassword2 = strtok (NULL," ");
781 if (!szAccount||!szPassword1 || !szPassword2)
782 return false;
784 std::string account_name = szAccount;
785 if(!AccountMgr::normilizeString(account_name))
787 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
788 SetSentErrorMessage(true);
789 return false;
792 uint32 targetAccountId = accmgr.GetId(account_name);
793 if (!targetAccountId)
795 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
796 SetSentErrorMessage(true);
797 return false;
800 /// can set password only for target with less security
801 /// This is also reject self apply in fact
802 if(HasLowerSecurityAccount (NULL,targetAccountId,true))
803 return false;
805 if (strcmp(szPassword1,szPassword2))
807 SendSysMessage (LANG_NEW_PASSWORDS_NOT_MATCH);
808 SetSentErrorMessage (true);
809 return false;
812 AccountOpResult result = accmgr.ChangePassword(targetAccountId, szPassword1);
814 switch(result)
816 case AOR_OK:
817 SendSysMessage(LANG_COMMAND_PASSWORD);
818 break;
819 case AOR_NAME_NOT_EXIST:
820 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
821 SetSentErrorMessage(true);
822 return false;
823 case AOR_PASS_TOO_LONG:
824 SendSysMessage(LANG_PASSWORD_TOO_LONG);
825 SetSentErrorMessage(true);
826 return false;
827 default:
828 SendSysMessage(LANG_COMMAND_NOTCHANGEPASSWORD);
829 SetSentErrorMessage(true);
830 return false;
833 return true;
836 bool ChatHandler::HandleAllowMovementCommand(const char* /*args*/)
838 if(sWorld.getAllowMovement())
840 sWorld.SetAllowMovement(false);
841 SendSysMessage(LANG_CREATURE_MOVE_DISABLED);
843 else
845 sWorld.SetAllowMovement(true);
846 SendSysMessage(LANG_CREATURE_MOVE_ENABLED);
848 return true;
851 bool ChatHandler::HandleMaxSkillCommand(const char* /*args*/)
853 Player* SelectedPlayer = getSelectedPlayer();
854 if(!SelectedPlayer)
856 SendSysMessage(LANG_NO_CHAR_SELECTED);
857 SetSentErrorMessage(true);
858 return false;
861 // each skills that have max skill value dependent from level seted to current level max skill value
862 SelectedPlayer->UpdateSkillsToMaxSkillsForLevel();
863 return true;
866 bool ChatHandler::HandleSetSkillCommand(const char* args)
868 // number or [name] Shift-click form |color|Hskill:skill_id|h[name]|h|r
869 char* skill_p = extractKeyFromLink((char*)args,"Hskill");
870 if(!skill_p)
871 return false;
873 char *level_p = strtok (NULL, " ");
875 if( !level_p)
876 return false;
878 char *max_p = strtok (NULL, " ");
880 int32 skill = atoi(skill_p);
882 if (skill <= 0)
884 PSendSysMessage(LANG_INVALID_SKILL_ID, skill);
885 SetSentErrorMessage(true);
886 return false;
889 int32 level = atol (level_p);
891 Player * target = getSelectedPlayer();
892 if(!target)
894 SendSysMessage(LANG_NO_CHAR_SELECTED);
895 SetSentErrorMessage(true);
896 return false;
899 SkillLineEntry const* sl = sSkillLineStore.LookupEntry(skill);
900 if(!sl)
902 PSendSysMessage(LANG_INVALID_SKILL_ID, skill);
903 SetSentErrorMessage(true);
904 return false;
907 if(!target->GetSkillValue(skill))
909 PSendSysMessage(LANG_SET_SKILL_ERROR, target->GetName(), skill, sl->name[0]);
910 SetSentErrorMessage(true);
911 return false;
914 int32 max = max_p ? atol (max_p) : target->GetPureMaxSkillValue(skill);
916 if( level <= 0 || level > max || max <= 0 )
917 return false;
919 target->SetSkill(skill, level, max);
920 PSendSysMessage(LANG_SET_SKILL, skill, sl->name[0], target->GetName(), level, max);
922 return true;
925 bool ChatHandler::HandleUnLearnCommand(const char* args)
927 if (!*args)
928 return false;
930 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
931 uint32 min_id = extractSpellIdFromLink((char*)args);
932 if(!min_id)
933 return false;
935 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
936 char* tail = strtok(NULL,"");
938 uint32 max_id = extractSpellIdFromLink(tail);
940 if (!max_id)
942 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
943 max_id = min_id+1;
945 else
947 if (max_id < min_id)
948 std::swap(min_id,max_id);
950 max_id=max_id+1;
953 Player* target = getSelectedPlayer();
954 if(!target)
956 SendSysMessage(LANG_NO_CHAR_SELECTED);
957 SetSentErrorMessage(true);
958 return false;
961 for(uint32 spell=min_id;spell<max_id;spell++)
963 if (target->HasSpell(spell))
964 target->removeSpell(spell);
965 else
966 SendSysMessage(LANG_FORGET_SPELL);
969 return true;
972 bool ChatHandler::HandleCooldownCommand(const char* args)
974 Player* target = getSelectedPlayer();
975 if(!target)
977 SendSysMessage(LANG_PLAYER_NOT_FOUND);
978 SetSentErrorMessage(true);
979 return false;
982 if (!*args)
984 target->RemoveAllSpellCooldown();
985 PSendSysMessage(LANG_REMOVEALL_COOLDOWN, target->GetName());
987 else
989 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
990 uint32 spell_id = extractSpellIdFromLink((char*)args);
991 if(!spell_id)
992 return false;
994 if(!sSpellStore.LookupEntry(spell_id))
996 PSendSysMessage(LANG_UNKNOWN_SPELL, target==m_session->GetPlayer() ? GetMangosString(LANG_YOU) : target->GetName());
997 SetSentErrorMessage(true);
998 return false;
1001 WorldPacket data( SMSG_CLEAR_COOLDOWN, (4+8) );
1002 data << uint32(spell_id);
1003 data << uint64(target->GetGUID());
1004 target->GetSession()->SendPacket(&data);
1005 target->RemoveSpellCooldown(spell_id);
1006 PSendSysMessage(LANG_REMOVE_COOLDOWN, spell_id, target==m_session->GetPlayer() ? GetMangosString(LANG_YOU) : target->GetName());
1008 return true;
1011 bool ChatHandler::HandleLearnAllCommand(const char* /*args*/)
1013 static const char *allSpellList[] =
1015 "3365",
1016 "6233",
1017 "6247",
1018 "6246",
1019 "6477",
1020 "6478",
1021 "22810",
1022 "8386",
1023 "21651",
1024 "21652",
1025 "522",
1026 "7266",
1027 "8597",
1028 "2479",
1029 "22027",
1030 "6603",
1031 "5019",
1032 "133",
1033 "168",
1034 "227",
1035 "5009",
1036 "9078",
1037 "668",
1038 "203",
1039 "20599",
1040 "20600",
1041 "81",
1042 "20597",
1043 "20598",
1044 "20864",
1045 "1459",
1046 "5504",
1047 "587",
1048 "5143",
1049 "118",
1050 "5505",
1051 "597",
1052 "604",
1053 "1449",
1054 "1460",
1055 "2855",
1056 "1008",
1057 "475",
1058 "5506",
1059 "1463",
1060 "12824",
1061 "8437",
1062 "990",
1063 "5145",
1064 "8450",
1065 "1461",
1066 "759",
1067 "8494",
1068 "8455",
1069 "8438",
1070 "6127",
1071 "8416",
1072 "6129",
1073 "8451",
1074 "8495",
1075 "8439",
1076 "3552",
1077 "8417",
1078 "10138",
1079 "12825",
1080 "10169",
1081 "10156",
1082 "10144",
1083 "10191",
1084 "10201",
1085 "10211",
1086 "10053",
1087 "10173",
1088 "10139",
1089 "10145",
1090 "10192",
1091 "10170",
1092 "10202",
1093 "10054",
1094 "10174",
1095 "10193",
1096 "12826",
1097 "2136",
1098 "143",
1099 "145",
1100 "2137",
1101 "2120",
1102 "3140",
1103 "543",
1104 "2138",
1105 "2948",
1106 "8400",
1107 "2121",
1108 "8444",
1109 "8412",
1110 "8457",
1111 "8401",
1112 "8422",
1113 "8445",
1114 "8402",
1115 "8413",
1116 "8458",
1117 "8423",
1118 "8446",
1119 "10148",
1120 "10197",
1121 "10205",
1122 "10149",
1123 "10215",
1124 "10223",
1125 "10206",
1126 "10199",
1127 "10150",
1128 "10216",
1129 "10207",
1130 "10225",
1131 "10151",
1132 "116",
1133 "205",
1134 "7300",
1135 "122",
1136 "837",
1137 "10",
1138 "7301",
1139 "7322",
1140 "6143",
1141 "120",
1142 "865",
1143 "8406",
1144 "6141",
1145 "7302",
1146 "8461",
1147 "8407",
1148 "8492",
1149 "8427",
1150 "8408",
1151 "6131",
1152 "7320",
1153 "10159",
1154 "8462",
1155 "10185",
1156 "10179",
1157 "10160",
1158 "10180",
1159 "10219",
1160 "10186",
1161 "10177",
1162 "10230",
1163 "10181",
1164 "10161",
1165 "10187",
1166 "10220",
1167 "2018",
1168 "2663",
1169 "12260",
1170 "2660",
1171 "3115",
1172 "3326",
1173 "2665",
1174 "3116",
1175 "2738",
1176 "3293",
1177 "2661",
1178 "3319",
1179 "2662",
1180 "9983",
1181 "8880",
1182 "2737",
1183 "2739",
1184 "7408",
1185 "3320",
1186 "2666",
1187 "3323",
1188 "3324",
1189 "3294",
1190 "22723",
1191 "23219",
1192 "23220",
1193 "23221",
1194 "23228",
1195 "23338",
1196 "10788",
1197 "10790",
1198 "5611",
1199 "5016",
1200 "5609",
1201 "2060",
1202 "10963",
1203 "10964",
1204 "10965",
1205 "22593",
1206 "22594",
1207 "596",
1208 "996",
1209 "499",
1210 "768",
1211 "17002",
1212 "1448",
1213 "1082",
1214 "16979",
1215 "1079",
1216 "5215",
1217 "20484",
1218 "5221",
1219 "15590",
1220 "17007",
1221 "6795",
1222 "6807",
1223 "5487",
1224 "1446",
1225 "1066",
1226 "5421",
1227 "3139",
1228 "779",
1229 "6811",
1230 "6808",
1231 "1445",
1232 "5216",
1233 "1737",
1234 "5222",
1235 "5217",
1236 "1432",
1237 "6812",
1238 "9492",
1239 "5210",
1240 "3030",
1241 "1441",
1242 "783",
1243 "6801",
1244 "20739",
1245 "8944",
1246 "9491",
1247 "22569",
1248 "5226",
1249 "6786",
1250 "1433",
1251 "8973",
1252 "1828",
1253 "9495",
1254 "9006",
1255 "6794",
1256 "8993",
1257 "5203",
1258 "16914",
1259 "6784",
1260 "9635",
1261 "22830",
1262 "20722",
1263 "9748",
1264 "6790",
1265 "9753",
1266 "9493",
1267 "9752",
1268 "9831",
1269 "9825",
1270 "9822",
1271 "5204",
1272 "5401",
1273 "22831",
1274 "6793",
1275 "9845",
1276 "17401",
1277 "9882",
1278 "9868",
1279 "20749",
1280 "9893",
1281 "9899",
1282 "9895",
1283 "9832",
1284 "9902",
1285 "9909",
1286 "22832",
1287 "9828",
1288 "9851",
1289 "9883",
1290 "9869",
1291 "17406",
1292 "17402",
1293 "9914",
1294 "20750",
1295 "9897",
1296 "9848",
1297 "3127",
1298 "107",
1299 "204",
1300 "9116",
1301 "2457",
1302 "78",
1303 "18848",
1304 "331",
1305 "403",
1306 "2098",
1307 "1752",
1308 "11278",
1309 "11288",
1310 "11284",
1311 "6461",
1312 "2344",
1313 "2345",
1314 "6463",
1315 "2346",
1316 "2352",
1317 "775",
1318 "1434",
1319 "1612",
1320 "71",
1321 "2468",
1322 "2458",
1323 "2467",
1324 "7164",
1325 "7178",
1326 "7367",
1327 "7376",
1328 "7381",
1329 "21156",
1330 "5209",
1331 "3029",
1332 "5201",
1333 "9849",
1334 "9850",
1335 "20719",
1336 "22568",
1337 "22827",
1338 "22828",
1339 "22829",
1340 "6809",
1341 "8972",
1342 "9005",
1343 "9823",
1344 "9827",
1345 "6783",
1346 "9913",
1347 "6785",
1348 "6787",
1349 "9866",
1350 "9867",
1351 "9894",
1352 "9896",
1353 "6800",
1354 "8992",
1355 "9829",
1356 "9830",
1357 "780",
1358 "769",
1359 "6749",
1360 "6750",
1361 "9755",
1362 "9754",
1363 "9908",
1364 "20745",
1365 "20742",
1366 "20747",
1367 "20748",
1368 "9746",
1369 "9745",
1370 "9880",
1371 "9881",
1372 "5391",
1373 "842",
1374 "3025",
1375 "3031",
1376 "3287",
1377 "3329",
1378 "1945",
1379 "3559",
1380 "4933",
1381 "4934",
1382 "4935",
1383 "4936",
1384 "5142",
1385 "5390",
1386 "5392",
1387 "5404",
1388 "5420",
1389 "6405",
1390 "7293",
1391 "7965",
1392 "8041",
1393 "8153",
1394 "9033",
1395 "9034",
1396 //"9036", problems with ghost state
1397 "16421",
1398 "21653",
1399 "22660",
1400 "5225",
1401 "9846",
1402 "2426",
1403 "5916",
1404 "6634",
1405 //"6718", phasing stealth, annoying for learn all case.
1406 "6719",
1407 "8822",
1408 "9591",
1409 "9590",
1410 "10032",
1411 "17746",
1412 "17747",
1413 "8203",
1414 "11392",
1415 "12495",
1416 "16380",
1417 "23452",
1418 "4079",
1419 "4996",
1420 "4997",
1421 "4998",
1422 "4999",
1423 "5000",
1424 "6348",
1425 "6349",
1426 "6481",
1427 "6482",
1428 "6483",
1429 "6484",
1430 "11362",
1431 "11410",
1432 "11409",
1433 "12510",
1434 "12509",
1435 "12885",
1436 "13142",
1437 "21463",
1438 "23460",
1439 "11421",
1440 "11416",
1441 "11418",
1442 "1851",
1443 "10059",
1444 "11423",
1445 "11417",
1446 "11422",
1447 "11419",
1448 "11424",
1449 "11420",
1450 "27",
1451 "31",
1452 "33",
1453 "34",
1454 "35",
1455 "15125",
1456 "21127",
1457 "22950",
1458 "1180",
1459 "201",
1460 "12593",
1461 "12842",
1462 "16770",
1463 "6057",
1464 "12051",
1465 "18468",
1466 "12606",
1467 "12605",
1468 "18466",
1469 "12502",
1470 "12043",
1471 "15060",
1472 "12042",
1473 "12341",
1474 "12848",
1475 "12344",
1476 "12353",
1477 "18460",
1478 "11366",
1479 "12350",
1480 "12352",
1481 "13043",
1482 "11368",
1483 "11113",
1484 "12400",
1485 "11129",
1486 "16766",
1487 "12573",
1488 "15053",
1489 "12580",
1490 "12475",
1491 "12472",
1492 "12953",
1493 "12488",
1494 "11189",
1495 "12985",
1496 "12519",
1497 "16758",
1498 "11958",
1499 "12490",
1500 "11426",
1501 "3565",
1502 "3562",
1503 "18960",
1504 "3567",
1505 "3561",
1506 "3566",
1507 "3563",
1508 "1953",
1509 "2139",
1510 "12505",
1511 "13018",
1512 "12522",
1513 "12523",
1514 "5146",
1515 "5144",
1516 "5148",
1517 "8419",
1518 "8418",
1519 "10213",
1520 "10212",
1521 "10157",
1522 "12524",
1523 "13019",
1524 "12525",
1525 "13020",
1526 "12526",
1527 "13021",
1528 "18809",
1529 "13031",
1530 "13032",
1531 "13033",
1532 "4036",
1533 "3920",
1534 "3919",
1535 "3918",
1536 "7430",
1537 "3922",
1538 "3923",
1539 "7411",
1540 "7418",
1541 "7421",
1542 "13262",
1543 "7412",
1544 "7415",
1545 "7413",
1546 "7416",
1547 "13920",
1548 "13921",
1549 "7745",
1550 "7779",
1551 "7428",
1552 "7457",
1553 "7857",
1554 "7748",
1555 "7426",
1556 "13421",
1557 "7454",
1558 "13378",
1559 "7788",
1560 "14807",
1561 "14293",
1562 "7795",
1563 "6296",
1564 "20608",
1565 "755",
1566 "444",
1567 "427",
1568 "428",
1569 "442",
1570 "447",
1571 "3578",
1572 "3581",
1573 "19027",
1574 "3580",
1575 "665",
1576 "3579",
1577 "3577",
1578 "6755",
1579 "3576",
1580 "2575",
1581 "2577",
1582 "2578",
1583 "2579",
1584 "2580",
1585 "2656",
1586 "2657",
1587 "2576",
1588 "3564",
1589 "10248",
1590 "8388",
1591 "2659",
1592 "14891",
1593 "3308",
1594 "3307",
1595 "10097",
1596 "2658",
1597 "3569",
1598 "16153",
1599 "3304",
1600 "10098",
1601 "4037",
1602 "3929",
1603 "3931",
1604 "3926",
1605 "3924",
1606 "3930",
1607 "3977",
1608 "3925",
1609 "136",
1610 "228",
1611 "5487",
1612 "43",
1613 "202",
1617 int loop = 0;
1618 while(strcmp(allSpellList[loop], "0"))
1620 uint32 spell = atol((char*)allSpellList[loop++]);
1622 if (m_session->GetPlayer()->HasSpell(spell))
1623 continue;
1625 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
1626 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
1628 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
1629 continue;
1632 m_session->GetPlayer()->learnSpell(spell);
1635 SendSysMessage(LANG_COMMAND_LEARN_MANY_SPELLS);
1637 return true;
1640 bool ChatHandler::HandleLearnAllGMCommand(const char* /*args*/)
1642 static const char *gmSpellList[] =
1644 "24347", // Become A Fish, No Breath Bar
1645 "35132", // Visual Boom
1646 "38488", // Attack 4000-8000 AOE
1647 "38795", // Attack 2000 AOE + Slow Down 90%
1648 "15712", // Attack 200
1649 "1852", // GM Spell Silence
1650 "31899", // Kill
1651 "31924", // Kill
1652 "29878", // Kill My Self
1653 "26644", // More Kill
1655 "28550", //Invisible 24
1656 "23452", //Invisible + Target
1660 uint16 gmSpellIter = 0;
1661 while( strcmp(gmSpellList[gmSpellIter], "0") )
1663 uint32 spell = atol((char*)gmSpellList[gmSpellIter++]);
1665 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
1666 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
1668 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
1669 continue;
1672 m_session->GetPlayer()->learnSpell(spell);
1675 SendSysMessage(LANG_LEARNING_GM_SKILLS);
1676 return true;
1679 bool ChatHandler::HandleLearnAllMyClassCommand(const char* /*args*/)
1681 HandleLearnAllMySpellsCommand("");
1682 HandleLearnAllMyTalentsCommand("");
1683 return true;
1686 bool ChatHandler::HandleLearnAllMySpellsCommand(const char* /*args*/)
1688 ChrClassesEntry const* clsEntry = sChrClassesStore.LookupEntry(m_session->GetPlayer()->getClass());
1689 if(!clsEntry)
1690 return true;
1691 uint32 family = clsEntry->spellfamily;
1693 for (uint32 i = 0; i < sSpellStore.GetNumRows(); i++)
1695 SpellEntry const *spellInfo = sSpellStore.LookupEntry(i);
1696 if(!spellInfo)
1697 continue;
1699 // skip server-side/triggered spells
1700 if(spellInfo->spellLevel==0)
1701 continue;
1703 // skip wrong class/race skills
1704 if(!m_session->GetPlayer()->IsSpellFitByClassAndRace(spellInfo->Id))
1705 continue;
1707 // skip other spell families
1708 if( spellInfo->SpellFamilyName != family)
1709 continue;
1711 // skip spells with first rank learned as talent (and all talents then also)
1712 uint32 first_rank = spellmgr.GetFirstSpellInChain(spellInfo->Id);
1713 if(GetTalentSpellCost(first_rank) > 0 )
1714 continue;
1716 // skip broken spells
1717 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
1718 continue;
1720 m_session->GetPlayer()->learnSpell(i);
1723 SendSysMessage(LANG_COMMAND_LEARN_CLASS_SPELLS);
1724 return true;
1727 static void learnAllHighRanks(Player* player, uint32 spellid)
1729 SpellChainMapNext const& nextMap = spellmgr.GetSpellChainNext();
1730 for(SpellChainMapNext::const_iterator itr = nextMap.lower_bound(spellid); itr != nextMap.upper_bound(spellid); ++itr)
1732 player->learnSpell(itr->second);
1733 learnAllHighRanks(player,itr->second);
1737 bool ChatHandler::HandleLearnAllMyTalentsCommand(const char* /*args*/)
1739 Player* player = m_session->GetPlayer();
1740 uint32 classMask = player->getClassMask();
1742 for (uint32 i = 0; i < sTalentStore.GetNumRows(); i++)
1744 TalentEntry const *talentInfo = sTalentStore.LookupEntry(i);
1745 if(!talentInfo)
1746 continue;
1748 TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab );
1749 if(!talentTabInfo)
1750 continue;
1752 if( (classMask & talentTabInfo->ClassMask) == 0 )
1753 continue;
1755 // search highest talent rank
1756 uint32 spellid = 0;
1757 int rank = 4;
1758 for(; rank >= 0; --rank)
1760 if(talentInfo->RankID[rank]!=0)
1762 spellid = talentInfo->RankID[rank];
1763 break;
1767 if(!spellid) // ??? none spells in talent
1768 continue;
1770 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid);
1771 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
1772 continue;
1774 // learn highest rank of talent
1775 player->learnSpell(spellid);
1777 // and learn all non-talent spell ranks (recursive by tree)
1778 learnAllHighRanks(player,spellid);
1781 SendSysMessage(LANG_COMMAND_LEARN_CLASS_TALENTS);
1782 return true;
1785 bool ChatHandler::HandleLearnAllLangCommand(const char* /*args*/)
1787 // skipping UNIVERSAL language (0)
1788 for(int i = 1; i < LANGUAGES_COUNT; ++i)
1789 m_session->GetPlayer()->learnSpell(lang_description[i].spell_id);
1791 SendSysMessage(LANG_COMMAND_LEARN_ALL_LANG);
1792 return true;
1795 bool ChatHandler::HandleLearnAllDefaultCommand(const char* args)
1797 char* pName = strtok((char*)args, "");
1798 Player *player = NULL;
1799 if (pName)
1801 std::string name = pName;
1803 if(!normalizePlayerName(name))
1805 SendSysMessage(LANG_PLAYER_NOT_FOUND);
1806 SetSentErrorMessage(true);
1807 return false;
1810 player = objmgr.GetPlayer(name.c_str());
1812 else
1813 player = getSelectedPlayer();
1815 if(!player)
1817 SendSysMessage(LANG_NO_CHAR_SELECTED);
1818 SetSentErrorMessage(true);
1819 return false;
1822 player->learnDefaultSpells();
1823 player->learnQuestRewardedSpells();
1825 PSendSysMessage(LANG_COMMAND_LEARN_ALL_DEFAULT_AND_QUEST,player->GetName());
1826 return true;
1829 bool ChatHandler::HandleLearnCommand(const char* args)
1831 Player* targetPlayer = getSelectedPlayer();
1833 if(!targetPlayer)
1835 SendSysMessage(LANG_PLAYER_NOT_FOUND);
1836 SetSentErrorMessage(true);
1837 return false;
1840 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
1841 uint32 spell = extractSpellIdFromLink((char*)args);
1842 if(!spell || !sSpellStore.LookupEntry(spell))
1843 return false;
1845 if (targetPlayer->HasSpell(spell))
1847 if(targetPlayer == m_session->GetPlayer())
1848 SendSysMessage(LANG_YOU_KNOWN_SPELL);
1849 else
1850 PSendSysMessage(LANG_TARGET_KNOWN_SPELL,targetPlayer->GetName());
1851 SetSentErrorMessage(true);
1852 return false;
1855 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
1856 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
1858 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
1859 SetSentErrorMessage(true);
1860 return false;
1863 targetPlayer->learnSpell(spell);
1865 return true;
1868 bool ChatHandler::HandleAddItemCommand(const char* args)
1870 if (!*args)
1871 return false;
1873 uint32 itemId = 0;
1875 if(args[0]=='[') // [name] manual form
1877 char* citemName = citemName = strtok((char*)args, "]");
1879 if(citemName && citemName[0])
1881 std::string itemName = citemName+1;
1882 WorldDatabase.escape_string(itemName);
1883 QueryResult *result = WorldDatabase.PQuery("SELECT entry FROM item_template WHERE name = '%s'", itemName.c_str());
1884 if (!result)
1886 PSendSysMessage(LANG_COMMAND_COULDNOTFIND, citemName+1);
1887 SetSentErrorMessage(true);
1888 return false;
1890 itemId = result->Fetch()->GetUInt16();
1891 delete result;
1893 else
1894 return false;
1896 else // item_id or [name] Shift-click form |color|Hitem:item_id:0:0:0|h[name]|h|r
1898 char* cId = extractKeyFromLink((char*)args,"Hitem");
1899 if(!cId)
1900 return false;
1901 itemId = atol(cId);
1904 char* ccount = strtok(NULL, " ");
1906 int32 count = 1;
1908 if (ccount)
1909 count = strtol(ccount, NULL, 10);
1911 if (count == 0)
1912 count = 1;
1914 Player* pl = m_session->GetPlayer();
1915 Player* plTarget = getSelectedPlayer();
1916 if(!plTarget)
1917 plTarget = pl;
1919 sLog.outDetail(GetMangosString(LANG_ADDITEM), itemId, count);
1921 ItemPrototype const *pProto = objmgr.GetItemPrototype(itemId);
1922 if(!pProto)
1924 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId);
1925 SetSentErrorMessage(true);
1926 return false;
1929 //Subtract
1930 if (count < 0)
1932 plTarget->DestroyItemCount(itemId, -count, true, false);
1933 PSendSysMessage(LANG_REMOVEITEM, itemId, -count, plTarget->GetName());
1934 return true;
1937 //Adding items
1938 uint32 noSpaceForCount = 0;
1940 // check space and find places
1941 ItemPosCountVec dest;
1942 uint8 msg = plTarget->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, itemId, count, &noSpaceForCount );
1943 if( msg != EQUIP_ERR_OK ) // convert to possible store amount
1944 count -= noSpaceForCount;
1946 if( count == 0 || dest.empty()) // can't add any
1948 PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount );
1949 SetSentErrorMessage(true);
1950 return false;
1953 Item* item = plTarget->StoreNewItem( dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId));
1955 // remove binding (let GM give it to another player later)
1956 if(pl==plTarget)
1957 for(ItemPosCountVec::const_iterator itr = dest.begin(); itr != dest.end(); ++itr)
1958 if(Item* item1 = pl->GetItemByPos(itr->pos))
1959 item1->SetBinding( false );
1961 if(count > 0 && item)
1963 pl->SendNewItem(item,count,false,true);
1964 if(pl!=plTarget)
1965 plTarget->SendNewItem(item,count,true,false);
1968 if(noSpaceForCount > 0)
1969 PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount);
1971 return true;
1974 bool ChatHandler::HandleAddItemSetCommand(const char* args)
1976 if (!*args)
1977 return false;
1979 char* cId = extractKeyFromLink((char*)args,"Hitemset"); // number or [name] Shift-click form |color|Hitemset:itemset_id|h[name]|h|r
1980 if (!cId)
1981 return false;
1983 uint32 itemsetId = atol(cId);
1985 // prevent generation all items with itemset field value '0'
1986 if (itemsetId == 0)
1988 PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND,itemsetId);
1989 SetSentErrorMessage(true);
1990 return false;
1993 Player* pl = m_session->GetPlayer();
1994 Player* plTarget = getSelectedPlayer();
1995 if(!plTarget)
1996 plTarget = pl;
1998 sLog.outDetail(GetMangosString(LANG_ADDITEMSET), itemsetId);
2000 bool found = false;
2001 for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
2003 ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype>(id);
2004 if (!pProto)
2005 continue;
2007 if (pProto->ItemSet == itemsetId)
2009 found = true;
2010 ItemPosCountVec dest;
2011 uint8 msg = plTarget->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, pProto->ItemId, 1 );
2012 if (msg == EQUIP_ERR_OK)
2014 Item* item = plTarget->StoreNewItem( dest, pProto->ItemId, true);
2016 // remove binding (let GM give it to another player later)
2017 if (pl==plTarget)
2018 item->SetBinding( false );
2020 pl->SendNewItem(item,1,false,true);
2021 if (pl!=plTarget)
2022 plTarget->SendNewItem(item,1,true,false);
2024 else
2026 pl->SendEquipError( msg, NULL, NULL );
2027 PSendSysMessage(LANG_ITEM_CANNOT_CREATE, pProto->ItemId, 1);
2032 if (!found)
2034 PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND,itemsetId);
2036 SetSentErrorMessage(true);
2037 return false;
2040 return true;
2043 bool ChatHandler::HandleListItemCommand(const char* args)
2045 if(!*args)
2046 return false;
2048 char* cId = extractKeyFromLink((char*)args,"Hitem");
2049 if(!cId)
2050 return false;
2052 uint32 item_id = atol(cId);
2053 if(!item_id)
2055 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
2056 SetSentErrorMessage(true);
2057 return false;
2060 ItemPrototype const* itemProto = objmgr.GetItemPrototype(item_id);
2061 if(!itemProto)
2063 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
2064 SetSentErrorMessage(true);
2065 return false;
2068 char* c_count = strtok(NULL, " ");
2069 int count = c_count ? atol(c_count) : 10;
2071 if(count < 0)
2072 return false;
2074 QueryResult *result;
2076 // inventory case
2077 uint32 inv_count = 0;
2078 result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM character_inventory WHERE item_template='%u'",item_id);
2079 if(result)
2081 inv_count = (*result)[0].GetUInt32();
2082 delete result;
2085 result=CharacterDatabase.PQuery(
2086 // 0 1 2 3 4 5
2087 "SELECT ci.item, cibag.slot AS bag, ci.slot, ci.guid, characters.account,characters.name "
2088 "FROM character_inventory AS ci LEFT JOIN character_inventory AS cibag ON (cibag.item=ci.bag),characters "
2089 "WHERE ci.item_template='%u' AND ci.guid = characters.guid LIMIT %u ",
2090 item_id,uint32(count));
2092 if(result)
2096 Field *fields = result->Fetch();
2097 uint32 item_guid = fields[0].GetUInt32();
2098 uint32 item_bag = fields[1].GetUInt32();
2099 uint32 item_slot = fields[2].GetUInt32();
2100 uint32 owner_guid = fields[3].GetUInt32();
2101 uint32 owner_acc = fields[4].GetUInt32();
2102 std::string owner_name = fields[5].GetCppString();
2104 char const* item_pos = 0;
2105 if(Player::IsEquipmentPos(item_bag,item_slot))
2106 item_pos = "[equipped]";
2107 else if(Player::IsInventoryPos(item_bag,item_slot))
2108 item_pos = "[in inventory]";
2109 else if(Player::IsBankPos(item_bag,item_slot))
2110 item_pos = "[in bank]";
2111 else
2112 item_pos = "";
2114 PSendSysMessage(LANG_ITEMLIST_SLOT,
2115 item_guid,owner_name.c_str(),owner_guid,owner_acc,item_pos);
2116 } while (result->NextRow());
2118 int64 res_count = result->GetRowCount();
2120 delete result;
2122 if(count > res_count)
2123 count-=res_count;
2124 else if(count)
2125 count = 0;
2128 // mail case
2129 uint32 mail_count = 0;
2130 result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM mail_items WHERE item_template='%u'", item_id);
2131 if(result)
2133 mail_count = (*result)[0].GetUInt32();
2134 delete result;
2137 if(count > 0)
2139 result=CharacterDatabase.PQuery(
2140 // 0 1 2 3 4 5 6
2141 "SELECT mail_items.item_guid, mail.sender, mail.receiver, char_s.account, char_s.name, char_r.account, char_r.name "
2142 "FROM mail,mail_items,characters as char_s,characters as char_r "
2143 "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",
2144 item_id,uint32(count));
2146 else
2147 result = NULL;
2149 if(result)
2153 Field *fields = result->Fetch();
2154 uint32 item_guid = fields[0].GetUInt32();
2155 uint32 item_s = fields[1].GetUInt32();
2156 uint32 item_r = fields[2].GetUInt32();
2157 uint32 item_s_acc = fields[3].GetUInt32();
2158 std::string item_s_name = fields[4].GetCppString();
2159 uint32 item_r_acc = fields[5].GetUInt32();
2160 std::string item_r_name = fields[6].GetCppString();
2162 char const* item_pos = "[in mail]";
2164 PSendSysMessage(LANG_ITEMLIST_MAIL,
2165 item_guid,item_s_name.c_str(),item_s,item_s_acc,item_r_name.c_str(),item_r,item_r_acc,item_pos);
2166 } while (result->NextRow());
2168 int64 res_count = result->GetRowCount();
2170 delete result;
2172 if(count > res_count)
2173 count-=res_count;
2174 else if(count)
2175 count = 0;
2178 // auction case
2179 uint32 auc_count = 0;
2180 result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM auctionhouse WHERE item_template='%u'",item_id);
2181 if(result)
2183 auc_count = (*result)[0].GetUInt32();
2184 delete result;
2187 if(count > 0)
2189 result=CharacterDatabase.PQuery(
2190 // 0 1 2 3
2191 "SELECT auctionhouse.itemguid, auctionhouse.itemowner, characters.account, characters.name "
2192 "FROM auctionhouse,characters WHERE auctionhouse.item_template='%u' AND characters.guid = auctionhouse.itemowner LIMIT %u",
2193 item_id,uint32(count));
2195 else
2196 result = NULL;
2198 if(result)
2202 Field *fields = result->Fetch();
2203 uint32 item_guid = fields[0].GetUInt32();
2204 uint32 owner = fields[1].GetUInt32();
2205 uint32 owner_acc = fields[2].GetUInt32();
2206 std::string owner_name = fields[3].GetCppString();
2208 char const* item_pos = "[in auction]";
2210 PSendSysMessage(LANG_ITEMLIST_AUCTION, item_guid, owner_name.c_str(), owner, owner_acc,item_pos);
2211 } while (result->NextRow());
2213 delete result;
2216 // guild bank case
2217 uint32 guild_count = 0;
2218 result=CharacterDatabase.PQuery("SELECT COUNT(item_entry) FROM guild_bank_item WHERE item_entry='%u'",item_id);
2219 if(result)
2221 guild_count = (*result)[0].GetUInt32();
2222 delete result;
2225 result=CharacterDatabase.PQuery(
2226 // 0 1 2
2227 "SELECT gi.item_guid, gi.guildid, guild.name "
2228 "FROM guild_bank_item AS gi, guild WHERE gi.item_entry='%u' AND gi.guildid = guild.guildid LIMIT %u ",
2229 item_id,uint32(count));
2231 if(result)
2235 Field *fields = result->Fetch();
2236 uint32 item_guid = fields[0].GetUInt32();
2237 uint32 guild_guid = fields[1].GetUInt32();
2238 std::string guild_name = fields[2].GetCppString();
2240 char const* item_pos = "[in guild bank]";
2242 PSendSysMessage(LANG_ITEMLIST_GUILD,item_guid,guild_name.c_str(),guild_guid,item_pos);
2243 } while (result->NextRow());
2245 int64 res_count = result->GetRowCount();
2247 delete result;
2249 if(count > res_count)
2250 count-=res_count;
2251 else if(count)
2252 count = 0;
2255 if(inv_count+mail_count+auc_count+guild_count == 0)
2257 SendSysMessage(LANG_COMMAND_NOITEMFOUND);
2258 SetSentErrorMessage(true);
2259 return false;
2262 PSendSysMessage(LANG_COMMAND_LISTITEMMESSAGE,item_id,inv_count+mail_count+auc_count+guild_count,inv_count,mail_count,auc_count,guild_count);
2264 return true;
2267 bool ChatHandler::HandleListObjectCommand(const char* args)
2269 if(!*args)
2270 return false;
2272 // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r
2273 char* cId = extractKeyFromLink((char*)args,"Hgameobject_entry");
2274 if(!cId)
2275 return false;
2277 uint32 go_id = atol(cId);
2278 if(!go_id)
2280 PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id);
2281 SetSentErrorMessage(true);
2282 return false;
2285 GameObjectInfo const * gInfo = objmgr.GetGameObjectInfo(go_id);
2286 if(!gInfo)
2288 PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id);
2289 SetSentErrorMessage(true);
2290 return false;
2293 char* c_count = strtok(NULL, " ");
2294 int count = c_count ? atol(c_count) : 10;
2296 if(count < 0)
2297 return false;
2299 QueryResult *result;
2301 uint32 obj_count = 0;
2302 result=WorldDatabase.PQuery("SELECT COUNT(guid) FROM gameobject WHERE id='%u'",go_id);
2303 if(result)
2305 obj_count = (*result)[0].GetUInt32();
2306 delete result;
2309 if(m_session)
2311 Player* pl = m_session->GetPlayer();
2312 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",
2313 pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),go_id,uint32(count));
2315 else
2316 result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map FROM gameobject WHERE id = '%u' LIMIT %u",
2317 go_id,uint32(count));
2319 if (result)
2323 Field *fields = result->Fetch();
2324 uint32 guid = fields[0].GetUInt32();
2325 float x = fields[1].GetFloat();
2326 float y = fields[2].GetFloat();
2327 float z = fields[3].GetFloat();
2328 int mapid = fields[4].GetUInt16();
2330 if (m_session)
2331 PSendSysMessage(LANG_GO_LIST_CHAT, guid, guid, gInfo->name, x, y, z, mapid);
2332 else
2333 PSendSysMessage(LANG_GO_LIST_CONSOLE, guid, gInfo->name, x, y, z, mapid);
2334 } while (result->NextRow());
2336 delete result;
2339 PSendSysMessage(LANG_COMMAND_LISTOBJMESSAGE,go_id,obj_count);
2340 return true;
2343 bool ChatHandler::HandleNearObjectCommand(const char* args)
2345 float distance = (!*args) ? 10 : atol(args);
2346 uint32 count = 0;
2348 Player* pl = m_session->GetPlayer();
2349 QueryResult *result = WorldDatabase.PQuery("SELECT guid, id, position_x, position_y, position_z, map, "
2350 "(POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ "
2351 "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_",
2352 pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),
2353 pl->GetMapId(),pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),distance*distance);
2355 if (result)
2359 Field *fields = result->Fetch();
2360 uint32 guid = fields[0].GetUInt32();
2361 uint32 entry = fields[1].GetUInt32();
2362 float x = fields[2].GetFloat();
2363 float y = fields[3].GetFloat();
2364 float z = fields[4].GetFloat();
2365 int mapid = fields[5].GetUInt16();
2367 GameObjectInfo const * gInfo = objmgr.GetGameObjectInfo(entry);
2369 if(!gInfo)
2370 continue;
2372 PSendSysMessage(LANG_GO_LIST_CHAT, guid, guid, gInfo->name, x, y, z, mapid);
2374 ++count;
2375 } while (result->NextRow());
2377 delete result;
2380 PSendSysMessage(LANG_COMMAND_NEAROBJMESSAGE,distance,count);
2381 return true;
2384 bool ChatHandler::HandleListCreatureCommand(const char* args)
2386 if(!*args)
2387 return false;
2389 // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
2390 char* cId = extractKeyFromLink((char*)args,"Hcreature_entry");
2391 if(!cId)
2392 return false;
2394 uint32 cr_id = atol(cId);
2395 if(!cr_id)
2397 PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id);
2398 SetSentErrorMessage(true);
2399 return false;
2402 CreatureInfo const* cInfo = objmgr.GetCreatureTemplate(cr_id);
2403 if(!cInfo)
2405 PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id);
2406 SetSentErrorMessage(true);
2407 return false;
2410 char* c_count = strtok(NULL, " ");
2411 int count = c_count ? atol(c_count) : 10;
2413 if(count < 0)
2414 return false;
2416 QueryResult *result;
2418 uint32 cr_count = 0;
2419 result=WorldDatabase.PQuery("SELECT COUNT(guid) FROM creature WHERE id='%u'",cr_id);
2420 if(result)
2422 cr_count = (*result)[0].GetUInt32();
2423 delete result;
2426 if(m_session)
2428 Player* pl = m_session->GetPlayer();
2429 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",
2430 pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), cr_id,uint32(count));
2432 else
2433 result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map FROM creature WHERE id = '%u' LIMIT %u",
2434 cr_id,uint32(count));
2436 if (result)
2440 Field *fields = result->Fetch();
2441 uint32 guid = fields[0].GetUInt32();
2442 float x = fields[1].GetFloat();
2443 float y = fields[2].GetFloat();
2444 float z = fields[3].GetFloat();
2445 int mapid = fields[4].GetUInt16();
2447 if (m_session)
2448 PSendSysMessage(LANG_CREATURE_LIST_CHAT, guid, guid, cInfo->Name, x, y, z, mapid);
2449 else
2450 PSendSysMessage(LANG_CREATURE_LIST_CONSOLE, guid, cInfo->Name, x, y, z, mapid);
2451 } while (result->NextRow());
2453 delete result;
2456 PSendSysMessage(LANG_COMMAND_LISTCREATUREMESSAGE,cr_id,cr_count);
2457 return true;
2460 bool ChatHandler::HandleLookupItemCommand(const char* args)
2462 if(!*args)
2463 return false;
2465 std::string namepart = args;
2466 std::wstring wnamepart;
2468 // converting string that we try to find to lower case
2469 if(!Utf8toWStr(namepart,wnamepart))
2470 return false;
2472 wstrToLower(wnamepart);
2474 uint32 counter = 0;
2476 // Search in `item_template`
2477 for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
2479 ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype >(id);
2480 if(!pProto)
2481 continue;
2483 int loc_idx = m_session ? m_session->GetSessionDbLocaleIndex() : objmgr.GetDBCLocaleIndex();
2484 if ( loc_idx >= 0 )
2486 ItemLocale const *il = objmgr.GetItemLocale(pProto->ItemId);
2487 if (il)
2489 if (il->Name.size() > loc_idx && !il->Name[loc_idx].empty())
2491 std::string name = il->Name[loc_idx];
2493 if (Utf8FitTo(name, wnamepart))
2495 if (m_session)
2496 PSendSysMessage(LANG_ITEM_LIST_CHAT, id, id, name.c_str());
2497 else
2498 PSendSysMessage(LANG_ITEM_LIST_CONSOLE, id, name.c_str());
2499 ++counter;
2500 continue;
2506 std::string name = pProto->Name1;
2507 if(name.empty())
2508 continue;
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;
2520 if (counter==0)
2521 SendSysMessage(LANG_COMMAND_NOITEMFOUND);
2523 return true;
2526 bool ChatHandler::HandleLookupItemSetCommand(const char* args)
2528 if(!*args)
2529 return false;
2531 std::string namepart = args;
2532 std::wstring wnamepart;
2534 if(!Utf8toWStr(namepart,wnamepart))
2535 return false;
2537 // converting string that we try to find to lower case
2538 wstrToLower( wnamepart );
2540 uint32 counter = 0; // Counter for figure out that we found smth.
2542 // Search in ItemSet.dbc
2543 for (uint32 id = 0; id < sItemSetStore.GetNumRows(); id++)
2545 ItemSetEntry const *set = sItemSetStore.LookupEntry(id);
2546 if(set)
2548 int loc = m_session ? m_session->GetSessionDbcLocale() : sWorld.GetDefaultDbcLocale();
2549 std::string name = set->name[loc];
2550 if(name.empty())
2551 continue;
2553 if (!Utf8FitTo(name, wnamepart))
2555 loc = 0;
2556 for(; loc < MAX_LOCALE; ++loc)
2558 if(m_session && loc==m_session->GetSessionDbcLocale())
2559 continue;
2561 name = set->name[loc];
2562 if(name.empty())
2563 continue;
2565 if (Utf8FitTo(name, wnamepart))
2566 break;
2570 if(loc < MAX_LOCALE)
2572 // send item set in "id - [namedlink locale]" format
2573 if (m_session)
2574 PSendSysMessage(LANG_ITEMSET_LIST_CHAT,id,id,name.c_str(),localeNames[loc]);
2575 else
2576 PSendSysMessage(LANG_ITEMSET_LIST_CONSOLE,id,name.c_str(),localeNames[loc]);
2577 ++counter;
2581 if (counter == 0) // if counter == 0 then we found nth
2582 SendSysMessage(LANG_COMMAND_NOITEMSETFOUND);
2583 return true;
2586 bool ChatHandler::HandleLookupSkillCommand(const char* args)
2588 if(!*args)
2589 return false;
2591 // can be NULL in console call
2592 Player* target = getSelectedPlayer();
2594 std::string namepart = args;
2595 std::wstring wnamepart;
2597 if(!Utf8toWStr(namepart,wnamepart))
2598 return false;
2600 // converting string that we try to find to lower case
2601 wstrToLower( wnamepart );
2603 uint32 counter = 0; // Counter for figure out that we found smth.
2605 // Search in SkillLine.dbc
2606 for (uint32 id = 0; id < sSkillLineStore.GetNumRows(); id++)
2608 SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(id);
2609 if(skillInfo)
2611 int loc = m_session ? m_session->GetSessionDbcLocale() : sWorld.GetDefaultDbcLocale();
2612 std::string name = skillInfo->name[loc];
2613 if(name.empty())
2614 continue;
2616 if (!Utf8FitTo(name, wnamepart))
2618 loc = 0;
2619 for(; loc < MAX_LOCALE; ++loc)
2621 if(m_session && loc==m_session->GetSessionDbcLocale())
2622 continue;
2624 name = skillInfo->name[loc];
2625 if(name.empty())
2626 continue;
2628 if (Utf8FitTo(name, wnamepart))
2629 break;
2633 if(loc < MAX_LOCALE)
2635 char const* knownStr = "";
2636 if(target && target->HasSkill(id))
2637 knownStr = GetMangosString(LANG_KNOWN);
2639 // send skill in "id - [namedlink locale]" format
2640 if (m_session)
2641 PSendSysMessage(LANG_SKILL_LIST_CHAT,id,id,name.c_str(),localeNames[loc],knownStr);
2642 else
2643 PSendSysMessage(LANG_SKILL_LIST_CONSOLE,id,name.c_str(),localeNames[loc],knownStr);
2645 ++counter;
2649 if (counter == 0) // if counter == 0 then we found nth
2650 SendSysMessage(LANG_COMMAND_NOSKILLFOUND);
2651 return true;
2654 bool ChatHandler::HandleLookupSpellCommand(const char* args)
2656 if(!*args)
2657 return false;
2659 // can be NULL at console call
2660 Player* target = getSelectedPlayer();
2662 std::string namepart = args;
2663 std::wstring wnamepart;
2665 if(!Utf8toWStr(namepart,wnamepart))
2666 return false;
2668 // converting string that we try to find to lower case
2669 wstrToLower( wnamepart );
2671 uint32 counter = 0; // Counter for figure out that we found smth.
2673 // Search in Spell.dbc
2674 for (uint32 id = 0; id < sSpellStore.GetNumRows(); id++)
2676 SpellEntry const *spellInfo = sSpellStore.LookupEntry(id);
2677 if(spellInfo)
2679 int loc = m_session ? m_session->GetSessionDbcLocale() : sWorld.GetDefaultDbcLocale();
2680 std::string name = spellInfo->SpellName[loc];
2681 if(name.empty())
2682 continue;
2684 if (!Utf8FitTo(name, wnamepart))
2686 loc = 0;
2687 for(; loc < MAX_LOCALE; ++loc)
2689 if(m_session && loc==m_session->GetSessionDbcLocale())
2690 continue;
2692 name = spellInfo->SpellName[loc];
2693 if(name.empty())
2694 continue;
2696 if (Utf8FitTo(name, wnamepart))
2697 break;
2701 if(loc < MAX_LOCALE)
2703 bool known = target && target->HasSpell(id);
2704 bool learn = (spellInfo->Effect[0] == SPELL_EFFECT_LEARN_SPELL);
2706 uint32 talentCost = GetTalentSpellCost(id);
2708 bool talent = (talentCost > 0);
2709 bool passive = IsPassiveSpell(id);
2710 bool active = target && target->HasAura(id);
2712 // unit32 used to prevent interpreting uint8 as char at output
2713 // find rank of learned spell for learning spell, or talent rank
2714 uint32 rank = talentCost ? talentCost : spellmgr.GetSpellRank(learn ? spellInfo->EffectTriggerSpell[0] : id);
2716 // send spell in "id - [name, rank N] [talent] [passive] [learn] [known]" format
2717 std::ostringstream ss;
2718 if (m_session)
2719 ss << id << " - |cffffffff|Hspell:" << id << "|h[" << name;
2720 else
2721 ss << id << " - " << name;
2723 // include rank in link name
2724 if(rank)
2725 ss << GetMangosString(LANG_SPELL_RANK) << rank;
2727 if (m_session)
2728 ss << " " << localeNames[loc] << "]|h|r";
2729 else
2730 ss << " " << localeNames[loc];
2732 if(talent)
2733 ss << GetMangosString(LANG_TALENT);
2734 if(passive)
2735 ss << GetMangosString(LANG_PASSIVE);
2736 if(learn)
2737 ss << GetMangosString(LANG_LEARN);
2738 if(known)
2739 ss << GetMangosString(LANG_KNOWN);
2740 if(active)
2741 ss << GetMangosString(LANG_ACTIVE);
2743 SendSysMessage(ss.str().c_str());
2745 ++counter;
2749 if (counter == 0) // if counter == 0 then we found nth
2750 SendSysMessage(LANG_COMMAND_NOSPELLFOUND);
2751 return true;
2754 bool ChatHandler::HandleLookupQuestCommand(const char* args)
2756 if(!*args)
2757 return false;
2759 // can be NULL at console call
2760 Player* target = getSelectedPlayer();
2762 std::string namepart = args;
2763 std::wstring wnamepart;
2765 // converting string that we try to find to lower case
2766 if(!Utf8toWStr(namepart,wnamepart))
2767 return false;
2769 wstrToLower(wnamepart);
2771 uint32 counter = 0 ;
2773 ObjectMgr::QuestMap const& qTemplates = objmgr.GetQuestTemplates();
2774 for (ObjectMgr::QuestMap::const_iterator iter = qTemplates.begin(); iter != qTemplates.end(); ++iter)
2776 Quest * qinfo = iter->second;
2778 int loc_idx = m_session ? m_session->GetSessionDbLocaleIndex() : objmgr.GetDBCLocaleIndex();
2779 if ( loc_idx >= 0 )
2781 QuestLocale const *il = objmgr.GetQuestLocale(qinfo->GetQuestId());
2782 if (il)
2784 if (il->Title.size() > loc_idx && !il->Title[loc_idx].empty())
2786 std::string title = il->Title[loc_idx];
2788 if (Utf8FitTo(title, wnamepart))
2790 char const* statusStr = "";
2792 if(target)
2794 QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId());
2796 if(status == QUEST_STATUS_COMPLETE)
2798 if(target->GetQuestRewardStatus(qinfo->GetQuestId()))
2799 statusStr = GetMangosString(LANG_COMMAND_QUEST_REWARDED);
2800 else
2801 statusStr = GetMangosString(LANG_COMMAND_QUEST_COMPLETE);
2803 else if(status == QUEST_STATUS_INCOMPLETE)
2804 statusStr = GetMangosString(LANG_COMMAND_QUEST_ACTIVE);
2807 if (m_session)
2808 PSendSysMessage(LANG_QUEST_LIST_CHAT,qinfo->GetQuestId(),qinfo->GetQuestId(),title.c_str(),statusStr);
2809 else
2810 PSendSysMessage(LANG_QUEST_LIST_CONSOLE,qinfo->GetQuestId(),title.c_str(),statusStr);
2811 ++counter;
2812 continue;
2818 std::string title = qinfo->GetTitle();
2819 if(title.empty())
2820 continue;
2822 if (Utf8FitTo(title, wnamepart))
2824 char const* statusStr = "";
2826 if(target)
2828 QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId());
2830 if(status == QUEST_STATUS_COMPLETE)
2832 if(target->GetQuestRewardStatus(qinfo->GetQuestId()))
2833 statusStr = GetMangosString(LANG_COMMAND_QUEST_REWARDED);
2834 else
2835 statusStr = GetMangosString(LANG_COMMAND_QUEST_COMPLETE);
2837 else if(status == QUEST_STATUS_INCOMPLETE)
2838 statusStr = GetMangosString(LANG_COMMAND_QUEST_ACTIVE);
2841 if (m_session)
2842 PSendSysMessage(LANG_QUEST_LIST_CHAT,qinfo->GetQuestId(),qinfo->GetQuestId(),title.c_str(),statusStr);
2843 else
2844 PSendSysMessage(LANG_QUEST_LIST_CONSOLE,qinfo->GetQuestId(),title.c_str(),statusStr);
2846 ++counter;
2850 if (counter==0)
2851 SendSysMessage(LANG_COMMAND_NOQUESTFOUND);
2853 return true;
2856 bool ChatHandler::HandleLookupCreatureCommand(const char* args)
2858 if (!*args)
2859 return false;
2861 std::string namepart = args;
2862 std::wstring wnamepart;
2864 // converting string that we try to find to lower case
2865 if (!Utf8toWStr (namepart,wnamepart))
2866 return false;
2868 wstrToLower (wnamepart);
2870 uint32 counter = 0;
2872 for (uint32 id = 0; id< sCreatureStorage.MaxEntry; ++id)
2874 CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo> (id);
2875 if(!cInfo)
2876 continue;
2878 int loc_idx = m_session ? m_session->GetSessionDbLocaleIndex() : objmgr.GetDBCLocaleIndex();
2879 if (loc_idx >= 0)
2881 CreatureLocale const *cl = objmgr.GetCreatureLocale (id);
2882 if (cl)
2884 if (cl->Name.size() > loc_idx && !cl->Name[loc_idx].empty ())
2886 std::string name = cl->Name[loc_idx];
2888 if (Utf8FitTo (name, wnamepart))
2890 if (m_session)
2891 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CHAT, id, id, name.c_str ());
2892 else
2893 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CONSOLE, id, name.c_str ());
2894 ++counter;
2895 continue;
2901 std::string name = cInfo->Name;
2902 if (name.empty ())
2903 continue;
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;
2915 if (counter==0)
2916 SendSysMessage (LANG_COMMAND_NOCREATUREFOUND);
2918 return true;
2921 bool ChatHandler::HandleLookupObjectCommand(const char* args)
2923 if(!*args)
2924 return false;
2926 std::string namepart = args;
2927 std::wstring wnamepart;
2929 // converting string that we try to find to lower case
2930 if(!Utf8toWStr(namepart,wnamepart))
2931 return false;
2933 wstrToLower(wnamepart);
2935 uint32 counter = 0;
2937 for (uint32 id = 0; id< sGOStorage.MaxEntry; id++ )
2939 GameObjectInfo const* gInfo = sGOStorage.LookupEntry<GameObjectInfo>(id);
2940 if(!gInfo)
2941 continue;
2943 int loc_idx = m_session ? m_session->GetSessionDbLocaleIndex() : objmgr.GetDBCLocaleIndex();
2944 if ( loc_idx >= 0 )
2946 GameObjectLocale const *gl = objmgr.GetGameObjectLocale(id);
2947 if (gl)
2949 if (gl->Name.size() > loc_idx && !gl->Name[loc_idx].empty())
2951 std::string name = gl->Name[loc_idx];
2953 if (Utf8FitTo(name, wnamepart))
2955 if (m_session)
2956 PSendSysMessage(LANG_GO_ENTRY_LIST_CHAT, id, id, name.c_str());
2957 else
2958 PSendSysMessage(LANG_GO_ENTRY_LIST_CONSOLE, id, name.c_str());
2959 ++counter;
2960 continue;
2966 std::string name = gInfo->name;
2967 if(name.empty())
2968 continue;
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;
2980 if(counter==0)
2981 SendSysMessage(LANG_COMMAND_NOGAMEOBJECTFOUND);
2983 return true;
2986 /** \brief GM command level 3 - Create a guild.
2988 * This command allows a GM (level 3) to create a guild.
2990 * The "args" parameter contains the name of the guild leader
2991 * and then the name of the guild.
2994 bool ChatHandler::HandleGuildCreateCommand(const char* args)
2997 if (!*args)
2998 return false;
3000 char *lname = strtok ((char*)args, " ");
3001 char *gname = strtok (NULL, "");
3003 if (!lname)
3004 return false;
3006 if (!gname)
3008 SendSysMessage (LANG_INSERT_GUILD_NAME);
3009 SetSentErrorMessage (true);
3010 return false;
3013 std::string guildname = gname;
3015 Player* player = ObjectAccessor::Instance ().FindPlayerByName (lname);
3016 if (!player)
3018 SendSysMessage (LANG_PLAYER_NOT_FOUND);
3019 SetSentErrorMessage (true);
3020 return false;
3023 if (player->GetGuildId())
3025 SendSysMessage (LANG_PLAYER_IN_GUILD);
3026 return true;
3029 Guild *guild = new Guild;
3030 if (!guild->create (player->GetGUID (),guildname))
3032 delete guild;
3033 SendSysMessage (LANG_GUILD_NOT_CREATED);
3034 SetSentErrorMessage (true);
3035 return false;
3038 objmgr.AddGuild (guild);
3039 return true;
3042 bool ChatHandler::HandleGuildInviteCommand(const char *args)
3044 if (!*args)
3045 return false;
3047 char* par1 = strtok ((char*)args, " ");
3048 char* par2 = strtok (NULL, "");
3049 if(!par1 || !par2)
3050 return false;
3052 std::string glName = par2;
3053 Guild* targetGuild = objmgr.GetGuildByName (glName);
3054 if (!targetGuild)
3055 return false;
3057 std::string plName = par1;
3058 if (!normalizePlayerName (plName))
3060 SendSysMessage (LANG_PLAYER_NOT_FOUND);
3061 SetSentErrorMessage (true);
3062 return false;
3065 uint64 plGuid = 0;
3066 if (Player* targetPlayer = ObjectAccessor::Instance ().FindPlayerByName (plName.c_str ()))
3067 plGuid = targetPlayer->GetGUID ();
3068 else
3069 plGuid = objmgr.GetPlayerGUIDByName (plName.c_str ());
3071 if (!plGuid)
3072 false;
3074 // player's guild membership checked in AddMember before add
3075 if (!targetGuild->AddMember (plGuid,targetGuild->GetLowestRank ()))
3076 return false;
3078 return true;
3081 bool ChatHandler::HandleGuildUninviteCommand(const char *args)
3083 if (!*args)
3084 return false;
3086 char* par1 = strtok ((char*)args, " ");
3087 if(!par1)
3088 return false;
3090 std::string plName = par1;
3091 if (!normalizePlayerName (plName))
3093 SendSysMessage (LANG_PLAYER_NOT_FOUND);
3094 SetSentErrorMessage (true);
3095 return false;
3098 uint64 plGuid = 0;
3099 uint32 glId = 0;
3100 if (Player* targetPlayer = ObjectAccessor::Instance ().FindPlayerByName (plName.c_str ()))
3102 plGuid = targetPlayer->GetGUID ();
3103 glId = targetPlayer->GetGuildId ();
3105 else
3107 plGuid = objmgr.GetPlayerGUIDByName (plName.c_str ());
3108 glId = Player::GetGuildIdFromDB (plGuid);
3111 if (!plGuid || !glId)
3112 return false;
3114 Guild* targetGuild = objmgr.GetGuildById (glId);
3115 if (!targetGuild)
3116 return false;
3118 targetGuild->DelMember (plGuid);
3120 return true;
3123 bool ChatHandler::HandleGuildRankCommand(const char *args)
3125 if (!*args)
3126 return false;
3128 char* par1 = strtok ((char*)args, " ");
3129 char* par2 = strtok (NULL, " ");
3130 if (!par1 || !par2)
3131 return false;
3132 std::string plName = par1;
3133 if (!normalizePlayerName (plName))
3135 SendSysMessage (LANG_PLAYER_NOT_FOUND);
3136 SetSentErrorMessage (true);
3137 return false;
3140 uint64 plGuid = 0;
3141 uint32 glId = 0;
3142 if (Player* targetPlayer = ObjectAccessor::Instance ().FindPlayerByName (plName.c_str ()))
3144 plGuid = targetPlayer->GetGUID ();
3145 glId = targetPlayer->GetGuildId ();
3147 else
3149 plGuid = objmgr.GetPlayerGUIDByName (plName.c_str ());
3150 glId = Player::GetGuildIdFromDB (plGuid);
3153 if (!plGuid || !glId)
3154 return false;
3156 Guild* targetGuild = objmgr.GetGuildById (glId);
3157 if (!targetGuild)
3158 return false;
3160 uint32 newrank = uint32 (atoi (par2));
3161 if (newrank > targetGuild->GetLowestRank ())
3162 return false;
3164 targetGuild->ChangeRank (plGuid,newrank);
3166 return true;
3169 bool ChatHandler::HandleGuildDeleteCommand(const char* args)
3171 if (!*args)
3172 return false;
3174 char* par1 = strtok ((char*)args, " ");
3175 if (!par1)
3176 return false;
3178 std::string gld = par1;
3180 Guild* targetGuild = objmgr.GetGuildByName (gld);
3181 if (!targetGuild)
3182 return false;
3184 targetGuild->Disband ();
3186 return true;
3189 bool ChatHandler::HandleGetDistanceCommand(const char* /*args*/)
3191 Unit* pUnit = getSelectedUnit();
3193 if(!pUnit)
3195 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3196 SetSentErrorMessage(true);
3197 return false;
3200 PSendSysMessage(LANG_DISTANCE, m_session->GetPlayer()->GetDistance(pUnit),m_session->GetPlayer()->GetDistance2d(pUnit));
3202 return true;
3205 // FIX-ME!!!
3207 bool ChatHandler::HandleAddWeaponCommand(const char* /*args*/)
3209 /*if (!*args)
3210 return false;
3212 uint64 guid = m_session->GetPlayer()->GetSelection();
3213 if (guid == 0)
3215 SendSysMessage(LANG_NO_SELECTION);
3216 return true;
3219 Creature *pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
3221 if(!pCreature)
3223 SendSysMessage(LANG_SELECT_CREATURE);
3224 return true;
3227 char* pSlotID = strtok((char*)args, " ");
3228 if (!pSlotID)
3229 return false;
3231 char* pItemID = strtok(NULL, " ");
3232 if (!pItemID)
3233 return false;
3235 uint32 ItemID = atoi(pItemID);
3236 uint32 SlotID = atoi(pSlotID);
3238 ItemPrototype* tmpItem = objmgr.GetItemPrototype(ItemID);
3240 bool added = false;
3241 if(tmpItem)
3243 switch(SlotID)
3245 case 1:
3246 pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, ItemID);
3247 added = true;
3248 break;
3249 case 2:
3250 pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_01, ItemID);
3251 added = true;
3252 break;
3253 case 3:
3254 pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_02, ItemID);
3255 added = true;
3256 break;
3257 default:
3258 PSendSysMessage(LANG_ITEM_SLOT_NOT_EXIST,SlotID);
3259 added = false;
3260 break;
3262 if(added)
3264 PSendSysMessage(LANG_ITEM_ADDED_TO_SLOT,ItemID,tmpItem->Name1,SlotID);
3267 else
3269 PSendSysMessage(LANG_ITEM_NOT_FOUND,ItemID);
3270 return true;
3273 return true;
3276 bool ChatHandler::HandleDieCommand(const char* /*args*/)
3278 Unit* target = getSelectedUnit();
3280 if(!target || !m_session->GetPlayer()->GetSelection())
3282 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3283 SetSentErrorMessage(true);
3284 return false;
3287 if( target->isAlive() )
3289 m_session->GetPlayer()->DealDamage(target, target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
3292 return true;
3295 bool ChatHandler::HandleDamageCommand(const char * args)
3297 if (!*args)
3298 return false;
3300 Unit* target = getSelectedUnit();
3302 if(!target || !m_session->GetPlayer()->GetSelection())
3304 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3305 SetSentErrorMessage(true);
3306 return false;
3309 if( !target->isAlive() )
3310 return true;
3312 char* damageStr = strtok((char*)args, " ");
3313 if(!damageStr)
3314 return false;
3316 int32 damage = atoi((char*)damageStr);
3317 if(damage <=0)
3318 return true;
3320 char* schoolStr = strtok((char*)NULL, " ");
3322 // flat melee damage without resistence/etc reduction
3323 if(!schoolStr)
3325 m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
3326 m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, SPELL_SCHOOL_MASK_NORMAL, damage, 0, 0, VICTIMSTATE_NORMAL, 0);
3327 return true;
3330 uint32 school = schoolStr ? atoi((char*)schoolStr) : SPELL_SCHOOL_NORMAL;
3331 if(school >= MAX_SPELL_SCHOOL)
3332 return false;
3334 SpellSchoolMask schoolmask = SpellSchoolMask(1 << school);
3336 if ( schoolmask & SPELL_SCHOOL_MASK_NORMAL )
3337 damage = m_session->GetPlayer()->CalcArmorReducedDamage(target, damage);
3339 char* spellStr = strtok((char*)NULL, " ");
3341 // melee damage by specific school
3342 if(!spellStr)
3344 uint32 absorb = 0;
3345 uint32 resist = 0;
3347 m_session->GetPlayer()->CalcAbsorbResist(target,schoolmask, SPELL_DIRECT_DAMAGE, damage, &absorb, &resist);
3349 if (damage <= absorb + resist)
3350 return true;
3352 damage -= absorb + resist;
3354 m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, schoolmask, NULL, false);
3355 m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, schoolmask, damage, absorb, resist, VICTIMSTATE_NORMAL, 0);
3356 return true;
3359 // non-melee damage
3361 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
3362 uint32 spellid = extractSpellIdFromLink((char*)args);
3363 if(!spellid || !sSpellStore.LookupEntry(spellid))
3364 return false;
3366 m_session->GetPlayer()->SpellNonMeleeDamageLog(target, spellid, damage, false);
3367 return true;
3370 bool ChatHandler::HandleModifyArenaCommand(const char * args)
3372 if (!*args)
3373 return false;
3375 Player *target = getSelectedPlayer();
3376 if(!target)
3378 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3379 SetSentErrorMessage(true);
3380 return false;
3383 int32 amount = (uint32)atoi(args);
3385 target->ModifyArenaPoints(amount);
3387 PSendSysMessage(LANG_COMMAND_MODIFY_ARENA, target->GetName(), target->GetArenaPoints());
3389 return true;
3392 bool ChatHandler::HandleReviveCommand(const char* args)
3394 Player* SelectedPlayer = NULL;
3396 if (*args)
3398 std::string name = args;
3399 if(!normalizePlayerName(name))
3401 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3402 SetSentErrorMessage(true);
3403 return false;
3406 SelectedPlayer = objmgr.GetPlayer(name.c_str());
3408 else
3409 SelectedPlayer = getSelectedPlayer();
3411 if(!SelectedPlayer)
3413 SendSysMessage(LANG_NO_CHAR_SELECTED);
3414 SetSentErrorMessage(true);
3415 return false;
3418 SelectedPlayer->ResurrectPlayer(0.5f);
3419 SelectedPlayer->SpawnCorpseBones();
3420 SelectedPlayer->SaveToDB();
3421 return true;
3424 bool ChatHandler::HandleAuraCommand(const char* args)
3426 char* px = strtok((char*)args, " ");
3427 if (!px)
3428 return false;
3430 Unit *target = getSelectedUnit();
3431 if(!target)
3433 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3434 SetSentErrorMessage(true);
3435 return false;
3438 uint32 spellID = (uint32)atoi(px);
3439 SpellEntry const *spellInfo = sSpellStore.LookupEntry( spellID );
3440 if(spellInfo)
3442 for(uint32 i = 0;i<3;i++)
3444 uint8 eff = spellInfo->Effect[i];
3445 if (eff>=TOTAL_SPELL_EFFECTS)
3446 continue;
3447 if( IsAreaAuraEffect(eff) ||
3448 eff == SPELL_EFFECT_APPLY_AURA ||
3449 eff == SPELL_EFFECT_PERSISTENT_AREA_AURA )
3451 Aura *Aur = CreateAura(spellInfo, i, NULL, target);
3452 target->AddAura(Aur);
3457 return true;
3460 bool ChatHandler::HandleUnAuraCommand(const char* args)
3462 char* px = strtok((char*)args, " ");
3463 if (!px)
3464 return false;
3466 Unit *target = getSelectedUnit();
3467 if(!target)
3469 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3470 SetSentErrorMessage(true);
3471 return false;
3474 std::string argstr = args;
3475 if (argstr == "all")
3477 target->RemoveAllAuras();
3478 return true;
3481 uint32 spellID = (uint32)atoi(px);
3482 target->RemoveAurasDueToSpell(spellID);
3484 return true;
3487 bool ChatHandler::HandleLinkGraveCommand(const char* args)
3489 if(!*args)
3490 return false;
3492 char* px = strtok((char*)args, " ");
3493 if (!px)
3494 return false;
3496 uint32 g_id = (uint32)atoi(px);
3498 uint32 g_team;
3500 char* px2 = strtok(NULL, " ");
3502 if (!px2)
3503 g_team = 0;
3504 else if (strncmp(px2,"horde",6)==0)
3505 g_team = HORDE;
3506 else if (strncmp(px2,"alliance",9)==0)
3507 g_team = ALLIANCE;
3508 else
3509 return false;
3511 WorldSafeLocsEntry const* graveyard = sWorldSafeLocsStore.LookupEntry(g_id);
3513 if(!graveyard )
3515 PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST, g_id);
3516 SetSentErrorMessage(true);
3517 return false;
3520 Player* player = m_session->GetPlayer();
3522 uint32 zoneId = player->GetZoneId();
3524 AreaTableEntry const *areaEntry = GetAreaEntryByAreaID(zoneId);
3525 if(!areaEntry || areaEntry->zone !=0 )
3527 PSendSysMessage(LANG_COMMAND_GRAVEYARDWRONGZONE, g_id,zoneId);
3528 SetSentErrorMessage(true);
3529 return false;
3532 if(objmgr.AddGraveYardLink(g_id,player->GetZoneId(),g_team))
3533 PSendSysMessage(LANG_COMMAND_GRAVEYARDLINKED, g_id,zoneId);
3534 else
3535 PSendSysMessage(LANG_COMMAND_GRAVEYARDALRLINKED, g_id,zoneId);
3537 return true;
3540 bool ChatHandler::HandleNearGraveCommand(const char* args)
3542 uint32 g_team;
3544 size_t argslen = strlen(args);
3546 if(!*args)
3547 g_team = 0;
3548 else if (strncmp((char*)args,"horde",argslen)==0)
3549 g_team = HORDE;
3550 else if (strncmp((char*)args,"alliance",argslen)==0)
3551 g_team = ALLIANCE;
3552 else
3553 return false;
3555 Player* player = m_session->GetPlayer();
3557 WorldSafeLocsEntry const* graveyard = objmgr.GetClosestGraveYard(
3558 player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(),player->GetMapId(),g_team);
3560 if(graveyard)
3562 uint32 g_id = graveyard->ID;
3564 GraveYardData const* data = objmgr.FindGraveYardData(g_id,player->GetZoneId());
3565 if (!data)
3567 PSendSysMessage(LANG_COMMAND_GRAVEYARDERROR,g_id);
3568 SetSentErrorMessage(true);
3569 return false;
3572 g_team = data->team;
3574 std::string team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_NOTEAM);
3576 if(g_team == 0)
3577 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ANY);
3578 else if(g_team == HORDE)
3579 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_HORDE);
3580 else if(g_team == ALLIANCE)
3581 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ALLIANCE);
3583 PSendSysMessage(LANG_COMMAND_GRAVEYARDNEAREST, g_id,team_name.c_str(),player->GetZoneId());
3585 else
3587 std::string team_name;
3589 if(g_team == 0)
3590 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ANY);
3591 else if(g_team == HORDE)
3592 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_HORDE);
3593 else if(g_team == ALLIANCE)
3594 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ALLIANCE);
3596 if(g_team == ~uint32(0))
3597 PSendSysMessage(LANG_COMMAND_ZONENOGRAVEYARDS, player->GetZoneId());
3598 else
3599 PSendSysMessage(LANG_COMMAND_ZONENOGRAFACTION, player->GetZoneId(),team_name.c_str());
3602 return true;
3605 //play npc emote
3606 bool ChatHandler::HandleNpcPlayEmoteCommand(const char* args)
3608 uint32 emote = atoi((char*)args);
3610 Creature* target = getSelectedCreature();
3611 if(!target)
3613 SendSysMessage(LANG_SELECT_CREATURE);
3614 SetSentErrorMessage(true);
3615 return false;
3618 target->SetUInt32Value(UNIT_NPC_EMOTESTATE,emote);
3620 return true;
3623 bool ChatHandler::HandleNpcInfoCommand(const char* /*args*/)
3625 Creature* target = getSelectedCreature();
3627 if(!target)
3629 SendSysMessage(LANG_SELECT_CREATURE);
3630 SetSentErrorMessage(true);
3631 return false;
3634 uint32 faction = target->getFaction();
3635 uint32 npcflags = target->GetUInt32Value(UNIT_NPC_FLAGS);
3636 uint32 displayid = target->GetDisplayId();
3637 uint32 nativeid = target->GetNativeDisplayId();
3638 uint32 Entry = target->GetEntry();
3639 CreatureInfo const* cInfo = target->GetCreatureInfo();
3641 int32 curRespawnDelay = target->GetRespawnTimeEx()-time(NULL);
3642 if(curRespawnDelay < 0)
3643 curRespawnDelay = 0;
3644 std::string curRespawnDelayStr = secsToTimeString(curRespawnDelay,true);
3645 std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(),true);
3647 PSendSysMessage(LANG_NPCINFO_CHAR, target->GetDBTableGUIDLow(), faction, npcflags, Entry, displayid, nativeid);
3648 PSendSysMessage(LANG_NPCINFO_LEVEL, target->getLevel());
3649 PSendSysMessage(LANG_NPCINFO_HEALTH,target->GetCreateHealth(), target->GetMaxHealth(), target->GetHealth());
3650 PSendSysMessage(LANG_NPCINFO_FLAGS, target->GetUInt32Value(UNIT_FIELD_FLAGS), target->GetUInt32Value(UNIT_DYNAMIC_FLAGS), target->getFaction());
3651 PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES, defRespawnDelayStr.c_str(),curRespawnDelayStr.c_str());
3652 PSendSysMessage(LANG_NPCINFO_LOOT, cInfo->lootid,cInfo->pickpocketLootId,cInfo->SkinLootId);
3653 PSendSysMessage(LANG_NPCINFO_DUNGEON_ID, target->GetInstanceId());
3654 PSendSysMessage(LANG_NPCINFO_POSITION,float(target->GetPositionX()), float(target->GetPositionY()), float(target->GetPositionZ()));
3656 if ((npcflags & UNIT_NPC_FLAG_VENDOR) )
3658 SendSysMessage(LANG_NPCINFO_VENDOR);
3660 if ((npcflags & UNIT_NPC_FLAG_TRAINER) )
3662 SendSysMessage(LANG_NPCINFO_TRAINER);
3665 return true;
3668 bool ChatHandler::HandleExploreCheatCommand(const char* args)
3670 if (!*args)
3671 return false;
3673 int flag = atoi((char*)args);
3675 Player *chr = getSelectedPlayer();
3676 if (chr == NULL)
3678 SendSysMessage(LANG_NO_CHAR_SELECTED);
3679 SetSentErrorMessage(true);
3680 return false;
3683 if (flag != 0)
3685 PSendSysMessage(LANG_YOU_SET_EXPLORE_ALL, chr->GetName());
3686 if (needReportToTarget(chr))
3687 ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_ALL,GetName());
3689 else
3691 PSendSysMessage(LANG_YOU_SET_EXPLORE_NOTHING, chr->GetName());
3692 if (needReportToTarget(chr))
3693 ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_NOTHING,GetName());
3696 for (uint8 i=0; i<128; i++)
3698 if (flag != 0)
3700 m_session->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i,0xFFFFFFFF);
3702 else
3704 m_session->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i,0);
3708 return true;
3711 bool ChatHandler::HandleHoverCommand(const char* args)
3713 char* px = strtok((char*)args, " ");
3714 uint32 flag;
3715 if (!px)
3716 flag = 1;
3717 else
3718 flag = atoi(px);
3720 m_session->GetPlayer()->SetHover(flag);
3722 if (flag)
3723 SendSysMessage(LANG_HOVER_ENABLED);
3724 else
3725 SendSysMessage(LANG_HOVER_DISABLED);
3727 return true;
3730 bool ChatHandler::HandleLevelUpCommand(const char* args)
3732 char* px = strtok((char*)args, " ");
3733 char* py = strtok((char*)NULL, " ");
3735 // command format parsing
3736 char* pname = (char*)NULL;
3737 int addlevel = 1;
3739 if(px && py) // .levelup name level
3741 addlevel = atoi(py);
3742 pname = px;
3744 else if(px && !py) // .levelup name OR .levelup level
3746 if(isalpha(px[0])) // .levelup name
3747 pname = px;
3748 else // .levelup level
3749 addlevel = atoi(px);
3751 // else .levelup - nothing do for preparing
3753 // player
3754 Player *chr = NULL;
3755 uint64 chr_guid = 0;
3757 std::string name;
3759 if(pname) // player by name
3761 name = pname;
3762 if(!normalizePlayerName(name))
3764 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3765 SetSentErrorMessage(true);
3766 return false;
3769 chr = objmgr.GetPlayer(name.c_str());
3770 if(!chr) // not in game
3772 chr_guid = objmgr.GetPlayerGUIDByName(name);
3773 if (chr_guid == 0)
3775 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3776 SetSentErrorMessage(true);
3777 return false;
3781 else // player by selection
3783 chr = getSelectedPlayer();
3785 if (chr == NULL)
3787 SendSysMessage(LANG_NO_CHAR_SELECTED);
3788 SetSentErrorMessage(true);
3789 return false;
3792 name = chr->GetName();
3795 assert(chr || chr_guid);
3797 int32 oldlevel = chr ? chr->getLevel() : Player::GetUInt32ValueFromDB(UNIT_FIELD_LEVEL,chr_guid);
3798 int32 newlevel = oldlevel + addlevel;
3799 if(newlevel < 1)
3800 newlevel = 1;
3801 if(newlevel > STRONG_MAX_LEVEL) // hardcoded maximum level
3802 newlevel = STRONG_MAX_LEVEL;
3804 if(chr)
3806 chr->GiveLevel(newlevel);
3807 chr->InitTalentForLevel();
3808 chr->SetUInt32Value(PLAYER_XP,0);
3810 if(oldlevel == newlevel)
3811 ChatHandler(chr).SendSysMessage(LANG_YOURS_LEVEL_PROGRESS_RESET);
3812 else
3813 if(oldlevel < newlevel)
3814 ChatHandler(chr).PSendSysMessage(LANG_YOURS_LEVEL_UP,newlevel-oldlevel);
3815 else
3816 if(oldlevel > newlevel)
3817 ChatHandler(chr).PSendSysMessage(LANG_YOURS_LEVEL_DOWN,newlevel-oldlevel);
3819 else
3821 // update level and XP at level, all other will be updated at loading
3822 Tokens values;
3823 Player::LoadValuesArrayFromDB(values,chr_guid);
3824 Player::SetUInt32ValueInArray(values,UNIT_FIELD_LEVEL,newlevel);
3825 Player::SetUInt32ValueInArray(values,PLAYER_XP,0);
3826 Player::SaveValuesArrayInDB(values,chr_guid);
3829 if(m_session->GetPlayer() != chr) // including chr==NULL
3830 PSendSysMessage(LANG_YOU_CHANGE_LVL,name.c_str(),newlevel);
3831 return true;
3834 bool ChatHandler::HandleShowAreaCommand(const char* args)
3836 if (!*args)
3837 return false;
3839 Player *chr = getSelectedPlayer();
3840 if (chr == NULL)
3842 SendSysMessage(LANG_NO_CHAR_SELECTED);
3843 SetSentErrorMessage(true);
3844 return false;
3847 int area = GetAreaFlagByAreaID(atoi((char*)args));
3848 int offset = area / 32;
3849 uint32 val = (uint32)(1 << (area % 32));
3851 if(area<0 || offset >= 128)
3853 SendSysMessage(LANG_BAD_VALUE);
3854 SetSentErrorMessage(true);
3855 return false;
3858 uint32 currFields = chr->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset);
3859 chr->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields | val));
3861 SendSysMessage(LANG_EXPLORE_AREA);
3862 return true;
3865 bool ChatHandler::HandleHideAreaCommand(const char* args)
3867 if (!*args)
3868 return false;
3870 Player *chr = getSelectedPlayer();
3871 if (chr == NULL)
3873 SendSysMessage(LANG_NO_CHAR_SELECTED);
3874 SetSentErrorMessage(true);
3875 return false;
3878 int area = GetAreaFlagByAreaID(atoi((char*)args));
3879 int offset = area / 32;
3880 uint32 val = (uint32)(1 << (area % 32));
3882 if(area<0 || offset >= 128)
3884 SendSysMessage(LANG_BAD_VALUE);
3885 SetSentErrorMessage(true);
3886 return false;
3889 uint32 currFields = chr->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset);
3890 chr->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields ^ val));
3892 SendSysMessage(LANG_UNEXPLORE_AREA);
3893 return true;
3896 bool ChatHandler::HandleUpdate(const char* args)
3898 if(!*args)
3899 return false;
3901 uint32 updateIndex;
3902 uint32 value;
3904 char* pUpdateIndex = strtok((char*)args, " ");
3906 Unit* chr = getSelectedUnit();
3907 if (chr == NULL)
3909 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3910 SetSentErrorMessage(true);
3911 return false;
3914 if(!pUpdateIndex)
3916 return true;
3918 updateIndex = atoi(pUpdateIndex);
3919 //check updateIndex
3920 if(chr->GetTypeId() == TYPEID_PLAYER)
3922 if (updateIndex>=PLAYER_END) return true;
3924 else
3926 if (updateIndex>=UNIT_END) return true;
3929 char* pvalue = strtok(NULL, " ");
3930 if (!pvalue)
3932 value=chr->GetUInt32Value(updateIndex);
3934 PSendSysMessage(LANG_UPDATE, chr->GetGUIDLow(),updateIndex,value);
3935 return true;
3938 value=atoi(pvalue);
3940 PSendSysMessage(LANG_UPDATE_CHANGE, chr->GetGUIDLow(),updateIndex,value);
3942 chr->SetUInt32Value(updateIndex,value);
3944 return true;
3947 bool ChatHandler::HandleBankCommand(const char* /*args*/)
3949 m_session->SendShowBank( m_session->GetPlayer()->GetGUID() );
3951 return true;
3954 bool ChatHandler::HandleChangeWeather(const char* args)
3956 if(!*args)
3957 return false;
3959 //Weather is OFF
3960 if (!sWorld.getConfig(CONFIG_WEATHER))
3962 SendSysMessage(LANG_WEATHER_DISABLED);
3963 SetSentErrorMessage(true);
3964 return false;
3967 //*Change the weather of a cell
3968 char* px = strtok((char*)args, " ");
3969 char* py = strtok(NULL, " ");
3971 if (!px || !py)
3972 return false;
3974 uint32 type = (uint32)atoi(px); //0 to 3, 0: fine, 1: rain, 2: snow, 3: sand
3975 float grade = (float)atof(py); //0 to 1, sending -1 is instand good weather
3977 Player *player = m_session->GetPlayer();
3978 uint32 zoneid = player->GetZoneId();
3980 Weather* wth = sWorld.FindWeather(zoneid);
3982 if(!wth)
3983 wth = sWorld.AddWeather(zoneid);
3984 if(!wth)
3986 SendSysMessage(LANG_NO_WEATHER);
3987 SetSentErrorMessage(true);
3988 return false;
3991 wth->SetWeather(WeatherType(type), grade);
3993 return true;
3996 bool ChatHandler::HandleSetValue(const char* args)
3998 if(!*args)
3999 return false;
4001 char* px = strtok((char*)args, " ");
4002 char* py = strtok(NULL, " ");
4003 char* pz = strtok(NULL, " ");
4005 if (!px || !py)
4006 return false;
4008 Unit* target = getSelectedUnit();
4009 if(!target)
4011 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
4012 SetSentErrorMessage(true);
4013 return false;
4016 uint64 guid = target->GetGUID();
4018 uint32 Opcode = (uint32)atoi(px);
4019 if(Opcode >= target->GetValuesCount())
4021 PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, GUID_LOPART(guid), target->GetValuesCount());
4022 return false;
4024 uint32 iValue;
4025 float fValue;
4026 bool isint32 = true;
4027 if(pz)
4028 isint32 = (bool)atoi(pz);
4029 if(isint32)
4031 iValue = (uint32)atoi(py);
4032 sLog.outDebug(GetMangosString(LANG_SET_UINT), GUID_LOPART(guid), Opcode, iValue);
4033 target->SetUInt32Value( Opcode , iValue );
4034 PSendSysMessage(LANG_SET_UINT_FIELD, GUID_LOPART(guid), Opcode,iValue);
4036 else
4038 fValue = (float)atof(py);
4039 sLog.outDebug(GetMangosString(LANG_SET_FLOAT), GUID_LOPART(guid), Opcode, fValue);
4040 target->SetFloatValue( Opcode , fValue );
4041 PSendSysMessage(LANG_SET_FLOAT_FIELD, GUID_LOPART(guid), Opcode,fValue);
4044 return true;
4047 bool ChatHandler::HandleGetValue(const char* args)
4049 if(!*args)
4050 return false;
4052 char* px = strtok((char*)args, " ");
4053 char* pz = strtok(NULL, " ");
4055 if (!px)
4056 return false;
4058 Unit* target = getSelectedUnit();
4059 if(!target)
4061 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
4062 SetSentErrorMessage(true);
4063 return false;
4066 uint64 guid = target->GetGUID();
4068 uint32 Opcode = (uint32)atoi(px);
4069 if(Opcode >= target->GetValuesCount())
4071 PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, GUID_LOPART(guid), target->GetValuesCount());
4072 return false;
4074 uint32 iValue;
4075 float fValue;
4076 bool isint32 = true;
4077 if(pz)
4078 isint32 = (bool)atoi(pz);
4080 if(isint32)
4082 iValue = target->GetUInt32Value( Opcode );
4083 sLog.outDebug(GetMangosString(LANG_GET_UINT), GUID_LOPART(guid), Opcode, iValue);
4084 PSendSysMessage(LANG_GET_UINT_FIELD, GUID_LOPART(guid), Opcode, iValue);
4086 else
4088 fValue = target->GetFloatValue( Opcode );
4089 sLog.outDebug(GetMangosString(LANG_GET_FLOAT), GUID_LOPART(guid), Opcode, fValue);
4090 PSendSysMessage(LANG_GET_FLOAT_FIELD, GUID_LOPART(guid), Opcode, fValue);
4093 return true;
4096 bool ChatHandler::HandleSet32Bit(const char* args)
4098 if(!*args)
4099 return false;
4101 char* px = strtok((char*)args, " ");
4102 char* py = strtok(NULL, " ");
4104 if (!px || !py)
4105 return false;
4107 uint32 Opcode = (uint32)atoi(px);
4108 uint32 Value = (uint32)atoi(py);
4109 if (Value > 32) //uint32 = 32 bits
4110 return false;
4112 sLog.outDebug(GetMangosString(LANG_SET_32BIT), Opcode, Value);
4114 m_session->GetPlayer( )->SetUInt32Value( Opcode , 2^Value );
4116 PSendSysMessage(LANG_SET_32BIT_FIELD, Opcode,1);
4117 return true;
4120 bool ChatHandler::HandleMod32Value(const char* args)
4122 if(!*args)
4123 return false;
4125 char* px = strtok((char*)args, " ");
4126 char* py = strtok(NULL, " ");
4128 if (!px || !py)
4129 return false;
4131 uint32 Opcode = (uint32)atoi(px);
4132 int Value = atoi(py);
4134 if(Opcode >= m_session->GetPlayer()->GetValuesCount())
4136 PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, m_session->GetPlayer()->GetGUIDLow(), m_session->GetPlayer( )->GetValuesCount());
4137 return false;
4140 sLog.outDebug(GetMangosString(LANG_CHANGE_32BIT), Opcode, Value);
4142 int CurrentValue = (int)m_session->GetPlayer( )->GetUInt32Value( Opcode );
4144 CurrentValue += Value;
4145 m_session->GetPlayer( )->SetUInt32Value( Opcode , (uint32)CurrentValue );
4147 PSendSysMessage(LANG_CHANGE_32BIT_FIELD, Opcode,CurrentValue);
4149 return true;
4152 bool ChatHandler::HandleAddTeleCommand(const char * args)
4154 if(!*args)
4155 return false;
4157 Player *player=m_session->GetPlayer();
4158 if (!player)
4159 return false;
4161 std::string name = args;
4163 if(objmgr.GetGameTele(name))
4165 SendSysMessage(LANG_COMMAND_TP_ALREADYEXIST);
4166 SetSentErrorMessage(true);
4167 return false;
4170 GameTele tele;
4171 tele.position_x = player->GetPositionX();
4172 tele.position_y = player->GetPositionY();
4173 tele.position_z = player->GetPositionZ();
4174 tele.orientation = player->GetOrientation();
4175 tele.mapId = player->GetMapId();
4176 tele.name = name;
4178 if(objmgr.AddGameTele(tele))
4180 SendSysMessage(LANG_COMMAND_TP_ADDED);
4182 else
4184 SendSysMessage(LANG_COMMAND_TP_ADDEDERR);
4185 SetSentErrorMessage(true);
4186 return false;
4189 return true;
4192 bool ChatHandler::HandleDelTeleCommand(const char * args)
4194 if(!*args)
4195 return false;
4197 std::string name = args;
4199 if(!objmgr.DeleteGameTele(name))
4201 SendSysMessage(LANG_COMMAND_TELE_NOTFOUND);
4202 SetSentErrorMessage(true);
4203 return false;
4206 SendSysMessage(LANG_COMMAND_TP_DELETED);
4207 return true;
4210 bool ChatHandler::HandleListAurasCommand (const char * /*args*/)
4212 Unit *unit = getSelectedUnit();
4213 if(!unit)
4215 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
4216 SetSentErrorMessage(true);
4217 return false;
4220 char const* talentStr = GetMangosString(LANG_TALENT);
4221 char const* passiveStr = GetMangosString(LANG_PASSIVE);
4223 Unit::AuraMap const& uAuras = unit->GetAuras();
4224 PSendSysMessage(LANG_COMMAND_TARGET_LISTAURAS, uAuras.size());
4225 for (Unit::AuraMap::const_iterator itr = uAuras.begin(); itr != uAuras.end(); ++itr)
4227 bool talent = GetTalentSpellCost(itr->second->GetId()) > 0;
4228 PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffIndex(),
4229 itr->second->GetModifier()->m_auraname, itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(),
4230 itr->second->GetSpellProto()->SpellName[m_session->GetSessionDbcLocale()],
4231 (itr->second->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
4232 IS_PLAYER_GUID(itr->second->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(itr->second->GetCasterGUID()));
4234 for (int i = 0; i < TOTAL_AURAS; i++)
4236 Unit::AuraList const& uAuraList = unit->GetAurasByType(AuraType(i));
4237 if (uAuraList.empty()) continue;
4238 PSendSysMessage(LANG_COMMAND_TARGET_LISTAURATYPE, uAuraList.size(), i);
4239 for (Unit::AuraList::const_iterator itr = uAuraList.begin(); itr != uAuraList.end(); ++itr)
4241 bool talent = GetTalentSpellCost((*itr)->GetId()) > 0;
4242 PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(),
4243 (*itr)->GetSpellProto()->SpellName[m_session->GetSessionDbcLocale()],((*itr)->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
4244 IS_PLAYER_GUID((*itr)->GetCasterGUID()) ? "player" : "creature",GUID_LOPART((*itr)->GetCasterGUID()));
4247 return true;
4250 bool ChatHandler::HandleResetHonorCommand (const char * args)
4252 char* pName = strtok((char*)args, "");
4253 Player *player = NULL;
4254 if (pName)
4256 std::string name = pName;
4257 if(!normalizePlayerName(name))
4259 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4260 SetSentErrorMessage(true);
4261 return false;
4264 uint64 guid = objmgr.GetPlayerGUIDByName(name.c_str());
4265 player = objmgr.GetPlayer(guid);
4267 else
4268 player = getSelectedPlayer();
4270 if(!player)
4272 SendSysMessage(LANG_NO_CHAR_SELECTED);
4273 return true;
4276 player->SetUInt32Value(PLAYER_FIELD_KILLS, 0);
4277 player->SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORBALE_KILLS, 0);
4278 player->SetUInt32Value(PLAYER_FIELD_HONOR_CURRENCY, 0);
4279 player->SetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, 0);
4280 player->SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, 0);
4282 return true;
4285 static bool HandleResetStatsOrLevelHelper(Player* player)
4287 PlayerInfo const *info = objmgr.GetPlayerInfo(player->getRace(), player->getClass());
4288 if(!info) return false;
4290 ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(player->getClass());
4291 if(!cEntry)
4293 sLog.outError("Class %u not found in DBC (Wrong DBC files?)",player->getClass());
4294 return false;
4297 uint8 powertype = cEntry->powerType;
4299 uint32 unitfield;
4300 if(powertype == POWER_RAGE)
4301 unitfield = 0x1100EE00;
4302 else if(powertype == POWER_ENERGY)
4303 unitfield = 0x00000000;
4304 else if(powertype == POWER_MANA)
4305 unitfield = 0x0000EE00;
4306 else
4308 sLog.outError("Invalid default powertype %u for player (class %u)",powertype,player->getClass());
4309 return false;
4312 // reset m_form if no aura
4313 if(!player->HasAuraType(SPELL_AURA_MOD_SHAPESHIFT))
4314 player->m_form = FORM_NONE;
4316 player->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE );
4317 player->SetFloatValue(UNIT_FIELD_COMBATREACH, 1.5f );
4319 player->setFactionForRace(player->getRace());
4321 player->SetUInt32Value(UNIT_FIELD_BYTES_0, ( ( player->getRace() ) | ( player->getClass() << 8 ) | ( player->getGender() << 16 ) | ( powertype << 24 ) ) );
4323 // reset only if player not in some form;
4324 if(player->m_form==FORM_NONE)
4326 switch(player->getGender())
4328 case GENDER_FEMALE:
4329 player->SetDisplayId(info->displayId_f);
4330 player->SetNativeDisplayId(info->displayId_f);
4331 break;
4332 case GENDER_MALE:
4333 player->SetDisplayId(info->displayId_m);
4334 player->SetNativeDisplayId(info->displayId_m);
4335 break;
4336 default:
4337 break;
4341 // set UNIT_FIELD_BYTES_1 to init state but preserve m_form value
4342 player->SetUInt32Value(UNIT_FIELD_BYTES_1, unitfield);
4343 player->SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP );
4344 player->SetByteValue(UNIT_FIELD_BYTES_2, 3, player->m_form);
4346 player->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
4348 //-1 is default value
4349 player->SetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, uint32(-1));
4351 //player->SetUInt32Value(PLAYER_FIELD_BYTES, 0xEEE00000 );
4352 return true;
4355 bool ChatHandler::HandleResetLevelCommand(const char * args)
4357 char* pName = strtok((char*)args, "");
4358 Player *player = NULL;
4359 if (pName)
4361 std::string name = pName;
4362 if(!normalizePlayerName(name))
4364 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4365 SetSentErrorMessage(true);
4366 return false;
4369 uint64 guid = objmgr.GetPlayerGUIDByName(name.c_str());
4370 player = objmgr.GetPlayer(guid);
4372 else
4373 player = getSelectedPlayer();
4375 if(!player)
4377 SendSysMessage(LANG_NO_CHAR_SELECTED);
4378 SetSentErrorMessage(true);
4379 return false;
4382 if(!HandleResetStatsOrLevelHelper(player))
4383 return false;
4385 player->SetLevel(1);
4386 player->InitStatsForLevel(true);
4387 player->InitTaxiNodesForLevel();
4388 player->InitGlyphsForLevel();
4389 player->InitTalentForLevel();
4390 player->SetUInt32Value(PLAYER_XP,0);
4392 // reset level to summoned pet
4393 Pet* pet = player->GetPet();
4394 if(pet && pet->getPetType()==SUMMON_PET)
4395 pet->InitStatsForLevel(1);
4397 return true;
4400 bool ChatHandler::HandleResetStatsCommand(const char * args)
4402 char* pName = strtok((char*)args, "");
4403 Player *player = NULL;
4404 if (pName)
4406 std::string name = pName;
4407 if(!normalizePlayerName(name))
4409 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4410 SetSentErrorMessage(true);
4411 return false;
4414 uint64 guid = objmgr.GetPlayerGUIDByName(name.c_str());
4415 player = objmgr.GetPlayer(guid);
4417 else
4418 player = getSelectedPlayer();
4420 if(!player)
4422 SendSysMessage(LANG_NO_CHAR_SELECTED);
4423 SetSentErrorMessage(true);
4424 return false;
4427 if(!HandleResetStatsOrLevelHelper(player))
4428 return false;
4430 player->InitStatsForLevel(true);
4431 player->InitTaxiNodesForLevel();
4432 player->InitGlyphsForLevel();
4433 player->InitTalentForLevel();
4435 return true;
4438 bool ChatHandler::HandleResetSpellsCommand(const char * args)
4440 char* pName = strtok((char*)args, "");
4441 Player *player = NULL;
4442 uint64 playerGUID = 0;
4443 if (pName)
4445 std::string name = pName;
4447 if(!normalizePlayerName(name))
4449 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4450 SetSentErrorMessage(true);
4451 return false;
4454 player = objmgr.GetPlayer(name.c_str());
4455 if(!player)
4456 playerGUID = objmgr.GetPlayerGUIDByName(name.c_str());
4458 else
4459 player = getSelectedPlayer();
4461 if(!player && !playerGUID)
4463 SendSysMessage(LANG_NO_CHAR_SELECTED);
4464 SetSentErrorMessage(true);
4465 return false;
4468 if(player)
4470 player->resetSpells();
4472 ChatHandler(player).SendSysMessage(LANG_RESET_SPELLS);
4474 if(m_session->GetPlayer()!=player)
4475 PSendSysMessage(LANG_RESET_SPELLS_ONLINE,player->GetName());
4477 else
4479 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",uint32(AT_LOGIN_RESET_SPELLS), GUID_LOPART(playerGUID));
4480 PSendSysMessage(LANG_RESET_SPELLS_OFFLINE,pName);
4483 return true;
4486 bool ChatHandler::HandleResetTalentsCommand(const char * args)
4488 char* pName = strtok((char*)args, "");
4489 Player *player = NULL;
4490 uint64 playerGUID = 0;
4491 if (pName)
4493 std::string name = pName;
4494 if(!normalizePlayerName(name))
4496 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4497 SetSentErrorMessage(true);
4498 return false;
4501 player = objmgr.GetPlayer(name.c_str());
4502 if(!player)
4503 playerGUID = objmgr.GetPlayerGUIDByName(name.c_str());
4505 else
4506 player = getSelectedPlayer();
4508 if(!player && !playerGUID)
4510 SendSysMessage(LANG_NO_CHAR_SELECTED);
4511 SetSentErrorMessage(true);
4512 return false;
4515 if(player)
4517 player->resetTalents(true);
4519 ChatHandler(player).SendSysMessage(LANG_RESET_TALENTS);
4521 if(m_session->GetPlayer()!=player)
4522 PSendSysMessage(LANG_RESET_TALENTS_ONLINE,player->GetName());
4524 else
4526 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",uint32(AT_LOGIN_RESET_TALENTS), GUID_LOPART(playerGUID) );
4527 PSendSysMessage(LANG_RESET_TALENTS_OFFLINE,pName);
4530 return true;
4533 bool ChatHandler::HandleResetAllCommand(const char * args)
4535 if(!*args)
4536 return false;
4538 std::string casename = args;
4540 AtLoginFlags atLogin;
4542 // Command specially created as single command to prevent using short case names
4543 if(casename=="spells")
4545 atLogin = AT_LOGIN_RESET_SPELLS;
4546 sWorld.SendWorldText(LANG_RESETALL_SPELLS);
4548 else if(casename=="talents")
4550 atLogin = AT_LOGIN_RESET_TALENTS;
4551 sWorld.SendWorldText(LANG_RESETALL_TALENTS);
4553 else
4555 PSendSysMessage(LANG_RESETALL_UNKNOWN_CASE,args);
4556 SetSentErrorMessage(true);
4557 return false;
4560 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE (at_login & '%u') = '0'",atLogin,atLogin);
4561 HashMapHolder<Player>::MapType const& plist = ObjectAccessor::Instance().GetPlayers();
4562 for(HashMapHolder<Player>::MapType::const_iterator itr = plist.begin(); itr != plist.end(); ++itr)
4563 itr->second->SetAtLoginFlag(atLogin);
4565 return true;
4568 bool ChatHandler::HandleServerShutDownCancelCommand(const char* args)
4570 sWorld.ShutdownCancel();
4571 return true;
4574 bool ChatHandler::HandleServerShutDownCommand(const char* args)
4576 if(!*args)
4577 return false;
4579 char* time_str = strtok ((char*) args, " ");
4580 char* exitcode_str = strtok (NULL, "");
4582 int32 time = atoi (time_str);
4584 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4585 if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0)
4586 return false;
4588 if (exitcode_str)
4590 int32 exitcode = atoi (exitcode_str);
4592 // Handle atoi() errors
4593 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4594 return false;
4596 // Exit code should be in range of 0-125, 126-255 is used
4597 // in many shells for their own return codes and code > 255
4598 // is not supported in many others
4599 if (exitcode < 0 || exitcode > 125)
4600 return false;
4602 sWorld.ShutdownServ (time, 0, exitcode);
4604 else
4605 sWorld.ShutdownServ(time,0,SHUTDOWN_EXIT_CODE);
4606 return true;
4609 bool ChatHandler::HandleServerRestartCommand(const char* args)
4611 if(!*args)
4612 return false;
4614 char* time_str = strtok ((char*) args, " ");
4615 char* exitcode_str = strtok (NULL, "");
4617 int32 time = atoi (time_str);
4619 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4620 if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0)
4621 return false;
4623 if (exitcode_str)
4625 int32 exitcode = atoi (exitcode_str);
4627 // Handle atoi() errors
4628 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4629 return false;
4631 // Exit code should be in range of 0-125, 126-255 is used
4632 // in many shells for their own return codes and code > 255
4633 // is not supported in many others
4634 if (exitcode < 0 || exitcode > 125)
4635 return false;
4637 sWorld.ShutdownServ (time, SHUTDOWN_MASK_RESTART, exitcode);
4639 else
4640 sWorld.ShutdownServ(time, SHUTDOWN_MASK_RESTART, RESTART_EXIT_CODE);
4641 return true;
4644 bool ChatHandler::HandleServerIdleRestartCommand(const char* args)
4646 if(!*args)
4647 return false;
4649 char* time_str = strtok ((char*) args, " ");
4650 char* exitcode_str = strtok (NULL, "");
4652 int32 time = atoi (time_str);
4654 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4655 if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0)
4656 return false;
4658 if (exitcode_str)
4660 int32 exitcode = atoi (exitcode_str);
4662 // Handle atoi() errors
4663 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4664 return false;
4666 // Exit code should be in range of 0-125, 126-255 is used
4667 // in many shells for their own return codes and code > 255
4668 // is not supported in many others
4669 if (exitcode < 0 || exitcode > 125)
4670 return false;
4672 sWorld.ShutdownServ (time, SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE, exitcode);
4674 else
4675 sWorld.ShutdownServ(time,SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE,RESTART_EXIT_CODE);
4676 return true;
4679 bool ChatHandler::HandleServerIdleShutDownCommand(const char* args)
4681 if(!*args)
4682 return false;
4684 char* time_str = strtok ((char*) args, " ");
4685 char* exitcode_str = strtok (NULL, "");
4687 int32 time = atoi (time_str);
4689 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4690 if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0)
4691 return false;
4693 if (exitcode_str)
4695 int32 exitcode = atoi (exitcode_str);
4697 // Handle atoi() errors
4698 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4699 return false;
4701 // Exit code should be in range of 0-125, 126-255 is used
4702 // in many shells for their own return codes and code > 255
4703 // is not supported in many others
4704 if (exitcode < 0 || exitcode > 125)
4705 return false;
4707 sWorld.ShutdownServ (time, SHUTDOWN_MASK_IDLE, exitcode);
4709 else
4710 sWorld.ShutdownServ(time,SHUTDOWN_MASK_IDLE,SHUTDOWN_EXIT_CODE);
4711 return true;
4714 bool ChatHandler::HandleAddQuest(const char* args)
4716 Player* player = getSelectedPlayer();
4717 if(!player)
4719 SendSysMessage(LANG_NO_CHAR_SELECTED);
4720 SetSentErrorMessage(true);
4721 return false;
4724 // .addquest #entry'
4725 // number or [name] Shift-click form |color|Hquest:quest_id|h[name]|h|r
4726 char* cId = extractKeyFromLink((char*)args,"Hquest");
4727 if(!cId)
4728 return false;
4730 uint32 entry = atol(cId);
4732 Quest const* pQuest = objmgr.GetQuestTemplate(entry);
4734 if(!pQuest)
4736 PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND,entry);
4737 SetSentErrorMessage(true);
4738 return false;
4741 // check item starting quest (it can work incorrectly if added without item in inventory)
4742 for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
4744 ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype>(id);
4745 if (!pProto)
4746 continue;
4748 if (pProto->StartQuest == entry)
4750 PSendSysMessage(LANG_COMMAND_QUEST_STARTFROMITEM, entry, pProto->ItemId);
4751 SetSentErrorMessage(true);
4752 return false;
4756 // ok, normal (creature/GO starting) quest
4757 if( player->CanAddQuest( pQuest, true ) )
4759 player->AddQuest( pQuest, NULL );
4761 if ( player->CanCompleteQuest( entry ) )
4762 player->CompleteQuest( entry );
4765 return true;
4768 bool ChatHandler::HandleRemoveQuest(const char* args)
4770 Player* player = getSelectedPlayer();
4771 if(!player)
4773 SendSysMessage(LANG_NO_CHAR_SELECTED);
4774 SetSentErrorMessage(true);
4775 return false;
4778 // .removequest #entry'
4779 // number or [name] Shift-click form |color|Hquest:quest_id|h[name]|h|r
4780 char* cId = extractKeyFromLink((char*)args,"Hquest");
4781 if(!cId)
4782 return false;
4784 uint32 entry = atol(cId);
4786 Quest const* pQuest = objmgr.GetQuestTemplate(entry);
4788 if(!pQuest)
4790 PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry);
4791 SetSentErrorMessage(true);
4792 return false;
4795 // remove all quest entries for 'entry' from quest log
4796 for(uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot )
4798 uint32 quest = player->GetQuestSlotQuestId(slot);
4799 if(quest==entry)
4801 player->SetQuestSlot(slot,0);
4803 // we ignore unequippable quest items in this case, its' still be equipped
4804 player->TakeQuestSourceItem( quest, false );
4808 // set quest status to not started (will updated in DB at next save)
4809 player->SetQuestStatus( entry, QUEST_STATUS_NONE);
4811 // reset rewarded for restart repeatable quest
4812 player->getQuestStatusMap()[entry].m_rewarded = false;
4814 SendSysMessage(LANG_COMMAND_QUEST_REMOVED);
4815 return true;
4818 bool ChatHandler::HandleCompleteQuest(const char* args)
4820 Player* player = getSelectedPlayer();
4821 if(!player)
4823 SendSysMessage(LANG_NO_CHAR_SELECTED);
4824 SetSentErrorMessage(true);
4825 return false;
4828 // .quest complete #entry
4829 // number or [name] Shift-click form |color|Hquest:quest_id|h[name]|h|r
4830 char* cId = extractKeyFromLink((char*)args,"Hquest");
4831 if(!cId)
4832 return false;
4834 uint32 entry = atol(cId);
4836 Quest const* pQuest = objmgr.GetQuestTemplate(entry);
4838 // If player doesn't have the quest
4839 if(!pQuest || player->GetQuestStatus(entry) == QUEST_STATUS_NONE)
4841 PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry);
4842 SetSentErrorMessage(true);
4843 return false;
4846 // Add quest items for quests that require items
4847 for(uint8 x = 0; x < QUEST_OBJECTIVES_COUNT; ++x)
4849 uint32 id = pQuest->ReqItemId[x];
4850 uint32 count = pQuest->ReqItemCount[x];
4851 if(!id || !count)
4852 continue;
4854 uint32 curItemCount = player->GetItemCount(id,true);
4856 ItemPosCountVec dest;
4857 uint8 msg = player->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, id, count-curItemCount );
4858 if( msg == EQUIP_ERR_OK )
4860 Item* item = player->StoreNewItem( dest, id, true);
4861 player->SendNewItem(item,count-curItemCount,true,false);
4865 // All creature/GO slain/casted (not required, but otherwise it will display "Creature slain 0/10")
4866 for(uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; i++)
4868 uint32 creature = pQuest->ReqCreatureOrGOId[i];
4869 uint32 creaturecount = pQuest->ReqCreatureOrGOCount[i];
4871 if(uint32 spell_id = pQuest->ReqSpell[i])
4873 for(uint16 z = 0; z < creaturecount; ++z)
4874 player->CastedCreatureOrGO(creature,0,spell_id);
4876 else if(creature > 0)
4878 for(uint16 z = 0; z < creaturecount; ++z)
4879 player->KilledMonster(creature,0);
4881 else if(creature < 0)
4883 for(uint16 z = 0; z < creaturecount; ++z)
4884 player->CastedCreatureOrGO(creature,0,0);
4888 // If the quest requires reputation to complete
4889 if(uint32 repFaction = pQuest->GetRepObjectiveFaction())
4891 uint32 repValue = pQuest->GetRepObjectiveValue();
4892 uint32 curRep = player->GetReputation(repFaction);
4893 if(curRep < repValue)
4895 FactionEntry const *factionEntry = sFactionStore.LookupEntry(repFaction);
4896 player->SetFactionReputation(factionEntry,repValue);
4900 // If the quest requires money
4901 int32 ReqOrRewMoney = pQuest->GetRewOrReqMoney();
4902 if(ReqOrRewMoney < 0)
4903 player->ModifyMoney(-ReqOrRewMoney);
4905 player->CompleteQuest(entry);
4906 return true;
4909 bool ChatHandler::HandleBanAccountCommand(const char* args)
4911 return HandleBanHelper(BAN_ACCOUNT,args);
4914 bool ChatHandler::HandleBanCharacterCommand(const char* args)
4916 return HandleBanHelper(BAN_CHARACTER,args);
4919 bool ChatHandler::HandleBanIPCommand(const char* args)
4921 return HandleBanHelper(BAN_IP,args);
4924 bool ChatHandler::HandleBanHelper(BanMode mode, const char* args)
4926 if(!args)
4927 return false;
4929 char* cnameOrIP = strtok ((char*)args, " ");
4930 if (!cnameOrIP)
4931 return false;
4933 std::string nameOrIP = cnameOrIP;
4935 char* duration = strtok (NULL," ");
4936 if(!duration || !atoi(duration))
4937 return false;
4939 char* reason = strtok (NULL,"");
4940 if(!reason)
4941 return false;
4943 switch(mode)
4945 case BAN_ACCOUNT:
4946 if(!AccountMgr::normilizeString(nameOrIP))
4948 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,nameOrIP.c_str());
4949 SetSentErrorMessage(true);
4950 return false;
4952 break;
4953 case BAN_CHARACTER:
4954 if(!normalizePlayerName(nameOrIP))
4956 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4957 SetSentErrorMessage(true);
4958 return false;
4960 break;
4961 case BAN_IP:
4962 if(!IsIPAddress(nameOrIP.c_str()))
4963 return false;
4964 break;
4967 switch(sWorld.BanAccount(mode, nameOrIP, duration, reason,m_session ? m_session->GetPlayerName() : ""))
4969 case BAN_SUCCESS:
4970 if(atoi(duration)>0)
4971 PSendSysMessage(LANG_BAN_YOUBANNED,nameOrIP.c_str(),secsToTimeString(TimeStringToSecs(duration),true).c_str(),reason);
4972 else
4973 PSendSysMessage(LANG_BAN_YOUPERMBANNED,nameOrIP.c_str(),reason);
4974 break;
4975 case BAN_SYNTAX_ERROR:
4976 return false;
4977 case BAN_NOTFOUND:
4978 switch(mode)
4980 default:
4981 PSendSysMessage(LANG_BAN_NOTFOUND,"account",nameOrIP.c_str());
4982 break;
4983 case BAN_CHARACTER:
4984 PSendSysMessage(LANG_BAN_NOTFOUND,"character",nameOrIP.c_str());
4985 break;
4986 case BAN_IP:
4987 PSendSysMessage(LANG_BAN_NOTFOUND,"ip",nameOrIP.c_str());
4988 break;
4990 SetSentErrorMessage(true);
4991 return false;
4994 return true;
4997 bool ChatHandler::HandleUnBanAccountCommand(const char* args)
4999 return HandleUnBanHelper(BAN_ACCOUNT,args);
5002 bool ChatHandler::HandleUnBanCharacterCommand(const char* args)
5004 return HandleUnBanHelper(BAN_CHARACTER,args);
5007 bool ChatHandler::HandleUnBanIPCommand(const char* args)
5009 return HandleUnBanHelper(BAN_IP,args);
5012 bool ChatHandler::HandleUnBanHelper(BanMode mode, const char* args)
5014 if(!args)
5015 return false;
5017 char* cnameOrIP = strtok ((char*)args, " ");
5018 if(!cnameOrIP)
5019 return false;
5021 std::string nameOrIP = cnameOrIP;
5023 switch(mode)
5025 case BAN_ACCOUNT:
5026 if(!AccountMgr::normilizeString(nameOrIP))
5028 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,nameOrIP.c_str());
5029 SetSentErrorMessage(true);
5030 return false;
5032 break;
5033 case BAN_CHARACTER:
5034 if(!normalizePlayerName(nameOrIP))
5036 SendSysMessage(LANG_PLAYER_NOT_FOUND);
5037 SetSentErrorMessage(true);
5038 return false;
5040 break;
5041 case BAN_IP:
5042 if(!IsIPAddress(nameOrIP.c_str()))
5043 return false;
5044 break;
5047 if(sWorld.RemoveBanAccount(mode,nameOrIP))
5048 PSendSysMessage(LANG_UNBAN_UNBANNED,nameOrIP.c_str());
5049 else
5050 PSendSysMessage(LANG_UNBAN_ERROR,nameOrIP.c_str());
5052 return true;
5055 bool ChatHandler::HandleBanInfoAccountCommand(const char* args)
5057 if(!args)
5058 return false;
5060 char* cname = strtok((char*)args, "");
5061 if(!cname)
5062 return false;
5064 std::string account_name = cname;
5065 if(!AccountMgr::normilizeString(account_name))
5067 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5068 SetSentErrorMessage(true);
5069 return false;
5072 uint32 accountid = accmgr.GetId(account_name);
5073 if(!accountid)
5075 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5076 return true;
5079 return HandleBanInfoHelper(accountid,account_name.c_str());
5082 bool ChatHandler::HandleBanInfoCharacterCommand(const char* args)
5084 if(!args)
5085 return false;
5087 char* cname = strtok ((char*)args, "");
5088 if(!cname)
5089 return false;
5091 std::string name = cname;
5092 if(!normalizePlayerName(name))
5094 SendSysMessage(LANG_PLAYER_NOT_FOUND);
5095 SetSentErrorMessage(true);
5096 return false;
5099 uint32 accountid = objmgr.GetPlayerAccountIdByPlayerName(name);
5100 if(!accountid)
5102 SendSysMessage(LANG_PLAYER_NOT_FOUND);
5103 SetSentErrorMessage(true);
5104 return false;
5107 std::string accountname;
5108 if(!accmgr.GetName(accountid,accountname))
5110 PSendSysMessage(LANG_BANINFO_NOCHARACTER);
5111 return true;
5114 return HandleBanInfoHelper(accountid,accountname.c_str());
5117 bool ChatHandler::HandleBanInfoHelper(uint32 accountid, char const* accountname)
5119 QueryResult *result = loginDatabase.PQuery("SELECT FROM_UNIXTIME(bandate), unbandate-bandate, active, unbandate,banreason,bannedby FROM account_banned WHERE id = '%u' ORDER BY bandate ASC",accountid);
5120 if(!result)
5122 PSendSysMessage(LANG_BANINFO_NOACCOUNTBAN, accountname);
5123 return true;
5126 PSendSysMessage(LANG_BANINFO_BANHISTORY,accountname);
5129 Field* fields = result->Fetch();
5131 time_t unbandate = time_t(fields[3].GetUInt64());
5132 bool active = false;
5133 if(fields[2].GetBool() && (fields[1].GetUInt64() == (uint64)0 ||unbandate >= time(NULL)) )
5134 active = true;
5135 bool permanent = (fields[1].GetUInt64() == (uint64)0);
5136 std::string bantime = permanent?GetMangosString(LANG_BANINFO_INFINITE):secsToTimeString(fields[1].GetUInt64(), true);
5137 PSendSysMessage(LANG_BANINFO_HISTORYENTRY,
5138 fields[0].GetString(), bantime.c_str(), active ? GetMangosString(LANG_BANINFO_YES):GetMangosString(LANG_BANINFO_NO), fields[4].GetString(), fields[5].GetString());
5139 }while (result->NextRow());
5141 delete result;
5142 return true;
5145 bool ChatHandler::HandleBanInfoIPCommand(const char* args)
5147 if(!args)
5148 return false;
5150 char* cIP = strtok ((char*)args, "");
5151 if(!cIP)
5152 return false;
5154 if (!IsIPAddress(cIP))
5155 return false;
5157 std::string IP = cIP;
5159 loginDatabase.escape_string(IP);
5160 QueryResult *result = loginDatabase.PQuery("SELECT ip, FROM_UNIXTIME(bandate), FROM_UNIXTIME(unbandate), unbandate-UNIX_TIMESTAMP(), banreason,bannedby,unbandate-bandate FROM ip_banned WHERE ip = '%s'",IP.c_str());
5161 if(!result)
5163 PSendSysMessage(LANG_BANINFO_NOIP);
5164 return true;
5167 Field *fields = result->Fetch();
5168 bool permanent = !fields[6].GetUInt64();
5169 PSendSysMessage(LANG_BANINFO_IPENTRY,
5170 fields[0].GetString(), fields[1].GetString(), permanent ? GetMangosString(LANG_BANINFO_NEVER):fields[2].GetString(),
5171 permanent ? GetMangosString(LANG_BANINFO_INFINITE):secsToTimeString(fields[3].GetUInt64(), true).c_str(), fields[4].GetString(), fields[5].GetString());
5172 delete result;
5173 return true;
5176 bool ChatHandler::HandleBanListCharacterCommand(const char* args)
5178 loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
5180 char* cFilter = strtok ((char*)args, " ");
5181 if(!cFilter)
5182 return false;
5184 std::string filter = cFilter;
5185 loginDatabase.escape_string(filter);
5186 QueryResult* result = CharacterDatabase.PQuery("SELECT account FROM characters WHERE name "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'"),filter.c_str());
5187 if (!result)
5189 PSendSysMessage(LANG_BANLIST_NOCHARACTER);
5190 return true;
5193 return HandleBanListHelper(result);
5196 bool ChatHandler::HandleBanListAccountCommand(const char* args)
5198 loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
5200 char* cFilter = strtok((char*)args, " ");
5201 std::string filter = cFilter ? cFilter : "";
5202 loginDatabase.escape_string(filter);
5204 QueryResult* result;
5206 if(filter.empty())
5208 result = loginDatabase.Query("SELECT account.id, username FROM account, account_banned"
5209 " WHERE account.id = account_banned.id AND active = 1 GROUP BY account.id");
5211 else
5213 result = loginDatabase.PQuery("SELECT account.id, username FROM account, account_banned"
5214 " WHERE account.id = account_banned.id AND active = 1 AND username "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")" GROUP BY account.id",
5215 filter.c_str());
5218 if (!result)
5220 PSendSysMessage(LANG_BANLIST_NOACCOUNT);
5221 return true;
5224 return HandleBanListHelper(result);
5227 bool ChatHandler::HandleBanListHelper(QueryResult* result)
5229 PSendSysMessage(LANG_BANLIST_MATCHINGACCOUNT);
5231 // Chat short output
5232 if(m_session)
5236 Field* fields = result->Fetch();
5237 uint32 accountid = fields[0].GetUInt32();
5239 QueryResult* banresult = loginDatabase.PQuery("SELECT account.username FROM account,account_banned WHERE account_banned.id='%u' AND account_banned.id=account.id",accountid);
5240 if(banresult)
5242 Field* fields2 = banresult->Fetch();
5243 PSendSysMessage("%s",fields2[0].GetString());
5244 delete banresult;
5246 } while (result->NextRow());
5248 // Console wide output
5249 else
5251 SendSysMessage(LANG_BANLIST_ACCOUNTS);
5252 SendSysMessage("===============================================================================");
5253 SendSysMessage(LANG_BANLIST_ACCOUNTS_HEADER);
5256 SendSysMessage("-------------------------------------------------------------------------------");
5257 Field *fields = result->Fetch();
5258 uint32 account_id = fields[0].GetUInt32 ();
5260 std::string account_name;
5262 // "account" case, name can be get in same query
5263 if(result->GetFieldCount() > 1)
5264 account_name = fields[1].GetCppString();
5265 // "character" case, name need extract from another DB
5266 else
5267 accmgr.GetName (account_id,account_name);
5269 // No SQL injection. id is uint32.
5270 QueryResult *banInfo = loginDatabase.PQuery("SELECT bandate,unbandate,bannedby,banreason FROM account_banned WHERE id = %u ORDER BY unbandate", account_id);
5271 if (banInfo)
5273 Field *fields2 = banInfo->Fetch();
5276 time_t t_ban = fields2[0].GetUInt64();
5277 tm* aTm_ban = localtime(&t_ban);
5279 if (fields2[0].GetUInt64() == fields2[1].GetUInt64())
5281 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|",
5282 account_name.c_str(),aTm_ban->tm_year%100, aTm_ban->tm_mon+1, aTm_ban->tm_mday, aTm_ban->tm_hour, aTm_ban->tm_min,
5283 fields2[2].GetString(),fields2[3].GetString());
5285 else
5287 time_t t_unban = fields2[1].GetUInt64();
5288 tm* aTm_unban = localtime(&t_unban);
5289 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|",
5290 account_name.c_str(),aTm_ban->tm_year%100, aTm_ban->tm_mon+1, aTm_ban->tm_mday, aTm_ban->tm_hour, aTm_ban->tm_min,
5291 aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min,
5292 fields2[2].GetString(),fields2[3].GetString());
5294 }while ( banInfo->NextRow() );
5295 delete banInfo;
5297 }while( result->NextRow() );
5298 SendSysMessage("===============================================================================");
5301 delete result;
5302 return true;
5305 bool ChatHandler::HandleBanListIPCommand(const char* args)
5307 loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
5309 char* cFilter = strtok((char*)args, " ");
5310 std::string filter = cFilter ? cFilter : "";
5311 loginDatabase.escape_string(filter);
5313 QueryResult* result;
5315 if(filter.empty())
5317 result = loginDatabase.Query ("SELECT ip,bandate,unbandate,bannedby,banreason FROM ip_banned"
5318 " WHERE (bandate=unbandate OR unbandate>UNIX_TIMESTAMP())"
5319 " ORDER BY unbandate" );
5321 else
5323 result = loginDatabase.PQuery( "SELECT ip,bandate,unbandate,bannedby,banreason FROM ip_banned"
5324 " WHERE (bandate=unbandate OR unbandate>UNIX_TIMESTAMP()) AND ip "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")
5325 " ORDER BY unbandate",filter.c_str() );
5328 if(!result)
5330 PSendSysMessage(LANG_BANLIST_NOIP);
5331 return true;
5334 PSendSysMessage(LANG_BANLIST_MATCHINGIP);
5335 // Chat short output
5336 if(m_session)
5340 Field* fields = result->Fetch();
5341 PSendSysMessage("%s",fields[0].GetString());
5342 } while (result->NextRow());
5344 // Console wide output
5345 else
5347 SendSysMessage(LANG_BANLIST_IPS);
5348 SendSysMessage("===============================================================================");
5349 SendSysMessage(LANG_BANLIST_IPS_HEADER);
5352 SendSysMessage("-------------------------------------------------------------------------------");
5353 Field *fields = result->Fetch();
5354 time_t t_ban = fields[1].GetUInt64();
5355 tm* aTm_ban = localtime(&t_ban);
5356 if ( fields[1].GetUInt64() == fields[2].GetUInt64() )
5358 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|",
5359 fields[0].GetString(), aTm_ban->tm_year%100, aTm_ban->tm_mon+1, aTm_ban->tm_mday, aTm_ban->tm_hour, aTm_ban->tm_min,
5360 fields[3].GetString(), fields[4].GetString());
5362 else
5364 time_t t_unban = fields[2].GetUInt64();
5365 tm* aTm_unban = localtime(&t_unban);
5366 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|",
5367 fields[0].GetString(), aTm_ban->tm_year%100, aTm_ban->tm_mon+1, aTm_ban->tm_mday, aTm_ban->tm_hour, aTm_ban->tm_min,
5368 aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min,
5369 fields[3].GetString(), fields[4].GetString());
5371 }while( result->NextRow() );
5372 SendSysMessage("===============================================================================");
5375 delete result;
5376 return true;
5379 bool ChatHandler::HandleRespawnCommand(const char* /*args*/)
5381 Player* pl = m_session->GetPlayer();
5383 // accept only explicitly selected target (not implicitly self targeting case)
5384 Unit* target = getSelectedUnit();
5385 if(pl->GetSelection() && target)
5387 if(target->GetTypeId()!=TYPEID_UNIT)
5389 SendSysMessage(LANG_SELECT_CREATURE);
5390 SetSentErrorMessage(true);
5391 return false;
5394 if(target->isDead())
5395 ((Creature*)target)->Respawn();
5396 return true;
5399 CellPair p(MaNGOS::ComputeCellPair(pl->GetPositionX(), pl->GetPositionY()));
5400 Cell cell(p);
5401 cell.data.Part.reserved = ALL_DISTRICT;
5402 cell.SetNoCreate();
5404 MaNGOS::RespawnDo u_do;
5405 MaNGOS::WorldObjectWorker<MaNGOS::RespawnDo> worker(u_do);
5407 TypeContainerVisitor<MaNGOS::WorldObjectWorker<MaNGOS::RespawnDo>, GridTypeMapContainer > obj_worker(worker);
5408 CellLock<GridReadGuard> cell_lock(cell, p);
5409 cell_lock->Visit(cell_lock, obj_worker, *pl->GetMap());
5411 return true;
5414 bool ChatHandler::HandleFlyModeCommand(const char* args)
5416 if(!args)
5417 return false;
5419 Unit *unit = getSelectedUnit();
5420 if (!unit || (unit->GetTypeId() != TYPEID_PLAYER))
5421 unit = m_session->GetPlayer();
5423 WorldPacket data(12);
5424 if (strncmp(args, "on", 3) == 0)
5425 data.SetOpcode(SMSG_MOVE_SET_CAN_FLY);
5426 else if (strncmp(args, "off", 4) == 0)
5427 data.SetOpcode(SMSG_MOVE_UNSET_CAN_FLY);
5428 else
5430 SendSysMessage(LANG_USE_BOL);
5431 return false;
5433 data.append(unit->GetPackGUID());
5434 data << uint32(0); // unknown
5435 unit->SendMessageToSet(&data, true);
5436 PSendSysMessage(LANG_COMMAND_FLYMODE_STATUS, unit->GetName(), args);
5437 return true;
5440 bool ChatHandler::HandleLoadPDumpCommand(const char *args)
5442 if(!args)
5443 return false;
5445 char * file = strtok((char*)args, " ");
5446 if(!file)
5447 return false;
5449 char * account = strtok(NULL, " ");
5450 if(!account)
5451 return false;
5453 std::string account_name = account;
5454 if(!AccountMgr::normilizeString(account_name))
5456 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5457 SetSentErrorMessage(true);
5458 return false;
5461 uint32 account_id = accmgr.GetId(account_name);
5462 if(!account_id)
5464 account_id = atoi(account); // use original string
5465 if(!account_id)
5467 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5468 SetSentErrorMessage(true);
5469 return false;
5473 if(!accmgr.GetName(account_id,account_name))
5475 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5476 SetSentErrorMessage(true);
5477 return false;
5480 char* guid_str = NULL;
5481 char* name_str = strtok(NULL, " ");
5483 std::string name;
5484 if(name_str)
5486 name = name_str;
5487 // normalize the name if specified and check if it exists
5488 if(!normalizePlayerName(name))
5490 PSendSysMessage(LANG_INVALID_CHARACTER_NAME);
5491 SetSentErrorMessage(true);
5492 return false;
5495 if(!ObjectMgr::IsValidName(name,true))
5497 PSendSysMessage(LANG_INVALID_CHARACTER_NAME);
5498 SetSentErrorMessage(true);
5499 return false;
5502 guid_str = strtok(NULL, " ");
5505 uint32 guid = 0;
5507 if(guid_str)
5509 guid = atoi(guid_str);
5510 if(!guid)
5512 PSendSysMessage(LANG_INVALID_CHARACTER_GUID);
5513 SetSentErrorMessage(true);
5514 return false;
5517 if(objmgr.GetPlayerAccountIdByGUID(guid))
5519 PSendSysMessage(LANG_CHARACTER_GUID_IN_USE,guid);
5520 SetSentErrorMessage(true);
5521 return false;
5525 switch(PlayerDumpReader().LoadDump(file, account_id, name, guid))
5527 case DUMP_SUCCESS:
5528 PSendSysMessage(LANG_COMMAND_IMPORT_SUCCESS);
5529 break;
5530 case DUMP_FILE_OPEN_ERROR:
5531 PSendSysMessage(LANG_FILE_OPEN_FAIL,file);
5532 SetSentErrorMessage(true);
5533 return false;
5534 case DUMP_FILE_BROKEN:
5535 PSendSysMessage(LANG_DUMP_BROKEN,file);
5536 SetSentErrorMessage(true);
5537 return false;
5538 case DUMP_TOO_MANY_CHARS:
5539 PSendSysMessage(LANG_ACCOUNT_CHARACTER_LIST_FULL,account_name.c_str(),account_id);
5540 SetSentErrorMessage(true);
5541 return false;
5542 default:
5543 PSendSysMessage(LANG_COMMAND_IMPORT_FAILED);
5544 SetSentErrorMessage(true);
5545 return false;
5548 return true;
5551 bool ChatHandler::HandleNpcChangeEntryCommand(const char *args)
5553 if(!args)
5554 return false;
5556 uint32 newEntryNum = atoi(args);
5557 if(!newEntryNum)
5558 return false;
5560 Unit* unit = getSelectedUnit();
5561 if(!unit || unit->GetTypeId() != TYPEID_UNIT)
5563 SendSysMessage(LANG_SELECT_CREATURE);
5564 SetSentErrorMessage(true);
5565 return false;
5567 Creature* creature = (Creature*)unit;
5568 if(creature->UpdateEntry(newEntryNum))
5569 SendSysMessage(LANG_DONE);
5570 else
5571 SendSysMessage(LANG_ERROR);
5572 return true;
5575 bool ChatHandler::HandleWritePDumpCommand(const char *args)
5577 if(!args)
5578 return false;
5580 char* file = strtok((char*)args, " ");
5581 char* p2 = strtok(NULL, " ");
5583 if(!file || !p2)
5584 return false;
5586 uint32 guid;
5587 // character name can't start from number
5588 if (isNumeric(p2[0]))
5589 guid = atoi(p2);
5590 else
5592 std::string name = p2;
5594 if (!normalizePlayerName (name))
5596 SendSysMessage (LANG_PLAYER_NOT_FOUND);
5597 SetSentErrorMessage (true);
5598 return false;
5601 guid = objmgr.GetPlayerGUIDByName(name);
5604 if(!objmgr.GetPlayerAccountIdByGUID(guid))
5606 PSendSysMessage(LANG_PLAYER_NOT_FOUND);
5607 SetSentErrorMessage(true);
5608 return false;
5611 switch(PlayerDumpWriter().WriteDump(file, guid))
5613 case DUMP_SUCCESS:
5614 PSendSysMessage(LANG_COMMAND_EXPORT_SUCCESS);
5615 break;
5616 case DUMP_FILE_OPEN_ERROR:
5617 PSendSysMessage(LANG_FILE_OPEN_FAIL,file);
5618 SetSentErrorMessage(true);
5619 return false;
5620 default:
5621 PSendSysMessage(LANG_COMMAND_EXPORT_FAILED);
5622 SetSentErrorMessage(true);
5623 return false;
5626 return true;
5629 bool ChatHandler::HandleMovegensCommand(const char* /*args*/)
5631 Unit* unit = getSelectedUnit();
5632 if(!unit)
5634 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5635 SetSentErrorMessage(true);
5636 return false;
5639 PSendSysMessage(LANG_MOVEGENS_LIST,(unit->GetTypeId()==TYPEID_PLAYER ? "Player" : "Creature" ),unit->GetGUIDLow());
5641 MotionMaster* mm = unit->GetMotionMaster();
5642 for(MotionMaster::const_iterator itr = mm->begin(); itr != mm->end(); ++itr)
5644 switch((*itr)->GetMovementGeneratorType())
5646 case IDLE_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_IDLE); break;
5647 case RANDOM_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_RANDOM); break;
5648 case WAYPOINT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_WAYPOINT); break;
5649 case ANIMAL_RANDOM_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_ANIMAL_RANDOM); break;
5650 case CONFUSED_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_CONFUSED); break;
5651 case TARGETED_MOTION_TYPE:
5653 if(unit->GetTypeId()==TYPEID_PLAYER)
5655 TargetedMovementGenerator<Player> const* mgen = static_cast<TargetedMovementGenerator<Player> const*>(*itr);
5656 Unit* target = mgen->GetTarget();
5657 if(target)
5658 PSendSysMessage(LANG_MOVEGENS_TARGETED_PLAYER,target->GetName(),target->GetGUIDLow());
5659 else
5660 SendSysMessage(LANG_MOVEGENS_TARGETED_NULL);
5662 else
5664 TargetedMovementGenerator<Creature> const* mgen = static_cast<TargetedMovementGenerator<Creature> const*>(*itr);
5665 Unit* target = mgen->GetTarget();
5666 if(target)
5667 PSendSysMessage(LANG_MOVEGENS_TARGETED_CREATURE,target->GetName(),target->GetGUIDLow());
5668 else
5669 SendSysMessage(LANG_MOVEGENS_TARGETED_NULL);
5671 break;
5673 case HOME_MOTION_TYPE:
5674 if(unit->GetTypeId()==TYPEID_UNIT)
5676 float x,y,z;
5677 (*itr)->GetDestination(x,y,z);
5678 PSendSysMessage(LANG_MOVEGENS_HOME_CREATURE,x,y,z);
5680 else
5681 SendSysMessage(LANG_MOVEGENS_HOME_PLAYER);
5682 break;
5683 case FLIGHT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_FLIGHT); break;
5684 case POINT_MOTION_TYPE:
5686 float x,y,z;
5687 (*itr)->GetDestination(x,y,z);
5688 PSendSysMessage(LANG_MOVEGENS_POINT,x,y,z);
5689 break;
5691 case FLEEING_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_FEAR); break;
5692 case DISTRACT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_DISTRACT); break;
5693 default:
5694 PSendSysMessage(LANG_MOVEGENS_UNKNOWN,(*itr)->GetMovementGeneratorType());
5695 break;
5698 return true;
5701 bool ChatHandler::HandlePLimitCommand(const char *args)
5703 if(*args)
5705 char* param = strtok((char*)args, " ");
5706 if(!param)
5707 return false;
5709 int l = strlen(param);
5711 if( strncmp(param,"player",l) == 0 )
5712 sWorld.SetPlayerLimit(-SEC_PLAYER);
5713 else if(strncmp(param,"moderator",l) == 0 )
5714 sWorld.SetPlayerLimit(-SEC_MODERATOR);
5715 else if(strncmp(param,"gamemaster",l) == 0 )
5716 sWorld.SetPlayerLimit(-SEC_GAMEMASTER);
5717 else if(strncmp(param,"administrator",l) == 0 )
5718 sWorld.SetPlayerLimit(-SEC_ADMINISTRATOR);
5719 else if(strncmp(param,"reset",l) == 0 )
5720 sWorld.SetPlayerLimit( sConfig.GetIntDefault("PlayerLimit", DEFAULT_PLAYER_LIMIT) );
5721 else
5723 int val = atoi(param);
5724 if(val < -SEC_ADMINISTRATOR) val = -SEC_ADMINISTRATOR;
5726 sWorld.SetPlayerLimit(val);
5729 // kick all low security level players
5730 if(sWorld.GetPlayerAmountLimit() > SEC_PLAYER)
5731 sWorld.KickAllLess(sWorld.GetPlayerSecurityLimit());
5734 uint32 pLimit = sWorld.GetPlayerAmountLimit();
5735 AccountTypes allowedAccountType = sWorld.GetPlayerSecurityLimit();
5736 char const* secName = "";
5737 switch(allowedAccountType)
5739 case SEC_PLAYER: secName = "Player"; break;
5740 case SEC_MODERATOR: secName = "Moderator"; break;
5741 case SEC_GAMEMASTER: secName = "Gamemaster"; break;
5742 case SEC_ADMINISTRATOR: secName = "Administrator"; break;
5743 default: secName = "<unknown>"; break;
5746 PSendSysMessage("Player limits: amount %u, min. security level %s.",pLimit,secName);
5748 return true;
5751 bool ChatHandler::HandleCastCommand(const char* args)
5753 if(!*args)
5754 return false;
5756 Unit* target = getSelectedUnit();
5758 if(!target)
5760 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5761 SetSentErrorMessage(true);
5762 return false;
5765 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5766 uint32 spell = extractSpellIdFromLink((char*)args);
5767 if(!spell)
5768 return false;
5770 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
5771 if(!spellInfo)
5772 return false;
5774 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
5776 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
5777 SetSentErrorMessage(true);
5778 return false;
5781 char* trig_str = strtok(NULL, " ");
5782 if(trig_str)
5784 int l = strlen(trig_str);
5785 if(strncmp(trig_str,"triggered",l) != 0 )
5786 return false;
5789 bool triggered = (trig_str != NULL);
5791 m_session->GetPlayer()->CastSpell(target,spell,triggered);
5793 return true;
5796 bool ChatHandler::HandleCastBackCommand(const char* args)
5798 Creature* caster = getSelectedCreature();
5800 if(!caster)
5802 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5803 SetSentErrorMessage(true);
5804 return false;
5807 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
5808 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5809 uint32 spell = extractSpellIdFromLink((char*)args);
5810 if(!spell || !sSpellStore.LookupEntry(spell))
5811 return false;
5813 char* trig_str = strtok(NULL, " ");
5814 if(trig_str)
5816 int l = strlen(trig_str);
5817 if(strncmp(trig_str,"triggered",l) != 0 )
5818 return false;
5821 bool triggered = (trig_str != NULL);
5823 // update orientation at server
5824 caster->SetOrientation(caster->GetAngle(m_session->GetPlayer()));
5826 // and client
5827 WorldPacket data;
5828 caster->BuildHeartBeatMsg(&data);
5829 caster->SendMessageToSet(&data,true);
5831 caster->CastSpell(m_session->GetPlayer(),spell,triggered);
5833 return true;
5836 bool ChatHandler::HandleCastDistCommand(const char* args)
5838 if(!*args)
5839 return false;
5841 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5842 uint32 spell = extractSpellIdFromLink((char*)args);
5843 if(!spell)
5844 return false;
5846 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
5847 if(!spellInfo)
5848 return false;
5850 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
5852 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
5853 SetSentErrorMessage(true);
5854 return false;
5857 char *distStr = strtok(NULL, " ");
5859 float dist = 0;
5861 if(distStr)
5862 sscanf(distStr, "%f", &dist);
5864 char* trig_str = strtok(NULL, " ");
5865 if(trig_str)
5867 int l = strlen(trig_str);
5868 if(strncmp(trig_str,"triggered",l) != 0 )
5869 return false;
5872 bool triggered = (trig_str != NULL);
5874 float x,y,z;
5875 m_session->GetPlayer()->GetClosePoint(x,y,z,dist);
5877 m_session->GetPlayer()->CastSpell(x,y,z,spell,triggered);
5878 return true;
5881 bool ChatHandler::HandleCastTargetCommand(const char* args)
5883 Creature* caster = getSelectedCreature();
5885 if(!caster)
5887 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5888 SetSentErrorMessage(true);
5889 return false;
5892 if(!caster->getVictim())
5894 SendSysMessage(LANG_SELECTED_TARGET_NOT_HAVE_VICTIM);
5895 SetSentErrorMessage(true);
5896 return false;
5899 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5900 uint32 spell = extractSpellIdFromLink((char*)args);
5901 if(!spell || !sSpellStore.LookupEntry(spell))
5902 return false;
5904 char* trig_str = strtok(NULL, " ");
5905 if(trig_str)
5907 int l = strlen(trig_str);
5908 if(strncmp(trig_str,"triggered",l) != 0 )
5909 return false;
5912 bool triggered = (trig_str != NULL);
5914 // update orientation at server
5915 caster->SetOrientation(caster->GetAngle(m_session->GetPlayer()));
5917 // and client
5918 WorldPacket data;
5919 caster->BuildHeartBeatMsg(&data);
5920 caster->SendMessageToSet(&data,true);
5922 caster->CastSpell(caster->getVictim(),spell,triggered);
5924 return true;
5928 ComeToMe command REQUIRED for 3rd party scripting library to have access to PointMovementGenerator
5929 Without this function 3rd party scripting library will get linking errors (unresolved external)
5930 when attempting to use the PointMovementGenerator
5932 bool ChatHandler::HandleComeToMeCommand(const char *args)
5934 Creature* caster = getSelectedCreature();
5936 if(!caster)
5938 SendSysMessage(LANG_SELECT_CREATURE);
5939 SetSentErrorMessage(true);
5940 return false;
5943 char* newFlagStr = strtok((char*)args, " ");
5945 if(!newFlagStr)
5946 return false;
5948 uint32 newFlags = atoi(newFlagStr);
5950 caster->SetUnitMovementFlags(newFlags);
5952 Player* pl = m_session->GetPlayer();
5954 caster->GetMotionMaster()->MovePoint(0, pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ());
5955 return true;
5958 bool ChatHandler::HandleCastSelfCommand(const char* args)
5960 if(!*args)
5961 return false;
5963 Unit* target = getSelectedUnit();
5965 if(!target)
5967 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5968 SetSentErrorMessage(true);
5969 return false;
5972 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5973 uint32 spell = extractSpellIdFromLink((char*)args);
5974 if(!spell)
5975 return false;
5977 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
5978 if(!spellInfo)
5979 return false;
5981 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
5983 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
5984 SetSentErrorMessage(true);
5985 return false;
5988 target->CastSpell(target,spell,false);
5990 return true;
5993 std::string GetTimeString(uint32 time)
5995 uint16 days = time / DAY, hours = (time % DAY) / HOUR, minute = (time % HOUR) / MINUTE;
5996 std::ostringstream ss;
5997 if(days) ss << days << "d ";
5998 if(hours) ss << hours << "h ";
5999 ss << minute << "m";
6000 return ss.str();
6003 bool ChatHandler::HandleInstanceListBindsCommand(const char* /*args*/)
6005 Player* player = getSelectedPlayer();
6006 if (!player) player = m_session->GetPlayer();
6007 uint32 counter = 0;
6008 for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++)
6010 Player::BoundInstancesMap &binds = player->GetBoundInstances(i);
6011 for(Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end(); ++itr)
6013 InstanceSave *save = itr->second.save;
6014 std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
6015 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());
6016 counter++;
6019 PSendSysMessage("player binds: %d", counter);
6020 counter = 0;
6021 Group *group = player->GetGroup();
6022 if(group)
6024 for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++)
6026 Group::BoundInstancesMap &binds = group->GetBoundInstances(i);
6027 for(Group::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end(); ++itr)
6029 InstanceSave *save = itr->second.save;
6030 std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
6031 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());
6032 counter++;
6036 PSendSysMessage("group binds: %d", counter);
6038 return true;
6041 bool ChatHandler::HandleInstanceUnbindCommand(const char* args)
6043 if(!*args)
6044 return false;
6046 std::string cmd = args;
6047 if(cmd == "all")
6049 Player* player = getSelectedPlayer();
6050 if (!player) player = m_session->GetPlayer();
6051 uint32 counter = 0;
6052 for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++)
6054 Player::BoundInstancesMap &binds = player->GetBoundInstances(i);
6055 for(Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end();)
6057 if(itr->first != player->GetMapId())
6059 InstanceSave *save = itr->second.save;
6060 std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
6061 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());
6062 player->UnbindInstance(itr, i);
6063 counter++;
6065 else
6066 ++itr;
6069 PSendSysMessage("instances unbound: %d", counter);
6071 return true;
6074 bool ChatHandler::HandleInstanceStatsCommand(const char* /*args*/)
6076 PSendSysMessage("instances loaded: %d", MapManager::Instance().GetNumInstances());
6077 PSendSysMessage("players in instances: %d", MapManager::Instance().GetNumPlayersInInstances());
6078 PSendSysMessage("instance saves: %d", sInstanceSaveManager.GetNumInstanceSaves());
6079 PSendSysMessage("players bound: %d", sInstanceSaveManager.GetNumBoundPlayersTotal());
6080 PSendSysMessage("groups bound: %d", sInstanceSaveManager.GetNumBoundGroupsTotal());
6081 return true;
6084 bool ChatHandler::HandleInstanceSaveDataCommand(const char * /*args*/)
6086 Player* pl = m_session->GetPlayer();
6088 Map* map = pl->GetMap();
6089 if (!map->IsDungeon())
6091 PSendSysMessage("Map is not a dungeon.");
6092 SetSentErrorMessage(true);
6093 return false;
6096 if (!((InstanceMap*)map)->GetInstanceData())
6098 PSendSysMessage("Map has no instance data.");
6099 SetSentErrorMessage(true);
6100 return false;
6103 ((InstanceMap*)map)->GetInstanceData()->SaveToDB();
6104 return true;
6107 /// Display the list of GMs
6108 bool ChatHandler::HandleGMListFullCommand(const char* /*args*/)
6110 ///- Get the accounts with GM Level >0
6111 QueryResult *result = loginDatabase.Query( "SELECT username,gmlevel FROM account WHERE gmlevel > 0" );
6112 if(result)
6114 SendSysMessage(LANG_GMLIST);
6115 SendSysMessage("========================");
6116 SendSysMessage(LANG_GMLIST_HEADER);
6117 SendSysMessage("========================");
6119 ///- Circle through them. Display username and GM level
6122 Field *fields = result->Fetch();
6123 PSendSysMessage("|%15s|%6s|", fields[0].GetString(),fields[1].GetString());
6124 }while( result->NextRow() );
6126 PSendSysMessage("========================");
6127 delete result;
6129 else
6130 PSendSysMessage(LANG_GMLIST_EMPTY);
6131 return true;
6134 /// Define the 'Message of the day' for the realm
6135 bool ChatHandler::HandleServerSetMotdCommand(const char* args)
6137 sWorld.SetMotd(args);
6138 PSendSysMessage(LANG_MOTD_NEW, args);
6139 return true;
6142 /// Set/Unset the expansion level for an account
6143 bool ChatHandler::HandleAccountSetAddonCommand(const char* args)
6145 ///- Get the command line arguments
6146 char *szAcc = strtok((char*)args," ");
6147 char *szExp = strtok(NULL," ");
6149 if(!szAcc)
6150 return false;
6152 std::string account_name;
6153 uint32 account_id;
6155 if(!szExp)
6157 Player* player = getSelectedPlayer();
6158 if(!player)
6159 return false;
6161 account_id = player->GetSession()->GetAccountId();
6162 accmgr.GetName(account_id,account_name);
6163 szExp = szAcc;
6165 else
6167 ///- Convert Account name to Upper Format
6168 account_name = szAcc;
6169 if(!AccountMgr::normilizeString(account_name))
6171 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
6172 SetSentErrorMessage(true);
6173 return false;
6176 account_id = accmgr.GetId(account_name);
6177 if(!account_id)
6179 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
6180 SetSentErrorMessage(true);
6181 return false;
6186 // Let set addon state only for lesser (strong) security level
6187 // or to self account
6188 if (m_session && m_session->GetAccountId () != account_id &&
6189 HasLowerSecurityAccount (NULL,account_id,true))
6190 return false;
6192 int lev=atoi(szExp); //get int anyway (0 if error)
6193 if(lev < 0)
6194 return false;
6196 // No SQL injection
6197 loginDatabase.PExecute("UPDATE account SET expansion = '%d' WHERE id = '%u'",lev,account_id);
6198 PSendSysMessage(LANG_ACCOUNT_SETADDON,account_name.c_str(),account_id,lev);
6199 return true;
6202 //Send items by mail
6203 bool ChatHandler::HandleSendItemsCommand(const char* args)
6205 if(!*args)
6206 return false;
6208 // format: name "subject text" "mail text" item1[:count1] item2[:count2] ... item12[:count12]
6210 char* pName = strtok((char*)args, " ");
6211 if(!pName)
6212 return false;
6214 char* tail1 = strtok(NULL, "");
6215 if(!tail1)
6216 return false;
6218 char* msgSubject;
6219 if(*tail1=='"')
6220 msgSubject = strtok(tail1+1, "\"");
6221 else
6223 char* space = strtok(tail1, "\"");
6224 if(!space)
6225 return false;
6226 msgSubject = strtok(NULL, "\"");
6229 if (!msgSubject)
6230 return false;
6232 char* tail2 = strtok(NULL, "");
6233 if(!tail2)
6234 return false;
6236 char* msgText;
6237 if(*tail2=='"')
6238 msgText = strtok(tail2+1, "\"");
6239 else
6241 char* space = strtok(tail2, "\"");
6242 if(!space)
6243 return false;
6244 msgText = strtok(NULL, "\"");
6247 if (!msgText)
6248 return false;
6250 // pName, msgSubject, msgText isn't NUL after prev. check
6251 std::string name = pName;
6252 std::string subject = msgSubject;
6253 std::string text = msgText;
6255 // extract items
6256 typedef std::pair<uint32,uint32> ItemPair;
6257 typedef std::list< ItemPair > ItemPairs;
6258 ItemPairs items;
6260 // get all tail string
6261 char* tail = strtok(NULL, "");
6263 // get from tail next item str
6264 while(char* itemStr = strtok(tail, " "))
6266 // and get new tail
6267 tail = strtok(NULL, "");
6269 // parse item str
6270 char* itemIdStr = strtok(itemStr, ":");
6271 char* itemCountStr = strtok(NULL, " ");
6273 uint32 item_id = atoi(itemIdStr);
6274 if(!item_id)
6275 return false;
6277 ItemPrototype const* item_proto = objmgr.GetItemPrototype(item_id);
6278 if(!item_proto)
6280 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
6281 SetSentErrorMessage(true);
6282 return false;
6285 uint32 item_count = itemCountStr ? atoi(itemCountStr) : 1;
6286 if(item_count < 1 || item_proto->MaxCount > 0 && item_count > uint32(item_proto->MaxCount))
6288 PSendSysMessage(LANG_COMMAND_INVALID_ITEM_COUNT, item_count,item_id);
6289 SetSentErrorMessage(true);
6290 return false;
6293 while(item_count > item_proto->GetMaxStackSize())
6295 items.push_back(ItemPair(item_id,item_proto->GetMaxStackSize()));
6296 item_count -= item_proto->GetMaxStackSize();
6299 items.push_back(ItemPair(item_id,item_count));
6301 if(items.size() > MAX_MAIL_ITEMS)
6303 PSendSysMessage(LANG_COMMAND_MAIL_ITEMS_LIMIT, MAX_MAIL_ITEMS);
6304 SetSentErrorMessage(true);
6305 return false;
6309 if(!normalizePlayerName(name))
6311 SendSysMessage(LANG_PLAYER_NOT_FOUND);
6312 SetSentErrorMessage(true);
6313 return false;
6316 uint64 receiver_guid = objmgr.GetPlayerGUIDByName(name);
6317 if(!receiver_guid)
6319 SendSysMessage(LANG_PLAYER_NOT_FOUND);
6320 SetSentErrorMessage(true);
6321 return false;
6324 // from console show not existed sender
6325 uint32 sender_guidlo = m_session ? m_session->GetPlayer()->GetGUIDLow() : 0;
6327 uint32 messagetype = MAIL_NORMAL;
6328 uint32 stationery = MAIL_STATIONERY_GM;
6329 uint32 itemTextId = !text.empty() ? objmgr.CreateItemText( text ) : 0;
6331 Player *receiver = objmgr.GetPlayer(receiver_guid);
6333 // fill mail
6334 MailItemsInfo mi; // item list preparing
6336 for(ItemPairs::const_iterator itr = items.begin(); itr != items.end(); ++itr)
6338 if(Item* item = Item::CreateItem(itr->first,itr->second,m_session ? m_session->GetPlayer() : 0))
6340 item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted
6341 mi.AddItem(item->GetGUIDLow(), item->GetEntry(), item);
6345 WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, &mi, 0, 0, MAIL_CHECK_MASK_NONE);
6347 PSendSysMessage(LANG_MAIL_SENT, name.c_str());
6348 return true;
6351 ///Send money by mail
6352 bool ChatHandler::HandleSendMoneyCommand(const char* args)
6354 if (!*args)
6355 return false;
6357 /// format: name "subject text" "mail text" money
6359 char* pName = strtok((char*)args, " ");
6360 if (!pName)
6361 return false;
6363 char* tail1 = strtok(NULL, "");
6364 if (!tail1)
6365 return false;
6367 char* msgSubject;
6368 if (*tail1=='"')
6369 msgSubject = strtok(tail1+1, "\"");
6370 else
6372 char* space = strtok(tail1, "\"");
6373 if (!space)
6374 return false;
6375 msgSubject = strtok(NULL, "\"");
6378 if (!msgSubject)
6379 return false;
6381 char* tail2 = strtok(NULL, "");
6382 if (!tail2)
6383 return false;
6385 char* msgText;
6386 if (*tail2=='"')
6387 msgText = strtok(tail2+1, "\"");
6388 else
6390 char* space = strtok(tail2, "\"");
6391 if (!space)
6392 return false;
6393 msgText = strtok(NULL, "\"");
6396 if (!msgText)
6397 return false;
6399 char* money_str = strtok(NULL, "");
6400 int32 money = money_str ? atoi(money_str) : 0;
6401 if (money <= 0)
6402 return false;
6404 // pName, msgSubject, msgText isn't NUL after prev. check
6405 std::string name = pName;
6406 std::string subject = msgSubject;
6407 std::string text = msgText;
6409 if (!normalizePlayerName(name))
6411 SendSysMessage(LANG_PLAYER_NOT_FOUND);
6412 SetSentErrorMessage(true);
6413 return false;
6416 uint64 receiver_guid = objmgr.GetPlayerGUIDByName(name);
6417 if (!receiver_guid)
6419 SendSysMessage(LANG_PLAYER_NOT_FOUND);
6420 SetSentErrorMessage(true);
6421 return false;
6424 uint32 mailId = objmgr.GenerateMailID();
6426 // from console show not existed sender
6427 uint32 sender_guidlo = m_session ? m_session->GetPlayer()->GetGUIDLow() : 0;
6429 uint32 messagetype = MAIL_NORMAL;
6430 uint32 stationery = MAIL_STATIONERY_GM;
6431 uint32 itemTextId = !text.empty() ? objmgr.CreateItemText( text ) : 0;
6433 Player *receiver = objmgr.GetPlayer(receiver_guid);
6435 WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, NULL, money, 0, MAIL_CHECK_MASK_NONE);
6437 PSendSysMessage(LANG_MAIL_SENT, name.c_str());
6438 return true;
6441 /// Send a message to a player in game
6442 bool ChatHandler::HandleSendMessageCommand(const char* args)
6444 ///- Get the command line arguments
6445 char* name_str = strtok((char*)args, " ");
6446 char* msg_str = strtok(NULL, "");
6448 if(!name_str || !msg_str)
6449 return false;
6451 std::string name = name_str;
6453 if(!normalizePlayerName(name))
6454 return false;
6456 ///- Find the player and check that he is not logging out.
6457 Player *rPlayer = objmgr.GetPlayer(name.c_str());
6458 if(!rPlayer)
6460 SendSysMessage(LANG_PLAYER_NOT_FOUND);
6461 SetSentErrorMessage(true);
6462 return false;
6465 if(rPlayer->GetSession()->isLogingOut())
6467 SendSysMessage(LANG_PLAYER_NOT_FOUND);
6468 SetSentErrorMessage(true);
6469 return false;
6472 ///- Send the message
6473 //Use SendAreaTriggerMessage for fastest delivery.
6474 rPlayer->GetSession()->SendAreaTriggerMessage("%s", msg_str);
6475 rPlayer->GetSession()->SendAreaTriggerMessage("|cffff0000[Message from administrator]:|r");
6477 //Confirmation message
6478 PSendSysMessage(LANG_SENDMESSAGE,name.c_str(),msg_str);
6479 return true;
6482 bool ChatHandler::HandleFlushArenaPointsCommand(const char * /*args*/)
6484 sBattleGroundMgr.DistributeArenaPoints();
6485 return true;
6488 bool ChatHandler::HandleModifyGenderCommand(const char *args)
6490 if(!*args)
6491 return false;
6493 Player *player = getSelectedPlayer();
6495 if(!player)
6497 PSendSysMessage(LANG_NO_PLAYER);
6498 SetSentErrorMessage(true);
6499 return false;
6502 PlayerInfo const* info = objmgr.GetPlayerInfo(player->getRace(), player->getClass());
6503 if(!info)
6504 return false;
6506 char const* gender_str = (char*)args;
6507 int gender_len = strlen(gender_str);
6509 Gender gender;
6511 if(!strncmp(gender_str, "male", gender_len)) // MALE
6513 if(player->getGender() == GENDER_MALE)
6514 return true;
6516 gender = GENDER_MALE;
6518 else if (!strncmp(gender_str, "female", gender_len)) // FEMALE
6520 if(player->getGender() == GENDER_FEMALE)
6521 return true;
6523 gender = GENDER_FEMALE;
6525 else
6527 SendSysMessage(LANG_MUST_MALE_OR_FEMALE);
6528 SetSentErrorMessage(true);
6529 return false;
6532 // Set gender
6533 player->SetByteValue(UNIT_FIELD_BYTES_0, 2, gender);
6534 player->SetByteValue(PLAYER_BYTES_3, 0, gender);
6536 // Change display ID
6537 player->SetDisplayId(gender ? info->displayId_f : info->displayId_m);
6538 player->SetNativeDisplayId(gender ? info->displayId_f : info->displayId_m);
6540 char const* gender_full = gender ? "female" : "male";
6542 PSendSysMessage(LANG_YOU_CHANGE_GENDER, player->GetName(), gender_full);
6544 if (needReportToTarget(player))
6545 ChatHandler(player).PSendSysMessage(LANG_YOUR_GENDER_CHANGED, gender_full, GetName());
6547 return true;