Better args checking in .sendmoney command.
[getmangos.git] / src / game / Level3.cpp
blob8d7e412c2e1a353b86558b6533f87ae74d9792eb
1 /*
2 * Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include "Common.h"
20 #include "Database/DatabaseEnv.h"
21 #include "WorldPacket.h"
22 #include "WorldSession.h"
23 #include "World.h"
24 #include "ObjectMgr.h"
25 #include "AccountMgr.h"
26 #include "PlayerDump.h"
27 #include "SpellMgr.h"
28 #include "Player.h"
29 #include "Opcodes.h"
30 #include "GameObject.h"
31 #include "Chat.h"
32 #include "Log.h"
33 #include "Guild.h"
34 #include "ObjectAccessor.h"
35 #include "MapManager.h"
36 #include "SpellAuras.h"
37 #include "ScriptCalls.h"
38 #include "Language.h"
39 #include "GridNotifiersImpl.h"
40 #include "CellImpl.h"
41 #include "Weather.h"
42 #include "PointMovementGenerator.h"
43 #include "TargetedMovementGenerator.h"
44 #include "SkillDiscovery.h"
45 #include "SkillExtraItems.h"
46 #include "SystemConfig.h"
47 #include "Config/ConfigEnv.h"
48 #include "Util.h"
49 #include "ItemEnchantmentMgr.h"
50 #include "InstanceSaveMgr.h"
51 #include "InstanceData.h"
53 //reload commands
54 bool ChatHandler::HandleReloadCommand(const char* arg)
56 // this is error catcher for wrong table name in .reload commands
57 PSendSysMessage("Db table with name starting from '%s' not found and can't be reloaded.",arg);
58 SetSentErrorMessage(true);
59 return false;
62 bool ChatHandler::HandleReloadAllCommand(const char*)
64 HandleReloadAreaTriggerTeleportCommand("");
65 HandleReloadSkillFishingBaseLevelCommand("");
67 HandleReloadAllAreaCommand("");
68 HandleReloadAllLootCommand("");
69 HandleReloadAllNpcCommand("");
70 HandleReloadAllQuestCommand("");
71 HandleReloadAllSpellCommand("");
72 HandleReloadAllItemCommand("");
73 HandleReloadAllLocalesCommand("");
75 HandleReloadCommandCommand("");
76 HandleReloadReservedNameCommand("");
77 HandleReloadMangosStringCommand("");
78 HandleReloadGameTeleCommand("");
79 return true;
82 bool ChatHandler::HandleReloadAllAreaCommand(const char*)
84 //HandleReloadQuestAreaTriggersCommand(""); -- reloaded in HandleReloadAllQuestCommand
85 HandleReloadAreaTriggerTeleportCommand("");
86 HandleReloadAreaTriggerTavernCommand("");
87 HandleReloadGameGraveyardZoneCommand("");
88 return true;
91 bool ChatHandler::HandleReloadAllLootCommand(const char*)
93 sLog.outString( "Re-Loading Loot Tables..." );
94 LoadLootTables();
95 SendGlobalSysMessage("DB tables `*_loot_template` reloaded.");
96 return true;
99 bool ChatHandler::HandleReloadAllNpcCommand(const char* /*args*/)
101 HandleReloadNpcGossipCommand("a");
102 HandleReloadNpcOptionCommand("a");
103 HandleReloadNpcTrainerCommand("a");
104 HandleReloadNpcVendorCommand("a");
105 return true;
108 bool ChatHandler::HandleReloadAllQuestCommand(const char* /*args*/)
110 HandleReloadQuestAreaTriggersCommand("a");
111 HandleReloadQuestTemplateCommand("a");
113 sLog.outString( "Re-Loading Quests Relations..." );
114 objmgr.LoadQuestRelations();
115 SendGlobalSysMessage("DB tables `*_questrelation` and `*_involvedrelation` reloaded.");
116 return true;
119 bool ChatHandler::HandleReloadAllScriptsCommand(const char*)
121 if(sWorld.IsScriptScheduled())
123 PSendSysMessage("DB scripts used currently, please attempt reload later.");
124 SetSentErrorMessage(true);
125 return false;
128 sLog.outString( "Re-Loading Scripts..." );
129 HandleReloadGameObjectScriptsCommand("a");
130 HandleReloadEventScriptsCommand("a");
131 HandleReloadQuestEndScriptsCommand("a");
132 HandleReloadQuestStartScriptsCommand("a");
133 HandleReloadSpellScriptsCommand("a");
134 SendGlobalSysMessage("DB tables `*_scripts` reloaded.");
135 HandleReloadDbScriptStringCommand("a");
136 return true;
139 bool ChatHandler::HandleReloadAllSpellCommand(const char*)
141 HandleReloadSkillDiscoveryTemplateCommand("a");
142 HandleReloadSkillExtraItemTemplateCommand("a");
143 HandleReloadSpellAffectCommand("a");
144 HandleReloadSpellChainCommand("a");
145 HandleReloadSpellElixirCommand("a");
146 HandleReloadSpellLearnSpellCommand("a");
147 HandleReloadSpellProcEventCommand("a");
148 HandleReloadSpellScriptTargetCommand("a");
149 HandleReloadSpellTargetPositionCommand("a");
150 HandleReloadSpellThreatsCommand("a");
151 HandleReloadSpellPetAurasCommand("a");
152 return true;
155 bool ChatHandler::HandleReloadAllItemCommand(const char*)
157 HandleReloadPageTextsCommand("a");
158 HandleReloadItemEnchantementsCommand("a");
159 return true;
162 bool ChatHandler::HandleReloadAllLocalesCommand(const char* /*args*/)
164 HandleReloadLocalesCreatureCommand("a");
165 HandleReloadLocalesGameobjectCommand("a");
166 HandleReloadLocalesItemCommand("a");
167 HandleReloadLocalesNpcTextCommand("a");
168 HandleReloadLocalesPageTextCommand("a");
169 HandleReloadLocalesQuestCommand("a");
170 return true;
173 bool ChatHandler::HandleReloadConfigCommand(const char* /*args*/)
175 sLog.outString( "Re-Loading config settings..." );
176 sWorld.LoadConfigSettings(true);
177 SendGlobalSysMessage("World config settings reloaded.");
178 return true;
181 bool ChatHandler::HandleReloadAreaTriggerTavernCommand(const char*)
183 sLog.outString( "Re-Loading Tavern Area Triggers..." );
184 objmgr.LoadTavernAreaTriggers();
185 SendGlobalSysMessage("DB table `areatrigger_tavern` reloaded.");
186 return true;
189 bool ChatHandler::HandleReloadAreaTriggerTeleportCommand(const char*)
191 sLog.outString( "Re-Loading AreaTrigger teleport definitions..." );
192 objmgr.LoadAreaTriggerTeleports();
193 SendGlobalSysMessage("DB table `areatrigger_teleport` reloaded.");
194 return true;
197 bool ChatHandler::HandleReloadCommandCommand(const char*)
199 load_command_table = true;
200 SendGlobalSysMessage("DB table `command` will be reloaded at next chat command use.");
201 return true;
204 bool ChatHandler::HandleReloadCreatureQuestRelationsCommand(const char*)
206 sLog.outString( "Loading Quests Relations... (`creature_questrelation`)" );
207 objmgr.LoadCreatureQuestRelations();
208 SendGlobalSysMessage("DB table `creature_questrelation` (creature quest givers) reloaded.");
209 return true;
212 bool ChatHandler::HandleReloadCreatureQuestInvRelationsCommand(const char*)
214 sLog.outString( "Loading Quests Relations... (`creature_involvedrelation`)" );
215 objmgr.LoadCreatureInvolvedRelations();
216 SendGlobalSysMessage("DB table `creature_involvedrelation` (creature quest takers) reloaded.");
217 return true;
220 bool ChatHandler::HandleReloadGOQuestRelationsCommand(const char*)
222 sLog.outString( "Loading Quests Relations... (`gameobject_questrelation`)" );
223 objmgr.LoadGameobjectQuestRelations();
224 SendGlobalSysMessage("DB table `gameobject_questrelation` (gameobject quest givers) reloaded.");
225 return true;
228 bool ChatHandler::HandleReloadGOQuestInvRelationsCommand(const char*)
230 sLog.outString( "Loading Quests Relations... (`gameobject_involvedrelation`)" );
231 objmgr.LoadGameobjectInvolvedRelations();
232 SendGlobalSysMessage("DB table `gameobject_involvedrelation` (gameobject quest takers) reloaded.");
233 return true;
236 bool ChatHandler::HandleReloadQuestAreaTriggersCommand(const char*)
238 sLog.outString( "Re-Loading Quest Area Triggers..." );
239 objmgr.LoadQuestAreaTriggers();
240 SendGlobalSysMessage("DB table `areatrigger_involvedrelation` (quest area triggers) reloaded.");
241 return true;
244 bool ChatHandler::HandleReloadQuestTemplateCommand(const char*)
246 sLog.outString( "Re-Loading Quest Templates..." );
247 objmgr.LoadQuests();
248 SendGlobalSysMessage("DB table `quest_template` (quest definitions) reloaded.");
249 return true;
252 bool ChatHandler::HandleReloadLootTemplatesCreatureCommand(const char*)
254 sLog.outString( "Re-Loading Loot Tables... (`creature_loot_template`)" );
255 LoadLootTemplates_Creature();
256 LootTemplates_Creature.CheckLootRefs();
257 SendGlobalSysMessage("DB table `creature_loot_template` reloaded.");
258 return true;
261 bool ChatHandler::HandleReloadLootTemplatesDisenchantCommand(const char*)
263 sLog.outString( "Re-Loading Loot Tables... (`disenchant_loot_template`)" );
264 LoadLootTemplates_Disenchant();
265 LootTemplates_Disenchant.CheckLootRefs();
266 SendGlobalSysMessage("DB table `disenchant_loot_template` reloaded.");
267 return true;
270 bool ChatHandler::HandleReloadLootTemplatesFishingCommand(const char*)
272 sLog.outString( "Re-Loading Loot Tables... (`fishing_loot_template`)" );
273 LoadLootTemplates_Fishing();
274 LootTemplates_Fishing.CheckLootRefs();
275 SendGlobalSysMessage("DB table `fishing_loot_template` reloaded.");
276 return true;
279 bool ChatHandler::HandleReloadLootTemplatesGameobjectCommand(const char*)
281 sLog.outString( "Re-Loading Loot Tables... (`gameobject_loot_template`)" );
282 LoadLootTemplates_Gameobject();
283 LootTemplates_Gameobject.CheckLootRefs();
284 SendGlobalSysMessage("DB table `gameobject_loot_template` reloaded.");
285 return true;
288 bool ChatHandler::HandleReloadLootTemplatesItemCommand(const char*)
290 sLog.outString( "Re-Loading Loot Tables... (`item_loot_template`)" );
291 LoadLootTemplates_Item();
292 LootTemplates_Item.CheckLootRefs();
293 SendGlobalSysMessage("DB table `item_loot_template` reloaded.");
294 return true;
297 bool ChatHandler::HandleReloadLootTemplatesPickpocketingCommand(const char*)
299 sLog.outString( "Re-Loading Loot Tables... (`pickpocketing_loot_template`)" );
300 LoadLootTemplates_Pickpocketing();
301 LootTemplates_Pickpocketing.CheckLootRefs();
302 SendGlobalSysMessage("DB table `pickpocketing_loot_template` reloaded.");
303 return true;
306 bool ChatHandler::HandleReloadLootTemplatesProspectingCommand(const char*)
308 sLog.outString( "Re-Loading Loot Tables... (`prospecting_loot_template`)" );
309 LoadLootTemplates_Prospecting();
310 LootTemplates_Prospecting.CheckLootRefs();
311 SendGlobalSysMessage("DB table `prospecting_loot_template` reloaded.");
312 return true;
315 bool ChatHandler::HandleReloadLootTemplatesQuestMailCommand(const char*)
317 sLog.outString( "Re-Loading Loot Tables... (`quest_mail_loot_template`)" );
318 LoadLootTemplates_QuestMail();
319 LootTemplates_QuestMail.CheckLootRefs();
320 SendGlobalSysMessage("DB table `quest_mail_loot_template` reloaded.");
321 return true;
324 bool ChatHandler::HandleReloadLootTemplatesReferenceCommand(const char*)
326 sLog.outString( "Re-Loading Loot Tables... (`reference_loot_template`)" );
327 LoadLootTemplates_Reference();
328 SendGlobalSysMessage("DB table `reference_loot_template` reloaded.");
329 return true;
332 bool ChatHandler::HandleReloadLootTemplatesSkinningCommand(const char*)
334 sLog.outString( "Re-Loading Loot Tables... (`skinning_loot_template`)" );
335 LoadLootTemplates_Skinning();
336 LootTemplates_Skinning.CheckLootRefs();
337 SendGlobalSysMessage("DB table `skinning_loot_template` reloaded.");
338 return true;
341 bool ChatHandler::HandleReloadMangosStringCommand(const char*)
343 sLog.outString( "Re-Loading mangos_string Table!" );
344 objmgr.LoadMangosStrings();
345 SendGlobalSysMessage("DB table `mangos_string` reloaded.");
346 return true;
349 bool ChatHandler::HandleReloadNpcOptionCommand(const char*)
351 sLog.outString( "Re-Loading `npc_option` Table!" );
352 objmgr.LoadNpcOptions();
353 SendGlobalSysMessage("DB table `npc_option` reloaded.");
354 return true;
357 bool ChatHandler::HandleReloadNpcGossipCommand(const char*)
359 sLog.outString( "Re-Loading `npc_gossip` Table!" );
360 objmgr.LoadNpcTextId();
361 SendGlobalSysMessage("DB table `npc_gossip` reloaded.");
362 return true;
365 bool ChatHandler::HandleReloadNpcTrainerCommand(const char*)
367 sLog.outString( "Re-Loading `npc_trainer` Table!" );
368 objmgr.LoadTrainerSpell();
369 SendGlobalSysMessage("DB table `npc_trainer` reloaded.");
370 return true;
373 bool ChatHandler::HandleReloadNpcVendorCommand(const char*)
375 sLog.outString( "Re-Loading `npc_vendor` Table!" );
376 objmgr.LoadVendors();
377 SendGlobalSysMessage("DB table `npc_vendor` reloaded.");
378 return true;
381 bool ChatHandler::HandleReloadReservedNameCommand(const char*)
383 sLog.outString( "Loading ReservedNames... (`reserved_name`)" );
384 objmgr.LoadReservedPlayersNames();
385 SendGlobalSysMessage("DB table `reserved_name` (player reserved names) reloaded.");
386 return true;
389 bool ChatHandler::HandleReloadSkillDiscoveryTemplateCommand(const char* /*args*/)
391 sLog.outString( "Re-Loading Skill Discovery Table..." );
392 LoadSkillDiscoveryTable();
393 SendGlobalSysMessage("DB table `skill_discovery_template` (recipes discovered at crafting) reloaded.");
394 return true;
397 bool ChatHandler::HandleReloadSkillExtraItemTemplateCommand(const char* /*args*/)
399 sLog.outString( "Re-Loading Skill Extra Item Table..." );
400 LoadSkillExtraItemTable();
401 SendGlobalSysMessage("DB table `skill_extra_item_template` (extra item creation when crafting) reloaded.");
402 return true;
405 bool ChatHandler::HandleReloadSkillFishingBaseLevelCommand(const char* /*args*/)
407 sLog.outString( "Re-Loading Skill Fishing base level requirements..." );
408 objmgr.LoadFishingBaseSkillLevel();
409 SendGlobalSysMessage("DB table `skill_fishing_base_level` (fishing base level for zone/subzone) reloaded.");
410 return true;
413 bool ChatHandler::HandleReloadSpellAffectCommand(const char*)
415 sLog.outString( "Re-Loading SpellAffect definitions..." );
416 spellmgr.LoadSpellAffects();
417 SendGlobalSysMessage("DB table `spell_affect` (spell mods apply requirements) reloaded.");
418 return true;
421 bool ChatHandler::HandleReloadSpellChainCommand(const char*)
423 sLog.outString( "Re-Loading Spell Chain Data... " );
424 spellmgr.LoadSpellChains();
425 SendGlobalSysMessage("DB table `spell_chain` (spell ranks) reloaded.");
426 return true;
429 bool ChatHandler::HandleReloadSpellElixirCommand(const char*)
431 sLog.outString( "Re-Loading Spell Elixir types..." );
432 spellmgr.LoadSpellElixirs();
433 SendGlobalSysMessage("DB table `spell_elixir` (spell elixir types) reloaded.");
434 return true;
437 bool ChatHandler::HandleReloadSpellLearnSpellCommand(const char*)
439 sLog.outString( "Re-Loading Spell Learn Spells..." );
440 spellmgr.LoadSpellLearnSpells();
441 SendGlobalSysMessage("DB table `spell_learn_spell` reloaded.");
442 return true;
445 bool ChatHandler::HandleReloadSpellProcEventCommand(const char*)
447 sLog.outString( "Re-Loading Spell Proc Event conditions..." );
448 spellmgr.LoadSpellProcEvents();
449 SendGlobalSysMessage("DB table `spell_proc_event` (spell proc trigger requirements) reloaded.");
450 return true;
453 bool ChatHandler::HandleReloadSpellScriptTargetCommand(const char*)
455 sLog.outString( "Re-Loading SpellsScriptTarget..." );
456 spellmgr.LoadSpellScriptTarget();
457 SendGlobalSysMessage("DB table `spell_script_target` (spell targets selection in case specific creature/GO requirements) reloaded.");
458 return true;
461 bool ChatHandler::HandleReloadSpellTargetPositionCommand(const char*)
463 sLog.outString( "Re-Loading Spell target coordinates..." );
464 spellmgr.LoadSpellTargetPositions();
465 SendGlobalSysMessage("DB table `spell_target_position` (destination coordinates for spell targets) reloaded.");
466 return true;
469 bool ChatHandler::HandleReloadSpellThreatsCommand(const char*)
471 sLog.outString( "Re-Loading Aggro Spells Definitions...");
472 spellmgr.LoadSpellThreats();
473 SendGlobalSysMessage("DB table `spell_threat` (spell aggro definitions) reloaded.");
474 return true;
477 bool ChatHandler::HandleReloadSpellPetAurasCommand(const char*)
479 sLog.outString( "Re-Loading Spell pet auras...");
480 spellmgr.LoadSpellPetAuras();
481 SendGlobalSysMessage("DB table `spell_pet_auras` reloaded.");
482 return true;
485 bool ChatHandler::HandleReloadPageTextsCommand(const char*)
487 sLog.outString( "Re-Loading Page Texts..." );
488 objmgr.LoadPageTexts();
489 SendGlobalSysMessage("DB table `page_texts` reloaded.");
490 return true;
493 bool ChatHandler::HandleReloadItemEnchantementsCommand(const char*)
495 sLog.outString( "Re-Loading Item Random Enchantments Table..." );
496 LoadRandomEnchantmentsTable();
497 SendGlobalSysMessage("DB table `item_enchantment_template` reloaded.");
498 return true;
501 bool ChatHandler::HandleReloadGameObjectScriptsCommand(const char* arg)
503 if(sWorld.IsScriptScheduled())
505 SendSysMessage("DB scripts used currently, please attempt reload later.");
506 SetSentErrorMessage(true);
507 return false;
510 if(*arg!='a')
511 sLog.outString( "Re-Loading Scripts from `gameobject_scripts`...");
513 objmgr.LoadGameObjectScripts();
515 if(*arg!='a')
516 SendGlobalSysMessage("DB table `gameobject_scripts` reloaded.");
518 return true;
521 bool ChatHandler::HandleReloadEventScriptsCommand(const char* arg)
523 if(sWorld.IsScriptScheduled())
525 SendSysMessage("DB scripts used currently, please attempt reload later.");
526 SetSentErrorMessage(true);
527 return false;
530 if(*arg!='a')
531 sLog.outString( "Re-Loading Scripts from `event_scripts`...");
533 objmgr.LoadEventScripts();
535 if(*arg!='a')
536 SendGlobalSysMessage("DB table `event_scripts` reloaded.");
538 return true;
541 bool ChatHandler::HandleReloadQuestEndScriptsCommand(const char* arg)
543 if(sWorld.IsScriptScheduled())
545 SendSysMessage("DB scripts used currently, please attempt reload later.");
546 SetSentErrorMessage(true);
547 return false;
550 if(*arg!='a')
551 sLog.outString( "Re-Loading Scripts from `quest_end_scripts`...");
553 objmgr.LoadQuestEndScripts();
555 if(*arg!='a')
556 SendGlobalSysMessage("DB table `quest_end_scripts` reloaded.");
558 return true;
561 bool ChatHandler::HandleReloadQuestStartScriptsCommand(const char* arg)
563 if(sWorld.IsScriptScheduled())
565 SendSysMessage("DB scripts used currently, please attempt reload later.");
566 SetSentErrorMessage(true);
567 return false;
570 if(*arg!='a')
571 sLog.outString( "Re-Loading Scripts from `quest_start_scripts`...");
573 objmgr.LoadQuestStartScripts();
575 if(*arg!='a')
576 SendGlobalSysMessage("DB table `quest_start_scripts` reloaded.");
578 return true;
581 bool ChatHandler::HandleReloadSpellScriptsCommand(const char* arg)
583 if(sWorld.IsScriptScheduled())
585 SendSysMessage("DB scripts used currently, please attempt reload later.");
586 SetSentErrorMessage(true);
587 return false;
590 if(*arg!='a')
591 sLog.outString( "Re-Loading Scripts from `spell_scripts`...");
593 objmgr.LoadSpellScripts();
595 if(*arg!='a')
596 SendGlobalSysMessage("DB table `spell_scripts` reloaded.");
598 return true;
601 bool ChatHandler::HandleReloadDbScriptStringCommand(const char* arg)
603 sLog.outString( "Re-Loading Script strings from `db_script_string`...");
604 objmgr.LoadDbScriptStrings();
605 SendGlobalSysMessage("DB table `db_script_string` reloaded.");
606 return true;
609 bool ChatHandler::HandleReloadGameGraveyardZoneCommand(const char* /*arg*/)
611 sLog.outString( "Re-Loading Graveyard-zone links...");
613 objmgr.LoadGraveyardZones();
615 SendGlobalSysMessage("DB table `game_graveyard_zone` reloaded.");
617 return true;
620 bool ChatHandler::HandleReloadGameTeleCommand(const char* /*arg*/)
622 sLog.outString( "Re-Loading Game Tele coordinates...");
624 objmgr.LoadGameTele();
626 SendGlobalSysMessage("DB table `game_tele` reloaded.");
628 return true;
631 bool ChatHandler::HandleReloadLocalesCreatureCommand(const char* /*arg*/)
633 sLog.outString( "Re-Loading Locales Creature ...");
634 objmgr.LoadCreatureLocales();
635 SendGlobalSysMessage("DB table `locales_creature` reloaded.");
636 return true;
639 bool ChatHandler::HandleReloadLocalesGameobjectCommand(const char* /*arg*/)
641 sLog.outString( "Re-Loading Locales Gameobject ... ");
642 objmgr.LoadGameObjectLocales();
643 SendGlobalSysMessage("DB table `locales_gameobject` reloaded.");
644 return true;
647 bool ChatHandler::HandleReloadLocalesItemCommand(const char* /*arg*/)
649 sLog.outString( "Re-Loading Locales Item ... ");
650 objmgr.LoadItemLocales();
651 SendGlobalSysMessage("DB table `locales_item` reloaded.");
652 return true;
655 bool ChatHandler::HandleReloadLocalesNpcTextCommand(const char* /*arg*/)
657 sLog.outString( "Re-Loading Locales NPC Text ... ");
658 objmgr.LoadNpcTextLocales();
659 SendGlobalSysMessage("DB table `locales_npc_text` reloaded.");
660 return true;
663 bool ChatHandler::HandleReloadLocalesPageTextCommand(const char* /*arg*/)
665 sLog.outString( "Re-Loading Locales Page Text ... ");
666 objmgr.LoadPageTextLocales();
667 SendGlobalSysMessage("DB table `locales_page_text` reloaded.");
668 return true;
671 bool ChatHandler::HandleReloadLocalesQuestCommand(const char* /*arg*/)
673 sLog.outString( "Re-Loading Locales Quest ... ");
674 objmgr.LoadQuestLocales();
675 SendGlobalSysMessage("DB table `locales_quest` reloaded.");
676 return true;
679 bool ChatHandler::HandleLoadScriptsCommand(const char* args)
681 if(!LoadScriptingModule(args)) return true;
683 sWorld.SendWorldText(LANG_SCRIPTS_RELOADED);
684 return true;
687 bool ChatHandler::HandleAccountSetGmLevelCommand(const char* args)
689 char* arg1 = strtok((char*)args, " ");
690 if( !arg1 )
691 return false;
693 /// must be NULL if targeted syntax and must be not nULL if not targeted
694 char* arg2 = strtok(NULL, " ");
696 std::string targetAccountName;
697 uint32 targetAccountId = 0;
698 uint32 targetSecurity = 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();
712 targetSecurity = targetPlayer->GetSession()->GetSecurity();
713 if(!accmgr.GetName(targetAccountId,targetAccountName))
715 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,targetAccountName.c_str());
716 SetSentErrorMessage(true);
717 return false;
720 else
722 /// wrong command syntax (second arg expected)
723 if(!arg2)
724 return false;
726 targetAccountName = arg1;
727 if(!AccountMgr::normilizeString(targetAccountName))
729 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,targetAccountName.c_str());
730 SetSentErrorMessage(true);
731 return false;
734 targetAccountId = accmgr.GetId(targetAccountName);
735 targetSecurity = accmgr.GetSecurity(targetAccountId);
738 int32 gm = (int32)atoi(arg2);
739 if ( gm < SEC_PLAYER || gm > SEC_ADMINISTRATOR )
741 SendSysMessage(LANG_BAD_VALUE);
742 SetSentErrorMessage(true);
743 return false;
746 /// m_session==NULL only for console
747 uint32 plSecurity = m_session ? m_session->GetSecurity() : SEC_CONSOLE;
749 /// can set security level only for target with less security and to less security that we have
750 /// This is also reject self apply in fact
751 if(targetSecurity >= plSecurity || 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 uint32 targetSecurity = accmgr.GetSecurity(targetAccountId);
802 /// m_session==NULL only for console
803 uint32 plSecurity = m_session ? m_session->GetSecurity() : SEC_CONSOLE;
805 /// can set password only for target with less security
806 /// This is also reject self apply in fact
807 if (targetSecurity >= plSecurity)
809 SendSysMessage (LANG_YOURS_SECURITY_IS_LOW);
810 SetSentErrorMessage (true);
811 return false;
814 if (strcmp(szPassword1,szPassword2))
816 SendSysMessage (LANG_NEW_PASSWORDS_NOT_MATCH);
817 SetSentErrorMessage (true);
818 return false;
821 AccountOpResult result = accmgr.ChangePassword(targetAccountId, szPassword1);
823 switch(result)
825 case AOR_OK:
826 SendSysMessage(LANG_COMMAND_PASSWORD);
827 break;
828 case AOR_NAME_NOT_EXIST:
829 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
830 SetSentErrorMessage(true);
831 return false;
832 case AOR_PASS_TOO_LONG:
833 SendSysMessage(LANG_PASSWORD_TOO_LONG);
834 SetSentErrorMessage(true);
835 return false;
836 default:
837 SendSysMessage(LANG_COMMAND_NOTCHANGEPASSWORD);
838 SetSentErrorMessage(true);
839 return false;
842 return true;
845 bool ChatHandler::HandleAllowMovementCommand(const char* /*args*/)
847 if(sWorld.getAllowMovement())
849 sWorld.SetAllowMovement(false);
850 SendSysMessage(LANG_CREATURE_MOVE_DISABLED);
852 else
854 sWorld.SetAllowMovement(true);
855 SendSysMessage(LANG_CREATURE_MOVE_ENABLED);
857 return true;
860 bool ChatHandler::HandleMaxSkillCommand(const char* /*args*/)
862 Player* SelectedPlayer = getSelectedPlayer();
863 if(!SelectedPlayer)
865 SendSysMessage(LANG_NO_CHAR_SELECTED);
866 SetSentErrorMessage(true);
867 return false;
870 // each skills that have max skill value dependent from level seted to current level max skill value
871 SelectedPlayer->UpdateSkillsToMaxSkillsForLevel();
872 return true;
875 bool ChatHandler::HandleSetSkillCommand(const char* args)
877 // number or [name] Shift-click form |color|Hskill:skill_id|h[name]|h|r
878 char* skill_p = extractKeyFromLink((char*)args,"Hskill");
879 if(!skill_p)
880 return false;
882 char *level_p = strtok (NULL, " ");
884 if( !level_p)
885 return false;
887 char *max_p = strtok (NULL, " ");
889 int32 skill = atoi(skill_p);
891 if (skill <= 0)
893 PSendSysMessage(LANG_INVALID_SKILL_ID, skill);
894 SetSentErrorMessage(true);
895 return false;
898 int32 level = atol (level_p);
900 Player * target = getSelectedPlayer();
901 if(!target)
903 SendSysMessage(LANG_NO_CHAR_SELECTED);
904 SetSentErrorMessage(true);
905 return false;
908 SkillLineEntry const* sl = sSkillLineStore.LookupEntry(skill);
909 if(!sl)
911 PSendSysMessage(LANG_INVALID_SKILL_ID, skill);
912 SetSentErrorMessage(true);
913 return false;
916 if(!target->GetSkillValue(skill))
918 PSendSysMessage(LANG_SET_SKILL_ERROR, target->GetName(), skill, sl->name[0]);
919 SetSentErrorMessage(true);
920 return false;
923 int32 max = max_p ? atol (max_p) : target->GetPureMaxSkillValue(skill);
925 if( level <= 0 || level > max || max <= 0 )
926 return false;
928 target->SetSkill(skill, level, max);
929 PSendSysMessage(LANG_SET_SKILL, skill, sl->name[0], target->GetName(), level, max);
931 return true;
934 bool ChatHandler::HandleUnLearnCommand(const char* args)
936 if (!*args)
937 return false;
939 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
940 uint32 min_id = extractSpellIdFromLink((char*)args);
941 if(!min_id)
942 return false;
944 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
945 char* tail = strtok(NULL,"");
947 uint32 max_id = extractSpellIdFromLink(tail);
949 if (!max_id)
951 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
952 max_id = min_id+1;
954 else
956 if (max_id < min_id)
957 std::swap(min_id,max_id);
959 max_id=max_id+1;
962 Player* target = getSelectedPlayer();
963 if(!target)
965 SendSysMessage(LANG_NO_CHAR_SELECTED);
966 SetSentErrorMessage(true);
967 return false;
970 for(uint32 spell=min_id;spell<max_id;spell++)
972 if (target->HasSpell(spell))
973 target->removeSpell(spell);
974 else
975 SendSysMessage(LANG_FORGET_SPELL);
978 return true;
981 bool ChatHandler::HandleCooldownCommand(const char* args)
983 Player* target = getSelectedPlayer();
984 if(!target)
986 SendSysMessage(LANG_PLAYER_NOT_FOUND);
987 SetSentErrorMessage(true);
988 return false;
991 if (!*args)
993 target->RemoveAllSpellCooldown();
994 PSendSysMessage(LANG_REMOVEALL_COOLDOWN, target->GetName());
996 else
998 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
999 uint32 spell_id = extractSpellIdFromLink((char*)args);
1000 if(!spell_id)
1001 return false;
1003 if(!sSpellStore.LookupEntry(spell_id))
1005 PSendSysMessage(LANG_UNKNOWN_SPELL, target==m_session->GetPlayer() ? GetMangosString(LANG_YOU) : target->GetName());
1006 SetSentErrorMessage(true);
1007 return false;
1010 WorldPacket data( SMSG_CLEAR_COOLDOWN, (4+8) );
1011 data << uint32(spell_id);
1012 data << uint64(target->GetGUID());
1013 target->GetSession()->SendPacket(&data);
1014 target->RemoveSpellCooldown(spell_id);
1015 PSendSysMessage(LANG_REMOVE_COOLDOWN, spell_id, target==m_session->GetPlayer() ? GetMangosString(LANG_YOU) : target->GetName());
1017 return true;
1020 bool ChatHandler::HandleLearnAllCommand(const char* /*args*/)
1022 static const char *allSpellList[] =
1024 "3365",
1025 "6233",
1026 "6247",
1027 "6246",
1028 "6477",
1029 "6478",
1030 "22810",
1031 "8386",
1032 "21651",
1033 "21652",
1034 "522",
1035 "7266",
1036 "8597",
1037 "2479",
1038 "22027",
1039 "6603",
1040 "5019",
1041 "133",
1042 "168",
1043 "227",
1044 "5009",
1045 "9078",
1046 "668",
1047 "203",
1048 "20599",
1049 "20600",
1050 "81",
1051 "20597",
1052 "20598",
1053 "20864",
1054 "1459",
1055 "5504",
1056 "587",
1057 "5143",
1058 "118",
1059 "5505",
1060 "597",
1061 "604",
1062 "1449",
1063 "1460",
1064 "2855",
1065 "1008",
1066 "475",
1067 "5506",
1068 "1463",
1069 "12824",
1070 "8437",
1071 "990",
1072 "5145",
1073 "8450",
1074 "1461",
1075 "759",
1076 "8494",
1077 "8455",
1078 "8438",
1079 "6127",
1080 "8416",
1081 "6129",
1082 "8451",
1083 "8495",
1084 "8439",
1085 "3552",
1086 "8417",
1087 "10138",
1088 "12825",
1089 "10169",
1090 "10156",
1091 "10144",
1092 "10191",
1093 "10201",
1094 "10211",
1095 "10053",
1096 "10173",
1097 "10139",
1098 "10145",
1099 "10192",
1100 "10170",
1101 "10202",
1102 "10054",
1103 "10174",
1104 "10193",
1105 "12826",
1106 "2136",
1107 "143",
1108 "145",
1109 "2137",
1110 "2120",
1111 "3140",
1112 "543",
1113 "2138",
1114 "2948",
1115 "8400",
1116 "2121",
1117 "8444",
1118 "8412",
1119 "8457",
1120 "8401",
1121 "8422",
1122 "8445",
1123 "8402",
1124 "8413",
1125 "8458",
1126 "8423",
1127 "8446",
1128 "10148",
1129 "10197",
1130 "10205",
1131 "10149",
1132 "10215",
1133 "10223",
1134 "10206",
1135 "10199",
1136 "10150",
1137 "10216",
1138 "10207",
1139 "10225",
1140 "10151",
1141 "116",
1142 "205",
1143 "7300",
1144 "122",
1145 "837",
1146 "10",
1147 "7301",
1148 "7322",
1149 "6143",
1150 "120",
1151 "865",
1152 "8406",
1153 "6141",
1154 "7302",
1155 "8461",
1156 "8407",
1157 "8492",
1158 "8427",
1159 "8408",
1160 "6131",
1161 "7320",
1162 "10159",
1163 "8462",
1164 "10185",
1165 "10179",
1166 "10160",
1167 "10180",
1168 "10219",
1169 "10186",
1170 "10177",
1171 "10230",
1172 "10181",
1173 "10161",
1174 "10187",
1175 "10220",
1176 "2018",
1177 "2663",
1178 "12260",
1179 "2660",
1180 "3115",
1181 "3326",
1182 "2665",
1183 "3116",
1184 "2738",
1185 "3293",
1186 "2661",
1187 "3319",
1188 "2662",
1189 "9983",
1190 "8880",
1191 "2737",
1192 "2739",
1193 "7408",
1194 "3320",
1195 "2666",
1196 "3323",
1197 "3324",
1198 "3294",
1199 "22723",
1200 "23219",
1201 "23220",
1202 "23221",
1203 "23228",
1204 "23338",
1205 "10788",
1206 "10790",
1207 "5611",
1208 "5016",
1209 "5609",
1210 "2060",
1211 "10963",
1212 "10964",
1213 "10965",
1214 "22593",
1215 "22594",
1216 "596",
1217 "996",
1218 "499",
1219 "768",
1220 "17002",
1221 "1448",
1222 "1082",
1223 "16979",
1224 "1079",
1225 "5215",
1226 "20484",
1227 "5221",
1228 "15590",
1229 "17007",
1230 "6795",
1231 "6807",
1232 "5487",
1233 "1446",
1234 "1066",
1235 "5421",
1236 "3139",
1237 "779",
1238 "6811",
1239 "6808",
1240 "1445",
1241 "5216",
1242 "1737",
1243 "5222",
1244 "5217",
1245 "1432",
1246 "6812",
1247 "9492",
1248 "5210",
1249 "3030",
1250 "1441",
1251 "783",
1252 "6801",
1253 "20739",
1254 "8944",
1255 "9491",
1256 "22569",
1257 "5226",
1258 "6786",
1259 "1433",
1260 "8973",
1261 "1828",
1262 "9495",
1263 "9006",
1264 "6794",
1265 "8993",
1266 "5203",
1267 "16914",
1268 "6784",
1269 "9635",
1270 "22830",
1271 "20722",
1272 "9748",
1273 "6790",
1274 "9753",
1275 "9493",
1276 "9752",
1277 "9831",
1278 "9825",
1279 "9822",
1280 "5204",
1281 "5401",
1282 "22831",
1283 "6793",
1284 "9845",
1285 "17401",
1286 "9882",
1287 "9868",
1288 "20749",
1289 "9893",
1290 "9899",
1291 "9895",
1292 "9832",
1293 "9902",
1294 "9909",
1295 "22832",
1296 "9828",
1297 "9851",
1298 "9883",
1299 "9869",
1300 "17406",
1301 "17402",
1302 "9914",
1303 "20750",
1304 "9897",
1305 "9848",
1306 "3127",
1307 "107",
1308 "204",
1309 "9116",
1310 "2457",
1311 "78",
1312 "18848",
1313 "331",
1314 "403",
1315 "2098",
1316 "1752",
1317 "11278",
1318 "11288",
1319 "11284",
1320 "6461",
1321 "2344",
1322 "2345",
1323 "6463",
1324 "2346",
1325 "2352",
1326 "775",
1327 "1434",
1328 "1612",
1329 "71",
1330 "2468",
1331 "2458",
1332 "2467",
1333 "7164",
1334 "7178",
1335 "7367",
1336 "7376",
1337 "7381",
1338 "21156",
1339 "5209",
1340 "3029",
1341 "5201",
1342 "9849",
1343 "9850",
1344 "20719",
1345 "22568",
1346 "22827",
1347 "22828",
1348 "22829",
1349 "6809",
1350 "8972",
1351 "9005",
1352 "9823",
1353 "9827",
1354 "6783",
1355 "9913",
1356 "6785",
1357 "6787",
1358 "9866",
1359 "9867",
1360 "9894",
1361 "9896",
1362 "6800",
1363 "8992",
1364 "9829",
1365 "9830",
1366 "780",
1367 "769",
1368 "6749",
1369 "6750",
1370 "9755",
1371 "9754",
1372 "9908",
1373 "20745",
1374 "20742",
1375 "20747",
1376 "20748",
1377 "9746",
1378 "9745",
1379 "9880",
1380 "9881",
1381 "5391",
1382 "842",
1383 "3025",
1384 "3031",
1385 "3287",
1386 "3329",
1387 "1945",
1388 "3559",
1389 "4933",
1390 "4934",
1391 "4935",
1392 "4936",
1393 "5142",
1394 "5390",
1395 "5392",
1396 "5404",
1397 "5420",
1398 "6405",
1399 "7293",
1400 "7965",
1401 "8041",
1402 "8153",
1403 "9033",
1404 "9034",
1405 //"9036", problems with ghost state
1406 "16421",
1407 "21653",
1408 "22660",
1409 "5225",
1410 "9846",
1411 "2426",
1412 "5916",
1413 "6634",
1414 //"6718", phasing stealth, annoying for learn all case.
1415 "6719",
1416 "8822",
1417 "9591",
1418 "9590",
1419 "10032",
1420 "17746",
1421 "17747",
1422 "8203",
1423 "11392",
1424 "12495",
1425 "16380",
1426 "23452",
1427 "4079",
1428 "4996",
1429 "4997",
1430 "4998",
1431 "4999",
1432 "5000",
1433 "6348",
1434 "6349",
1435 "6481",
1436 "6482",
1437 "6483",
1438 "6484",
1439 "11362",
1440 "11410",
1441 "11409",
1442 "12510",
1443 "12509",
1444 "12885",
1445 "13142",
1446 "21463",
1447 "23460",
1448 "11421",
1449 "11416",
1450 "11418",
1451 "1851",
1452 "10059",
1453 "11423",
1454 "11417",
1455 "11422",
1456 "11419",
1457 "11424",
1458 "11420",
1459 "27",
1460 "31",
1461 "33",
1462 "34",
1463 "35",
1464 "15125",
1465 "21127",
1466 "22950",
1467 "1180",
1468 "201",
1469 "12593",
1470 "12842",
1471 "16770",
1472 "6057",
1473 "12051",
1474 "18468",
1475 "12606",
1476 "12605",
1477 "18466",
1478 "12502",
1479 "12043",
1480 "15060",
1481 "12042",
1482 "12341",
1483 "12848",
1484 "12344",
1485 "12353",
1486 "18460",
1487 "11366",
1488 "12350",
1489 "12352",
1490 "13043",
1491 "11368",
1492 "11113",
1493 "12400",
1494 "11129",
1495 "16766",
1496 "12573",
1497 "15053",
1498 "12580",
1499 "12475",
1500 "12472",
1501 "12953",
1502 "12488",
1503 "11189",
1504 "12985",
1505 "12519",
1506 "16758",
1507 "11958",
1508 "12490",
1509 "11426",
1510 "3565",
1511 "3562",
1512 "18960",
1513 "3567",
1514 "3561",
1515 "3566",
1516 "3563",
1517 "1953",
1518 "2139",
1519 "12505",
1520 "13018",
1521 "12522",
1522 "12523",
1523 "5146",
1524 "5144",
1525 "5148",
1526 "8419",
1527 "8418",
1528 "10213",
1529 "10212",
1530 "10157",
1531 "12524",
1532 "13019",
1533 "12525",
1534 "13020",
1535 "12526",
1536 "13021",
1537 "18809",
1538 "13031",
1539 "13032",
1540 "13033",
1541 "4036",
1542 "3920",
1543 "3919",
1544 "3918",
1545 "7430",
1546 "3922",
1547 "3923",
1548 "7411",
1549 "7418",
1550 "7421",
1551 "13262",
1552 "7412",
1553 "7415",
1554 "7413",
1555 "7416",
1556 "13920",
1557 "13921",
1558 "7745",
1559 "7779",
1560 "7428",
1561 "7457",
1562 "7857",
1563 "7748",
1564 "7426",
1565 "13421",
1566 "7454",
1567 "13378",
1568 "7788",
1569 "14807",
1570 "14293",
1571 "7795",
1572 "6296",
1573 "20608",
1574 "755",
1575 "444",
1576 "427",
1577 "428",
1578 "442",
1579 "447",
1580 "3578",
1581 "3581",
1582 "19027",
1583 "3580",
1584 "665",
1585 "3579",
1586 "3577",
1587 "6755",
1588 "3576",
1589 "2575",
1590 "2577",
1591 "2578",
1592 "2579",
1593 "2580",
1594 "2656",
1595 "2657",
1596 "2576",
1597 "3564",
1598 "10248",
1599 "8388",
1600 "2659",
1601 "14891",
1602 "3308",
1603 "3307",
1604 "10097",
1605 "2658",
1606 "3569",
1607 "16153",
1608 "3304",
1609 "10098",
1610 "4037",
1611 "3929",
1612 "3931",
1613 "3926",
1614 "3924",
1615 "3930",
1616 "3977",
1617 "3925",
1618 "136",
1619 "228",
1620 "5487",
1621 "43",
1622 "202",
1626 int loop = 0;
1627 while(strcmp(allSpellList[loop], "0"))
1629 uint32 spell = atol((char*)allSpellList[loop++]);
1631 if (m_session->GetPlayer()->HasSpell(spell))
1632 continue;
1634 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
1635 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
1637 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
1638 continue;
1641 m_session->GetPlayer()->learnSpell(spell);
1644 SendSysMessage(LANG_COMMAND_LEARN_MANY_SPELLS);
1646 return true;
1649 bool ChatHandler::HandleLearnAllGMCommand(const char* /*args*/)
1651 static const char *gmSpellList[] =
1653 "24347", // Become A Fish, No Breath Bar
1654 "35132", // Visual Boom
1655 "38488", // Attack 4000-8000 AOE
1656 "38795", // Attack 2000 AOE + Slow Down 90%
1657 "15712", // Attack 200
1658 "1852", // GM Spell Silence
1659 "31899", // Kill
1660 "31924", // Kill
1661 "29878", // Kill My Self
1662 "26644", // More Kill
1664 "28550", //Invisible 24
1665 "23452", //Invisible + Target
1669 uint16 gmSpellIter = 0;
1670 while( strcmp(gmSpellList[gmSpellIter], "0") )
1672 uint32 spell = atol((char*)gmSpellList[gmSpellIter++]);
1674 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
1675 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
1677 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
1678 continue;
1681 m_session->GetPlayer()->learnSpell(spell);
1684 SendSysMessage(LANG_LEARNING_GM_SKILLS);
1685 return true;
1688 bool ChatHandler::HandleLearnAllMyClassCommand(const char* /*args*/)
1690 HandleLearnAllMySpellsCommand("");
1691 HandleLearnAllMyTalentsCommand("");
1692 return true;
1695 bool ChatHandler::HandleLearnAllMySpellsCommand(const char* /*args*/)
1697 ChrClassesEntry const* clsEntry = sChrClassesStore.LookupEntry(m_session->GetPlayer()->getClass());
1698 if(!clsEntry)
1699 return true;
1700 uint32 family = clsEntry->spellfamily;
1702 for (uint32 i = 0; i < sSpellStore.GetNumRows(); i++)
1704 SpellEntry const *spellInfo = sSpellStore.LookupEntry(i);
1705 if(!spellInfo)
1706 continue;
1708 // skip wrong class/race skills
1709 if(!m_session->GetPlayer()->IsSpellFitByClassAndRace(spellInfo->Id))
1710 continue;
1712 // skip other spell families
1713 if( spellInfo->SpellFamilyName != family)
1714 continue;
1716 //TODO: skip triggered spells
1718 // skip spells with first rank learned as talent (and all talents then also)
1719 uint32 first_rank = spellmgr.GetFirstSpellInChain(spellInfo->Id);
1720 if(GetTalentSpellCost(first_rank) > 0 )
1721 continue;
1723 // skip broken spells
1724 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
1725 continue;
1727 m_session->GetPlayer()->learnSpell(i);
1730 SendSysMessage(LANG_COMMAND_LEARN_CLASS_SPELLS);
1731 return true;
1734 static void learnAllHighRanks(Player* player, uint32 spellid)
1736 SpellChainMapNext const& nextMap = spellmgr.GetSpellChainNext();
1737 for(SpellChainMapNext::const_iterator itr = nextMap.lower_bound(spellid); itr != nextMap.upper_bound(spellid); ++itr)
1739 player->learnSpell(itr->second);
1740 learnAllHighRanks(player,itr->second);
1744 bool ChatHandler::HandleLearnAllMyTalentsCommand(const char* /*args*/)
1746 Player* player = m_session->GetPlayer();
1747 uint32 classMask = player->getClassMask();
1749 for (uint32 i = 0; i < sTalentStore.GetNumRows(); i++)
1751 TalentEntry const *talentInfo = sTalentStore.LookupEntry(i);
1752 if(!talentInfo)
1753 continue;
1755 TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab );
1756 if(!talentTabInfo)
1757 continue;
1759 if( (classMask & talentTabInfo->ClassMask) == 0 )
1760 continue;
1762 // search highest talent rank
1763 uint32 spellid = 0;
1764 int rank = 4;
1765 for(; rank >= 0; --rank)
1767 if(talentInfo->RankID[rank]!=0)
1769 spellid = talentInfo->RankID[rank];
1770 break;
1774 if(!spellid) // ??? none spells in talent
1775 continue;
1777 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid);
1778 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
1779 continue;
1781 // learn highest rank of talent
1782 player->learnSpell(spellid);
1784 // and learn all non-talent spell ranks (recursive by tree)
1785 learnAllHighRanks(player,spellid);
1788 SendSysMessage(LANG_COMMAND_LEARN_CLASS_TALENTS);
1789 return true;
1792 bool ChatHandler::HandleLearnAllLangCommand(const char* /*args*/)
1794 // skipping UNIVERSAL language (0)
1795 for(int i = 1; i < LANGUAGES_COUNT; ++i)
1796 m_session->GetPlayer()->learnSpell(lang_description[i].spell_id);
1798 SendSysMessage(LANG_COMMAND_LEARN_ALL_LANG);
1799 return true;
1802 bool ChatHandler::HandleLearnAllDefaultCommand(const char* args)
1804 char* pName = strtok((char*)args, "");
1805 Player *player = NULL;
1806 if (pName)
1808 std::string name = pName;
1810 if(!normalizePlayerName(name))
1812 SendSysMessage(LANG_PLAYER_NOT_FOUND);
1813 SetSentErrorMessage(true);
1814 return false;
1817 player = objmgr.GetPlayer(name.c_str());
1819 else
1820 player = getSelectedPlayer();
1822 if(!player)
1824 SendSysMessage(LANG_NO_CHAR_SELECTED);
1825 SetSentErrorMessage(true);
1826 return false;
1829 player->learnDefaultSpells();
1830 player->learnQuestRewardedSpells();
1832 PSendSysMessage(LANG_COMMAND_LEARN_ALL_DEFAULT_AND_QUEST,player->GetName());
1833 return true;
1836 bool ChatHandler::HandleLearnCommand(const char* args)
1838 Player* targetPlayer = getSelectedPlayer();
1840 if(!targetPlayer)
1842 SendSysMessage(LANG_PLAYER_NOT_FOUND);
1843 SetSentErrorMessage(true);
1844 return false;
1847 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
1848 uint32 spell = extractSpellIdFromLink((char*)args);
1849 if(!spell || !sSpellStore.LookupEntry(spell))
1850 return false;
1852 if (targetPlayer->HasSpell(spell))
1854 if(targetPlayer == m_session->GetPlayer())
1855 SendSysMessage(LANG_YOU_KNOWN_SPELL);
1856 else
1857 PSendSysMessage(LANG_TARGET_KNOWN_SPELL,targetPlayer->GetName());
1858 SetSentErrorMessage(true);
1859 return false;
1862 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
1863 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
1865 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
1866 SetSentErrorMessage(true);
1867 return false;
1870 targetPlayer->learnSpell(spell);
1872 return true;
1875 bool ChatHandler::HandleAddItemCommand(const char* args)
1877 if (!*args)
1878 return false;
1880 uint32 itemId = 0;
1882 if(args[0]=='[') // [name] manual form
1884 char* citemName = citemName = strtok((char*)args, "]");
1886 if(citemName && citemName[0])
1888 std::string itemName = citemName+1;
1889 WorldDatabase.escape_string(itemName);
1890 QueryResult *result = WorldDatabase.PQuery("SELECT entry FROM item_template WHERE name = '%s'", itemName.c_str());
1891 if (!result)
1893 PSendSysMessage(LANG_COMMAND_COULDNOTFIND, citemName+1);
1894 SetSentErrorMessage(true);
1895 return false;
1897 itemId = result->Fetch()->GetUInt16();
1898 delete result;
1900 else
1901 return false;
1903 else // item_id or [name] Shift-click form |color|Hitem:item_id:0:0:0|h[name]|h|r
1905 char* cId = extractKeyFromLink((char*)args,"Hitem");
1906 if(!cId)
1907 return false;
1908 itemId = atol(cId);
1911 char* ccount = strtok(NULL, " ");
1913 int32 count = 1;
1915 if (ccount)
1916 count = strtol(ccount, NULL, 10);
1918 if (count == 0)
1919 count = 1;
1921 Player* pl = m_session->GetPlayer();
1922 Player* plTarget = getSelectedPlayer();
1923 if(!plTarget)
1924 plTarget = pl;
1926 sLog.outDetail(GetMangosString(LANG_ADDITEM), itemId, count);
1928 ItemPrototype const *pProto = objmgr.GetItemPrototype(itemId);
1929 if(!pProto)
1931 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId);
1932 SetSentErrorMessage(true);
1933 return false;
1936 //Subtract
1937 if (count < 0)
1939 plTarget->DestroyItemCount(itemId, -count, true, false);
1940 PSendSysMessage(LANG_REMOVEITEM, itemId, -count, plTarget->GetName());
1941 return true;
1944 //Adding items
1945 uint32 noSpaceForCount = 0;
1947 // check space and find places
1948 ItemPosCountVec dest;
1949 uint8 msg = plTarget->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, itemId, count, &noSpaceForCount );
1950 if( msg != EQUIP_ERR_OK ) // convert to possible store amount
1951 count -= noSpaceForCount;
1953 if( count == 0 || dest.empty()) // can't add any
1955 PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount );
1956 SetSentErrorMessage(true);
1957 return false;
1960 Item* item = plTarget->StoreNewItem( dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId));
1962 // remove binding (let GM give it to another player later)
1963 if(pl==plTarget)
1964 for(ItemPosCountVec::const_iterator itr = dest.begin(); itr != dest.end(); ++itr)
1965 if(Item* item1 = pl->GetItemByPos(itr->pos))
1966 item1->SetBinding( false );
1968 if(count > 0 && item)
1970 pl->SendNewItem(item,count,false,true);
1971 if(pl!=plTarget)
1972 plTarget->SendNewItem(item,count,true,false);
1975 if(noSpaceForCount > 0)
1976 PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount);
1978 return true;
1981 bool ChatHandler::HandleAddItemSetCommand(const char* args)
1983 if (!*args)
1984 return false;
1986 char* cId = extractKeyFromLink((char*)args,"Hitemset"); // number or [name] Shift-click form |color|Hitemset:itemset_id|h[name]|h|r
1987 if (!cId)
1988 return false;
1990 uint32 itemsetId = atol(cId);
1992 // prevent generation all items with itemset field value '0'
1993 if (itemsetId == 0)
1995 PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND,itemsetId);
1996 SetSentErrorMessage(true);
1997 return false;
2000 Player* pl = m_session->GetPlayer();
2001 Player* plTarget = getSelectedPlayer();
2002 if(!plTarget)
2003 plTarget = pl;
2005 sLog.outDetail(GetMangosString(LANG_ADDITEMSET), itemsetId);
2007 bool found = false;
2008 for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
2010 ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype>(id);
2011 if (!pProto)
2012 continue;
2014 if (pProto->ItemSet == itemsetId)
2016 found = true;
2017 ItemPosCountVec dest;
2018 uint8 msg = plTarget->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, pProto->ItemId, 1 );
2019 if (msg == EQUIP_ERR_OK)
2021 Item* item = plTarget->StoreNewItem( dest, pProto->ItemId, true);
2023 // remove binding (let GM give it to another player later)
2024 if (pl==plTarget)
2025 item->SetBinding( false );
2027 pl->SendNewItem(item,1,false,true);
2028 if (pl!=plTarget)
2029 plTarget->SendNewItem(item,1,true,false);
2031 else
2033 pl->SendEquipError( msg, NULL, NULL );
2034 PSendSysMessage(LANG_ITEM_CANNOT_CREATE, pProto->ItemId, 1);
2039 if (!found)
2041 PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND,itemsetId);
2043 SetSentErrorMessage(true);
2044 return false;
2047 return true;
2050 bool ChatHandler::HandleListItemCommand(const char* args)
2052 if(!*args)
2053 return false;
2055 char* cId = extractKeyFromLink((char*)args,"Hitem");
2056 if(!cId)
2057 return false;
2059 uint32 item_id = atol(cId);
2060 if(!item_id)
2062 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
2063 SetSentErrorMessage(true);
2064 return false;
2067 ItemPrototype const* itemProto = objmgr.GetItemPrototype(item_id);
2068 if(!itemProto)
2070 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
2071 SetSentErrorMessage(true);
2072 return false;
2075 char* c_count = strtok(NULL, " ");
2076 int count = c_count ? atol(c_count) : 10;
2078 if(count < 0)
2079 return false;
2081 QueryResult *result;
2083 // inventory case
2084 uint32 inv_count = 0;
2085 result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM character_inventory WHERE item_template='%u'",item_id);
2086 if(result)
2088 inv_count = (*result)[0].GetUInt32();
2089 delete result;
2092 result=CharacterDatabase.PQuery(
2093 // 0 1 2 3 4 5
2094 "SELECT ci.item, cibag.slot AS bag, ci.slot, ci.guid, characters.account,characters.name "
2095 "FROM character_inventory AS ci LEFT JOIN character_inventory AS cibag ON (cibag.item=ci.bag),characters "
2096 "WHERE ci.item_template='%u' AND ci.guid = characters.guid LIMIT %u ",
2097 item_id,uint32(count));
2099 if(result)
2103 Field *fields = result->Fetch();
2104 uint32 item_guid = fields[0].GetUInt32();
2105 uint32 item_bag = fields[1].GetUInt32();
2106 uint32 item_slot = fields[2].GetUInt32();
2107 uint32 owner_guid = fields[3].GetUInt32();
2108 uint32 owner_acc = fields[4].GetUInt32();
2109 std::string owner_name = fields[5].GetCppString();
2111 char const* item_pos = 0;
2112 if(Player::IsEquipmentPos(item_bag,item_slot))
2113 item_pos = "[equipped]";
2114 else if(Player::IsInventoryPos(item_bag,item_slot))
2115 item_pos = "[in inventory]";
2116 else if(Player::IsBankPos(item_bag,item_slot))
2117 item_pos = "[in bank]";
2118 else
2119 item_pos = "";
2121 PSendSysMessage(LANG_ITEMLIST_SLOT,
2122 item_guid,owner_name.c_str(),owner_guid,owner_acc,item_pos);
2123 } while (result->NextRow());
2125 int64 res_count = result->GetRowCount();
2127 delete result;
2129 if(count > res_count)
2130 count-=res_count;
2131 else if(count)
2132 count = 0;
2135 // mail case
2136 uint32 mail_count = 0;
2137 result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM mail_items WHERE item_template='%u'", item_id);
2138 if(result)
2140 mail_count = (*result)[0].GetUInt32();
2141 delete result;
2144 if(count > 0)
2146 result=CharacterDatabase.PQuery(
2147 // 0 1 2 3 4 5 6
2148 "SELECT mail_items.item_guid, mail.sender, mail.receiver, char_s.account, char_s.name, char_r.account, char_r.name "
2149 "FROM mail,mail_items,characters as char_s,characters as char_r "
2150 "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",
2151 item_id,uint32(count));
2153 else
2154 result = NULL;
2156 if(result)
2160 Field *fields = result->Fetch();
2161 uint32 item_guid = fields[0].GetUInt32();
2162 uint32 item_s = fields[1].GetUInt32();
2163 uint32 item_r = fields[2].GetUInt32();
2164 uint32 item_s_acc = fields[3].GetUInt32();
2165 std::string item_s_name = fields[4].GetCppString();
2166 uint32 item_r_acc = fields[5].GetUInt32();
2167 std::string item_r_name = fields[6].GetCppString();
2169 char const* item_pos = "[in mail]";
2171 PSendSysMessage(LANG_ITEMLIST_MAIL,
2172 item_guid,item_s_name.c_str(),item_s,item_s_acc,item_r_name.c_str(),item_r,item_r_acc,item_pos);
2173 } while (result->NextRow());
2175 int64 res_count = result->GetRowCount();
2177 delete result;
2179 if(count > res_count)
2180 count-=res_count;
2181 else if(count)
2182 count = 0;
2185 // auction case
2186 uint32 auc_count = 0;
2187 result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM auctionhouse WHERE item_template='%u'",item_id);
2188 if(result)
2190 auc_count = (*result)[0].GetUInt32();
2191 delete result;
2194 if(count > 0)
2196 result=CharacterDatabase.PQuery(
2197 // 0 1 2 3
2198 "SELECT auctionhouse.itemguid, auctionhouse.itemowner, characters.account, characters.name "
2199 "FROM auctionhouse,characters WHERE auctionhouse.item_template='%u' AND characters.guid = auctionhouse.itemowner LIMIT %u",
2200 item_id,uint32(count));
2202 else
2203 result = NULL;
2205 if(result)
2209 Field *fields = result->Fetch();
2210 uint32 item_guid = fields[0].GetUInt32();
2211 uint32 owner = fields[1].GetUInt32();
2212 uint32 owner_acc = fields[2].GetUInt32();
2213 std::string owner_name = fields[3].GetCppString();
2215 char const* item_pos = "[in auction]";
2217 PSendSysMessage(LANG_ITEMLIST_AUCTION, item_guid, owner_name.c_str(), owner, owner_acc,item_pos);
2218 } while (result->NextRow());
2220 delete result;
2223 // guild bank case
2224 uint32 guild_count = 0;
2225 result=CharacterDatabase.PQuery("SELECT COUNT(item_entry) FROM guild_bank_item WHERE item_entry='%u'",item_id);
2226 if(result)
2228 guild_count = (*result)[0].GetUInt32();
2229 delete result;
2232 result=CharacterDatabase.PQuery(
2233 // 0 1 2
2234 "SELECT gi.item_guid, gi.guildid, guild.name "
2235 "FROM guild_bank_item AS gi, guild WHERE gi.item_entry='%u' AND gi.guildid = guild.guildid LIMIT %u ",
2236 item_id,uint32(count));
2238 if(result)
2242 Field *fields = result->Fetch();
2243 uint32 item_guid = fields[0].GetUInt32();
2244 uint32 guild_guid = fields[1].GetUInt32();
2245 std::string guild_name = fields[2].GetCppString();
2247 char const* item_pos = "[in guild bank]";
2249 PSendSysMessage(LANG_ITEMLIST_GUILD,item_guid,guild_name.c_str(),guild_guid,item_pos);
2250 } while (result->NextRow());
2252 int64 res_count = result->GetRowCount();
2254 delete result;
2256 if(count > res_count)
2257 count-=res_count;
2258 else if(count)
2259 count = 0;
2262 if(inv_count+mail_count+auc_count+guild_count == 0)
2264 SendSysMessage(LANG_COMMAND_NOITEMFOUND);
2265 SetSentErrorMessage(true);
2266 return false;
2269 PSendSysMessage(LANG_COMMAND_LISTITEMMESSAGE,item_id,inv_count+mail_count+auc_count+guild_count,inv_count,mail_count,auc_count,guild_count);
2271 return true;
2274 bool ChatHandler::HandleListObjectCommand(const char* args)
2276 if(!*args)
2277 return false;
2279 // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r
2280 char* cId = extractKeyFromLink((char*)args,"Hgameobject_entry");
2281 if(!cId)
2282 return false;
2284 uint32 go_id = atol(cId);
2285 if(!go_id)
2287 PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id);
2288 SetSentErrorMessage(true);
2289 return false;
2292 GameObjectInfo const * gInfo = objmgr.GetGameObjectInfo(go_id);
2293 if(!gInfo)
2295 PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id);
2296 SetSentErrorMessage(true);
2297 return false;
2300 char* c_count = strtok(NULL, " ");
2301 int count = c_count ? atol(c_count) : 10;
2303 if(count < 0)
2304 return false;
2306 QueryResult *result;
2308 uint32 obj_count = 0;
2309 result=WorldDatabase.PQuery("SELECT COUNT(guid) FROM gameobject WHERE id='%u'",go_id);
2310 if(result)
2312 obj_count = (*result)[0].GetUInt32();
2313 delete result;
2316 if(m_session)
2318 Player* pl = m_session->GetPlayer();
2319 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",
2320 pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),go_id,uint32(count));
2322 else
2323 result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map FROM gameobject WHERE id = '%u' LIMIT %u",
2324 go_id,uint32(count));
2326 if (result)
2330 Field *fields = result->Fetch();
2331 uint32 guid = fields[0].GetUInt32();
2332 float x = fields[1].GetFloat();
2333 float y = fields[2].GetFloat();
2334 float z = fields[3].GetFloat();
2335 int mapid = fields[4].GetUInt16();
2337 if (m_session)
2338 PSendSysMessage(LANG_GO_LIST_CHAT, guid, guid, gInfo->name, x, y, z, mapid);
2339 else
2340 PSendSysMessage(LANG_GO_LIST_CONSOLE, guid, gInfo->name, x, y, z, mapid);
2341 } while (result->NextRow());
2343 delete result;
2346 PSendSysMessage(LANG_COMMAND_LISTOBJMESSAGE,go_id,obj_count);
2347 return true;
2350 bool ChatHandler::HandleNearObjectCommand(const char* args)
2352 float distance = (!*args) ? 10 : atol(args);
2353 uint32 count = 0;
2355 Player* pl = m_session->GetPlayer();
2356 QueryResult *result = WorldDatabase.PQuery("SELECT guid, id, position_x, position_y, position_z, map, "
2357 "(POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ "
2358 "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_",
2359 pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),
2360 pl->GetMapId(),pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),distance*distance);
2362 if (result)
2366 Field *fields = result->Fetch();
2367 uint32 guid = fields[0].GetUInt32();
2368 uint32 entry = fields[1].GetUInt32();
2369 float x = fields[2].GetFloat();
2370 float y = fields[3].GetFloat();
2371 float z = fields[4].GetFloat();
2372 int mapid = fields[5].GetUInt16();
2374 GameObjectInfo const * gInfo = objmgr.GetGameObjectInfo(entry);
2376 if(!gInfo)
2377 continue;
2379 PSendSysMessage(LANG_GO_LIST_CHAT, guid, guid, gInfo->name, x, y, z, mapid);
2381 ++count;
2382 } while (result->NextRow());
2384 delete result;
2387 PSendSysMessage(LANG_COMMAND_NEAROBJMESSAGE,distance,count);
2388 return true;
2391 bool ChatHandler::HandleListCreatureCommand(const char* args)
2393 if(!*args)
2394 return false;
2396 // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
2397 char* cId = extractKeyFromLink((char*)args,"Hcreature_entry");
2398 if(!cId)
2399 return false;
2401 uint32 cr_id = atol(cId);
2402 if(!cr_id)
2404 PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id);
2405 SetSentErrorMessage(true);
2406 return false;
2409 CreatureInfo const* cInfo = objmgr.GetCreatureTemplate(cr_id);
2410 if(!cInfo)
2412 PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id);
2413 SetSentErrorMessage(true);
2414 return false;
2417 char* c_count = strtok(NULL, " ");
2418 int count = c_count ? atol(c_count) : 10;
2420 if(count < 0)
2421 return false;
2423 QueryResult *result;
2425 uint32 cr_count = 0;
2426 result=WorldDatabase.PQuery("SELECT COUNT(guid) FROM creature WHERE id='%u'",cr_id);
2427 if(result)
2429 cr_count = (*result)[0].GetUInt32();
2430 delete result;
2433 if(m_session)
2435 Player* pl = m_session->GetPlayer();
2436 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",
2437 pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), cr_id,uint32(count));
2439 else
2440 result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map FROM creature WHERE id = '%u' LIMIT %u",
2441 cr_id,uint32(count));
2443 if (result)
2447 Field *fields = result->Fetch();
2448 uint32 guid = fields[0].GetUInt32();
2449 float x = fields[1].GetFloat();
2450 float y = fields[2].GetFloat();
2451 float z = fields[3].GetFloat();
2452 int mapid = fields[4].GetUInt16();
2454 if (m_session)
2455 PSendSysMessage(LANG_CREATURE_LIST_CHAT, guid, guid, cInfo->Name, x, y, z, mapid);
2456 else
2457 PSendSysMessage(LANG_CREATURE_LIST_CONSOLE, guid, cInfo->Name, x, y, z, mapid);
2458 } while (result->NextRow());
2460 delete result;
2463 PSendSysMessage(LANG_COMMAND_LISTCREATUREMESSAGE,cr_id,cr_count);
2464 return true;
2467 bool ChatHandler::HandleLookupItemCommand(const char* args)
2469 if(!*args)
2470 return false;
2472 std::string namepart = args;
2473 std::wstring wnamepart;
2475 // converting string that we try to find to lower case
2476 if(!Utf8toWStr(namepart,wnamepart))
2477 return false;
2479 wstrToLower(wnamepart);
2481 uint32 counter = 0;
2483 // Search in `item_template`
2484 for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
2486 ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype >(id);
2487 if(!pProto)
2488 continue;
2490 int loc_idx = m_session ? m_session->GetSessionDbLocaleIndex() : objmgr.GetDBCLocaleIndex();
2491 if ( loc_idx >= 0 )
2493 ItemLocale const *il = objmgr.GetItemLocale(pProto->ItemId);
2494 if (il)
2496 if (il->Name.size() > loc_idx && !il->Name[loc_idx].empty())
2498 std::string name = il->Name[loc_idx];
2500 if (Utf8FitTo(name, wnamepart))
2502 if (m_session)
2503 PSendSysMessage(LANG_ITEM_LIST_CHAT, id, id, name.c_str());
2504 else
2505 PSendSysMessage(LANG_ITEM_LIST_CONSOLE, id, name.c_str());
2506 ++counter;
2507 continue;
2513 std::string name = pProto->Name1;
2514 if(name.empty())
2515 continue;
2517 if (Utf8FitTo(name, wnamepart))
2519 if (m_session)
2520 PSendSysMessage(LANG_ITEM_LIST_CHAT, id, id, name.c_str());
2521 else
2522 PSendSysMessage(LANG_ITEM_LIST_CONSOLE, id, name.c_str());
2523 ++counter;
2527 if (counter==0)
2528 SendSysMessage(LANG_COMMAND_NOITEMFOUND);
2530 return true;
2533 bool ChatHandler::HandleLookupItemSetCommand(const char* args)
2535 if(!*args)
2536 return false;
2538 std::string namepart = args;
2539 std::wstring wnamepart;
2541 if(!Utf8toWStr(namepart,wnamepart))
2542 return false;
2544 // converting string that we try to find to lower case
2545 wstrToLower( wnamepart );
2547 uint32 counter = 0; // Counter for figure out that we found smth.
2549 // Search in ItemSet.dbc
2550 for (uint32 id = 0; id < sItemSetStore.GetNumRows(); id++)
2552 ItemSetEntry const *set = sItemSetStore.LookupEntry(id);
2553 if(set)
2555 int loc = m_session ? m_session->GetSessionDbcLocale() : sWorld.GetDefaultDbcLocale();
2556 std::string name = set->name[loc];
2557 if(name.empty())
2558 continue;
2560 if (!Utf8FitTo(name, wnamepart))
2562 loc = 0;
2563 for(; loc < MAX_LOCALE; ++loc)
2565 if(m_session && loc==m_session->GetSessionDbcLocale())
2566 continue;
2568 name = set->name[loc];
2569 if(name.empty())
2570 continue;
2572 if (Utf8FitTo(name, wnamepart))
2573 break;
2577 if(loc < MAX_LOCALE)
2579 // send item set in "id - [namedlink locale]" format
2580 if (m_session)
2581 PSendSysMessage(LANG_ITEMSET_LIST_CHAT,id,id,name.c_str(),localeNames[loc]);
2582 else
2583 PSendSysMessage(LANG_ITEMSET_LIST_CONSOLE,id,name.c_str(),localeNames[loc]);
2584 ++counter;
2588 if (counter == 0) // if counter == 0 then we found nth
2589 SendSysMessage(LANG_COMMAND_NOITEMSETFOUND);
2590 return true;
2593 bool ChatHandler::HandleLookupSkillCommand(const char* args)
2595 if(!*args)
2596 return false;
2598 // can be NULL in console call
2599 Player* target = getSelectedPlayer();
2601 std::string namepart = args;
2602 std::wstring wnamepart;
2604 if(!Utf8toWStr(namepart,wnamepart))
2605 return false;
2607 // converting string that we try to find to lower case
2608 wstrToLower( wnamepart );
2610 uint32 counter = 0; // Counter for figure out that we found smth.
2612 // Search in SkillLine.dbc
2613 for (uint32 id = 0; id < sSkillLineStore.GetNumRows(); id++)
2615 SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(id);
2616 if(skillInfo)
2618 int loc = m_session ? m_session->GetSessionDbcLocale() : sWorld.GetDefaultDbcLocale();
2619 std::string name = skillInfo->name[loc];
2620 if(name.empty())
2621 continue;
2623 if (!Utf8FitTo(name, wnamepart))
2625 loc = 0;
2626 for(; loc < MAX_LOCALE; ++loc)
2628 if(m_session && loc==m_session->GetSessionDbcLocale())
2629 continue;
2631 name = skillInfo->name[loc];
2632 if(name.empty())
2633 continue;
2635 if (Utf8FitTo(name, wnamepart))
2636 break;
2640 if(loc < MAX_LOCALE)
2642 char const* knownStr = "";
2643 if(target && target->HasSkill(id))
2644 knownStr = GetMangosString(LANG_KNOWN);
2646 // send skill in "id - [namedlink locale]" format
2647 if (m_session)
2648 PSendSysMessage(LANG_SKILL_LIST_CHAT,id,id,name.c_str(),localeNames[loc],knownStr);
2649 else
2650 PSendSysMessage(LANG_SKILL_LIST_CONSOLE,id,name.c_str(),localeNames[loc],knownStr);
2652 ++counter;
2656 if (counter == 0) // if counter == 0 then we found nth
2657 SendSysMessage(LANG_COMMAND_NOSKILLFOUND);
2658 return true;
2661 bool ChatHandler::HandleLookupSpellCommand(const char* args)
2663 if(!*args)
2664 return false;
2666 // can be NULL at console call
2667 Player* target = getSelectedPlayer();
2669 std::string namepart = args;
2670 std::wstring wnamepart;
2672 if(!Utf8toWStr(namepart,wnamepart))
2673 return false;
2675 // converting string that we try to find to lower case
2676 wstrToLower( wnamepart );
2678 uint32 counter = 0; // Counter for figure out that we found smth.
2680 // Search in Spell.dbc
2681 for (uint32 id = 0; id < sSpellStore.GetNumRows(); id++)
2683 SpellEntry const *spellInfo = sSpellStore.LookupEntry(id);
2684 if(spellInfo)
2686 int loc = m_session ? m_session->GetSessionDbcLocale() : sWorld.GetDefaultDbcLocale();
2687 std::string name = spellInfo->SpellName[loc];
2688 if(name.empty())
2689 continue;
2691 if (!Utf8FitTo(name, wnamepart))
2693 loc = 0;
2694 for(; loc < MAX_LOCALE; ++loc)
2696 if(m_session && loc==m_session->GetSessionDbcLocale())
2697 continue;
2699 name = spellInfo->SpellName[loc];
2700 if(name.empty())
2701 continue;
2703 if (Utf8FitTo(name, wnamepart))
2704 break;
2708 if(loc < MAX_LOCALE)
2710 bool known = target && target->HasSpell(id);
2711 bool learn = (spellInfo->Effect[0] == SPELL_EFFECT_LEARN_SPELL);
2713 uint32 talentCost = GetTalentSpellCost(id);
2715 bool talent = (talentCost > 0);
2716 bool passive = IsPassiveSpell(id);
2717 bool active = target && (target->HasAura(id,0) || target->HasAura(id,1) || target->HasAura(id,2));
2719 // unit32 used to prevent interpreting uint8 as char at output
2720 // find rank of learned spell for learning spell, or talent rank
2721 uint32 rank = talentCost ? talentCost : spellmgr.GetSpellRank(learn ? spellInfo->EffectTriggerSpell[0] : id);
2723 // send spell in "id - [name, rank N] [talent] [passive] [learn] [known]" format
2724 std::ostringstream ss;
2725 if (m_session)
2726 ss << id << " - |cffffffff|Hspell:" << id << "|h[" << name;
2727 else
2728 ss << id << " - " << name;
2730 // include rank in link name
2731 if(rank)
2732 ss << GetMangosString(LANG_SPELL_RANK) << rank;
2734 if (m_session)
2735 ss << " " << localeNames[loc] << "]|h|r";
2736 else
2737 ss << " " << localeNames[loc];
2739 if(talent)
2740 ss << GetMangosString(LANG_TALENT);
2741 if(passive)
2742 ss << GetMangosString(LANG_PASSIVE);
2743 if(learn)
2744 ss << GetMangosString(LANG_LEARN);
2745 if(known)
2746 ss << GetMangosString(LANG_KNOWN);
2747 if(active)
2748 ss << GetMangosString(LANG_ACTIVE);
2750 SendSysMessage(ss.str().c_str());
2752 ++counter;
2756 if (counter == 0) // if counter == 0 then we found nth
2757 SendSysMessage(LANG_COMMAND_NOSPELLFOUND);
2758 return true;
2761 bool ChatHandler::HandleLookupQuestCommand(const char* args)
2763 if(!*args)
2764 return false;
2766 // can be NULL at console call
2767 Player* target = getSelectedPlayer();
2769 std::string namepart = args;
2770 std::wstring wnamepart;
2772 // converting string that we try to find to lower case
2773 if(!Utf8toWStr(namepart,wnamepart))
2774 return false;
2776 wstrToLower(wnamepart);
2778 uint32 counter = 0 ;
2780 ObjectMgr::QuestMap const& qTemplates = objmgr.GetQuestTemplates();
2781 for (ObjectMgr::QuestMap::const_iterator iter = qTemplates.begin(); iter != qTemplates.end(); ++iter)
2783 Quest * qinfo = iter->second;
2785 int loc_idx = m_session ? m_session->GetSessionDbLocaleIndex() : objmgr.GetDBCLocaleIndex();
2786 if ( loc_idx >= 0 )
2788 QuestLocale const *il = objmgr.GetQuestLocale(qinfo->GetQuestId());
2789 if (il)
2791 if (il->Title.size() > loc_idx && !il->Title[loc_idx].empty())
2793 std::string title = il->Title[loc_idx];
2795 if (Utf8FitTo(title, wnamepart))
2797 char const* statusStr = "";
2799 if(target)
2801 QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId());
2803 if(status == QUEST_STATUS_COMPLETE)
2805 if(target->GetQuestRewardStatus(qinfo->GetQuestId()))
2806 statusStr = GetMangosString(LANG_COMMAND_QUEST_REWARDED);
2807 else
2808 statusStr = GetMangosString(LANG_COMMAND_QUEST_COMPLETE);
2810 else if(status == QUEST_STATUS_INCOMPLETE)
2811 statusStr = GetMangosString(LANG_COMMAND_QUEST_ACTIVE);
2814 if (m_session)
2815 PSendSysMessage(LANG_QUEST_LIST_CHAT,qinfo->GetQuestId(),qinfo->GetQuestId(),title.c_str(),statusStr);
2816 else
2817 PSendSysMessage(LANG_QUEST_LIST_CONSOLE,qinfo->GetQuestId(),title.c_str(),statusStr);
2818 ++counter;
2819 continue;
2825 std::string title = qinfo->GetTitle();
2826 if(title.empty())
2827 continue;
2829 if (Utf8FitTo(title, wnamepart))
2831 char const* statusStr = "";
2833 if(target)
2835 QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId());
2837 if(status == QUEST_STATUS_COMPLETE)
2839 if(target->GetQuestRewardStatus(qinfo->GetQuestId()))
2840 statusStr = GetMangosString(LANG_COMMAND_QUEST_REWARDED);
2841 else
2842 statusStr = GetMangosString(LANG_COMMAND_QUEST_COMPLETE);
2844 else if(status == QUEST_STATUS_INCOMPLETE)
2845 statusStr = GetMangosString(LANG_COMMAND_QUEST_ACTIVE);
2848 if (m_session)
2849 PSendSysMessage(LANG_QUEST_LIST_CHAT,qinfo->GetQuestId(),qinfo->GetQuestId(),title.c_str(),statusStr);
2850 else
2851 PSendSysMessage(LANG_QUEST_LIST_CONSOLE,qinfo->GetQuestId(),title.c_str(),statusStr);
2853 ++counter;
2857 if (counter==0)
2858 SendSysMessage(LANG_COMMAND_NOQUESTFOUND);
2860 return true;
2863 bool ChatHandler::HandleLookupCreatureCommand(const char* args)
2865 if (!*args)
2866 return false;
2868 std::string namepart = args;
2869 std::wstring wnamepart;
2871 // converting string that we try to find to lower case
2872 if (!Utf8toWStr (namepart,wnamepart))
2873 return false;
2875 wstrToLower (wnamepart);
2877 uint32 counter = 0;
2879 for (uint32 id = 0; id< sCreatureStorage.MaxEntry; ++id)
2881 CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo> (id);
2882 if(!cInfo)
2883 continue;
2885 int loc_idx = m_session ? m_session->GetSessionDbLocaleIndex() : objmgr.GetDBCLocaleIndex();
2886 if (loc_idx >= 0)
2888 CreatureLocale const *cl = objmgr.GetCreatureLocale (id);
2889 if (cl)
2891 if (cl->Name.size() > loc_idx && !cl->Name[loc_idx].empty ())
2893 std::string name = cl->Name[loc_idx];
2895 if (Utf8FitTo (name, wnamepart))
2897 if (m_session)
2898 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CHAT, id, id, name.c_str ());
2899 else
2900 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CONSOLE, id, name.c_str ());
2901 ++counter;
2902 continue;
2908 std::string name = cInfo->Name;
2909 if (name.empty ())
2910 continue;
2912 if (Utf8FitTo(name, wnamepart))
2914 if (m_session)
2915 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CHAT, id, id, name.c_str ());
2916 else
2917 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CONSOLE, id, name.c_str ());
2918 ++counter;
2922 if (counter==0)
2923 SendSysMessage (LANG_COMMAND_NOCREATUREFOUND);
2925 return true;
2928 bool ChatHandler::HandleLookupObjectCommand(const char* args)
2930 if(!*args)
2931 return false;
2933 std::string namepart = args;
2934 std::wstring wnamepart;
2936 // converting string that we try to find to lower case
2937 if(!Utf8toWStr(namepart,wnamepart))
2938 return false;
2940 wstrToLower(wnamepart);
2942 uint32 counter = 0;
2944 for (uint32 id = 0; id< sGOStorage.MaxEntry; id++ )
2946 GameObjectInfo const* gInfo = sGOStorage.LookupEntry<GameObjectInfo>(id);
2947 if(!gInfo)
2948 continue;
2950 int loc_idx = m_session ? m_session->GetSessionDbLocaleIndex() : objmgr.GetDBCLocaleIndex();
2951 if ( loc_idx >= 0 )
2953 GameObjectLocale const *gl = objmgr.GetGameObjectLocale(id);
2954 if (gl)
2956 if (gl->Name.size() > loc_idx && !gl->Name[loc_idx].empty())
2958 std::string name = gl->Name[loc_idx];
2960 if (Utf8FitTo(name, wnamepart))
2962 if (m_session)
2963 PSendSysMessage(LANG_GO_ENTRY_LIST_CHAT, id, id, name.c_str());
2964 else
2965 PSendSysMessage(LANG_GO_ENTRY_LIST_CONSOLE, id, name.c_str());
2966 ++counter;
2967 continue;
2973 std::string name = gInfo->name;
2974 if(name.empty())
2975 continue;
2977 if(Utf8FitTo(name, wnamepart))
2979 if (m_session)
2980 PSendSysMessage(LANG_GO_ENTRY_LIST_CHAT, id, id, name.c_str());
2981 else
2982 PSendSysMessage(LANG_GO_ENTRY_LIST_CONSOLE, id, name.c_str());
2983 ++counter;
2987 if(counter==0)
2988 SendSysMessage(LANG_COMMAND_NOGAMEOBJECTFOUND);
2990 return true;
2993 /** \brief GM command level 3 - Create a guild.
2995 * This command allows a GM (level 3) to create a guild.
2997 * The "args" parameter contains the name of the guild leader
2998 * and then the name of the guild.
3001 bool ChatHandler::HandleGuildCreateCommand(const char* args)
3004 if (!*args)
3005 return false;
3007 char *lname = strtok ((char*)args, " ");
3008 char *gname = strtok (NULL, "");
3010 if (!lname)
3011 return false;
3013 if (!gname)
3015 SendSysMessage (LANG_INSERT_GUILD_NAME);
3016 SetSentErrorMessage (true);
3017 return false;
3020 std::string guildname = gname;
3022 Player* player = ObjectAccessor::Instance ().FindPlayerByName (lname);
3023 if (!player)
3025 SendSysMessage (LANG_PLAYER_NOT_FOUND);
3026 SetSentErrorMessage (true);
3027 return false;
3030 if (player->GetGuildId())
3032 SendSysMessage (LANG_PLAYER_IN_GUILD);
3033 return true;
3036 Guild *guild = new Guild;
3037 if (!guild->create (player->GetGUID (),guildname))
3039 delete guild;
3040 SendSysMessage (LANG_GUILD_NOT_CREATED);
3041 SetSentErrorMessage (true);
3042 return false;
3045 objmgr.AddGuild (guild);
3046 return true;
3049 bool ChatHandler::HandleGuildInviteCommand(const char *args)
3051 if (!*args)
3052 return false;
3054 char* par1 = strtok ((char*)args, " ");
3055 char* par2 = strtok (NULL, "");
3056 if(!par1 || !par2)
3057 return false;
3059 std::string glName = par2;
3060 Guild* targetGuild = objmgr.GetGuildByName (glName);
3061 if (!targetGuild)
3062 return false;
3064 std::string plName = par1;
3065 if (!normalizePlayerName (plName))
3067 SendSysMessage (LANG_PLAYER_NOT_FOUND);
3068 SetSentErrorMessage (true);
3069 return false;
3072 uint64 plGuid = 0;
3073 if (Player* targetPlayer = ObjectAccessor::Instance ().FindPlayerByName (plName.c_str ()))
3074 plGuid = targetPlayer->GetGUID ();
3075 else
3076 plGuid = objmgr.GetPlayerGUIDByName (plName.c_str ());
3078 if (!plGuid)
3079 false;
3081 // player's guild membership checked in AddMember before add
3082 if (!targetGuild->AddMember (plGuid,targetGuild->GetLowestRank ()))
3083 return false;
3085 return true;
3088 bool ChatHandler::HandleGuildUninviteCommand(const char *args)
3090 if (!*args)
3091 return false;
3093 char* par1 = strtok ((char*)args, " ");
3094 if(!par1)
3095 return false;
3097 std::string plName = par1;
3098 if (!normalizePlayerName (plName))
3100 SendSysMessage (LANG_PLAYER_NOT_FOUND);
3101 SetSentErrorMessage (true);
3102 return false;
3105 uint64 plGuid = 0;
3106 uint32 glId = 0;
3107 if (Player* targetPlayer = ObjectAccessor::Instance ().FindPlayerByName (plName.c_str ()))
3109 plGuid = targetPlayer->GetGUID ();
3110 glId = targetPlayer->GetGuildId ();
3112 else
3114 plGuid = objmgr.GetPlayerGUIDByName (plName.c_str ());
3115 glId = Player::GetGuildIdFromDB (plGuid);
3118 if (!plGuid || !glId)
3119 return false;
3121 Guild* targetGuild = objmgr.GetGuildById (glId);
3122 if (!targetGuild)
3123 return false;
3125 targetGuild->DelMember (plGuid);
3127 return true;
3130 bool ChatHandler::HandleGuildRankCommand(const char *args)
3132 if (!*args)
3133 return false;
3135 char* par1 = strtok ((char*)args, " ");
3136 char* par2 = strtok (NULL, " ");
3137 if (!par1 || !par2)
3138 return false;
3139 std::string plName = par1;
3140 if (!normalizePlayerName (plName))
3142 SendSysMessage (LANG_PLAYER_NOT_FOUND);
3143 SetSentErrorMessage (true);
3144 return false;
3147 uint64 plGuid = 0;
3148 uint32 glId = 0;
3149 if (Player* targetPlayer = ObjectAccessor::Instance ().FindPlayerByName (plName.c_str ()))
3151 plGuid = targetPlayer->GetGUID ();
3152 glId = targetPlayer->GetGuildId ();
3154 else
3156 plGuid = objmgr.GetPlayerGUIDByName (plName.c_str ());
3157 glId = Player::GetGuildIdFromDB (plGuid);
3160 if (!plGuid || !glId)
3161 return false;
3163 Guild* targetGuild = objmgr.GetGuildById (glId);
3164 if (!targetGuild)
3165 return false;
3167 uint32 newrank = uint32 (atoi (par2));
3168 if (newrank > targetGuild->GetLowestRank ())
3169 return false;
3171 targetGuild->ChangeRank (plGuid,newrank);
3173 return true;
3176 bool ChatHandler::HandleGuildDeleteCommand(const char* args)
3178 if (!*args)
3179 return false;
3181 char* par1 = strtok ((char*)args, " ");
3182 if (!par1)
3183 return false;
3185 std::string gld = par1;
3187 Guild* targetGuild = objmgr.GetGuildByName (gld);
3188 if (!targetGuild)
3189 return false;
3191 targetGuild->Disband ();
3193 return true;
3196 bool ChatHandler::HandleGetDistanceCommand(const char* /*args*/)
3198 Unit* pUnit = getSelectedUnit();
3200 if(!pUnit)
3202 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3203 SetSentErrorMessage(true);
3204 return false;
3207 PSendSysMessage(LANG_DISTANCE, m_session->GetPlayer()->GetDistance(pUnit),m_session->GetPlayer()->GetDistance2d(pUnit));
3209 return true;
3212 // FIX-ME!!!
3214 bool ChatHandler::HandleAddWeaponCommand(const char* /*args*/)
3216 /*if (!*args)
3217 return false;
3219 uint64 guid = m_session->GetPlayer()->GetSelection();
3220 if (guid == 0)
3222 SendSysMessage(LANG_NO_SELECTION);
3223 return true;
3226 Creature *pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
3228 if(!pCreature)
3230 SendSysMessage(LANG_SELECT_CREATURE);
3231 return true;
3234 char* pSlotID = strtok((char*)args, " ");
3235 if (!pSlotID)
3236 return false;
3238 char* pItemID = strtok(NULL, " ");
3239 if (!pItemID)
3240 return false;
3242 uint32 ItemID = atoi(pItemID);
3243 uint32 SlotID = atoi(pSlotID);
3245 ItemPrototype* tmpItem = objmgr.GetItemPrototype(ItemID);
3247 bool added = false;
3248 if(tmpItem)
3250 switch(SlotID)
3252 case 1:
3253 pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, ItemID);
3254 added = true;
3255 break;
3256 case 2:
3257 pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_01, ItemID);
3258 added = true;
3259 break;
3260 case 3:
3261 pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_02, ItemID);
3262 added = true;
3263 break;
3264 default:
3265 PSendSysMessage(LANG_ITEM_SLOT_NOT_EXIST,SlotID);
3266 added = false;
3267 break;
3269 if(added)
3271 PSendSysMessage(LANG_ITEM_ADDED_TO_SLOT,ItemID,tmpItem->Name1,SlotID);
3274 else
3276 PSendSysMessage(LANG_ITEM_NOT_FOUND,ItemID);
3277 return true;
3280 return true;
3283 bool ChatHandler::HandleDieCommand(const char* /*args*/)
3285 Unit* target = getSelectedUnit();
3287 if(!target || !m_session->GetPlayer()->GetSelection())
3289 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3290 SetSentErrorMessage(true);
3291 return false;
3294 if( target->isAlive() )
3296 m_session->GetPlayer()->DealDamage(target, target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
3299 return true;
3302 bool ChatHandler::HandleDamageCommand(const char * args)
3304 if (!*args)
3305 return false;
3307 Unit* target = getSelectedUnit();
3309 if(!target || !m_session->GetPlayer()->GetSelection())
3311 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3312 SetSentErrorMessage(true);
3313 return false;
3316 if( !target->isAlive() )
3317 return true;
3319 char* damageStr = strtok((char*)args, " ");
3320 if(!damageStr)
3321 return false;
3323 int32 damage = atoi((char*)damageStr);
3324 if(damage <=0)
3325 return true;
3327 char* schoolStr = strtok((char*)NULL, " ");
3329 // flat melee damage without resistence/etc reduction
3330 if(!schoolStr)
3332 m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
3333 m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, SPELL_SCHOOL_MASK_NORMAL, damage, 0, 0, VICTIMSTATE_NORMAL, 0);
3334 return true;
3337 uint32 school = schoolStr ? atoi((char*)schoolStr) : SPELL_SCHOOL_NORMAL;
3338 if(school >= MAX_SPELL_SCHOOL)
3339 return false;
3341 SpellSchoolMask schoolmask = SpellSchoolMask(1 << school);
3343 if ( schoolmask & SPELL_SCHOOL_MASK_NORMAL )
3344 damage = m_session->GetPlayer()->CalcArmorReducedDamage(target, damage);
3346 char* spellStr = strtok((char*)NULL, " ");
3348 // melee damage by specific school
3349 if(!spellStr)
3351 uint32 absorb = 0;
3352 uint32 resist = 0;
3354 m_session->GetPlayer()->CalcAbsorbResist(target,schoolmask, SPELL_DIRECT_DAMAGE, damage, &absorb, &resist);
3356 if (damage <= absorb + resist)
3357 return true;
3359 damage -= absorb + resist;
3361 m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, schoolmask, NULL, false);
3362 m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, schoolmask, damage, absorb, resist, VICTIMSTATE_NORMAL, 0);
3363 return true;
3366 // non-melee damage
3368 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
3369 uint32 spellid = extractSpellIdFromLink((char*)args);
3370 if(!spellid || !sSpellStore.LookupEntry(spellid))
3371 return false;
3373 m_session->GetPlayer()->SpellNonMeleeDamageLog(target, spellid, damage, false);
3374 return true;
3377 bool ChatHandler::HandleModifyArenaCommand(const char * args)
3379 if (!*args)
3380 return false;
3382 Player *target = getSelectedPlayer();
3383 if(!target)
3385 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3386 SetSentErrorMessage(true);
3387 return false;
3390 int32 amount = (uint32)atoi(args);
3392 target->ModifyArenaPoints(amount);
3394 PSendSysMessage(LANG_COMMAND_MODIFY_ARENA, target->GetName(), target->GetArenaPoints());
3396 return true;
3399 bool ChatHandler::HandleReviveCommand(const char* args)
3401 Player* SelectedPlayer = NULL;
3403 if (*args)
3405 std::string name = args;
3406 if(!normalizePlayerName(name))
3408 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3409 SetSentErrorMessage(true);
3410 return false;
3413 SelectedPlayer = objmgr.GetPlayer(name.c_str());
3415 else
3416 SelectedPlayer = getSelectedPlayer();
3418 if(!SelectedPlayer)
3420 SendSysMessage(LANG_NO_CHAR_SELECTED);
3421 SetSentErrorMessage(true);
3422 return false;
3425 SelectedPlayer->ResurrectPlayer(0.5f);
3426 SelectedPlayer->SpawnCorpseBones();
3427 SelectedPlayer->SaveToDB();
3428 return true;
3431 bool ChatHandler::HandleAuraCommand(const char* args)
3433 char* px = strtok((char*)args, " ");
3434 if (!px)
3435 return false;
3437 Unit *target = getSelectedUnit();
3438 if(!target)
3440 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3441 SetSentErrorMessage(true);
3442 return false;
3445 uint32 spellID = (uint32)atoi(px);
3446 SpellEntry const *spellInfo = sSpellStore.LookupEntry( spellID );
3447 if(spellInfo)
3449 for(uint32 i = 0;i<3;i++)
3451 uint8 eff = spellInfo->Effect[i];
3452 if (eff>=TOTAL_SPELL_EFFECTS)
3453 continue;
3454 if( IsAreaAuraEffect(eff) ||
3455 eff == SPELL_EFFECT_APPLY_AURA ||
3456 eff == SPELL_EFFECT_PERSISTENT_AREA_AURA )
3458 Aura *Aur = CreateAura(spellInfo, i, NULL, target);
3459 target->AddAura(Aur);
3464 return true;
3467 bool ChatHandler::HandleUnAuraCommand(const char* args)
3469 char* px = strtok((char*)args, " ");
3470 if (!px)
3471 return false;
3473 Unit *target = getSelectedUnit();
3474 if(!target)
3476 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3477 SetSentErrorMessage(true);
3478 return false;
3481 std::string argstr = args;
3482 if (argstr == "all")
3484 target->RemoveAllAuras();
3485 return true;
3488 uint32 spellID = (uint32)atoi(px);
3489 target->RemoveAurasDueToSpell(spellID);
3491 return true;
3494 bool ChatHandler::HandleLinkGraveCommand(const char* args)
3496 if(!*args)
3497 return false;
3499 char* px = strtok((char*)args, " ");
3500 if (!px)
3501 return false;
3503 uint32 g_id = (uint32)atoi(px);
3505 uint32 g_team;
3507 char* px2 = strtok(NULL, " ");
3509 if (!px2)
3510 g_team = 0;
3511 else if (strncmp(px2,"horde",6)==0)
3512 g_team = HORDE;
3513 else if (strncmp(px2,"alliance",9)==0)
3514 g_team = ALLIANCE;
3515 else
3516 return false;
3518 WorldSafeLocsEntry const* graveyard = sWorldSafeLocsStore.LookupEntry(g_id);
3520 if(!graveyard )
3522 PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST, g_id);
3523 SetSentErrorMessage(true);
3524 return false;
3527 Player* player = m_session->GetPlayer();
3529 uint32 zoneId = player->GetZoneId();
3531 AreaTableEntry const *areaEntry = GetAreaEntryByAreaID(zoneId);
3532 if(!areaEntry || areaEntry->zone !=0 )
3534 PSendSysMessage(LANG_COMMAND_GRAVEYARDWRONGZONE, g_id,zoneId);
3535 SetSentErrorMessage(true);
3536 return false;
3539 if(objmgr.AddGraveYardLink(g_id,player->GetZoneId(),g_team))
3540 PSendSysMessage(LANG_COMMAND_GRAVEYARDLINKED, g_id,zoneId);
3541 else
3542 PSendSysMessage(LANG_COMMAND_GRAVEYARDALRLINKED, g_id,zoneId);
3544 return true;
3547 bool ChatHandler::HandleNearGraveCommand(const char* args)
3549 uint32 g_team;
3551 size_t argslen = strlen(args);
3553 if(!*args)
3554 g_team = 0;
3555 else if (strncmp((char*)args,"horde",argslen)==0)
3556 g_team = HORDE;
3557 else if (strncmp((char*)args,"alliance",argslen)==0)
3558 g_team = ALLIANCE;
3559 else
3560 return false;
3562 Player* player = m_session->GetPlayer();
3564 WorldSafeLocsEntry const* graveyard = objmgr.GetClosestGraveYard(
3565 player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(),player->GetMapId(),g_team);
3567 if(graveyard)
3569 uint32 g_id = graveyard->ID;
3571 GraveYardData const* data = objmgr.FindGraveYardData(g_id,player->GetZoneId());
3572 if (!data)
3574 PSendSysMessage(LANG_COMMAND_GRAVEYARDERROR,g_id);
3575 SetSentErrorMessage(true);
3576 return false;
3579 g_team = data->team;
3581 std::string team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_NOTEAM);
3583 if(g_team == 0)
3584 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ANY);
3585 else if(g_team == HORDE)
3586 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_HORDE);
3587 else if(g_team == ALLIANCE)
3588 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ALLIANCE);
3590 PSendSysMessage(LANG_COMMAND_GRAVEYARDNEAREST, g_id,team_name.c_str(),player->GetZoneId());
3592 else
3594 std::string team_name;
3596 if(g_team == 0)
3597 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ANY);
3598 else if(g_team == HORDE)
3599 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_HORDE);
3600 else if(g_team == ALLIANCE)
3601 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ALLIANCE);
3603 if(g_team == ~uint32(0))
3604 PSendSysMessage(LANG_COMMAND_ZONENOGRAVEYARDS, player->GetZoneId());
3605 else
3606 PSendSysMessage(LANG_COMMAND_ZONENOGRAFACTION, player->GetZoneId(),team_name.c_str());
3609 return true;
3612 //play npc emote
3613 bool ChatHandler::HandleNpcPlayEmoteCommand(const char* args)
3615 uint32 emote = atoi((char*)args);
3617 Creature* target = getSelectedCreature();
3618 if(!target)
3620 SendSysMessage(LANG_SELECT_CREATURE);
3621 SetSentErrorMessage(true);
3622 return false;
3625 target->SetUInt32Value(UNIT_NPC_EMOTESTATE,emote);
3627 return true;
3630 bool ChatHandler::HandleNpcInfoCommand(const char* /*args*/)
3632 Creature* target = getSelectedCreature();
3634 if(!target)
3636 SendSysMessage(LANG_SELECT_CREATURE);
3637 SetSentErrorMessage(true);
3638 return false;
3641 uint32 faction = target->getFaction();
3642 uint32 npcflags = target->GetUInt32Value(UNIT_NPC_FLAGS);
3643 uint32 displayid = target->GetDisplayId();
3644 uint32 nativeid = target->GetNativeDisplayId();
3645 uint32 Entry = target->GetEntry();
3646 CreatureInfo const* cInfo = target->GetCreatureInfo();
3648 int32 curRespawnDelay = target->GetRespawnTimeEx()-time(NULL);
3649 if(curRespawnDelay < 0)
3650 curRespawnDelay = 0;
3651 std::string curRespawnDelayStr = secsToTimeString(curRespawnDelay,true);
3652 std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(),true);
3654 PSendSysMessage(LANG_NPCINFO_CHAR, target->GetDBTableGUIDLow(), faction, npcflags, Entry, displayid, nativeid);
3655 PSendSysMessage(LANG_NPCINFO_LEVEL, target->getLevel());
3656 PSendSysMessage(LANG_NPCINFO_HEALTH,target->GetCreateHealth(), target->GetMaxHealth(), target->GetHealth());
3657 PSendSysMessage(LANG_NPCINFO_FLAGS, target->GetUInt32Value(UNIT_FIELD_FLAGS), target->GetUInt32Value(UNIT_DYNAMIC_FLAGS), target->getFaction());
3658 PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES, defRespawnDelayStr.c_str(),curRespawnDelayStr.c_str());
3659 PSendSysMessage(LANG_NPCINFO_LOOT, cInfo->lootid,cInfo->pickpocketLootId,cInfo->SkinLootId);
3660 PSendSysMessage(LANG_NPCINFO_DUNGEON_ID, target->GetInstanceId());
3661 PSendSysMessage(LANG_NPCINFO_POSITION,float(target->GetPositionX()), float(target->GetPositionY()), float(target->GetPositionZ()));
3663 if ((npcflags & UNIT_NPC_FLAG_VENDOR) )
3665 SendSysMessage(LANG_NPCINFO_VENDOR);
3667 if ((npcflags & UNIT_NPC_FLAG_TRAINER) )
3669 SendSysMessage(LANG_NPCINFO_TRAINER);
3672 return true;
3675 bool ChatHandler::HandleExploreCheatCommand(const char* args)
3677 if (!*args)
3678 return false;
3680 int flag = atoi((char*)args);
3682 Player *chr = getSelectedPlayer();
3683 if (chr == NULL)
3685 SendSysMessage(LANG_NO_CHAR_SELECTED);
3686 SetSentErrorMessage(true);
3687 return false;
3690 if (flag != 0)
3692 PSendSysMessage(LANG_YOU_SET_EXPLORE_ALL, chr->GetName());
3693 if (needReportToTarget(chr))
3694 ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_ALL,GetName());
3696 else
3698 PSendSysMessage(LANG_YOU_SET_EXPLORE_NOTHING, chr->GetName());
3699 if (needReportToTarget(chr))
3700 ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_NOTHING,GetName());
3703 for (uint8 i=0; i<128; i++)
3705 if (flag != 0)
3707 m_session->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i,0xFFFFFFFF);
3709 else
3711 m_session->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i,0);
3715 return true;
3718 bool ChatHandler::HandleHoverCommand(const char* args)
3720 char* px = strtok((char*)args, " ");
3721 uint32 flag;
3722 if (!px)
3723 flag = 1;
3724 else
3725 flag = atoi(px);
3727 m_session->GetPlayer()->SetHover(flag);
3729 if (flag)
3730 SendSysMessage(LANG_HOVER_ENABLED);
3731 else
3732 SendSysMessage(LANG_HOVER_DISABLED);
3734 return true;
3737 bool ChatHandler::HandleLevelUpCommand(const char* args)
3739 char* px = strtok((char*)args, " ");
3740 char* py = strtok((char*)NULL, " ");
3742 // command format parsing
3743 char* pname = (char*)NULL;
3744 int addlevel = 1;
3746 if(px && py) // .levelup name level
3748 addlevel = atoi(py);
3749 pname = px;
3751 else if(px && !py) // .levelup name OR .levelup level
3753 if(isalpha(px[0])) // .levelup name
3754 pname = px;
3755 else // .levelup level
3756 addlevel = atoi(px);
3758 // else .levelup - nothing do for preparing
3760 // player
3761 Player *chr = NULL;
3762 uint64 chr_guid = 0;
3764 std::string name;
3766 if(pname) // player by name
3768 name = pname;
3769 if(!normalizePlayerName(name))
3771 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3772 SetSentErrorMessage(true);
3773 return false;
3776 chr = objmgr.GetPlayer(name.c_str());
3777 if(!chr) // not in game
3779 chr_guid = objmgr.GetPlayerGUIDByName(name);
3780 if (chr_guid == 0)
3782 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3783 SetSentErrorMessage(true);
3784 return false;
3788 else // player by selection
3790 chr = getSelectedPlayer();
3792 if (chr == NULL)
3794 SendSysMessage(LANG_NO_CHAR_SELECTED);
3795 SetSentErrorMessage(true);
3796 return false;
3799 name = chr->GetName();
3802 assert(chr || chr_guid);
3804 int32 oldlevel = chr ? chr->getLevel() : Player::GetUInt32ValueFromDB(UNIT_FIELD_LEVEL,chr_guid);
3805 int32 newlevel = oldlevel + addlevel;
3806 if(newlevel < 1)
3807 newlevel = 1;
3808 if(newlevel > 255) // hardcoded maximum level
3809 newlevel = 255;
3811 if(chr)
3813 chr->GiveLevel(newlevel);
3814 chr->InitTalentForLevel();
3815 chr->SetUInt32Value(PLAYER_XP,0);
3817 if(oldlevel == newlevel)
3818 ChatHandler(chr).SendSysMessage(LANG_YOURS_LEVEL_PROGRESS_RESET);
3819 else
3820 if(oldlevel < newlevel)
3821 ChatHandler(chr).PSendSysMessage(LANG_YOURS_LEVEL_UP,newlevel-oldlevel);
3822 else
3823 if(oldlevel > newlevel)
3824 ChatHandler(chr).PSendSysMessage(LANG_YOURS_LEVEL_DOWN,newlevel-oldlevel);
3826 else
3828 // update level and XP at level, all other will be updated at loading
3829 Tokens values;
3830 Player::LoadValuesArrayFromDB(values,chr_guid);
3831 Player::SetUInt32ValueInArray(values,UNIT_FIELD_LEVEL,newlevel);
3832 Player::SetUInt32ValueInArray(values,PLAYER_XP,0);
3833 Player::SaveValuesArrayInDB(values,chr_guid);
3836 if(m_session->GetPlayer() != chr) // including chr==NULL
3837 PSendSysMessage(LANG_YOU_CHANGE_LVL,name.c_str(),newlevel);
3838 return true;
3841 bool ChatHandler::HandleShowAreaCommand(const char* args)
3843 if (!*args)
3844 return false;
3846 int area = atoi((char*)args);
3848 Player *chr = getSelectedPlayer();
3849 if (chr == NULL)
3851 SendSysMessage(LANG_NO_CHAR_SELECTED);
3852 SetSentErrorMessage(true);
3853 return false;
3856 int offset = area / 32;
3857 uint32 val = (uint32)(1 << (area % 32));
3859 if(offset >= 128)
3861 SendSysMessage(LANG_BAD_VALUE);
3862 SetSentErrorMessage(true);
3863 return false;
3866 uint32 currFields = chr->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset);
3867 chr->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields | val));
3869 SendSysMessage(LANG_EXPLORE_AREA);
3870 return true;
3873 bool ChatHandler::HandleHideAreaCommand(const char* args)
3875 if (!*args)
3876 return false;
3878 int area = atoi((char*)args);
3880 Player *chr = getSelectedPlayer();
3881 if (chr == NULL)
3883 SendSysMessage(LANG_NO_CHAR_SELECTED);
3884 SetSentErrorMessage(true);
3885 return false;
3888 int offset = area / 32;
3889 uint32 val = (uint32)(1 << (area % 32));
3891 if(offset >= 128)
3893 SendSysMessage(LANG_BAD_VALUE);
3894 SetSentErrorMessage(true);
3895 return false;
3898 uint32 currFields = chr->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset);
3899 chr->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields ^ val));
3901 SendSysMessage(LANG_UNEXPLORE_AREA);
3902 return true;
3905 bool ChatHandler::HandleUpdate(const char* args)
3907 if(!*args)
3908 return false;
3910 uint32 updateIndex;
3911 uint32 value;
3913 char* pUpdateIndex = strtok((char*)args, " ");
3915 Unit* chr = getSelectedUnit();
3916 if (chr == NULL)
3918 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3919 SetSentErrorMessage(true);
3920 return false;
3923 if(!pUpdateIndex)
3925 return true;
3927 updateIndex = atoi(pUpdateIndex);
3928 //check updateIndex
3929 if(chr->GetTypeId() == TYPEID_PLAYER)
3931 if (updateIndex>=PLAYER_END) return true;
3933 else
3935 if (updateIndex>=UNIT_END) return true;
3938 char* pvalue = strtok(NULL, " ");
3939 if (!pvalue)
3941 value=chr->GetUInt32Value(updateIndex);
3943 PSendSysMessage(LANG_UPDATE, chr->GetGUIDLow(),updateIndex,value);
3944 return true;
3947 value=atoi(pvalue);
3949 PSendSysMessage(LANG_UPDATE_CHANGE, chr->GetGUIDLow(),updateIndex,value);
3951 chr->SetUInt32Value(updateIndex,value);
3953 return true;
3956 bool ChatHandler::HandleBankCommand(const char* /*args*/)
3958 m_session->SendShowBank( m_session->GetPlayer()->GetGUID() );
3960 return true;
3963 bool ChatHandler::HandleChangeWeather(const char* args)
3965 if(!*args)
3966 return false;
3968 //Weather is OFF
3969 if (!sWorld.getConfig(CONFIG_WEATHER))
3971 SendSysMessage(LANG_WEATHER_DISABLED);
3972 SetSentErrorMessage(true);
3973 return false;
3976 //*Change the weather of a cell
3977 char* px = strtok((char*)args, " ");
3978 char* py = strtok(NULL, " ");
3980 if (!px || !py)
3981 return false;
3983 uint32 type = (uint32)atoi(px); //0 to 3, 0: fine, 1: rain, 2: snow, 3: sand
3984 float grade = (float)atof(py); //0 to 1, sending -1 is instand good weather
3986 Player *player = m_session->GetPlayer();
3987 uint32 zoneid = player->GetZoneId();
3989 Weather* wth = sWorld.FindWeather(zoneid);
3991 if(!wth)
3992 wth = sWorld.AddWeather(zoneid);
3993 if(!wth)
3995 SendSysMessage(LANG_NO_WEATHER);
3996 SetSentErrorMessage(true);
3997 return false;
4000 wth->SetWeather(WeatherType(type), grade);
4002 return true;
4005 bool ChatHandler::HandleSetValue(const char* args)
4007 if(!*args)
4008 return false;
4010 char* px = strtok((char*)args, " ");
4011 char* py = strtok(NULL, " ");
4012 char* pz = strtok(NULL, " ");
4014 if (!px || !py)
4015 return false;
4017 Unit* target = getSelectedUnit();
4018 if(!target)
4020 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
4021 SetSentErrorMessage(true);
4022 return false;
4025 uint64 guid = target->GetGUID();
4027 uint32 Opcode = (uint32)atoi(px);
4028 if(Opcode >= target->GetValuesCount())
4030 PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, GUID_LOPART(guid), target->GetValuesCount());
4031 return false;
4033 uint32 iValue;
4034 float fValue;
4035 bool isint32 = true;
4036 if(pz)
4037 isint32 = (bool)atoi(pz);
4038 if(isint32)
4040 iValue = (uint32)atoi(py);
4041 sLog.outDebug(GetMangosString(LANG_SET_UINT), GUID_LOPART(guid), Opcode, iValue);
4042 target->SetUInt32Value( Opcode , iValue );
4043 PSendSysMessage(LANG_SET_UINT_FIELD, GUID_LOPART(guid), Opcode,iValue);
4045 else
4047 fValue = (float)atof(py);
4048 sLog.outDebug(GetMangosString(LANG_SET_FLOAT), GUID_LOPART(guid), Opcode, fValue);
4049 target->SetFloatValue( Opcode , fValue );
4050 PSendSysMessage(LANG_SET_FLOAT_FIELD, GUID_LOPART(guid), Opcode,fValue);
4053 return true;
4056 bool ChatHandler::HandleGetValue(const char* args)
4058 if(!*args)
4059 return false;
4061 char* px = strtok((char*)args, " ");
4062 char* pz = strtok(NULL, " ");
4064 if (!px)
4065 return false;
4067 Unit* target = getSelectedUnit();
4068 if(!target)
4070 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
4071 SetSentErrorMessage(true);
4072 return false;
4075 uint64 guid = target->GetGUID();
4077 uint32 Opcode = (uint32)atoi(px);
4078 if(Opcode >= target->GetValuesCount())
4080 PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, GUID_LOPART(guid), target->GetValuesCount());
4081 return false;
4083 uint32 iValue;
4084 float fValue;
4085 bool isint32 = true;
4086 if(pz)
4087 isint32 = (bool)atoi(pz);
4089 if(isint32)
4091 iValue = target->GetUInt32Value( Opcode );
4092 sLog.outDebug(GetMangosString(LANG_GET_UINT), GUID_LOPART(guid), Opcode, iValue);
4093 PSendSysMessage(LANG_GET_UINT_FIELD, GUID_LOPART(guid), Opcode, iValue);
4095 else
4097 fValue = target->GetFloatValue( Opcode );
4098 sLog.outDebug(GetMangosString(LANG_GET_FLOAT), GUID_LOPART(guid), Opcode, fValue);
4099 PSendSysMessage(LANG_GET_FLOAT_FIELD, GUID_LOPART(guid), Opcode, fValue);
4102 return true;
4105 bool ChatHandler::HandleSet32Bit(const char* args)
4107 if(!*args)
4108 return false;
4110 char* px = strtok((char*)args, " ");
4111 char* py = strtok(NULL, " ");
4113 if (!px || !py)
4114 return false;
4116 uint32 Opcode = (uint32)atoi(px);
4117 uint32 Value = (uint32)atoi(py);
4118 if (Value > 32) //uint32 = 32 bits
4119 return false;
4121 sLog.outDebug(GetMangosString(LANG_SET_32BIT), Opcode, Value);
4123 m_session->GetPlayer( )->SetUInt32Value( Opcode , 2^Value );
4125 PSendSysMessage(LANG_SET_32BIT_FIELD, Opcode,1);
4126 return true;
4129 bool ChatHandler::HandleMod32Value(const char* args)
4131 if(!*args)
4132 return false;
4134 char* px = strtok((char*)args, " ");
4135 char* py = strtok(NULL, " ");
4137 if (!px || !py)
4138 return false;
4140 uint32 Opcode = (uint32)atoi(px);
4141 int Value = atoi(py);
4143 if(Opcode >= m_session->GetPlayer()->GetValuesCount())
4145 PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, m_session->GetPlayer()->GetGUIDLow(), m_session->GetPlayer( )->GetValuesCount());
4146 return false;
4149 sLog.outDebug(GetMangosString(LANG_CHANGE_32BIT), Opcode, Value);
4151 int CurrentValue = (int)m_session->GetPlayer( )->GetUInt32Value( Opcode );
4153 CurrentValue += Value;
4154 m_session->GetPlayer( )->SetUInt32Value( Opcode , (uint32)CurrentValue );
4156 PSendSysMessage(LANG_CHANGE_32BIT_FIELD, Opcode,CurrentValue);
4158 return true;
4161 bool ChatHandler::HandleAddTeleCommand(const char * args)
4163 if(!*args)
4164 return false;
4166 Player *player=m_session->GetPlayer();
4167 if (!player)
4168 return false;
4170 std::string name = args;
4172 if(objmgr.GetGameTele(name))
4174 SendSysMessage(LANG_COMMAND_TP_ALREADYEXIST);
4175 SetSentErrorMessage(true);
4176 return false;
4179 GameTele tele;
4180 tele.position_x = player->GetPositionX();
4181 tele.position_y = player->GetPositionY();
4182 tele.position_z = player->GetPositionZ();
4183 tele.orientation = player->GetOrientation();
4184 tele.mapId = player->GetMapId();
4185 tele.name = name;
4187 if(objmgr.AddGameTele(tele))
4189 SendSysMessage(LANG_COMMAND_TP_ADDED);
4191 else
4193 SendSysMessage(LANG_COMMAND_TP_ADDEDERR);
4194 SetSentErrorMessage(true);
4195 return false;
4198 return true;
4201 bool ChatHandler::HandleDelTeleCommand(const char * args)
4203 if(!*args)
4204 return false;
4206 std::string name = args;
4208 if(!objmgr.DeleteGameTele(name))
4210 SendSysMessage(LANG_COMMAND_TELE_NOTFOUND);
4211 SetSentErrorMessage(true);
4212 return false;
4215 SendSysMessage(LANG_COMMAND_TP_DELETED);
4216 return true;
4219 bool ChatHandler::HandleListAurasCommand (const char * /*args*/)
4221 Unit *unit = getSelectedUnit();
4222 if(!unit)
4224 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
4225 SetSentErrorMessage(true);
4226 return false;
4229 char const* talentStr = GetMangosString(LANG_TALENT);
4230 char const* passiveStr = GetMangosString(LANG_PASSIVE);
4232 Unit::AuraMap const& uAuras = unit->GetAuras();
4233 PSendSysMessage(LANG_COMMAND_TARGET_LISTAURAS, uAuras.size());
4234 for (Unit::AuraMap::const_iterator itr = uAuras.begin(); itr != uAuras.end(); ++itr)
4236 bool talent = GetTalentSpellCost(itr->second->GetId()) > 0;
4237 PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffIndex(),
4238 itr->second->GetModifier()->m_auraname, itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(),
4239 itr->second->GetSpellProto()->SpellName[m_session->GetSessionDbcLocale()],
4240 (itr->second->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
4241 IS_PLAYER_GUID(itr->second->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(itr->second->GetCasterGUID()));
4243 for (int i = 0; i < TOTAL_AURAS; i++)
4245 Unit::AuraList const& uAuraList = unit->GetAurasByType(AuraType(i));
4246 if (uAuraList.empty()) continue;
4247 PSendSysMessage(LANG_COMMAND_TARGET_LISTAURATYPE, uAuraList.size(), i);
4248 for (Unit::AuraList::const_iterator itr = uAuraList.begin(); itr != uAuraList.end(); ++itr)
4250 bool talent = GetTalentSpellCost((*itr)->GetId()) > 0;
4251 PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(),
4252 (*itr)->GetSpellProto()->SpellName[m_session->GetSessionDbcLocale()],((*itr)->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
4253 IS_PLAYER_GUID((*itr)->GetCasterGUID()) ? "player" : "creature",GUID_LOPART((*itr)->GetCasterGUID()));
4256 return true;
4259 bool ChatHandler::HandleResetHonorCommand (const char * args)
4261 char* pName = strtok((char*)args, "");
4262 Player *player = NULL;
4263 if (pName)
4265 std::string name = pName;
4266 if(!normalizePlayerName(name))
4268 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4269 SetSentErrorMessage(true);
4270 return false;
4273 uint64 guid = objmgr.GetPlayerGUIDByName(name.c_str());
4274 player = objmgr.GetPlayer(guid);
4276 else
4277 player = getSelectedPlayer();
4279 if(!player)
4281 SendSysMessage(LANG_NO_CHAR_SELECTED);
4282 return true;
4285 player->SetUInt32Value(PLAYER_FIELD_KILLS, 0);
4286 player->SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORBALE_KILLS, 0);
4287 player->SetUInt32Value(PLAYER_FIELD_HONOR_CURRENCY, 0);
4288 player->SetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, 0);
4289 player->SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, 0);
4291 return true;
4294 static bool HandleResetStatsOrLevelHelper(Player* player)
4296 PlayerInfo const *info = objmgr.GetPlayerInfo(player->getRace(), player->getClass());
4297 if(!info) return false;
4299 ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(player->getClass());
4300 if(!cEntry)
4302 sLog.outError("Class %u not found in DBC (Wrong DBC files?)",player->getClass());
4303 return false;
4306 uint8 powertype = cEntry->powerType;
4308 uint32 unitfield;
4309 if(powertype == POWER_RAGE)
4310 unitfield = 0x1100EE00;
4311 else if(powertype == POWER_ENERGY)
4312 unitfield = 0x00000000;
4313 else if(powertype == POWER_MANA)
4314 unitfield = 0x0000EE00;
4315 else
4317 sLog.outError("Invalid default powertype %u for player (class %u)",powertype,player->getClass());
4318 return false;
4321 // reset m_form if no aura
4322 if(!player->HasAuraType(SPELL_AURA_MOD_SHAPESHIFT))
4323 player->m_form = FORM_NONE;
4325 player->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE );
4326 player->SetFloatValue(UNIT_FIELD_COMBATREACH, 1.5f );
4328 player->setFactionForRace(player->getRace());
4330 player->SetUInt32Value(UNIT_FIELD_BYTES_0, ( ( player->getRace() ) | ( player->getClass() << 8 ) | ( player->getGender() << 16 ) | ( powertype << 24 ) ) );
4332 // reset only if player not in some form;
4333 if(player->m_form==FORM_NONE)
4335 switch(player->getGender())
4337 case GENDER_FEMALE:
4338 player->SetDisplayId(info->displayId_f);
4339 player->SetNativeDisplayId(info->displayId_f);
4340 break;
4341 case GENDER_MALE:
4342 player->SetDisplayId(info->displayId_m);
4343 player->SetNativeDisplayId(info->displayId_m);
4344 break;
4345 default:
4346 break;
4350 // set UNIT_FIELD_BYTES_1 to init state but preserve m_form value
4351 player->SetUInt32Value(UNIT_FIELD_BYTES_1, unitfield);
4352 player->SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_UNK3 | UNIT_BYTE2_FLAG_UNK5 );
4353 player->SetByteValue(UNIT_FIELD_BYTES_2, 3, player->m_form);
4355 player->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
4357 //-1 is default value
4358 player->SetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, uint32(-1));
4360 //player->SetUInt32Value(PLAYER_FIELD_BYTES, 0xEEE00000 );
4361 return true;
4364 bool ChatHandler::HandleResetLevelCommand(const char * args)
4366 char* pName = strtok((char*)args, "");
4367 Player *player = NULL;
4368 if (pName)
4370 std::string name = pName;
4371 if(!normalizePlayerName(name))
4373 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4374 SetSentErrorMessage(true);
4375 return false;
4378 uint64 guid = objmgr.GetPlayerGUIDByName(name.c_str());
4379 player = objmgr.GetPlayer(guid);
4381 else
4382 player = getSelectedPlayer();
4384 if(!player)
4386 SendSysMessage(LANG_NO_CHAR_SELECTED);
4387 SetSentErrorMessage(true);
4388 return false;
4391 if(!HandleResetStatsOrLevelHelper(player))
4392 return false;
4394 player->SetLevel(1);
4395 player->InitStatsForLevel(true);
4396 player->InitTaxiNodesForLevel();
4397 player->InitTalentForLevel();
4398 player->SetUInt32Value(PLAYER_XP,0);
4400 // reset level to summoned pet
4401 Pet* pet = player->GetPet();
4402 if(pet && pet->getPetType()==SUMMON_PET)
4403 pet->InitStatsForLevel(1);
4405 return true;
4408 bool ChatHandler::HandleResetStatsCommand(const char * args)
4410 char* pName = strtok((char*)args, "");
4411 Player *player = NULL;
4412 if (pName)
4414 std::string name = pName;
4415 if(!normalizePlayerName(name))
4417 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4418 SetSentErrorMessage(true);
4419 return false;
4422 uint64 guid = objmgr.GetPlayerGUIDByName(name.c_str());
4423 player = objmgr.GetPlayer(guid);
4425 else
4426 player = getSelectedPlayer();
4428 if(!player)
4430 SendSysMessage(LANG_NO_CHAR_SELECTED);
4431 SetSentErrorMessage(true);
4432 return false;
4435 if(!HandleResetStatsOrLevelHelper(player))
4436 return false;
4438 player->InitStatsForLevel(true);
4439 player->InitTaxiNodesForLevel();
4440 player->InitTalentForLevel();
4442 return true;
4445 bool ChatHandler::HandleResetSpellsCommand(const char * args)
4447 char* pName = strtok((char*)args, "");
4448 Player *player = NULL;
4449 uint64 playerGUID = 0;
4450 if (pName)
4452 std::string name = pName;
4454 if(!normalizePlayerName(name))
4456 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4457 SetSentErrorMessage(true);
4458 return false;
4461 player = objmgr.GetPlayer(name.c_str());
4462 if(!player)
4463 playerGUID = objmgr.GetPlayerGUIDByName(name.c_str());
4465 else
4466 player = getSelectedPlayer();
4468 if(!player && !playerGUID)
4470 SendSysMessage(LANG_NO_CHAR_SELECTED);
4471 SetSentErrorMessage(true);
4472 return false;
4475 if(player)
4477 player->resetSpells();
4479 ChatHandler(player).SendSysMessage(LANG_RESET_SPELLS);
4481 if(m_session->GetPlayer()!=player)
4482 PSendSysMessage(LANG_RESET_SPELLS_ONLINE,player->GetName());
4484 else
4486 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",uint32(AT_LOGIN_RESET_SPELLS), GUID_LOPART(playerGUID));
4487 PSendSysMessage(LANG_RESET_SPELLS_OFFLINE,pName);
4490 return true;
4493 bool ChatHandler::HandleResetTalentsCommand(const char * args)
4495 char* pName = strtok((char*)args, "");
4496 Player *player = NULL;
4497 uint64 playerGUID = 0;
4498 if (pName)
4500 std::string name = pName;
4501 if(!normalizePlayerName(name))
4503 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4504 SetSentErrorMessage(true);
4505 return false;
4508 player = objmgr.GetPlayer(name.c_str());
4509 if(!player)
4510 playerGUID = objmgr.GetPlayerGUIDByName(name.c_str());
4512 else
4513 player = getSelectedPlayer();
4515 if(!player && !playerGUID)
4517 SendSysMessage(LANG_NO_CHAR_SELECTED);
4518 SetSentErrorMessage(true);
4519 return false;
4522 if(player)
4524 player->resetTalents(true);
4526 ChatHandler(player).SendSysMessage(LANG_RESET_TALENTS);
4528 if(m_session->GetPlayer()!=player)
4529 PSendSysMessage(LANG_RESET_TALENTS_ONLINE,player->GetName());
4531 else
4533 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",uint32(AT_LOGIN_RESET_TALENTS), GUID_LOPART(playerGUID) );
4534 PSendSysMessage(LANG_RESET_TALENTS_OFFLINE,pName);
4537 return true;
4540 bool ChatHandler::HandleResetAllCommand(const char * args)
4542 if(!*args)
4543 return false;
4545 std::string casename = args;
4547 AtLoginFlags atLogin;
4549 // Command specially created as single command to prevent using short case names
4550 if(casename=="spells")
4552 atLogin = AT_LOGIN_RESET_SPELLS;
4553 sWorld.SendWorldText(LANG_RESETALL_SPELLS);
4555 else if(casename=="talents")
4557 atLogin = AT_LOGIN_RESET_TALENTS;
4558 sWorld.SendWorldText(LANG_RESETALL_TALENTS);
4560 else
4562 PSendSysMessage(LANG_RESETALL_UNKNOWN_CASE,args);
4563 SetSentErrorMessage(true);
4564 return false;
4567 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u'",atLogin);
4568 HashMapHolder<Player>::MapType const& plist = ObjectAccessor::Instance().GetPlayers();
4569 for(HashMapHolder<Player>::MapType::const_iterator itr = plist.begin(); itr != plist.end(); ++itr)
4570 itr->second->SetAtLoginFlag(atLogin);
4572 return true;
4575 bool ChatHandler::HandleShutDownCommand(const char* args)
4577 if(!*args)
4578 return false;
4580 if(std::string(args)=="cancel")
4582 sWorld.ShutdownCancel();
4584 else
4586 int32 time = atoi(args);
4588 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4589 if(time == 0 && (args[0]!='0' || args[1]!='\0') || time < 0)
4590 return false;
4592 sWorld.ShutdownServ(time);
4594 return true;
4597 bool ChatHandler::HandleRestartCommand(const char* args)
4599 if(!*args)
4600 return false;
4602 if(std::string(args)=="cancel")
4604 sWorld.ShutdownCancel();
4606 else
4608 int32 time = atoi(args);
4610 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4611 if(time == 0 && (args[0]!='0' || args[1]!='\0') || time < 0)
4612 return false;
4614 sWorld.ShutdownServ(time, SHUTDOWN_MASK_RESTART);
4616 return true;
4619 bool ChatHandler::HandleIdleRestartCommand(const char* args)
4621 if(!*args)
4622 return false;
4624 if(std::string(args)=="cancel")
4626 sWorld.ShutdownCancel();
4628 else
4630 int32 time = atoi(args);
4632 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4633 if(time == 0 && (args[0]!='0' || args[1]!='\0') || time < 0)
4634 return false;
4636 sWorld.ShutdownServ(time,SHUTDOWN_MASK_RESTART+SHUTDOWN_MASK_IDLE);
4638 return true;
4641 bool ChatHandler::HandleIdleShutDownCommand(const char* args)
4643 if(!*args)
4644 return false;
4646 if(std::string(args)=="cancel")
4648 sWorld.ShutdownCancel();
4650 else
4652 int32 time = atoi(args);
4654 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4655 if(time == 0 && (args[0]!='0' || args[1]!='\0') || time < 0)
4656 return false;
4658 sWorld.ShutdownServ(time,SHUTDOWN_MASK_IDLE);
4660 return true;
4663 bool ChatHandler::HandleAddQuest(const char* args)
4665 Player* player = getSelectedPlayer();
4666 if(!player)
4668 SendSysMessage(LANG_NO_CHAR_SELECTED);
4669 SetSentErrorMessage(true);
4670 return false;
4673 // .addquest #entry'
4674 // number or [name] Shift-click form |color|Hquest:quest_id|h[name]|h|r
4675 char* cId = extractKeyFromLink((char*)args,"Hquest");
4676 if(!cId)
4677 return false;
4679 uint32 entry = atol(cId);
4681 Quest const* pQuest = objmgr.GetQuestTemplate(entry);
4683 if(!pQuest)
4685 PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND,entry);
4686 SetSentErrorMessage(true);
4687 return false;
4690 // check item starting quest (it can work incorrectly if added without item in inventory)
4691 for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
4693 ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype>(id);
4694 if (!pProto)
4695 continue;
4697 if (pProto->StartQuest == entry)
4699 PSendSysMessage(LANG_COMMAND_QUEST_STARTFROMITEM, entry, pProto->ItemId);
4700 SetSentErrorMessage(true);
4701 return false;
4705 // ok, normal (creature/GO starting) quest
4706 if( player->CanAddQuest( pQuest, true ) )
4708 player->AddQuest( pQuest, NULL );
4710 if ( player->CanCompleteQuest( entry ) )
4711 player->CompleteQuest( entry );
4714 return true;
4717 bool ChatHandler::HandleRemoveQuest(const char* args)
4719 Player* player = getSelectedPlayer();
4720 if(!player)
4722 SendSysMessage(LANG_NO_CHAR_SELECTED);
4723 SetSentErrorMessage(true);
4724 return false;
4727 // .removequest #entry'
4728 // number or [name] Shift-click form |color|Hquest:quest_id|h[name]|h|r
4729 char* cId = extractKeyFromLink((char*)args,"Hquest");
4730 if(!cId)
4731 return false;
4733 uint32 entry = atol(cId);
4735 Quest const* pQuest = objmgr.GetQuestTemplate(entry);
4737 if(!pQuest)
4739 PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry);
4740 SetSentErrorMessage(true);
4741 return false;
4744 // remove all quest entries for 'entry' from quest log
4745 for(uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot )
4747 uint32 quest = player->GetQuestSlotQuestId(slot);
4748 if(quest==entry)
4750 player->SetQuestSlot(slot,0);
4752 // we ignore unequippable quest items in this case, its' still be equipped
4753 player->TakeQuestSourceItem( quest, false );
4757 // set quest status to not started (will updated in DB at next save)
4758 player->SetQuestStatus( entry, QUEST_STATUS_NONE);
4760 // reset rewarded for restart repeatable quest
4761 player->getQuestStatusMap()[entry].m_rewarded = false;
4763 SendSysMessage(LANG_COMMAND_QUEST_REMOVED);
4764 return true;
4767 bool ChatHandler::HandleCompleteQuest(const char* args)
4769 Player* player = getSelectedPlayer();
4770 if(!player)
4772 SendSysMessage(LANG_NO_CHAR_SELECTED);
4773 SetSentErrorMessage(true);
4774 return false;
4777 // .quest complete #entry
4778 // number or [name] Shift-click form |color|Hquest:quest_id|h[name]|h|r
4779 char* cId = extractKeyFromLink((char*)args,"Hquest");
4780 if(!cId)
4781 return false;
4783 uint32 entry = atol(cId);
4785 Quest const* pQuest = objmgr.GetQuestTemplate(entry);
4787 // If player doesn't have the quest
4788 if(!pQuest || player->GetQuestStatus(entry) == QUEST_STATUS_NONE)
4790 PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry);
4791 SetSentErrorMessage(true);
4792 return false;
4795 // Add quest items for quests that require items
4796 for(uint8 x = 0; x < QUEST_OBJECTIVES_COUNT; ++x)
4798 uint32 id = pQuest->ReqItemId[x];
4799 uint32 count = pQuest->ReqItemCount[x];
4800 if(!id || !count)
4801 continue;
4803 uint32 curItemCount = player->GetItemCount(id,true);
4805 ItemPosCountVec dest;
4806 uint8 msg = player->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, id, count-curItemCount );
4807 if( msg == EQUIP_ERR_OK )
4809 Item* item = player->StoreNewItem( dest, id, true);
4810 player->SendNewItem(item,count-curItemCount,true,false);
4814 // All creature/GO slain/casted (not required, but otherwise it will display "Creature slain 0/10")
4815 for(uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; i++)
4817 uint32 creature = pQuest->ReqCreatureOrGOId[i];
4818 uint32 creaturecount = pQuest->ReqCreatureOrGOCount[i];
4820 if(uint32 spell_id = pQuest->ReqSpell[i])
4822 for(uint16 z = 0; z < creaturecount; ++z)
4823 player->CastedCreatureOrGO(creature,0,spell_id);
4825 else if(creature > 0)
4827 for(uint16 z = 0; z < creaturecount; ++z)
4828 player->KilledMonster(creature,0);
4830 else if(creature < 0)
4832 for(uint16 z = 0; z < creaturecount; ++z)
4833 player->CastedCreatureOrGO(creature,0,0);
4837 // If the quest requires reputation to complete
4838 if(uint32 repFaction = pQuest->GetRepObjectiveFaction())
4840 uint32 repValue = pQuest->GetRepObjectiveValue();
4841 uint32 curRep = player->GetReputation(repFaction);
4842 if(curRep < repValue)
4844 FactionEntry const *factionEntry = sFactionStore.LookupEntry(repFaction);
4845 player->SetFactionReputation(factionEntry,repValue);
4849 // If the quest requires money
4850 int32 ReqOrRewMoney = pQuest->GetRewOrReqMoney();
4851 if(ReqOrRewMoney < 0)
4852 player->ModifyMoney(-ReqOrRewMoney);
4854 player->CompleteQuest(entry);
4855 return true;
4858 bool ChatHandler::HandleBanAccountCommand(const char* args)
4860 return HandleBanHelper(BAN_ACCOUNT,args);
4863 bool ChatHandler::HandleBanCharacterCommand(const char* args)
4865 return HandleBanHelper(BAN_CHARACTER,args);
4868 bool ChatHandler::HandleBanIPCommand(const char* args)
4870 return HandleBanHelper(BAN_IP,args);
4873 bool ChatHandler::HandleBanHelper(BanMode mode, const char* args)
4875 if(!args)
4876 return false;
4878 char* cnameOrIP = strtok ((char*)args, " ");
4879 if (!cnameOrIP)
4880 return false;
4882 std::string nameOrIP = cnameOrIP;
4884 char* duration = strtok (NULL," ");
4885 if(!duration || !atoi(duration))
4886 return false;
4888 char* reason = strtok (NULL,"");
4889 if(!reason)
4890 return false;
4892 switch(mode)
4894 case BAN_ACCOUNT:
4895 if(!AccountMgr::normilizeString(nameOrIP))
4897 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,nameOrIP.c_str());
4898 SetSentErrorMessage(true);
4899 return false;
4901 break;
4902 case BAN_CHARACTER:
4903 if(!normalizePlayerName(nameOrIP))
4905 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4906 SetSentErrorMessage(true);
4907 return false;
4909 break;
4910 case BAN_IP:
4911 if(!IsIPAddress(nameOrIP.c_str()))
4912 return false;
4913 break;
4916 switch(sWorld.BanAccount(mode, nameOrIP, duration, reason,m_session ? m_session->GetPlayerName() : ""))
4918 case BAN_SUCCESS:
4919 if(atoi(duration)>0)
4920 PSendSysMessage(LANG_BAN_YOUBANNED,nameOrIP.c_str(),secsToTimeString(TimeStringToSecs(duration),true).c_str(),reason);
4921 else
4922 PSendSysMessage(LANG_BAN_YOUPERMBANNED,nameOrIP.c_str(),reason);
4923 break;
4924 case BAN_SYNTAX_ERROR:
4925 return false;
4926 case BAN_NOTFOUND:
4927 switch(mode)
4929 default:
4930 PSendSysMessage(LANG_BAN_NOTFOUND,"account",nameOrIP.c_str());
4931 break;
4932 case BAN_CHARACTER:
4933 PSendSysMessage(LANG_BAN_NOTFOUND,"character",nameOrIP.c_str());
4934 break;
4935 case BAN_IP:
4936 PSendSysMessage(LANG_BAN_NOTFOUND,"ip",nameOrIP.c_str());
4937 break;
4939 SetSentErrorMessage(true);
4940 return false;
4943 return true;
4946 bool ChatHandler::HandleUnBanAccountCommand(const char* args)
4948 return HandleUnBanHelper(BAN_ACCOUNT,args);
4951 bool ChatHandler::HandleUnBanCharacterCommand(const char* args)
4953 return HandleUnBanHelper(BAN_CHARACTER,args);
4956 bool ChatHandler::HandleUnBanIPCommand(const char* args)
4958 return HandleUnBanHelper(BAN_IP,args);
4961 bool ChatHandler::HandleUnBanHelper(BanMode mode, const char* args)
4963 if(!args)
4964 return false;
4966 char* cnameOrIP = strtok ((char*)args, " ");
4967 if(!cnameOrIP)
4968 return false;
4970 std::string nameOrIP = cnameOrIP;
4972 switch(mode)
4974 case BAN_ACCOUNT:
4975 if(!AccountMgr::normilizeString(nameOrIP))
4977 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,nameOrIP.c_str());
4978 SetSentErrorMessage(true);
4979 return false;
4981 break;
4982 case BAN_CHARACTER:
4983 if(!normalizePlayerName(nameOrIP))
4985 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4986 SetSentErrorMessage(true);
4987 return false;
4989 break;
4990 case BAN_IP:
4991 if(!IsIPAddress(nameOrIP.c_str()))
4992 return false;
4993 break;
4996 if(sWorld.RemoveBanAccount(mode,nameOrIP))
4997 PSendSysMessage(LANG_UNBAN_UNBANNED,nameOrIP.c_str());
4998 else
4999 PSendSysMessage(LANG_UNBAN_ERROR,nameOrIP.c_str());
5001 return true;
5004 bool ChatHandler::HandleBanInfoAccountCommand(const char* args)
5006 if(!args)
5007 return false;
5009 char* cname = strtok((char*)args, "");
5010 if(!cname)
5011 return false;
5013 std::string account_name = cname;
5014 if(!AccountMgr::normilizeString(account_name))
5016 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5017 SetSentErrorMessage(true);
5018 return false;
5021 uint32 accountid = accmgr.GetId(account_name);
5022 if(!accountid)
5024 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5025 return true;
5028 return HandleBanInfoHelper(accountid,account_name.c_str());
5031 bool ChatHandler::HandleBanInfoCharacterCommand(const char* args)
5033 if(!args)
5034 return false;
5036 char* cname = strtok ((char*)args, "");
5037 if(!cname)
5038 return false;
5040 std::string name = cname;
5041 if(!normalizePlayerName(name))
5043 SendSysMessage(LANG_PLAYER_NOT_FOUND);
5044 SetSentErrorMessage(true);
5045 return false;
5048 uint32 accountid = objmgr.GetPlayerAccountIdByPlayerName(name);
5049 if(!accountid)
5051 SendSysMessage(LANG_PLAYER_NOT_FOUND);
5052 SetSentErrorMessage(true);
5053 return false;
5056 std::string accountname;
5057 if(!accmgr.GetName(accountid,accountname))
5059 PSendSysMessage(LANG_BANINFO_NOCHARACTER);
5060 return true;
5063 return HandleBanInfoHelper(accountid,accountname.c_str());
5066 bool ChatHandler::HandleBanInfoHelper(uint32 accountid, char const* accountname)
5068 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);
5069 if(!result)
5071 PSendSysMessage(LANG_BANINFO_NOACCOUNTBAN, accountname);
5072 return true;
5075 PSendSysMessage(LANG_BANINFO_BANHISTORY,accountname);
5078 Field* fields = result->Fetch();
5080 time_t unbandate = time_t(fields[3].GetUInt64());
5081 bool active = false;
5082 if(fields[2].GetBool() && (fields[1].GetUInt64() == (uint64)0 ||unbandate >= time(NULL)) )
5083 active = true;
5084 bool permanent = (fields[1].GetUInt64() == (uint64)0);
5085 std::string bantime = permanent?GetMangosString(LANG_BANINFO_INFINITE):secsToTimeString(fields[1].GetUInt64(), true);
5086 PSendSysMessage(LANG_BANINFO_HISTORYENTRY,
5087 fields[0].GetString(), bantime.c_str(), active ? GetMangosString(LANG_BANINFO_YES):GetMangosString(LANG_BANINFO_NO), fields[4].GetString(), fields[5].GetString());
5088 }while (result->NextRow());
5090 delete result;
5091 return true;
5094 bool ChatHandler::HandleBanInfoIPCommand(const char* args)
5096 if(!args)
5097 return false;
5099 char* cIP = strtok ((char*)args, "");
5100 if(!cIP)
5101 return false;
5103 if (!IsIPAddress(cIP))
5104 return false;
5106 std::string IP = cIP;
5108 loginDatabase.escape_string(IP);
5109 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());
5110 if(!result)
5112 PSendSysMessage(LANG_BANINFO_NOIP);
5113 return true;
5116 Field *fields = result->Fetch();
5117 bool permanent = !fields[6].GetUInt64();
5118 PSendSysMessage(LANG_BANINFO_IPENTRY,
5119 fields[0].GetString(), fields[1].GetString(), permanent ? GetMangosString(LANG_BANINFO_NEVER):fields[2].GetString(),
5120 permanent ? GetMangosString(LANG_BANINFO_INFINITE):secsToTimeString(fields[3].GetUInt64(), true).c_str(), fields[4].GetString(), fields[5].GetString());
5121 delete result;
5122 return true;
5125 bool ChatHandler::HandleBanListCharacterCommand(const char* args)
5127 loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
5129 char* cFilter = strtok ((char*)args, " ");
5130 if(!cFilter)
5131 return false;
5133 std::string filter = cFilter;
5134 loginDatabase.escape_string(filter);
5135 QueryResult* result = CharacterDatabase.PQuery("SELECT account FROM characters WHERE name "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'"),filter.c_str());
5136 if (!result)
5138 PSendSysMessage(LANG_BANLIST_NOCHARACTER);
5139 return true;
5142 return HandleBanListHelper(result);
5145 bool ChatHandler::HandleBanListAccountCommand(const char* args)
5147 loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
5149 char* cFilter = strtok((char*)args, " ");
5150 std::string filter = cFilter ? cFilter : "";
5151 loginDatabase.escape_string(filter);
5153 QueryResult* result;
5155 if(filter.empty())
5157 result = loginDatabase.Query("SELECT account.id, username FROM account, account_banned"
5158 " WHERE account.id = account_banned.id AND active = 1 GROUP BY account.id");
5160 else
5162 result = loginDatabase.PQuery("SELECT account.id, username FROM account, account_banned"
5163 " WHERE account.id = account_banned.id AND active = 1 AND username "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")" GROUP BY account.id",
5164 filter.c_str());
5167 if (!result)
5169 PSendSysMessage(LANG_BANLIST_NOACCOUNT);
5170 return true;
5173 return HandleBanListHelper(result);
5176 bool ChatHandler::HandleBanListHelper(QueryResult* result)
5178 PSendSysMessage(LANG_BANLIST_MATCHINGACCOUNT);
5180 // Chat short output
5181 if(m_session)
5185 Field* fields = result->Fetch();
5186 uint32 accountid = fields[0].GetUInt32();
5188 QueryResult* banresult = loginDatabase.PQuery("SELECT account.username FROM account,account_banned WHERE account_banned.id='%u' AND account_banned.id=account.id",accountid);
5189 if(banresult)
5191 Field* fields2 = banresult->Fetch();
5192 PSendSysMessage("%s",fields2[0].GetString());
5193 delete banresult;
5195 } while (result->NextRow());
5197 // Console wide output
5198 else
5200 SendSysMessage(LANG_BANLIST_ACCOUNTS);
5201 SendSysMessage("===============================================================================");
5202 SendSysMessage(LANG_BANLIST_ACCOUNTS_HEADER);
5205 SendSysMessage("-------------------------------------------------------------------------------");
5206 Field *fields = result->Fetch();
5207 uint32 account_id = fields[0].GetUInt32 ();
5209 std::string account_name;
5211 // "account" case, name can be get in same query
5212 if(result->GetFieldCount() > 1)
5213 account_name = fields[1].GetCppString();
5214 // "character" case, name need extract from another DB
5215 else
5216 accmgr.GetName (account_id,account_name);
5218 // No SQL injection. id is uint32.
5219 QueryResult *banInfo = loginDatabase.PQuery("SELECT bandate,unbandate,bannedby,banreason FROM account_banned WHERE id = %u ORDER BY unbandate", account_id);
5220 if (banInfo)
5222 Field *fields2 = banInfo->Fetch();
5225 time_t t_ban = fields2[0].GetUInt64();
5226 tm* aTm_ban = localtime(&t_ban);
5228 if (fields2[0].GetUInt64() == fields2[1].GetUInt64())
5230 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|",
5231 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,
5232 fields2[2].GetString(),fields2[3].GetString());
5234 else
5236 time_t t_unban = fields2[1].GetUInt64();
5237 tm* aTm_unban = localtime(&t_unban);
5238 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|",
5239 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,
5240 aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min,
5241 fields2[2].GetString(),fields2[3].GetString());
5243 }while ( banInfo->NextRow() );
5244 delete banInfo;
5246 }while( result->NextRow() );
5247 SendSysMessage("===============================================================================");
5250 delete result;
5251 return true;
5254 bool ChatHandler::HandleBanListIPCommand(const char* args)
5256 loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
5258 char* cFilter = strtok((char*)args, " ");
5259 std::string filter = cFilter ? cFilter : "";
5260 loginDatabase.escape_string(filter);
5262 QueryResult* result;
5264 if(filter.empty())
5266 result = loginDatabase.Query ("SELECT ip,bandate,unbandate,bannedby,banreason FROM ip_banned"
5267 " WHERE (bandate=unbandate OR unbandate>UNIX_TIMESTAMP())"
5268 " ORDER BY unbandate" );
5270 else
5272 result = loginDatabase.PQuery( "SELECT ip,bandate,unbandate,bannedby,banreason FROM ip_banned"
5273 " WHERE (bandate=unbandate OR unbandate>UNIX_TIMESTAMP()) AND ip "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")
5274 " ORDER BY unbandate",filter.c_str() );
5277 if(!result)
5279 PSendSysMessage(LANG_BANLIST_NOIP);
5280 return true;
5283 PSendSysMessage(LANG_BANLIST_MATCHINGIP);
5284 // Chat short output
5285 if(m_session)
5289 Field* fields = result->Fetch();
5290 PSendSysMessage("%s",fields[0].GetString());
5291 } while (result->NextRow());
5293 // Console wide output
5294 else
5296 SendSysMessage(LANG_BANLIST_IPS);
5297 SendSysMessage("===============================================================================");
5298 SendSysMessage(LANG_BANLIST_IPS_HEADER);
5301 SendSysMessage("-------------------------------------------------------------------------------");
5302 Field *fields = result->Fetch();
5303 time_t t_ban = fields[1].GetUInt64();
5304 tm* aTm_ban = localtime(&t_ban);
5305 if ( fields[1].GetUInt64() == fields[2].GetUInt64() )
5307 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|",
5308 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,
5309 fields[3].GetString(), fields[4].GetString());
5311 else
5313 time_t t_unban = fields[2].GetUInt64();
5314 tm* aTm_unban = localtime(&t_unban);
5315 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|",
5316 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,
5317 aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min,
5318 fields[3].GetString(), fields[4].GetString());
5320 }while( result->NextRow() );
5321 SendSysMessage("===============================================================================");
5324 delete result;
5325 return true;
5328 bool ChatHandler::HandleRespawnCommand(const char* /*args*/)
5330 Player* pl = m_session->GetPlayer();
5332 // accept only explicitly selected target (not implicitly self targeting case)
5333 Unit* target = getSelectedUnit();
5334 if(pl->GetSelection() && target)
5336 if(target->GetTypeId()!=TYPEID_UNIT)
5338 SendSysMessage(LANG_SELECT_CREATURE);
5339 SetSentErrorMessage(true);
5340 return false;
5343 if(target->isDead())
5344 ((Creature*)target)->Respawn();
5345 return true;
5348 CellPair p(MaNGOS::ComputeCellPair(pl->GetPositionX(), pl->GetPositionY()));
5349 Cell cell(p);
5350 cell.data.Part.reserved = ALL_DISTRICT;
5351 cell.SetNoCreate();
5353 MaNGOS::RespawnDo u_do;
5354 MaNGOS::WorldObjectWorker<MaNGOS::RespawnDo> worker(u_do);
5356 TypeContainerVisitor<MaNGOS::WorldObjectWorker<MaNGOS::RespawnDo>, GridTypeMapContainer > obj_worker(worker);
5357 CellLock<GridReadGuard> cell_lock(cell, p);
5358 cell_lock->Visit(cell_lock, obj_worker, *MapManager::Instance().GetMap(pl->GetMapId(), pl));
5360 return true;
5363 bool ChatHandler::HandleFlyModeCommand(const char* args)
5365 if(!args)
5366 return false;
5368 Unit *unit = getSelectedUnit();
5369 if (!unit || (unit->GetTypeId() != TYPEID_PLAYER))
5370 unit = m_session->GetPlayer();
5372 WorldPacket data(12);
5373 if (strncmp(args, "on", 3) == 0)
5374 data.SetOpcode(SMSG_MOVE_SET_CAN_FLY);
5375 else if (strncmp(args, "off", 4) == 0)
5376 data.SetOpcode(SMSG_MOVE_UNSET_CAN_FLY);
5377 else
5379 SendSysMessage(LANG_USE_BOL);
5380 return false;
5382 data.append(unit->GetPackGUID());
5383 data << uint32(0); // unknown
5384 unit->SendMessageToSet(&data, true);
5385 PSendSysMessage(LANG_COMMAND_FLYMODE_STATUS, unit->GetName(), args);
5386 return true;
5389 bool ChatHandler::HandleLoadPDumpCommand(const char *args)
5391 if(!args)
5392 return false;
5394 char * file = strtok((char*)args, " ");
5395 if(!file)
5396 return false;
5398 char * account = strtok(NULL, " ");
5399 if(!account)
5400 return false;
5402 std::string account_name = account;
5403 if(!AccountMgr::normilizeString(account_name))
5405 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5406 SetSentErrorMessage(true);
5407 return false;
5410 uint32 account_id = accmgr.GetId(account_name);
5411 if(!account_id)
5413 account_id = atoi(account); // use original string
5414 if(!account_id)
5416 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5417 SetSentErrorMessage(true);
5418 return false;
5422 if(!accmgr.GetName(account_id,account_name))
5424 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5425 SetSentErrorMessage(true);
5426 return false;
5429 char* guid_str = NULL;
5430 char* name_str = strtok(NULL, " ");
5432 std::string name;
5433 if(name_str)
5435 name = name_str;
5436 // normalize the name if specified and check if it exists
5437 if(!normalizePlayerName(name))
5439 PSendSysMessage(LANG_INVALID_CHARACTER_NAME);
5440 SetSentErrorMessage(true);
5441 return false;
5444 if(!ObjectMgr::IsValidName(name,true))
5446 PSendSysMessage(LANG_INVALID_CHARACTER_NAME);
5447 SetSentErrorMessage(true);
5448 return false;
5451 guid_str = strtok(NULL, " ");
5454 uint32 guid = 0;
5456 if(guid_str)
5458 guid = atoi(guid_str);
5459 if(!guid)
5461 PSendSysMessage(LANG_INVALID_CHARACTER_GUID);
5462 SetSentErrorMessage(true);
5463 return false;
5466 if(objmgr.GetPlayerAccountIdByGUID(guid))
5468 PSendSysMessage(LANG_CHARACTER_GUID_IN_USE,guid);
5469 SetSentErrorMessage(true);
5470 return false;
5474 switch(PlayerDumpReader().LoadDump(file, account_id, name, guid))
5476 case DUMP_SUCCESS:
5477 PSendSysMessage(LANG_COMMAND_IMPORT_SUCCESS);
5478 break;
5479 case DUMP_FILE_OPEN_ERROR:
5480 PSendSysMessage(LANG_FILE_OPEN_FAIL,file);
5481 SetSentErrorMessage(true);
5482 return false;
5483 case DUMP_FILE_BROKEN:
5484 PSendSysMessage(LANG_DUMP_BROKEN,file);
5485 SetSentErrorMessage(true);
5486 return false;
5487 case DUMP_TOO_MANY_CHARS:
5488 PSendSysMessage(LANG_ACCOUNT_CHARACTER_LIST_FULL,account_name.c_str(),account_id);
5489 SetSentErrorMessage(true);
5490 return false;
5491 default:
5492 PSendSysMessage(LANG_COMMAND_IMPORT_FAILED);
5493 SetSentErrorMessage(true);
5494 return false;
5497 return true;
5500 bool ChatHandler::HandleNpcChangeEntryCommand(const char *args)
5502 if(!args)
5503 return false;
5505 uint32 newEntryNum = atoi(args);
5506 if(!newEntryNum)
5507 return false;
5509 Unit* unit = getSelectedUnit();
5510 if(!unit || unit->GetTypeId() != TYPEID_UNIT)
5512 SendSysMessage(LANG_SELECT_CREATURE);
5513 SetSentErrorMessage(true);
5514 return false;
5516 Creature* creature = (Creature*)unit;
5517 if(creature->UpdateEntry(newEntryNum))
5518 SendSysMessage(LANG_DONE);
5519 else
5520 SendSysMessage(LANG_ERROR);
5521 return true;
5524 bool ChatHandler::HandleWritePDumpCommand(const char *args)
5526 if(!args)
5527 return false;
5529 char* file = strtok((char*)args, " ");
5530 char* p2 = strtok(NULL, " ");
5532 if(!file || !p2)
5533 return false;
5535 uint32 guid = objmgr.GetPlayerGUIDByName(p2);
5536 if(!guid)
5537 guid = atoi(p2);
5539 if(!objmgr.GetPlayerAccountIdByGUID(guid))
5541 PSendSysMessage(LANG_PLAYER_NOT_FOUND);
5542 SetSentErrorMessage(true);
5543 return false;
5546 switch(PlayerDumpWriter().WriteDump(file, guid))
5548 case DUMP_SUCCESS:
5549 PSendSysMessage(LANG_COMMAND_EXPORT_SUCCESS);
5550 break;
5551 case DUMP_FILE_OPEN_ERROR:
5552 PSendSysMessage(LANG_FILE_OPEN_FAIL,file);
5553 SetSentErrorMessage(true);
5554 return false;
5555 default:
5556 PSendSysMessage(LANG_COMMAND_EXPORT_FAILED);
5557 SetSentErrorMessage(true);
5558 return false;
5561 return true;
5564 bool ChatHandler::HandleMovegensCommand(const char* /*args*/)
5566 Unit* unit = getSelectedUnit();
5567 if(!unit)
5569 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5570 SetSentErrorMessage(true);
5571 return false;
5574 PSendSysMessage(LANG_MOVEGENS_LIST,(unit->GetTypeId()==TYPEID_PLAYER ? "Player" : "Creature" ),unit->GetGUIDLow());
5576 MotionMaster* mm = unit->GetMotionMaster();
5577 for(MotionMaster::const_iterator itr = mm->begin(); itr != mm->end(); ++itr)
5579 switch((*itr)->GetMovementGeneratorType())
5581 case IDLE_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_IDLE); break;
5582 case RANDOM_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_RANDOM); break;
5583 case WAYPOINT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_WAYPOINT); break;
5584 case ANIMAL_RANDOM_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_ANIMAL_RANDOM); break;
5585 case CONFUSED_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_CONFUSED); break;
5586 case TARGETED_MOTION_TYPE:
5588 if(unit->GetTypeId()==TYPEID_PLAYER)
5590 TargetedMovementGenerator<Player> const* mgen = static_cast<TargetedMovementGenerator<Player> const*>(*itr);
5591 Unit* target = mgen->GetTarget();
5592 if(target)
5593 PSendSysMessage(LANG_MOVEGENS_TARGETED_PLAYER,target->GetName(),target->GetGUIDLow());
5594 else
5595 SendSysMessage(LANG_MOVEGENS_TARGETED_NULL);
5597 else
5599 TargetedMovementGenerator<Creature> const* mgen = static_cast<TargetedMovementGenerator<Creature> const*>(*itr);
5600 Unit* target = mgen->GetTarget();
5601 if(target)
5602 PSendSysMessage(LANG_MOVEGENS_TARGETED_CREATURE,target->GetName(),target->GetGUIDLow());
5603 else
5604 SendSysMessage(LANG_MOVEGENS_TARGETED_NULL);
5606 break;
5608 case HOME_MOTION_TYPE:
5609 if(unit->GetTypeId()==TYPEID_UNIT)
5611 float x,y,z;
5612 (*itr)->GetDestination(x,y,z);
5613 PSendSysMessage(LANG_MOVEGENS_HOME_CREATURE,x,y,z);
5615 else
5616 SendSysMessage(LANG_MOVEGENS_HOME_PLAYER);
5617 break;
5618 case FLIGHT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_FLIGHT); break;
5619 case POINT_MOTION_TYPE:
5621 float x,y,z;
5622 (*itr)->GetDestination(x,y,z);
5623 PSendSysMessage(LANG_MOVEGENS_POINT,x,y,z);
5624 break;
5626 case FLEEING_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_FEAR); break;
5627 case DISTRACT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_DISTRACT); break;
5628 default:
5629 PSendSysMessage(LANG_MOVEGENS_UNKNOWN,(*itr)->GetMovementGeneratorType());
5630 break;
5633 return true;
5636 bool ChatHandler::HandlePLimitCommand(const char *args)
5638 if(*args)
5640 char* param = strtok((char*)args, " ");
5641 if(!param)
5642 return false;
5644 int l = strlen(param);
5646 if( strncmp(param,"player",l) == 0 )
5647 sWorld.SetPlayerLimit(-SEC_PLAYER);
5648 else if(strncmp(param,"moderator",l) == 0 )
5649 sWorld.SetPlayerLimit(-SEC_MODERATOR);
5650 else if(strncmp(param,"gamemaster",l) == 0 )
5651 sWorld.SetPlayerLimit(-SEC_GAMEMASTER);
5652 else if(strncmp(param,"administrator",l) == 0 )
5653 sWorld.SetPlayerLimit(-SEC_ADMINISTRATOR);
5654 else if(strncmp(param,"reset",l) == 0 )
5655 sWorld.SetPlayerLimit( sConfig.GetIntDefault("PlayerLimit", DEFAULT_PLAYER_LIMIT) );
5656 else
5658 int val = atoi(param);
5659 if(val < -SEC_ADMINISTRATOR) val = -SEC_ADMINISTRATOR;
5661 sWorld.SetPlayerLimit(val);
5664 // kick all low security level players
5665 if(sWorld.GetPlayerAmountLimit() > SEC_PLAYER)
5666 sWorld.KickAllLess(sWorld.GetPlayerSecurityLimit());
5669 uint32 pLimit = sWorld.GetPlayerAmountLimit();
5670 AccountTypes allowedAccountType = sWorld.GetPlayerSecurityLimit();
5671 char const* secName = "";
5672 switch(allowedAccountType)
5674 case SEC_PLAYER: secName = "Player"; break;
5675 case SEC_MODERATOR: secName = "Moderator"; break;
5676 case SEC_GAMEMASTER: secName = "Gamemaster"; break;
5677 case SEC_ADMINISTRATOR: secName = "Administrator"; break;
5678 default: secName = "<unknown>"; break;
5681 PSendSysMessage("Player limits: amount %u, min. security level %s.",pLimit,secName);
5683 return true;
5686 bool ChatHandler::HandleCastCommand(const char* args)
5688 if(!*args)
5689 return false;
5691 Unit* target = getSelectedUnit();
5693 if(!target)
5695 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5696 SetSentErrorMessage(true);
5697 return false;
5700 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5701 uint32 spell = extractSpellIdFromLink((char*)args);
5702 if(!spell)
5703 return false;
5705 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
5706 if(!spellInfo)
5707 return false;
5709 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
5711 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
5712 SetSentErrorMessage(true);
5713 return false;
5716 char* trig_str = strtok(NULL, " ");
5717 if(trig_str)
5719 int l = strlen(trig_str);
5720 if(strncmp(trig_str,"triggered",l) != 0 )
5721 return false;
5724 bool triggered = (trig_str != NULL);
5726 m_session->GetPlayer()->CastSpell(target,spell,triggered);
5728 return true;
5731 bool ChatHandler::HandleCastBackCommand(const char* args)
5733 Creature* caster = getSelectedCreature();
5735 if(!caster)
5737 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5738 SetSentErrorMessage(true);
5739 return false;
5742 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
5743 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5744 uint32 spell = extractSpellIdFromLink((char*)args);
5745 if(!spell || !sSpellStore.LookupEntry(spell))
5746 return false;
5748 char* trig_str = strtok(NULL, " ");
5749 if(trig_str)
5751 int l = strlen(trig_str);
5752 if(strncmp(trig_str,"triggered",l) != 0 )
5753 return false;
5756 bool triggered = (trig_str != NULL);
5758 // update orientation at server
5759 caster->SetOrientation(caster->GetAngle(m_session->GetPlayer()));
5761 // and client
5762 WorldPacket data;
5763 caster->BuildHeartBeatMsg(&data);
5764 caster->SendMessageToSet(&data,true);
5766 caster->CastSpell(m_session->GetPlayer(),spell,triggered);
5768 return true;
5771 bool ChatHandler::HandleCastDistCommand(const char* args)
5773 if(!*args)
5774 return false;
5776 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5777 uint32 spell = extractSpellIdFromLink((char*)args);
5778 if(!spell)
5779 return false;
5781 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
5782 if(!spellInfo)
5783 return false;
5785 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
5787 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
5788 SetSentErrorMessage(true);
5789 return false;
5792 char *distStr = strtok(NULL, " ");
5794 float dist = 0;
5796 if(distStr)
5797 sscanf(distStr, "%f", &dist);
5799 char* trig_str = strtok(NULL, " ");
5800 if(trig_str)
5802 int l = strlen(trig_str);
5803 if(strncmp(trig_str,"triggered",l) != 0 )
5804 return false;
5807 bool triggered = (trig_str != NULL);
5809 float x,y,z;
5810 m_session->GetPlayer()->GetClosePoint(x,y,z,dist);
5812 m_session->GetPlayer()->CastSpell(x,y,z,spell,triggered);
5813 return true;
5816 bool ChatHandler::HandleCastTargetCommand(const char* args)
5818 Creature* caster = getSelectedCreature();
5820 if(!caster)
5822 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5823 SetSentErrorMessage(true);
5824 return false;
5827 if(!caster->getVictim())
5829 SendSysMessage(LANG_SELECTED_TARGET_NOT_HAVE_VICTIM);
5830 SetSentErrorMessage(true);
5831 return false;
5834 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5835 uint32 spell = extractSpellIdFromLink((char*)args);
5836 if(!spell || !sSpellStore.LookupEntry(spell))
5837 return false;
5839 char* trig_str = strtok(NULL, " ");
5840 if(trig_str)
5842 int l = strlen(trig_str);
5843 if(strncmp(trig_str,"triggered",l) != 0 )
5844 return false;
5847 bool triggered = (trig_str != NULL);
5849 // update orientation at server
5850 caster->SetOrientation(caster->GetAngle(m_session->GetPlayer()));
5852 // and client
5853 WorldPacket data;
5854 caster->BuildHeartBeatMsg(&data);
5855 caster->SendMessageToSet(&data,true);
5857 caster->CastSpell(caster->getVictim(),spell,triggered);
5859 return true;
5863 ComeToMe command REQUIRED for 3rd party scripting library to have access to PointMovementGenerator
5864 Without this function 3rd party scripting library will get linking errors (unresolved external)
5865 when attempting to use the PointMovementGenerator
5867 bool ChatHandler::HandleComeToMeCommand(const char *args)
5869 Creature* caster = getSelectedCreature();
5871 if(!caster)
5873 SendSysMessage(LANG_SELECT_CREATURE);
5874 SetSentErrorMessage(true);
5875 return false;
5878 char* newFlagStr = strtok((char*)args, " ");
5880 if(!newFlagStr)
5881 return false;
5883 uint32 newFlags = atoi(newFlagStr);
5885 caster->SetUnitMovementFlags(newFlags);
5887 Player* pl = m_session->GetPlayer();
5889 caster->GetMotionMaster()->MovePoint(0, pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ());
5890 return true;
5893 bool ChatHandler::HandleCastSelfCommand(const char* args)
5895 if(!*args)
5896 return false;
5898 Unit* target = getSelectedUnit();
5900 if(!target)
5902 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5903 SetSentErrorMessage(true);
5904 return false;
5907 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5908 uint32 spell = extractSpellIdFromLink((char*)args);
5909 if(!spell)
5910 return false;
5912 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
5913 if(!spellInfo)
5914 return false;
5916 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
5918 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
5919 SetSentErrorMessage(true);
5920 return false;
5923 target->CastSpell(target,spell,false);
5925 return true;
5928 std::string GetTimeString(uint32 time)
5930 uint16 days = time / DAY, hours = (time % DAY) / HOUR, minute = (time % HOUR) / MINUTE;
5931 std::ostringstream ss;
5932 if(days) ss << days << "d ";
5933 if(hours) ss << hours << "h ";
5934 ss << minute << "m";
5935 return ss.str();
5938 bool ChatHandler::HandleInstanceListBindsCommand(const char* /*args*/)
5940 Player* player = getSelectedPlayer();
5941 if (!player) player = m_session->GetPlayer();
5942 uint32 counter = 0;
5943 for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++)
5945 Player::BoundInstancesMap &binds = player->GetBoundInstances(i);
5946 for(Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end(); ++itr)
5948 InstanceSave *save = itr->second.save;
5949 std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
5950 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());
5951 counter++;
5954 PSendSysMessage("player binds: %d", counter);
5955 counter = 0;
5956 Group *group = player->GetGroup();
5957 if(group)
5959 for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++)
5961 Group::BoundInstancesMap &binds = group->GetBoundInstances(i);
5962 for(Group::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end(); ++itr)
5964 InstanceSave *save = itr->second.save;
5965 std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
5966 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());
5967 counter++;
5971 PSendSysMessage("group binds: %d", counter);
5973 return true;
5976 bool ChatHandler::HandleInstanceUnbindCommand(const char* args)
5978 if(!*args)
5979 return false;
5981 std::string cmd = args;
5982 if(cmd == "all")
5984 Player* player = getSelectedPlayer();
5985 if (!player) player = m_session->GetPlayer();
5986 uint32 counter = 0;
5987 for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++)
5989 Player::BoundInstancesMap &binds = player->GetBoundInstances(i);
5990 for(Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end();)
5992 if(itr->first != player->GetMapId())
5994 InstanceSave *save = itr->second.save;
5995 std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
5996 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());
5997 player->UnbindInstance(itr, i);
5998 counter++;
6000 else
6001 ++itr;
6004 PSendSysMessage("instances unbound: %d", counter);
6006 return true;
6009 bool ChatHandler::HandleInstanceStatsCommand(const char* /*args*/)
6011 PSendSysMessage("instances loaded: %d", MapManager::Instance().GetNumInstances());
6012 PSendSysMessage("players in instances: %d", MapManager::Instance().GetNumPlayersInInstances());
6013 PSendSysMessage("instance saves: %d", sInstanceSaveManager.GetNumInstanceSaves());
6014 PSendSysMessage("players bound: %d", sInstanceSaveManager.GetNumBoundPlayersTotal());
6015 PSendSysMessage("groups bound: %d", sInstanceSaveManager.GetNumBoundGroupsTotal());
6016 return true;
6019 bool ChatHandler::HandleInstanceSaveDataCommand(const char * /*args*/)
6021 Player* pl = m_session->GetPlayer();
6023 Map* map = pl->GetMap();
6024 if (!map->IsDungeon())
6026 PSendSysMessage("Map is not a dungeon.");
6027 SetSentErrorMessage(true);
6028 return false;
6031 if (!((InstanceMap*)map)->GetInstanceData())
6033 PSendSysMessage("Map has no instance data.");
6034 SetSentErrorMessage(true);
6035 return false;
6038 ((InstanceMap*)map)->GetInstanceData()->SaveToDB();
6039 return true;
6042 /// Display the list of GMs
6043 bool ChatHandler::HandleGMListFullCommand(const char* /*args*/)
6045 ///- Get the accounts with GM Level >0
6046 QueryResult *result = loginDatabase.Query( "SELECT username,gmlevel FROM account WHERE gmlevel > 0" );
6047 if(result)
6049 SendSysMessage(LANG_GMLIST);
6050 SendSysMessage("========================");
6051 SendSysMessage(LANG_GMLIST_HEADER);
6052 SendSysMessage("========================");
6054 ///- Circle through them. Display username and GM level
6057 Field *fields = result->Fetch();
6058 PSendSysMessage("|%15s|%6s|", fields[0].GetString(),fields[1].GetString());
6059 }while( result->NextRow() );
6061 PSendSysMessage("========================");
6062 delete result;
6064 else
6065 PSendSysMessage(LANG_GMLIST_EMPTY);
6066 return true;
6069 /// Define the 'Message of the day' for the realm
6070 bool ChatHandler::HandleServerSetMotdCommand(const char* args)
6072 sWorld.SetMotd(args);
6073 PSendSysMessage(LANG_MOTD_NEW, args);
6074 return true;
6077 /// Set/Unset the expansion level for an account
6078 bool ChatHandler::HandleAccountSetAddonCommand(const char* args)
6080 ///- Get the command line arguments
6081 char *szAcc = strtok((char*)args," ");
6082 char *szExp = strtok(NULL," ");
6084 if(!szAcc)
6085 return false;
6087 std::string account_name;
6088 uint32 account_id;
6090 if(!szExp)
6092 Player* player = getSelectedPlayer();
6093 if(!player)
6094 return false;
6096 account_id = player->GetSession()->GetAccountId();
6097 accmgr.GetName(account_id,account_name);
6098 szExp = szAcc;
6100 else
6102 ///- Convert Account name to Upper Format
6103 account_name = szAcc;
6104 if(!AccountMgr::normilizeString(account_name))
6106 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
6107 SetSentErrorMessage(true);
6108 return false;
6111 account_id = accmgr.GetId(account_name);
6112 if(!account_id)
6114 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
6115 SetSentErrorMessage(true);
6116 return false;
6120 int lev=atoi(szExp); //get int anyway (0 if error)
6121 if(lev < 0)
6122 return false;
6124 // No SQL injection
6125 loginDatabase.PExecute("UPDATE account SET expansion = '%d' WHERE id = '%u'",lev,account_id);
6126 PSendSysMessage(LANG_ACCOUNT_SETADDON,account_name.c_str(),account_id,lev);
6127 return true;
6130 //Send items by mail
6131 bool ChatHandler::HandleSendItemsCommand(const char* args)
6133 if(!*args)
6134 return false;
6136 // format: name "subject text" "mail text" item1[:count1] item2[:count2] ... item12[:count12]
6138 char* pName = strtok((char*)args, " ");
6139 if(!pName)
6140 return false;
6142 char* tail1 = strtok(NULL, "");
6143 if(!tail1)
6144 return false;
6146 char* msgSubject;
6147 if(*tail1=='"')
6148 msgSubject = strtok(tail1+1, "\"");
6149 else
6151 char* space = strtok(tail1, "\"");
6152 if(!space)
6153 return false;
6154 msgSubject = strtok(NULL, "\"");
6157 if (!msgSubject)
6158 return false;
6160 char* tail2 = strtok(NULL, "");
6161 if(!tail2)
6162 return false;
6164 char* msgText;
6165 if(*tail2=='"')
6166 msgText = strtok(tail2+1, "\"");
6167 else
6169 char* space = strtok(tail2, "\"");
6170 if(!space)
6171 return false;
6172 msgText = strtok(NULL, "\"");
6175 if (!msgText)
6176 return false;
6178 // pName, msgSubject, msgText isn't NUL after prev. check
6179 std::string name = pName;
6180 std::string subject = msgSubject;
6181 std::string text = msgText;
6183 // extract items
6184 typedef std::pair<uint32,uint32> ItemPair;
6185 typedef std::list< ItemPair > ItemPairs;
6186 ItemPairs items;
6188 // get all tail string
6189 char* tail = strtok(NULL, "");
6191 // get from tail next item str
6192 while(char* itemStr = strtok(tail, " "))
6194 // and get new tail
6195 tail = strtok(NULL, "");
6197 // parse item str
6198 char* itemIdStr = strtok(itemStr, ":");
6199 char* itemCountStr = strtok(NULL, " ");
6201 uint32 item_id = atoi(itemIdStr);
6202 if(!item_id)
6203 return false;
6205 ItemPrototype const* item_proto = objmgr.GetItemPrototype(item_id);
6206 if(!item_proto)
6208 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
6209 SetSentErrorMessage(true);
6210 return false;
6213 uint32 item_count = itemCountStr ? atoi(itemCountStr) : 1;
6214 if(item_count < 1 || item_proto->MaxCount && item_count > item_proto->MaxCount)
6216 PSendSysMessage(LANG_COMMAND_INVALID_ITEM_COUNT, item_count,item_id);
6217 SetSentErrorMessage(true);
6218 return false;
6221 while(item_count > item_proto->Stackable)
6223 items.push_back(ItemPair(item_id,item_proto->Stackable));
6224 item_count -= item_proto->Stackable;
6227 items.push_back(ItemPair(item_id,item_count));
6229 if(items.size() > MAX_MAIL_ITEMS)
6231 PSendSysMessage(LANG_COMMAND_MAIL_ITEMS_LIMIT, MAX_MAIL_ITEMS);
6232 SetSentErrorMessage(true);
6233 return false;
6237 if(!normalizePlayerName(name))
6239 SendSysMessage(LANG_PLAYER_NOT_FOUND);
6240 SetSentErrorMessage(true);
6241 return false;
6244 uint64 receiver_guid = objmgr.GetPlayerGUIDByName(name);
6245 if(!receiver_guid)
6247 SendSysMessage(LANG_PLAYER_NOT_FOUND);
6248 SetSentErrorMessage(true);
6249 return false;
6252 // from console show not existed sender
6253 uint32 sender_guidlo = m_session ? m_session->GetPlayer()->GetGUIDLow() : 0;
6255 uint32 messagetype = MAIL_NORMAL;
6256 uint32 stationery = MAIL_STATIONERY_GM;
6257 uint32 itemTextId = !text.empty() ? objmgr.CreateItemText( text ) : 0;
6259 Player *receiver = objmgr.GetPlayer(receiver_guid);
6261 // fill mail
6262 MailItemsInfo mi; // item list preparing
6264 for(ItemPairs::const_iterator itr = items.begin(); itr != items.end(); ++itr)
6266 if(Item* item = Item::CreateItem(itr->first,itr->second,m_session ? m_session->GetPlayer() : 0))
6268 item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted
6269 mi.AddItem(item->GetGUIDLow(), item->GetEntry(), item);
6273 WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, &mi, 0, 0, MAIL_CHECK_MASK_NONE);
6275 PSendSysMessage(LANG_MAIL_SENT, name.c_str());
6276 return true;
6279 ///Send money by mail
6280 bool ChatHandler::HandleSendMoneyCommand(const char* args)
6282 if (!*args)
6283 return false;
6285 /// format: name "subject text" "mail text" money
6287 char* pName = strtok((char*)args, " ");
6288 if (!pName)
6289 return false;
6291 char* tail1 = strtok(NULL, "");
6292 if (!tail1)
6293 return false;
6295 char* msgSubject;
6296 if (*tail1=='"')
6297 msgSubject = strtok(tail1+1, "\"");
6298 else
6300 char* space = strtok(tail1, "\"");
6301 if (!space)
6302 return false;
6303 msgSubject = strtok(NULL, "\"");
6306 if (!msgSubject)
6307 return false;
6309 char* tail2 = strtok(NULL, "");
6310 if (!tail2)
6311 return false;
6313 char* msgText;
6314 if (*tail2=='"')
6315 msgText = strtok(tail2+1, "\"");
6316 else
6318 char* space = strtok(tail2, "\"");
6319 if (!space)
6320 return false;
6321 msgText = strtok(NULL, "\"");
6324 if (!msgText)
6325 return false;
6327 char* money_str = strtok(NULL, "");
6328 int32 money = money_str ? atoi(money_str) : 0;
6329 if (money <= 0)
6330 return false;
6332 // pName, msgSubject, msgText isn't NUL after prev. check
6333 std::string name = pName;
6334 std::string subject = msgSubject;
6335 std::string text = msgText;
6337 if (!normalizePlayerName(name))
6339 SendSysMessage(LANG_PLAYER_NOT_FOUND);
6340 SetSentErrorMessage(true);
6341 return false;
6344 uint64 receiver_guid = objmgr.GetPlayerGUIDByName(name);
6345 if (!receiver_guid)
6347 SendSysMessage(LANG_PLAYER_NOT_FOUND);
6348 SetSentErrorMessage(true);
6349 return false;
6352 uint32 mailId = objmgr.GenerateMailID();
6354 // from console show not existed sender
6355 uint32 sender_guidlo = m_session ? m_session->GetPlayer()->GetGUIDLow() : 0;
6357 uint32 messagetype = MAIL_NORMAL;
6358 uint32 stationery = MAIL_STATIONERY_GM;
6359 uint32 itemTextId = !text.empty() ? objmgr.CreateItemText( text ) : 0;
6361 Player *receiver = objmgr.GetPlayer(receiver_guid);
6363 WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, NULL, money, 0, MAIL_CHECK_MASK_NONE);
6365 PSendSysMessage(LANG_MAIL_SENT, name.c_str());
6366 return true;
6369 /// Send a message to a player in game
6370 bool ChatHandler::HandleSendMessageCommand(const char* args)
6372 ///- Get the command line arguments
6373 char* name_str = strtok((char*)args, " ");
6374 char* msg_str = strtok(NULL, "");
6376 if(!name_str || !msg_str)
6377 return false;
6379 std::string name = name_str;
6381 if(!normalizePlayerName(name))
6382 return false;
6384 ///- Find the player and check that he is not logging out.
6385 Player *rPlayer = objmgr.GetPlayer(name.c_str());
6386 if(!rPlayer)
6388 SendSysMessage(LANG_PLAYER_NOT_FOUND);
6389 SetSentErrorMessage(true);
6390 return false;
6393 if(rPlayer->GetSession()->isLogingOut())
6395 SendSysMessage(LANG_PLAYER_NOT_FOUND);
6396 SetSentErrorMessage(true);
6397 return false;
6400 ///- Send the message
6401 //Use SendAreaTriggerMessage for fastest delivery.
6402 rPlayer->GetSession()->SendAreaTriggerMessage("%s", msg_str);
6403 rPlayer->GetSession()->SendAreaTriggerMessage("|cffff0000[Message from administrator]:|r");
6405 //Confirmation message
6406 PSendSysMessage(LANG_SENDMESSAGE,name.c_str(),msg_str);
6407 return true;
6410 bool ChatHandler::HandleModifyGenderCommand(const char *args)
6412 if(!*args)
6413 return false;
6415 Player *player = getSelectedPlayer();
6417 if(!player)
6419 PSendSysMessage(LANG_NO_PLAYER);
6420 SetSentErrorMessage(true);
6421 return false;
6424 char const* gender_str = (char*)args;
6425 int gender_len = strlen(gender_str);
6427 uint32 displayId = player->GetNativeDisplayId();
6428 char const* gender_full = NULL;
6429 uint32 new_displayId = displayId;
6430 Gender gender;
6432 if(!strncmp(gender_str,"male",gender_len)) // MALE
6434 if(player->getGender() == GENDER_MALE)
6435 return true;
6437 gender_full = "male";
6438 new_displayId = player->getRace() == RACE_BLOODELF ? displayId+1 : displayId-1;
6439 gender = GENDER_MALE;
6441 else if (!strncmp(gender_str,"female",gender_len)) // FEMALE
6443 if(player->getGender() == GENDER_FEMALE)
6444 return true;
6446 gender_full = "female";
6447 new_displayId = player->getRace() == RACE_BLOODELF ? displayId-1 : displayId+1;
6448 gender = GENDER_FEMALE;
6450 else
6452 SendSysMessage(LANG_MUST_MALE_OR_FEMALE);
6453 SetSentErrorMessage(true);
6454 return false;
6457 // Set gender
6458 player->SetByteValue(UNIT_FIELD_BYTES_0, 2, gender);
6460 // Change display ID
6461 player->SetDisplayId(new_displayId);
6462 player->SetNativeDisplayId(new_displayId);
6464 PSendSysMessage(LANG_YOU_CHANGE_GENDER, player->GetName(),gender_full);
6465 if (needReportToTarget(player))
6466 ChatHandler(player).PSendSysMessage(LANG_YOUR_GENDER_CHANGED, gender_full,GetName());
6467 return true;