[6982] Implemented gmlevel-based command security
[getmangos.git] / src / game / Level3.cpp
blob5383ecfcb8c946c251aa003b3c5b2eceb99eecb2
1 /*
2 * Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include "Common.h"
20 #include "Database/DatabaseEnv.h"
21 #include "WorldPacket.h"
22 #include "WorldSession.h"
23 #include "World.h"
24 #include "ObjectMgr.h"
25 #include "AccountMgr.h"
26 #include "PlayerDump.h"
27 #include "SpellMgr.h"
28 #include "Player.h"
29 #include "Opcodes.h"
30 #include "GameObject.h"
31 #include "Chat.h"
32 #include "Log.h"
33 #include "Guild.h"
34 #include "ObjectAccessor.h"
35 #include "MapManager.h"
36 #include "SpellAuras.h"
37 #include "ScriptCalls.h"
38 #include "Language.h"
39 #include "GridNotifiersImpl.h"
40 #include "CellImpl.h"
41 #include "Weather.h"
42 #include "PointMovementGenerator.h"
43 #include "TargetedMovementGenerator.h"
44 #include "SkillDiscovery.h"
45 #include "SkillExtraItems.h"
46 #include "SystemConfig.h"
47 #include "Config/ConfigEnv.h"
48 #include "Util.h"
49 #include "ItemEnchantmentMgr.h"
50 #include "BattleGroundMgr.h"
51 #include "InstanceSaveMgr.h"
52 #include "InstanceData.h"
54 //reload commands
55 bool ChatHandler::HandleReloadAllCommand(const char*)
57 HandleReloadAreaTriggerTeleportCommand("");
58 HandleReloadSkillFishingBaseLevelCommand("");
60 HandleReloadAllAreaCommand("");
61 HandleReloadAllLootCommand("");
62 HandleReloadAllNpcCommand("");
63 HandleReloadAllQuestCommand("");
64 HandleReloadAllSpellCommand("");
65 HandleReloadAllItemCommand("");
66 HandleReloadAllLocalesCommand("");
68 HandleReloadCommandCommand("");
69 HandleReloadReservedNameCommand("");
70 HandleReloadMangosStringCommand("");
71 HandleReloadGameTeleCommand("");
72 return true;
75 bool ChatHandler::HandleReloadAllAreaCommand(const char*)
77 //HandleReloadQuestAreaTriggersCommand(""); -- reloaded in HandleReloadAllQuestCommand
78 HandleReloadAreaTriggerTeleportCommand("");
79 HandleReloadAreaTriggerTavernCommand("");
80 HandleReloadGameGraveyardZoneCommand("");
81 return true;
84 bool ChatHandler::HandleReloadAllLootCommand(const char*)
86 sLog.outString( "Re-Loading Loot Tables..." );
87 LoadLootTables();
88 SendGlobalSysMessage("DB tables `*_loot_template` reloaded.");
89 return true;
92 bool ChatHandler::HandleReloadAllNpcCommand(const char* /*args*/)
94 HandleReloadNpcGossipCommand("a");
95 HandleReloadNpcOptionCommand("a");
96 HandleReloadNpcTrainerCommand("a");
97 HandleReloadNpcVendorCommand("a");
98 return true;
101 bool ChatHandler::HandleReloadAllQuestCommand(const char* /*args*/)
103 HandleReloadQuestAreaTriggersCommand("a");
104 HandleReloadQuestTemplateCommand("a");
106 sLog.outString( "Re-Loading Quests Relations..." );
107 objmgr.LoadQuestRelations();
108 SendGlobalSysMessage("DB tables `*_questrelation` and `*_involvedrelation` reloaded.");
109 return true;
112 bool ChatHandler::HandleReloadAllScriptsCommand(const char*)
114 if(sWorld.IsScriptScheduled())
116 PSendSysMessage("DB scripts used currently, please attempt reload later.");
117 SetSentErrorMessage(true);
118 return false;
121 sLog.outString( "Re-Loading Scripts..." );
122 HandleReloadGameObjectScriptsCommand("a");
123 HandleReloadEventScriptsCommand("a");
124 HandleReloadQuestEndScriptsCommand("a");
125 HandleReloadQuestStartScriptsCommand("a");
126 HandleReloadSpellScriptsCommand("a");
127 SendGlobalSysMessage("DB tables `*_scripts` reloaded.");
128 HandleReloadDbScriptStringCommand("a");
129 return true;
132 bool ChatHandler::HandleReloadAllSpellCommand(const char*)
134 HandleReloadSkillDiscoveryTemplateCommand("a");
135 HandleReloadSkillExtraItemTemplateCommand("a");
136 HandleReloadSpellAffectCommand("a");
137 HandleReloadSpellChainCommand("a");
138 HandleReloadSpellElixirCommand("a");
139 HandleReloadSpellLearnSpellCommand("a");
140 HandleReloadSpellProcEventCommand("a");
141 HandleReloadSpellScriptTargetCommand("a");
142 HandleReloadSpellTargetPositionCommand("a");
143 HandleReloadSpellThreatsCommand("a");
144 HandleReloadSpellPetAurasCommand("a");
145 return true;
148 bool ChatHandler::HandleReloadAllItemCommand(const char*)
150 HandleReloadPageTextsCommand("a");
151 HandleReloadItemEnchantementsCommand("a");
152 return true;
155 bool ChatHandler::HandleReloadAllLocalesCommand(const char* /*args*/)
157 HandleReloadLocalesCreatureCommand("a");
158 HandleReloadLocalesGameobjectCommand("a");
159 HandleReloadLocalesItemCommand("a");
160 HandleReloadLocalesNpcTextCommand("a");
161 HandleReloadLocalesPageTextCommand("a");
162 HandleReloadLocalesQuestCommand("a");
163 return true;
166 bool ChatHandler::HandleReloadConfigCommand(const char* /*args*/)
168 sLog.outString( "Re-Loading config settings..." );
169 sWorld.LoadConfigSettings(true);
170 SendGlobalSysMessage("World config settings reloaded.");
171 return true;
174 bool ChatHandler::HandleReloadAreaTriggerTavernCommand(const char*)
176 sLog.outString( "Re-Loading Tavern Area Triggers..." );
177 objmgr.LoadTavernAreaTriggers();
178 SendGlobalSysMessage("DB table `areatrigger_tavern` reloaded.");
179 return true;
182 bool ChatHandler::HandleReloadAreaTriggerTeleportCommand(const char*)
184 sLog.outString( "Re-Loading AreaTrigger teleport definitions..." );
185 objmgr.LoadAreaTriggerTeleports();
186 SendGlobalSysMessage("DB table `areatrigger_teleport` reloaded.");
187 return true;
190 bool ChatHandler::HandleReloadCommandCommand(const char*)
192 load_command_table = true;
193 SendGlobalSysMessage("DB table `command` will be reloaded at next chat command use.");
194 return true;
197 bool ChatHandler::HandleReloadCreatureQuestRelationsCommand(const char*)
199 sLog.outString( "Loading Quests Relations... (`creature_questrelation`)" );
200 objmgr.LoadCreatureQuestRelations();
201 SendGlobalSysMessage("DB table `creature_questrelation` (creature quest givers) reloaded.");
202 return true;
205 bool ChatHandler::HandleReloadCreatureQuestInvRelationsCommand(const char*)
207 sLog.outString( "Loading Quests Relations... (`creature_involvedrelation`)" );
208 objmgr.LoadCreatureInvolvedRelations();
209 SendGlobalSysMessage("DB table `creature_involvedrelation` (creature quest takers) reloaded.");
210 return true;
213 bool ChatHandler::HandleReloadGOQuestRelationsCommand(const char*)
215 sLog.outString( "Loading Quests Relations... (`gameobject_questrelation`)" );
216 objmgr.LoadGameobjectQuestRelations();
217 SendGlobalSysMessage("DB table `gameobject_questrelation` (gameobject quest givers) reloaded.");
218 return true;
221 bool ChatHandler::HandleReloadGOQuestInvRelationsCommand(const char*)
223 sLog.outString( "Loading Quests Relations... (`gameobject_involvedrelation`)" );
224 objmgr.LoadGameobjectInvolvedRelations();
225 SendGlobalSysMessage("DB table `gameobject_involvedrelation` (gameobject quest takers) reloaded.");
226 return true;
229 bool ChatHandler::HandleReloadQuestAreaTriggersCommand(const char*)
231 sLog.outString( "Re-Loading Quest Area Triggers..." );
232 objmgr.LoadQuestAreaTriggers();
233 SendGlobalSysMessage("DB table `areatrigger_involvedrelation` (quest area triggers) reloaded.");
234 return true;
237 bool ChatHandler::HandleReloadQuestTemplateCommand(const char*)
239 sLog.outString( "Re-Loading Quest Templates..." );
240 objmgr.LoadQuests();
241 SendGlobalSysMessage("DB table `quest_template` (quest definitions) reloaded.");
242 return true;
245 bool ChatHandler::HandleReloadLootTemplatesCreatureCommand(const char*)
247 sLog.outString( "Re-Loading Loot Tables... (`creature_loot_template`)" );
248 LoadLootTemplates_Creature();
249 LootTemplates_Creature.CheckLootRefs();
250 SendGlobalSysMessage("DB table `creature_loot_template` reloaded.");
251 return true;
254 bool ChatHandler::HandleReloadLootTemplatesDisenchantCommand(const char*)
256 sLog.outString( "Re-Loading Loot Tables... (`disenchant_loot_template`)" );
257 LoadLootTemplates_Disenchant();
258 LootTemplates_Disenchant.CheckLootRefs();
259 SendGlobalSysMessage("DB table `disenchant_loot_template` reloaded.");
260 return true;
263 bool ChatHandler::HandleReloadLootTemplatesFishingCommand(const char*)
265 sLog.outString( "Re-Loading Loot Tables... (`fishing_loot_template`)" );
266 LoadLootTemplates_Fishing();
267 LootTemplates_Fishing.CheckLootRefs();
268 SendGlobalSysMessage("DB table `fishing_loot_template` reloaded.");
269 return true;
272 bool ChatHandler::HandleReloadLootTemplatesGameobjectCommand(const char*)
274 sLog.outString( "Re-Loading Loot Tables... (`gameobject_loot_template`)" );
275 LoadLootTemplates_Gameobject();
276 LootTemplates_Gameobject.CheckLootRefs();
277 SendGlobalSysMessage("DB table `gameobject_loot_template` reloaded.");
278 return true;
281 bool ChatHandler::HandleReloadLootTemplatesItemCommand(const char*)
283 sLog.outString( "Re-Loading Loot Tables... (`item_loot_template`)" );
284 LoadLootTemplates_Item();
285 LootTemplates_Item.CheckLootRefs();
286 SendGlobalSysMessage("DB table `item_loot_template` reloaded.");
287 return true;
290 bool ChatHandler::HandleReloadLootTemplatesMillingCommand(const char*)
292 sLog.outString( "Re-Loading Loot Tables... (`milling_loot_template`)" );
293 LoadLootTemplates_Milling();
294 LootTemplates_Milling.CheckLootRefs();
295 SendGlobalSysMessage("DB table `milling_loot_template` reloaded.");
296 return true;
299 bool ChatHandler::HandleReloadLootTemplatesPickpocketingCommand(const char*)
301 sLog.outString( "Re-Loading Loot Tables... (`pickpocketing_loot_template`)" );
302 LoadLootTemplates_Pickpocketing();
303 LootTemplates_Pickpocketing.CheckLootRefs();
304 SendGlobalSysMessage("DB table `pickpocketing_loot_template` reloaded.");
305 return true;
308 bool ChatHandler::HandleReloadLootTemplatesProspectingCommand(const char*)
310 sLog.outString( "Re-Loading Loot Tables... (`prospecting_loot_template`)" );
311 LoadLootTemplates_Prospecting();
312 LootTemplates_Prospecting.CheckLootRefs();
313 SendGlobalSysMessage("DB table `prospecting_loot_template` reloaded.");
314 return true;
317 bool ChatHandler::HandleReloadLootTemplatesQuestMailCommand(const char*)
319 sLog.outString( "Re-Loading Loot Tables... (`quest_mail_loot_template`)" );
320 LoadLootTemplates_QuestMail();
321 LootTemplates_QuestMail.CheckLootRefs();
322 SendGlobalSysMessage("DB table `quest_mail_loot_template` reloaded.");
323 return true;
326 bool ChatHandler::HandleReloadLootTemplatesReferenceCommand(const char*)
328 sLog.outString( "Re-Loading Loot Tables... (`reference_loot_template`)" );
329 LoadLootTemplates_Reference();
330 SendGlobalSysMessage("DB table `reference_loot_template` reloaded.");
331 return true;
334 bool ChatHandler::HandleReloadLootTemplatesSkinningCommand(const char*)
336 sLog.outString( "Re-Loading Loot Tables... (`skinning_loot_template`)" );
337 LoadLootTemplates_Skinning();
338 LootTemplates_Skinning.CheckLootRefs();
339 SendGlobalSysMessage("DB table `skinning_loot_template` reloaded.");
340 return true;
343 bool ChatHandler::HandleReloadMangosStringCommand(const char*)
345 sLog.outString( "Re-Loading mangos_string Table!" );
346 objmgr.LoadMangosStrings();
347 SendGlobalSysMessage("DB table `mangos_string` reloaded.");
348 return true;
351 bool ChatHandler::HandleReloadNpcOptionCommand(const char*)
353 sLog.outString( "Re-Loading `npc_option` Table!" );
354 objmgr.LoadNpcOptions();
355 SendGlobalSysMessage("DB table `npc_option` reloaded.");
356 return true;
359 bool ChatHandler::HandleReloadNpcGossipCommand(const char*)
361 sLog.outString( "Re-Loading `npc_gossip` Table!" );
362 objmgr.LoadNpcTextId();
363 SendGlobalSysMessage("DB table `npc_gossip` reloaded.");
364 return true;
367 bool ChatHandler::HandleReloadNpcTrainerCommand(const char*)
369 sLog.outString( "Re-Loading `npc_trainer` Table!" );
370 objmgr.LoadTrainerSpell();
371 SendGlobalSysMessage("DB table `npc_trainer` reloaded.");
372 return true;
375 bool ChatHandler::HandleReloadNpcVendorCommand(const char*)
377 sLog.outString( "Re-Loading `npc_vendor` Table!" );
378 objmgr.LoadVendors();
379 SendGlobalSysMessage("DB table `npc_vendor` reloaded.");
380 return true;
383 bool ChatHandler::HandleReloadReservedNameCommand(const char*)
385 sLog.outString( "Loading ReservedNames... (`reserved_name`)" );
386 objmgr.LoadReservedPlayersNames();
387 SendGlobalSysMessage("DB table `reserved_name` (player reserved names) reloaded.");
388 return true;
391 bool ChatHandler::HandleReloadSkillDiscoveryTemplateCommand(const char* /*args*/)
393 sLog.outString( "Re-Loading Skill Discovery Table..." );
394 LoadSkillDiscoveryTable();
395 SendGlobalSysMessage("DB table `skill_discovery_template` (recipes discovered at crafting) reloaded.");
396 return true;
399 bool ChatHandler::HandleReloadSkillExtraItemTemplateCommand(const char* /*args*/)
401 sLog.outString( "Re-Loading Skill Extra Item Table..." );
402 LoadSkillExtraItemTable();
403 SendGlobalSysMessage("DB table `skill_extra_item_template` (extra item creation when crafting) reloaded.");
404 return true;
407 bool ChatHandler::HandleReloadSkillFishingBaseLevelCommand(const char* /*args*/)
409 sLog.outString( "Re-Loading Skill Fishing base level requirements..." );
410 objmgr.LoadFishingBaseSkillLevel();
411 SendGlobalSysMessage("DB table `skill_fishing_base_level` (fishing base level for zone/subzone) reloaded.");
412 return true;
415 bool ChatHandler::HandleReloadSpellAffectCommand(const char*)
417 sLog.outString( "Re-Loading SpellAffect definitions..." );
418 spellmgr.LoadSpellAffects();
419 SendGlobalSysMessage("DB table `spell_affect` (spell mods apply requirements) reloaded.");
420 return true;
423 bool ChatHandler::HandleReloadSpellChainCommand(const char*)
425 sLog.outString( "Re-Loading Spell Chain Data... " );
426 spellmgr.LoadSpellChains();
427 SendGlobalSysMessage("DB table `spell_chain` (spell ranks) reloaded.");
428 return true;
431 bool ChatHandler::HandleReloadSpellElixirCommand(const char*)
433 sLog.outString( "Re-Loading Spell Elixir types..." );
434 spellmgr.LoadSpellElixirs();
435 SendGlobalSysMessage("DB table `spell_elixir` (spell elixir types) reloaded.");
436 return true;
439 bool ChatHandler::HandleReloadSpellLearnSpellCommand(const char*)
441 sLog.outString( "Re-Loading Spell Learn Spells..." );
442 spellmgr.LoadSpellLearnSpells();
443 SendGlobalSysMessage("DB table `spell_learn_spell` reloaded.");
444 return true;
447 bool ChatHandler::HandleReloadSpellProcEventCommand(const char*)
449 sLog.outString( "Re-Loading Spell Proc Event conditions..." );
450 spellmgr.LoadSpellProcEvents();
451 SendGlobalSysMessage("DB table `spell_proc_event` (spell proc trigger requirements) reloaded.");
452 return true;
455 bool ChatHandler::HandleReloadSpellScriptTargetCommand(const char*)
457 sLog.outString( "Re-Loading SpellsScriptTarget..." );
458 spellmgr.LoadSpellScriptTarget();
459 SendGlobalSysMessage("DB table `spell_script_target` (spell targets selection in case specific creature/GO requirements) reloaded.");
460 return true;
463 bool ChatHandler::HandleReloadSpellTargetPositionCommand(const char*)
465 sLog.outString( "Re-Loading Spell target coordinates..." );
466 spellmgr.LoadSpellTargetPositions();
467 SendGlobalSysMessage("DB table `spell_target_position` (destination coordinates for spell targets) reloaded.");
468 return true;
471 bool ChatHandler::HandleReloadSpellThreatsCommand(const char*)
473 sLog.outString( "Re-Loading Aggro Spells Definitions...");
474 spellmgr.LoadSpellThreats();
475 SendGlobalSysMessage("DB table `spell_threat` (spell aggro definitions) reloaded.");
476 return true;
479 bool ChatHandler::HandleReloadSpellPetAurasCommand(const char*)
481 sLog.outString( "Re-Loading Spell pet auras...");
482 spellmgr.LoadSpellPetAuras();
483 SendGlobalSysMessage("DB table `spell_pet_auras` reloaded.");
484 return true;
487 bool ChatHandler::HandleReloadPageTextsCommand(const char*)
489 sLog.outString( "Re-Loading Page Texts..." );
490 objmgr.LoadPageTexts();
491 SendGlobalSysMessage("DB table `page_texts` reloaded.");
492 return true;
495 bool ChatHandler::HandleReloadItemEnchantementsCommand(const char*)
497 sLog.outString( "Re-Loading Item Random Enchantments Table..." );
498 LoadRandomEnchantmentsTable();
499 SendGlobalSysMessage("DB table `item_enchantment_template` reloaded.");
500 return true;
503 bool ChatHandler::HandleReloadGameObjectScriptsCommand(const char* arg)
505 if(sWorld.IsScriptScheduled())
507 SendSysMessage("DB scripts used currently, please attempt reload later.");
508 SetSentErrorMessage(true);
509 return false;
512 if(*arg!='a')
513 sLog.outString( "Re-Loading Scripts from `gameobject_scripts`...");
515 objmgr.LoadGameObjectScripts();
517 if(*arg!='a')
518 SendGlobalSysMessage("DB table `gameobject_scripts` reloaded.");
520 return true;
523 bool ChatHandler::HandleReloadEventScriptsCommand(const char* arg)
525 if(sWorld.IsScriptScheduled())
527 SendSysMessage("DB scripts used currently, please attempt reload later.");
528 SetSentErrorMessage(true);
529 return false;
532 if(*arg!='a')
533 sLog.outString( "Re-Loading Scripts from `event_scripts`...");
535 objmgr.LoadEventScripts();
537 if(*arg!='a')
538 SendGlobalSysMessage("DB table `event_scripts` reloaded.");
540 return true;
543 bool ChatHandler::HandleReloadQuestEndScriptsCommand(const char* arg)
545 if(sWorld.IsScriptScheduled())
547 SendSysMessage("DB scripts used currently, please attempt reload later.");
548 SetSentErrorMessage(true);
549 return false;
552 if(*arg!='a')
553 sLog.outString( "Re-Loading Scripts from `quest_end_scripts`...");
555 objmgr.LoadQuestEndScripts();
557 if(*arg!='a')
558 SendGlobalSysMessage("DB table `quest_end_scripts` reloaded.");
560 return true;
563 bool ChatHandler::HandleReloadQuestStartScriptsCommand(const char* arg)
565 if(sWorld.IsScriptScheduled())
567 SendSysMessage("DB scripts used currently, please attempt reload later.");
568 SetSentErrorMessage(true);
569 return false;
572 if(*arg!='a')
573 sLog.outString( "Re-Loading Scripts from `quest_start_scripts`...");
575 objmgr.LoadQuestStartScripts();
577 if(*arg!='a')
578 SendGlobalSysMessage("DB table `quest_start_scripts` reloaded.");
580 return true;
583 bool ChatHandler::HandleReloadSpellScriptsCommand(const char* arg)
585 if(sWorld.IsScriptScheduled())
587 SendSysMessage("DB scripts used currently, please attempt reload later.");
588 SetSentErrorMessage(true);
589 return false;
592 if(*arg!='a')
593 sLog.outString( "Re-Loading Scripts from `spell_scripts`...");
595 objmgr.LoadSpellScripts();
597 if(*arg!='a')
598 SendGlobalSysMessage("DB table `spell_scripts` reloaded.");
600 return true;
603 bool ChatHandler::HandleReloadDbScriptStringCommand(const char* arg)
605 sLog.outString( "Re-Loading Script strings from `db_script_string`...");
606 objmgr.LoadDbScriptStrings();
607 SendGlobalSysMessage("DB table `db_script_string` reloaded.");
608 return true;
611 bool ChatHandler::HandleReloadGameGraveyardZoneCommand(const char* /*arg*/)
613 sLog.outString( "Re-Loading Graveyard-zone links...");
615 objmgr.LoadGraveyardZones();
617 SendGlobalSysMessage("DB table `game_graveyard_zone` reloaded.");
619 return true;
622 bool ChatHandler::HandleReloadGameTeleCommand(const char* /*arg*/)
624 sLog.outString( "Re-Loading Game Tele coordinates...");
626 objmgr.LoadGameTele();
628 SendGlobalSysMessage("DB table `game_tele` reloaded.");
630 return true;
633 bool ChatHandler::HandleReloadLocalesCreatureCommand(const char* /*arg*/)
635 sLog.outString( "Re-Loading Locales Creature ...");
636 objmgr.LoadCreatureLocales();
637 SendGlobalSysMessage("DB table `locales_creature` reloaded.");
638 return true;
641 bool ChatHandler::HandleReloadLocalesGameobjectCommand(const char* /*arg*/)
643 sLog.outString( "Re-Loading Locales Gameobject ... ");
644 objmgr.LoadGameObjectLocales();
645 SendGlobalSysMessage("DB table `locales_gameobject` reloaded.");
646 return true;
649 bool ChatHandler::HandleReloadLocalesItemCommand(const char* /*arg*/)
651 sLog.outString( "Re-Loading Locales Item ... ");
652 objmgr.LoadItemLocales();
653 SendGlobalSysMessage("DB table `locales_item` reloaded.");
654 return true;
657 bool ChatHandler::HandleReloadLocalesNpcTextCommand(const char* /*arg*/)
659 sLog.outString( "Re-Loading Locales NPC Text ... ");
660 objmgr.LoadNpcTextLocales();
661 SendGlobalSysMessage("DB table `locales_npc_text` reloaded.");
662 return true;
665 bool ChatHandler::HandleReloadLocalesPageTextCommand(const char* /*arg*/)
667 sLog.outString( "Re-Loading Locales Page Text ... ");
668 objmgr.LoadPageTextLocales();
669 SendGlobalSysMessage("DB table `locales_page_text` reloaded.");
670 return true;
673 bool ChatHandler::HandleReloadLocalesQuestCommand(const char* /*arg*/)
675 sLog.outString( "Re-Loading Locales Quest ... ");
676 objmgr.LoadQuestLocales();
677 SendGlobalSysMessage("DB table `locales_quest` reloaded.");
678 return true;
681 bool ChatHandler::HandleLoadScriptsCommand(const char* args)
683 if(!LoadScriptingModule(args)) return true;
685 sWorld.SendWorldText(LANG_SCRIPTS_RELOADED);
686 return true;
689 bool ChatHandler::HandleAccountSetGmLevelCommand(const char* args)
691 char* arg1 = strtok((char*)args, " ");
692 if( !arg1 )
693 return false;
695 /// must be NULL if targeted syntax and must be not nULL if not targeted
696 char* arg2 = strtok(NULL, " ");
698 std::string targetAccountName;
699 uint32 targetAccountId = 0;
700 uint32 targetSecurity = 0;
702 /// only target player different from self allowed (if targetPlayer!=NULL then not console)
703 Player* targetPlayer = getSelectedPlayer();
704 if(targetPlayer && m_session->GetPlayer()!=targetPlayer)
706 /// wrong command syntax or unexpected targeting
707 if(arg2)
708 return false;
710 /// security level expected in arg2 after this if.
711 arg2 = arg1;
713 targetAccountId = targetPlayer->GetSession()->GetAccountId();
714 targetSecurity = targetPlayer->GetSession()->GetSecurity();
715 if(!accmgr.GetName(targetAccountId,targetAccountName))
717 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,targetAccountName.c_str());
718 SetSentErrorMessage(true);
719 return false;
722 else
724 /// wrong command syntax (second arg expected)
725 if(!arg2)
726 return false;
728 targetAccountName = arg1;
729 if(!AccountMgr::normilizeString(targetAccountName))
731 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,targetAccountName.c_str());
732 SetSentErrorMessage(true);
733 return false;
736 targetAccountId = accmgr.GetId(targetAccountName);
737 targetSecurity = accmgr.GetSecurity(targetAccountId);
740 int32 gm = (int32)atoi(arg2);
741 if ( gm < SEC_PLAYER || gm > SEC_ADMINISTRATOR )
743 SendSysMessage(LANG_BAD_VALUE);
744 SetSentErrorMessage(true);
745 return false;
748 /// m_session==NULL only for console
749 uint32 plSecurity = m_session ? m_session->GetSecurity() : SEC_CONSOLE;
751 /// can set security level only for target with less security and to less security that we have
752 /// This is also reject self apply in fact
753 if(targetSecurity >= plSecurity || uint32(gm) >= plSecurity )
755 SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
756 SetSentErrorMessage(true);
757 return false;
760 if(targetPlayer)
762 ChatHandler(targetPlayer).PSendSysMessage(LANG_YOURS_SECURITY_CHANGED,GetName(), gm);
763 targetPlayer->GetSession()->SetSecurity(gm);
766 PSendSysMessage(LANG_YOU_CHANGE_SECURITY, targetAccountName.c_str(), gm);
767 loginDatabase.PExecute("UPDATE account SET gmlevel = '%i' WHERE id = '%u'", gm, targetAccountId);
769 return true;
772 /// Set password for account
773 bool ChatHandler::HandleAccountSetPasswordCommand(const char* args)
775 if(!*args)
776 return false;
778 ///- Get the command line arguments
779 char *szAccount = strtok ((char*)args," ");
780 char *szPassword1 = strtok (NULL," ");
781 char *szPassword2 = strtok (NULL," ");
783 if (!szAccount||!szPassword1 || !szPassword2)
784 return false;
786 std::string account_name = szAccount;
787 if(!AccountMgr::normilizeString(account_name))
789 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
790 SetSentErrorMessage(true);
791 return false;
794 uint32 targetAccountId = accmgr.GetId(account_name);
795 if (!targetAccountId)
797 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
798 SetSentErrorMessage(true);
799 return false;
802 uint32 targetSecurity = accmgr.GetSecurity(targetAccountId);
804 /// m_session==NULL only for console
805 uint32 plSecurity = m_session ? m_session->GetSecurity() : SEC_CONSOLE;
807 /// can set password only for target with less security
808 /// This is also reject self apply in fact
809 if (targetSecurity >= plSecurity)
811 SendSysMessage (LANG_YOURS_SECURITY_IS_LOW);
812 SetSentErrorMessage (true);
813 return false;
816 if (strcmp(szPassword1,szPassword2))
818 SendSysMessage (LANG_NEW_PASSWORDS_NOT_MATCH);
819 SetSentErrorMessage (true);
820 return false;
823 AccountOpResult result = accmgr.ChangePassword(targetAccountId, szPassword1);
825 switch(result)
827 case AOR_OK:
828 SendSysMessage(LANG_COMMAND_PASSWORD);
829 break;
830 case AOR_NAME_NOT_EXIST:
831 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
832 SetSentErrorMessage(true);
833 return false;
834 case AOR_PASS_TOO_LONG:
835 SendSysMessage(LANG_PASSWORD_TOO_LONG);
836 SetSentErrorMessage(true);
837 return false;
838 default:
839 SendSysMessage(LANG_COMMAND_NOTCHANGEPASSWORD);
840 SetSentErrorMessage(true);
841 return false;
844 return true;
847 bool ChatHandler::HandleAllowMovementCommand(const char* /*args*/)
849 if(sWorld.getAllowMovement())
851 sWorld.SetAllowMovement(false);
852 SendSysMessage(LANG_CREATURE_MOVE_DISABLED);
854 else
856 sWorld.SetAllowMovement(true);
857 SendSysMessage(LANG_CREATURE_MOVE_ENABLED);
859 return true;
862 bool ChatHandler::HandleMaxSkillCommand(const char* /*args*/)
864 Player* SelectedPlayer = getSelectedPlayer();
865 if(!SelectedPlayer)
867 SendSysMessage(LANG_NO_CHAR_SELECTED);
868 SetSentErrorMessage(true);
869 return false;
872 // each skills that have max skill value dependent from level seted to current level max skill value
873 SelectedPlayer->UpdateSkillsToMaxSkillsForLevel();
874 return true;
877 bool ChatHandler::HandleSetSkillCommand(const char* args)
879 // number or [name] Shift-click form |color|Hskill:skill_id|h[name]|h|r
880 char* skill_p = extractKeyFromLink((char*)args,"Hskill");
881 if(!skill_p)
882 return false;
884 char *level_p = strtok (NULL, " ");
886 if( !level_p)
887 return false;
889 char *max_p = strtok (NULL, " ");
891 int32 skill = atoi(skill_p);
893 if (skill <= 0)
895 PSendSysMessage(LANG_INVALID_SKILL_ID, skill);
896 SetSentErrorMessage(true);
897 return false;
900 int32 level = atol (level_p);
902 Player * target = getSelectedPlayer();
903 if(!target)
905 SendSysMessage(LANG_NO_CHAR_SELECTED);
906 SetSentErrorMessage(true);
907 return false;
910 SkillLineEntry const* sl = sSkillLineStore.LookupEntry(skill);
911 if(!sl)
913 PSendSysMessage(LANG_INVALID_SKILL_ID, skill);
914 SetSentErrorMessage(true);
915 return false;
918 if(!target->GetSkillValue(skill))
920 PSendSysMessage(LANG_SET_SKILL_ERROR, target->GetName(), skill, sl->name[0]);
921 SetSentErrorMessage(true);
922 return false;
925 int32 max = max_p ? atol (max_p) : target->GetPureMaxSkillValue(skill);
927 if( level <= 0 || level > max || max <= 0 )
928 return false;
930 target->SetSkill(skill, level, max);
931 PSendSysMessage(LANG_SET_SKILL, skill, sl->name[0], target->GetName(), level, max);
933 return true;
936 bool ChatHandler::HandleUnLearnCommand(const char* args)
938 if (!*args)
939 return false;
941 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
942 uint32 min_id = extractSpellIdFromLink((char*)args);
943 if(!min_id)
944 return false;
946 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
947 char* tail = strtok(NULL,"");
949 uint32 max_id = extractSpellIdFromLink(tail);
951 if (!max_id)
953 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
954 max_id = min_id+1;
956 else
958 if (max_id < min_id)
959 std::swap(min_id,max_id);
961 max_id=max_id+1;
964 Player* target = getSelectedPlayer();
965 if(!target)
967 SendSysMessage(LANG_NO_CHAR_SELECTED);
968 SetSentErrorMessage(true);
969 return false;
972 for(uint32 spell=min_id;spell<max_id;spell++)
974 if (target->HasSpell(spell))
975 target->removeSpell(spell);
976 else
977 SendSysMessage(LANG_FORGET_SPELL);
980 return true;
983 bool ChatHandler::HandleCooldownCommand(const char* args)
985 Player* target = getSelectedPlayer();
986 if(!target)
988 SendSysMessage(LANG_PLAYER_NOT_FOUND);
989 SetSentErrorMessage(true);
990 return false;
993 if (!*args)
995 target->RemoveAllSpellCooldown();
996 PSendSysMessage(LANG_REMOVEALL_COOLDOWN, target->GetName());
998 else
1000 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
1001 uint32 spell_id = extractSpellIdFromLink((char*)args);
1002 if(!spell_id)
1003 return false;
1005 if(!sSpellStore.LookupEntry(spell_id))
1007 PSendSysMessage(LANG_UNKNOWN_SPELL, target==m_session->GetPlayer() ? GetMangosString(LANG_YOU) : target->GetName());
1008 SetSentErrorMessage(true);
1009 return false;
1012 WorldPacket data( SMSG_CLEAR_COOLDOWN, (4+8) );
1013 data << uint32(spell_id);
1014 data << uint64(target->GetGUID());
1015 target->GetSession()->SendPacket(&data);
1016 target->RemoveSpellCooldown(spell_id);
1017 PSendSysMessage(LANG_REMOVE_COOLDOWN, spell_id, target==m_session->GetPlayer() ? GetMangosString(LANG_YOU) : target->GetName());
1019 return true;
1022 bool ChatHandler::HandleLearnAllCommand(const char* /*args*/)
1024 static const char *allSpellList[] =
1026 "3365",
1027 "6233",
1028 "6247",
1029 "6246",
1030 "6477",
1031 "6478",
1032 "22810",
1033 "8386",
1034 "21651",
1035 "21652",
1036 "522",
1037 "7266",
1038 "8597",
1039 "2479",
1040 "22027",
1041 "6603",
1042 "5019",
1043 "133",
1044 "168",
1045 "227",
1046 "5009",
1047 "9078",
1048 "668",
1049 "203",
1050 "20599",
1051 "20600",
1052 "81",
1053 "20597",
1054 "20598",
1055 "20864",
1056 "1459",
1057 "5504",
1058 "587",
1059 "5143",
1060 "118",
1061 "5505",
1062 "597",
1063 "604",
1064 "1449",
1065 "1460",
1066 "2855",
1067 "1008",
1068 "475",
1069 "5506",
1070 "1463",
1071 "12824",
1072 "8437",
1073 "990",
1074 "5145",
1075 "8450",
1076 "1461",
1077 "759",
1078 "8494",
1079 "8455",
1080 "8438",
1081 "6127",
1082 "8416",
1083 "6129",
1084 "8451",
1085 "8495",
1086 "8439",
1087 "3552",
1088 "8417",
1089 "10138",
1090 "12825",
1091 "10169",
1092 "10156",
1093 "10144",
1094 "10191",
1095 "10201",
1096 "10211",
1097 "10053",
1098 "10173",
1099 "10139",
1100 "10145",
1101 "10192",
1102 "10170",
1103 "10202",
1104 "10054",
1105 "10174",
1106 "10193",
1107 "12826",
1108 "2136",
1109 "143",
1110 "145",
1111 "2137",
1112 "2120",
1113 "3140",
1114 "543",
1115 "2138",
1116 "2948",
1117 "8400",
1118 "2121",
1119 "8444",
1120 "8412",
1121 "8457",
1122 "8401",
1123 "8422",
1124 "8445",
1125 "8402",
1126 "8413",
1127 "8458",
1128 "8423",
1129 "8446",
1130 "10148",
1131 "10197",
1132 "10205",
1133 "10149",
1134 "10215",
1135 "10223",
1136 "10206",
1137 "10199",
1138 "10150",
1139 "10216",
1140 "10207",
1141 "10225",
1142 "10151",
1143 "116",
1144 "205",
1145 "7300",
1146 "122",
1147 "837",
1148 "10",
1149 "7301",
1150 "7322",
1151 "6143",
1152 "120",
1153 "865",
1154 "8406",
1155 "6141",
1156 "7302",
1157 "8461",
1158 "8407",
1159 "8492",
1160 "8427",
1161 "8408",
1162 "6131",
1163 "7320",
1164 "10159",
1165 "8462",
1166 "10185",
1167 "10179",
1168 "10160",
1169 "10180",
1170 "10219",
1171 "10186",
1172 "10177",
1173 "10230",
1174 "10181",
1175 "10161",
1176 "10187",
1177 "10220",
1178 "2018",
1179 "2663",
1180 "12260",
1181 "2660",
1182 "3115",
1183 "3326",
1184 "2665",
1185 "3116",
1186 "2738",
1187 "3293",
1188 "2661",
1189 "3319",
1190 "2662",
1191 "9983",
1192 "8880",
1193 "2737",
1194 "2739",
1195 "7408",
1196 "3320",
1197 "2666",
1198 "3323",
1199 "3324",
1200 "3294",
1201 "22723",
1202 "23219",
1203 "23220",
1204 "23221",
1205 "23228",
1206 "23338",
1207 "10788",
1208 "10790",
1209 "5611",
1210 "5016",
1211 "5609",
1212 "2060",
1213 "10963",
1214 "10964",
1215 "10965",
1216 "22593",
1217 "22594",
1218 "596",
1219 "996",
1220 "499",
1221 "768",
1222 "17002",
1223 "1448",
1224 "1082",
1225 "16979",
1226 "1079",
1227 "5215",
1228 "20484",
1229 "5221",
1230 "15590",
1231 "17007",
1232 "6795",
1233 "6807",
1234 "5487",
1235 "1446",
1236 "1066",
1237 "5421",
1238 "3139",
1239 "779",
1240 "6811",
1241 "6808",
1242 "1445",
1243 "5216",
1244 "1737",
1245 "5222",
1246 "5217",
1247 "1432",
1248 "6812",
1249 "9492",
1250 "5210",
1251 "3030",
1252 "1441",
1253 "783",
1254 "6801",
1255 "20739",
1256 "8944",
1257 "9491",
1258 "22569",
1259 "5226",
1260 "6786",
1261 "1433",
1262 "8973",
1263 "1828",
1264 "9495",
1265 "9006",
1266 "6794",
1267 "8993",
1268 "5203",
1269 "16914",
1270 "6784",
1271 "9635",
1272 "22830",
1273 "20722",
1274 "9748",
1275 "6790",
1276 "9753",
1277 "9493",
1278 "9752",
1279 "9831",
1280 "9825",
1281 "9822",
1282 "5204",
1283 "5401",
1284 "22831",
1285 "6793",
1286 "9845",
1287 "17401",
1288 "9882",
1289 "9868",
1290 "20749",
1291 "9893",
1292 "9899",
1293 "9895",
1294 "9832",
1295 "9902",
1296 "9909",
1297 "22832",
1298 "9828",
1299 "9851",
1300 "9883",
1301 "9869",
1302 "17406",
1303 "17402",
1304 "9914",
1305 "20750",
1306 "9897",
1307 "9848",
1308 "3127",
1309 "107",
1310 "204",
1311 "9116",
1312 "2457",
1313 "78",
1314 "18848",
1315 "331",
1316 "403",
1317 "2098",
1318 "1752",
1319 "11278",
1320 "11288",
1321 "11284",
1322 "6461",
1323 "2344",
1324 "2345",
1325 "6463",
1326 "2346",
1327 "2352",
1328 "775",
1329 "1434",
1330 "1612",
1331 "71",
1332 "2468",
1333 "2458",
1334 "2467",
1335 "7164",
1336 "7178",
1337 "7367",
1338 "7376",
1339 "7381",
1340 "21156",
1341 "5209",
1342 "3029",
1343 "5201",
1344 "9849",
1345 "9850",
1346 "20719",
1347 "22568",
1348 "22827",
1349 "22828",
1350 "22829",
1351 "6809",
1352 "8972",
1353 "9005",
1354 "9823",
1355 "9827",
1356 "6783",
1357 "9913",
1358 "6785",
1359 "6787",
1360 "9866",
1361 "9867",
1362 "9894",
1363 "9896",
1364 "6800",
1365 "8992",
1366 "9829",
1367 "9830",
1368 "780",
1369 "769",
1370 "6749",
1371 "6750",
1372 "9755",
1373 "9754",
1374 "9908",
1375 "20745",
1376 "20742",
1377 "20747",
1378 "20748",
1379 "9746",
1380 "9745",
1381 "9880",
1382 "9881",
1383 "5391",
1384 "842",
1385 "3025",
1386 "3031",
1387 "3287",
1388 "3329",
1389 "1945",
1390 "3559",
1391 "4933",
1392 "4934",
1393 "4935",
1394 "4936",
1395 "5142",
1396 "5390",
1397 "5392",
1398 "5404",
1399 "5420",
1400 "6405",
1401 "7293",
1402 "7965",
1403 "8041",
1404 "8153",
1405 "9033",
1406 "9034",
1407 //"9036", problems with ghost state
1408 "16421",
1409 "21653",
1410 "22660",
1411 "5225",
1412 "9846",
1413 "2426",
1414 "5916",
1415 "6634",
1416 //"6718", phasing stealth, annoying for learn all case.
1417 "6719",
1418 "8822",
1419 "9591",
1420 "9590",
1421 "10032",
1422 "17746",
1423 "17747",
1424 "8203",
1425 "11392",
1426 "12495",
1427 "16380",
1428 "23452",
1429 "4079",
1430 "4996",
1431 "4997",
1432 "4998",
1433 "4999",
1434 "5000",
1435 "6348",
1436 "6349",
1437 "6481",
1438 "6482",
1439 "6483",
1440 "6484",
1441 "11362",
1442 "11410",
1443 "11409",
1444 "12510",
1445 "12509",
1446 "12885",
1447 "13142",
1448 "21463",
1449 "23460",
1450 "11421",
1451 "11416",
1452 "11418",
1453 "1851",
1454 "10059",
1455 "11423",
1456 "11417",
1457 "11422",
1458 "11419",
1459 "11424",
1460 "11420",
1461 "27",
1462 "31",
1463 "33",
1464 "34",
1465 "35",
1466 "15125",
1467 "21127",
1468 "22950",
1469 "1180",
1470 "201",
1471 "12593",
1472 "12842",
1473 "16770",
1474 "6057",
1475 "12051",
1476 "18468",
1477 "12606",
1478 "12605",
1479 "18466",
1480 "12502",
1481 "12043",
1482 "15060",
1483 "12042",
1484 "12341",
1485 "12848",
1486 "12344",
1487 "12353",
1488 "18460",
1489 "11366",
1490 "12350",
1491 "12352",
1492 "13043",
1493 "11368",
1494 "11113",
1495 "12400",
1496 "11129",
1497 "16766",
1498 "12573",
1499 "15053",
1500 "12580",
1501 "12475",
1502 "12472",
1503 "12953",
1504 "12488",
1505 "11189",
1506 "12985",
1507 "12519",
1508 "16758",
1509 "11958",
1510 "12490",
1511 "11426",
1512 "3565",
1513 "3562",
1514 "18960",
1515 "3567",
1516 "3561",
1517 "3566",
1518 "3563",
1519 "1953",
1520 "2139",
1521 "12505",
1522 "13018",
1523 "12522",
1524 "12523",
1525 "5146",
1526 "5144",
1527 "5148",
1528 "8419",
1529 "8418",
1530 "10213",
1531 "10212",
1532 "10157",
1533 "12524",
1534 "13019",
1535 "12525",
1536 "13020",
1537 "12526",
1538 "13021",
1539 "18809",
1540 "13031",
1541 "13032",
1542 "13033",
1543 "4036",
1544 "3920",
1545 "3919",
1546 "3918",
1547 "7430",
1548 "3922",
1549 "3923",
1550 "7411",
1551 "7418",
1552 "7421",
1553 "13262",
1554 "7412",
1555 "7415",
1556 "7413",
1557 "7416",
1558 "13920",
1559 "13921",
1560 "7745",
1561 "7779",
1562 "7428",
1563 "7457",
1564 "7857",
1565 "7748",
1566 "7426",
1567 "13421",
1568 "7454",
1569 "13378",
1570 "7788",
1571 "14807",
1572 "14293",
1573 "7795",
1574 "6296",
1575 "20608",
1576 "755",
1577 "444",
1578 "427",
1579 "428",
1580 "442",
1581 "447",
1582 "3578",
1583 "3581",
1584 "19027",
1585 "3580",
1586 "665",
1587 "3579",
1588 "3577",
1589 "6755",
1590 "3576",
1591 "2575",
1592 "2577",
1593 "2578",
1594 "2579",
1595 "2580",
1596 "2656",
1597 "2657",
1598 "2576",
1599 "3564",
1600 "10248",
1601 "8388",
1602 "2659",
1603 "14891",
1604 "3308",
1605 "3307",
1606 "10097",
1607 "2658",
1608 "3569",
1609 "16153",
1610 "3304",
1611 "10098",
1612 "4037",
1613 "3929",
1614 "3931",
1615 "3926",
1616 "3924",
1617 "3930",
1618 "3977",
1619 "3925",
1620 "136",
1621 "228",
1622 "5487",
1623 "43",
1624 "202",
1628 int loop = 0;
1629 while(strcmp(allSpellList[loop], "0"))
1631 uint32 spell = atol((char*)allSpellList[loop++]);
1633 if (m_session->GetPlayer()->HasSpell(spell))
1634 continue;
1636 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
1637 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
1639 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
1640 continue;
1643 m_session->GetPlayer()->learnSpell(spell);
1646 SendSysMessage(LANG_COMMAND_LEARN_MANY_SPELLS);
1648 return true;
1651 bool ChatHandler::HandleLearnAllGMCommand(const char* /*args*/)
1653 static const char *gmSpellList[] =
1655 "24347", // Become A Fish, No Breath Bar
1656 "35132", // Visual Boom
1657 "38488", // Attack 4000-8000 AOE
1658 "38795", // Attack 2000 AOE + Slow Down 90%
1659 "15712", // Attack 200
1660 "1852", // GM Spell Silence
1661 "31899", // Kill
1662 "31924", // Kill
1663 "29878", // Kill My Self
1664 "26644", // More Kill
1666 "28550", //Invisible 24
1667 "23452", //Invisible + Target
1671 uint16 gmSpellIter = 0;
1672 while( strcmp(gmSpellList[gmSpellIter], "0") )
1674 uint32 spell = atol((char*)gmSpellList[gmSpellIter++]);
1676 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
1677 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
1679 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
1680 continue;
1683 m_session->GetPlayer()->learnSpell(spell);
1686 SendSysMessage(LANG_LEARNING_GM_SKILLS);
1687 return true;
1690 bool ChatHandler::HandleLearnAllMyClassCommand(const char* /*args*/)
1692 HandleLearnAllMySpellsCommand("");
1693 HandleLearnAllMyTalentsCommand("");
1694 return true;
1697 bool ChatHandler::HandleLearnAllMySpellsCommand(const char* /*args*/)
1699 ChrClassesEntry const* clsEntry = sChrClassesStore.LookupEntry(m_session->GetPlayer()->getClass());
1700 if(!clsEntry)
1701 return true;
1702 uint32 family = clsEntry->spellfamily;
1704 for (uint32 i = 0; i < sSpellStore.GetNumRows(); i++)
1706 SpellEntry const *spellInfo = sSpellStore.LookupEntry(i);
1707 if(!spellInfo)
1708 continue;
1710 // skip server-side/triggered spells
1711 if(spellInfo->spellLevel==0)
1712 continue;
1714 // skip wrong class/race skills
1715 if(!m_session->GetPlayer()->IsSpellFitByClassAndRace(spellInfo->Id))
1716 continue;
1718 // skip other spell families
1719 if( spellInfo->SpellFamilyName != family)
1720 continue;
1722 // skip spells with first rank learned as talent (and all talents then also)
1723 uint32 first_rank = spellmgr.GetFirstSpellInChain(spellInfo->Id);
1724 if(GetTalentSpellCost(first_rank) > 0 )
1725 continue;
1727 // skip broken spells
1728 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
1729 continue;
1731 m_session->GetPlayer()->learnSpell(i);
1734 SendSysMessage(LANG_COMMAND_LEARN_CLASS_SPELLS);
1735 return true;
1738 static void learnAllHighRanks(Player* player, uint32 spellid)
1740 SpellChainMapNext const& nextMap = spellmgr.GetSpellChainNext();
1741 for(SpellChainMapNext::const_iterator itr = nextMap.lower_bound(spellid); itr != nextMap.upper_bound(spellid); ++itr)
1743 player->learnSpell(itr->second);
1744 learnAllHighRanks(player,itr->second);
1748 bool ChatHandler::HandleLearnAllMyTalentsCommand(const char* /*args*/)
1750 Player* player = m_session->GetPlayer();
1751 uint32 classMask = player->getClassMask();
1753 for (uint32 i = 0; i < sTalentStore.GetNumRows(); i++)
1755 TalentEntry const *talentInfo = sTalentStore.LookupEntry(i);
1756 if(!talentInfo)
1757 continue;
1759 TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab );
1760 if(!talentTabInfo)
1761 continue;
1763 if( (classMask & talentTabInfo->ClassMask) == 0 )
1764 continue;
1766 // search highest talent rank
1767 uint32 spellid = 0;
1768 int rank = 4;
1769 for(; rank >= 0; --rank)
1771 if(talentInfo->RankID[rank]!=0)
1773 spellid = talentInfo->RankID[rank];
1774 break;
1778 if(!spellid) // ??? none spells in talent
1779 continue;
1781 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid);
1782 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
1783 continue;
1785 // learn highest rank of talent
1786 player->learnSpell(spellid);
1788 // and learn all non-talent spell ranks (recursive by tree)
1789 learnAllHighRanks(player,spellid);
1792 SendSysMessage(LANG_COMMAND_LEARN_CLASS_TALENTS);
1793 return true;
1796 bool ChatHandler::HandleLearnAllLangCommand(const char* /*args*/)
1798 // skipping UNIVERSAL language (0)
1799 for(int i = 1; i < LANGUAGES_COUNT; ++i)
1800 m_session->GetPlayer()->learnSpell(lang_description[i].spell_id);
1802 SendSysMessage(LANG_COMMAND_LEARN_ALL_LANG);
1803 return true;
1806 bool ChatHandler::HandleLearnAllDefaultCommand(const char* args)
1808 char* pName = strtok((char*)args, "");
1809 Player *player = NULL;
1810 if (pName)
1812 std::string name = pName;
1814 if(!normalizePlayerName(name))
1816 SendSysMessage(LANG_PLAYER_NOT_FOUND);
1817 SetSentErrorMessage(true);
1818 return false;
1821 player = objmgr.GetPlayer(name.c_str());
1823 else
1824 player = getSelectedPlayer();
1826 if(!player)
1828 SendSysMessage(LANG_NO_CHAR_SELECTED);
1829 SetSentErrorMessage(true);
1830 return false;
1833 player->learnDefaultSpells();
1834 player->learnQuestRewardedSpells();
1836 PSendSysMessage(LANG_COMMAND_LEARN_ALL_DEFAULT_AND_QUEST,player->GetName());
1837 return true;
1840 bool ChatHandler::HandleLearnCommand(const char* args)
1842 Player* targetPlayer = getSelectedPlayer();
1844 if(!targetPlayer)
1846 SendSysMessage(LANG_PLAYER_NOT_FOUND);
1847 SetSentErrorMessage(true);
1848 return false;
1851 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
1852 uint32 spell = extractSpellIdFromLink((char*)args);
1853 if(!spell || !sSpellStore.LookupEntry(spell))
1854 return false;
1856 if (targetPlayer->HasSpell(spell))
1858 if(targetPlayer == m_session->GetPlayer())
1859 SendSysMessage(LANG_YOU_KNOWN_SPELL);
1860 else
1861 PSendSysMessage(LANG_TARGET_KNOWN_SPELL,targetPlayer->GetName());
1862 SetSentErrorMessage(true);
1863 return false;
1866 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
1867 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
1869 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
1870 SetSentErrorMessage(true);
1871 return false;
1874 targetPlayer->learnSpell(spell);
1876 return true;
1879 bool ChatHandler::HandleAddItemCommand(const char* args)
1881 if (!*args)
1882 return false;
1884 uint32 itemId = 0;
1886 if(args[0]=='[') // [name] manual form
1888 char* citemName = citemName = strtok((char*)args, "]");
1890 if(citemName && citemName[0])
1892 std::string itemName = citemName+1;
1893 WorldDatabase.escape_string(itemName);
1894 QueryResult *result = WorldDatabase.PQuery("SELECT entry FROM item_template WHERE name = '%s'", itemName.c_str());
1895 if (!result)
1897 PSendSysMessage(LANG_COMMAND_COULDNOTFIND, citemName+1);
1898 SetSentErrorMessage(true);
1899 return false;
1901 itemId = result->Fetch()->GetUInt16();
1902 delete result;
1904 else
1905 return false;
1907 else // item_id or [name] Shift-click form |color|Hitem:item_id:0:0:0|h[name]|h|r
1909 char* cId = extractKeyFromLink((char*)args,"Hitem");
1910 if(!cId)
1911 return false;
1912 itemId = atol(cId);
1915 char* ccount = strtok(NULL, " ");
1917 int32 count = 1;
1919 if (ccount)
1920 count = strtol(ccount, NULL, 10);
1922 if (count == 0)
1923 count = 1;
1925 Player* pl = m_session->GetPlayer();
1926 Player* plTarget = getSelectedPlayer();
1927 if(!plTarget)
1928 plTarget = pl;
1930 sLog.outDetail(GetMangosString(LANG_ADDITEM), itemId, count);
1932 ItemPrototype const *pProto = objmgr.GetItemPrototype(itemId);
1933 if(!pProto)
1935 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId);
1936 SetSentErrorMessage(true);
1937 return false;
1940 //Subtract
1941 if (count < 0)
1943 plTarget->DestroyItemCount(itemId, -count, true, false);
1944 PSendSysMessage(LANG_REMOVEITEM, itemId, -count, plTarget->GetName());
1945 return true;
1948 //Adding items
1949 uint32 noSpaceForCount = 0;
1951 // check space and find places
1952 ItemPosCountVec dest;
1953 uint8 msg = plTarget->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, itemId, count, &noSpaceForCount );
1954 if( msg != EQUIP_ERR_OK ) // convert to possible store amount
1955 count -= noSpaceForCount;
1957 if( count == 0 || dest.empty()) // can't add any
1959 PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount );
1960 SetSentErrorMessage(true);
1961 return false;
1964 Item* item = plTarget->StoreNewItem( dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId));
1966 // remove binding (let GM give it to another player later)
1967 if(pl==plTarget)
1968 for(ItemPosCountVec::const_iterator itr = dest.begin(); itr != dest.end(); ++itr)
1969 if(Item* item1 = pl->GetItemByPos(itr->pos))
1970 item1->SetBinding( false );
1972 if(count > 0 && item)
1974 pl->SendNewItem(item,count,false,true);
1975 if(pl!=plTarget)
1976 plTarget->SendNewItem(item,count,true,false);
1979 if(noSpaceForCount > 0)
1980 PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount);
1982 return true;
1985 bool ChatHandler::HandleAddItemSetCommand(const char* args)
1987 if (!*args)
1988 return false;
1990 char* cId = extractKeyFromLink((char*)args,"Hitemset"); // number or [name] Shift-click form |color|Hitemset:itemset_id|h[name]|h|r
1991 if (!cId)
1992 return false;
1994 uint32 itemsetId = atol(cId);
1996 // prevent generation all items with itemset field value '0'
1997 if (itemsetId == 0)
1999 PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND,itemsetId);
2000 SetSentErrorMessage(true);
2001 return false;
2004 Player* pl = m_session->GetPlayer();
2005 Player* plTarget = getSelectedPlayer();
2006 if(!plTarget)
2007 plTarget = pl;
2009 sLog.outDetail(GetMangosString(LANG_ADDITEMSET), itemsetId);
2011 bool found = false;
2012 for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
2014 ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype>(id);
2015 if (!pProto)
2016 continue;
2018 if (pProto->ItemSet == itemsetId)
2020 found = true;
2021 ItemPosCountVec dest;
2022 uint8 msg = plTarget->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, pProto->ItemId, 1 );
2023 if (msg == EQUIP_ERR_OK)
2025 Item* item = plTarget->StoreNewItem( dest, pProto->ItemId, true);
2027 // remove binding (let GM give it to another player later)
2028 if (pl==plTarget)
2029 item->SetBinding( false );
2031 pl->SendNewItem(item,1,false,true);
2032 if (pl!=plTarget)
2033 plTarget->SendNewItem(item,1,true,false);
2035 else
2037 pl->SendEquipError( msg, NULL, NULL );
2038 PSendSysMessage(LANG_ITEM_CANNOT_CREATE, pProto->ItemId, 1);
2043 if (!found)
2045 PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND,itemsetId);
2047 SetSentErrorMessage(true);
2048 return false;
2051 return true;
2054 bool ChatHandler::HandleListItemCommand(const char* args)
2056 if(!*args)
2057 return false;
2059 char* cId = extractKeyFromLink((char*)args,"Hitem");
2060 if(!cId)
2061 return false;
2063 uint32 item_id = atol(cId);
2064 if(!item_id)
2066 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
2067 SetSentErrorMessage(true);
2068 return false;
2071 ItemPrototype const* itemProto = objmgr.GetItemPrototype(item_id);
2072 if(!itemProto)
2074 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
2075 SetSentErrorMessage(true);
2076 return false;
2079 char* c_count = strtok(NULL, " ");
2080 int count = c_count ? atol(c_count) : 10;
2082 if(count < 0)
2083 return false;
2085 QueryResult *result;
2087 // inventory case
2088 uint32 inv_count = 0;
2089 result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM character_inventory WHERE item_template='%u'",item_id);
2090 if(result)
2092 inv_count = (*result)[0].GetUInt32();
2093 delete result;
2096 result=CharacterDatabase.PQuery(
2097 // 0 1 2 3 4 5
2098 "SELECT ci.item, cibag.slot AS bag, ci.slot, ci.guid, characters.account,characters.name "
2099 "FROM character_inventory AS ci LEFT JOIN character_inventory AS cibag ON (cibag.item=ci.bag),characters "
2100 "WHERE ci.item_template='%u' AND ci.guid = characters.guid LIMIT %u ",
2101 item_id,uint32(count));
2103 if(result)
2107 Field *fields = result->Fetch();
2108 uint32 item_guid = fields[0].GetUInt32();
2109 uint32 item_bag = fields[1].GetUInt32();
2110 uint32 item_slot = fields[2].GetUInt32();
2111 uint32 owner_guid = fields[3].GetUInt32();
2112 uint32 owner_acc = fields[4].GetUInt32();
2113 std::string owner_name = fields[5].GetCppString();
2115 char const* item_pos = 0;
2116 if(Player::IsEquipmentPos(item_bag,item_slot))
2117 item_pos = "[equipped]";
2118 else if(Player::IsInventoryPos(item_bag,item_slot))
2119 item_pos = "[in inventory]";
2120 else if(Player::IsBankPos(item_bag,item_slot))
2121 item_pos = "[in bank]";
2122 else
2123 item_pos = "";
2125 PSendSysMessage(LANG_ITEMLIST_SLOT,
2126 item_guid,owner_name.c_str(),owner_guid,owner_acc,item_pos);
2127 } while (result->NextRow());
2129 int64 res_count = result->GetRowCount();
2131 delete result;
2133 if(count > res_count)
2134 count-=res_count;
2135 else if(count)
2136 count = 0;
2139 // mail case
2140 uint32 mail_count = 0;
2141 result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM mail_items WHERE item_template='%u'", item_id);
2142 if(result)
2144 mail_count = (*result)[0].GetUInt32();
2145 delete result;
2148 if(count > 0)
2150 result=CharacterDatabase.PQuery(
2151 // 0 1 2 3 4 5 6
2152 "SELECT mail_items.item_guid, mail.sender, mail.receiver, char_s.account, char_s.name, char_r.account, char_r.name "
2153 "FROM mail,mail_items,characters as char_s,characters as char_r "
2154 "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",
2155 item_id,uint32(count));
2157 else
2158 result = NULL;
2160 if(result)
2164 Field *fields = result->Fetch();
2165 uint32 item_guid = fields[0].GetUInt32();
2166 uint32 item_s = fields[1].GetUInt32();
2167 uint32 item_r = fields[2].GetUInt32();
2168 uint32 item_s_acc = fields[3].GetUInt32();
2169 std::string item_s_name = fields[4].GetCppString();
2170 uint32 item_r_acc = fields[5].GetUInt32();
2171 std::string item_r_name = fields[6].GetCppString();
2173 char const* item_pos = "[in mail]";
2175 PSendSysMessage(LANG_ITEMLIST_MAIL,
2176 item_guid,item_s_name.c_str(),item_s,item_s_acc,item_r_name.c_str(),item_r,item_r_acc,item_pos);
2177 } while (result->NextRow());
2179 int64 res_count = result->GetRowCount();
2181 delete result;
2183 if(count > res_count)
2184 count-=res_count;
2185 else if(count)
2186 count = 0;
2189 // auction case
2190 uint32 auc_count = 0;
2191 result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM auctionhouse WHERE item_template='%u'",item_id);
2192 if(result)
2194 auc_count = (*result)[0].GetUInt32();
2195 delete result;
2198 if(count > 0)
2200 result=CharacterDatabase.PQuery(
2201 // 0 1 2 3
2202 "SELECT auctionhouse.itemguid, auctionhouse.itemowner, characters.account, characters.name "
2203 "FROM auctionhouse,characters WHERE auctionhouse.item_template='%u' AND characters.guid = auctionhouse.itemowner LIMIT %u",
2204 item_id,uint32(count));
2206 else
2207 result = NULL;
2209 if(result)
2213 Field *fields = result->Fetch();
2214 uint32 item_guid = fields[0].GetUInt32();
2215 uint32 owner = fields[1].GetUInt32();
2216 uint32 owner_acc = fields[2].GetUInt32();
2217 std::string owner_name = fields[3].GetCppString();
2219 char const* item_pos = "[in auction]";
2221 PSendSysMessage(LANG_ITEMLIST_AUCTION, item_guid, owner_name.c_str(), owner, owner_acc,item_pos);
2222 } while (result->NextRow());
2224 delete result;
2227 // guild bank case
2228 uint32 guild_count = 0;
2229 result=CharacterDatabase.PQuery("SELECT COUNT(item_entry) FROM guild_bank_item WHERE item_entry='%u'",item_id);
2230 if(result)
2232 guild_count = (*result)[0].GetUInt32();
2233 delete result;
2236 result=CharacterDatabase.PQuery(
2237 // 0 1 2
2238 "SELECT gi.item_guid, gi.guildid, guild.name "
2239 "FROM guild_bank_item AS gi, guild WHERE gi.item_entry='%u' AND gi.guildid = guild.guildid LIMIT %u ",
2240 item_id,uint32(count));
2242 if(result)
2246 Field *fields = result->Fetch();
2247 uint32 item_guid = fields[0].GetUInt32();
2248 uint32 guild_guid = fields[1].GetUInt32();
2249 std::string guild_name = fields[2].GetCppString();
2251 char const* item_pos = "[in guild bank]";
2253 PSendSysMessage(LANG_ITEMLIST_GUILD,item_guid,guild_name.c_str(),guild_guid,item_pos);
2254 } while (result->NextRow());
2256 int64 res_count = result->GetRowCount();
2258 delete result;
2260 if(count > res_count)
2261 count-=res_count;
2262 else if(count)
2263 count = 0;
2266 if(inv_count+mail_count+auc_count+guild_count == 0)
2268 SendSysMessage(LANG_COMMAND_NOITEMFOUND);
2269 SetSentErrorMessage(true);
2270 return false;
2273 PSendSysMessage(LANG_COMMAND_LISTITEMMESSAGE,item_id,inv_count+mail_count+auc_count+guild_count,inv_count,mail_count,auc_count,guild_count);
2275 return true;
2278 bool ChatHandler::HandleListObjectCommand(const char* args)
2280 if(!*args)
2281 return false;
2283 // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r
2284 char* cId = extractKeyFromLink((char*)args,"Hgameobject_entry");
2285 if(!cId)
2286 return false;
2288 uint32 go_id = atol(cId);
2289 if(!go_id)
2291 PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id);
2292 SetSentErrorMessage(true);
2293 return false;
2296 GameObjectInfo const * gInfo = objmgr.GetGameObjectInfo(go_id);
2297 if(!gInfo)
2299 PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id);
2300 SetSentErrorMessage(true);
2301 return false;
2304 char* c_count = strtok(NULL, " ");
2305 int count = c_count ? atol(c_count) : 10;
2307 if(count < 0)
2308 return false;
2310 QueryResult *result;
2312 uint32 obj_count = 0;
2313 result=WorldDatabase.PQuery("SELECT COUNT(guid) FROM gameobject WHERE id='%u'",go_id);
2314 if(result)
2316 obj_count = (*result)[0].GetUInt32();
2317 delete result;
2320 if(m_session)
2322 Player* pl = m_session->GetPlayer();
2323 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",
2324 pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),go_id,uint32(count));
2326 else
2327 result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map FROM gameobject WHERE id = '%u' LIMIT %u",
2328 go_id,uint32(count));
2330 if (result)
2334 Field *fields = result->Fetch();
2335 uint32 guid = fields[0].GetUInt32();
2336 float x = fields[1].GetFloat();
2337 float y = fields[2].GetFloat();
2338 float z = fields[3].GetFloat();
2339 int mapid = fields[4].GetUInt16();
2341 if (m_session)
2342 PSendSysMessage(LANG_GO_LIST_CHAT, guid, guid, gInfo->name, x, y, z, mapid);
2343 else
2344 PSendSysMessage(LANG_GO_LIST_CONSOLE, guid, gInfo->name, x, y, z, mapid);
2345 } while (result->NextRow());
2347 delete result;
2350 PSendSysMessage(LANG_COMMAND_LISTOBJMESSAGE,go_id,obj_count);
2351 return true;
2354 bool ChatHandler::HandleNearObjectCommand(const char* args)
2356 float distance = (!*args) ? 10 : atol(args);
2357 uint32 count = 0;
2359 Player* pl = m_session->GetPlayer();
2360 QueryResult *result = WorldDatabase.PQuery("SELECT guid, id, position_x, position_y, position_z, map, "
2361 "(POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ "
2362 "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_",
2363 pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),
2364 pl->GetMapId(),pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),distance*distance);
2366 if (result)
2370 Field *fields = result->Fetch();
2371 uint32 guid = fields[0].GetUInt32();
2372 uint32 entry = fields[1].GetUInt32();
2373 float x = fields[2].GetFloat();
2374 float y = fields[3].GetFloat();
2375 float z = fields[4].GetFloat();
2376 int mapid = fields[5].GetUInt16();
2378 GameObjectInfo const * gInfo = objmgr.GetGameObjectInfo(entry);
2380 if(!gInfo)
2381 continue;
2383 PSendSysMessage(LANG_GO_LIST_CHAT, guid, guid, gInfo->name, x, y, z, mapid);
2385 ++count;
2386 } while (result->NextRow());
2388 delete result;
2391 PSendSysMessage(LANG_COMMAND_NEAROBJMESSAGE,distance,count);
2392 return true;
2395 bool ChatHandler::HandleListCreatureCommand(const char* args)
2397 if(!*args)
2398 return false;
2400 // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
2401 char* cId = extractKeyFromLink((char*)args,"Hcreature_entry");
2402 if(!cId)
2403 return false;
2405 uint32 cr_id = atol(cId);
2406 if(!cr_id)
2408 PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id);
2409 SetSentErrorMessage(true);
2410 return false;
2413 CreatureInfo const* cInfo = objmgr.GetCreatureTemplate(cr_id);
2414 if(!cInfo)
2416 PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id);
2417 SetSentErrorMessage(true);
2418 return false;
2421 char* c_count = strtok(NULL, " ");
2422 int count = c_count ? atol(c_count) : 10;
2424 if(count < 0)
2425 return false;
2427 QueryResult *result;
2429 uint32 cr_count = 0;
2430 result=WorldDatabase.PQuery("SELECT COUNT(guid) FROM creature WHERE id='%u'",cr_id);
2431 if(result)
2433 cr_count = (*result)[0].GetUInt32();
2434 delete result;
2437 if(m_session)
2439 Player* pl = m_session->GetPlayer();
2440 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",
2441 pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), cr_id,uint32(count));
2443 else
2444 result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map FROM creature WHERE id = '%u' LIMIT %u",
2445 cr_id,uint32(count));
2447 if (result)
2451 Field *fields = result->Fetch();
2452 uint32 guid = fields[0].GetUInt32();
2453 float x = fields[1].GetFloat();
2454 float y = fields[2].GetFloat();
2455 float z = fields[3].GetFloat();
2456 int mapid = fields[4].GetUInt16();
2458 if (m_session)
2459 PSendSysMessage(LANG_CREATURE_LIST_CHAT, guid, guid, cInfo->Name, x, y, z, mapid);
2460 else
2461 PSendSysMessage(LANG_CREATURE_LIST_CONSOLE, guid, cInfo->Name, x, y, z, mapid);
2462 } while (result->NextRow());
2464 delete result;
2467 PSendSysMessage(LANG_COMMAND_LISTCREATUREMESSAGE,cr_id,cr_count);
2468 return true;
2471 bool ChatHandler::HandleLookupItemCommand(const char* args)
2473 if(!*args)
2474 return false;
2476 std::string namepart = args;
2477 std::wstring wnamepart;
2479 // converting string that we try to find to lower case
2480 if(!Utf8toWStr(namepart,wnamepart))
2481 return false;
2483 wstrToLower(wnamepart);
2485 uint32 counter = 0;
2487 // Search in `item_template`
2488 for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
2490 ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype >(id);
2491 if(!pProto)
2492 continue;
2494 int loc_idx = m_session ? m_session->GetSessionDbLocaleIndex() : objmgr.GetDBCLocaleIndex();
2495 if ( loc_idx >= 0 )
2497 ItemLocale const *il = objmgr.GetItemLocale(pProto->ItemId);
2498 if (il)
2500 if (il->Name.size() > loc_idx && !il->Name[loc_idx].empty())
2502 std::string name = il->Name[loc_idx];
2504 if (Utf8FitTo(name, wnamepart))
2506 if (m_session)
2507 PSendSysMessage(LANG_ITEM_LIST_CHAT, id, id, name.c_str());
2508 else
2509 PSendSysMessage(LANG_ITEM_LIST_CONSOLE, id, name.c_str());
2510 ++counter;
2511 continue;
2517 std::string name = pProto->Name1;
2518 if(name.empty())
2519 continue;
2521 if (Utf8FitTo(name, wnamepart))
2523 if (m_session)
2524 PSendSysMessage(LANG_ITEM_LIST_CHAT, id, id, name.c_str());
2525 else
2526 PSendSysMessage(LANG_ITEM_LIST_CONSOLE, id, name.c_str());
2527 ++counter;
2531 if (counter==0)
2532 SendSysMessage(LANG_COMMAND_NOITEMFOUND);
2534 return true;
2537 bool ChatHandler::HandleLookupItemSetCommand(const char* args)
2539 if(!*args)
2540 return false;
2542 std::string namepart = args;
2543 std::wstring wnamepart;
2545 if(!Utf8toWStr(namepart,wnamepart))
2546 return false;
2548 // converting string that we try to find to lower case
2549 wstrToLower( wnamepart );
2551 uint32 counter = 0; // Counter for figure out that we found smth.
2553 // Search in ItemSet.dbc
2554 for (uint32 id = 0; id < sItemSetStore.GetNumRows(); id++)
2556 ItemSetEntry const *set = sItemSetStore.LookupEntry(id);
2557 if(set)
2559 int loc = m_session ? m_session->GetSessionDbcLocale() : sWorld.GetDefaultDbcLocale();
2560 std::string name = set->name[loc];
2561 if(name.empty())
2562 continue;
2564 if (!Utf8FitTo(name, wnamepart))
2566 loc = 0;
2567 for(; loc < MAX_LOCALE; ++loc)
2569 if(m_session && loc==m_session->GetSessionDbcLocale())
2570 continue;
2572 name = set->name[loc];
2573 if(name.empty())
2574 continue;
2576 if (Utf8FitTo(name, wnamepart))
2577 break;
2581 if(loc < MAX_LOCALE)
2583 // send item set in "id - [namedlink locale]" format
2584 if (m_session)
2585 PSendSysMessage(LANG_ITEMSET_LIST_CHAT,id,id,name.c_str(),localeNames[loc]);
2586 else
2587 PSendSysMessage(LANG_ITEMSET_LIST_CONSOLE,id,name.c_str(),localeNames[loc]);
2588 ++counter;
2592 if (counter == 0) // if counter == 0 then we found nth
2593 SendSysMessage(LANG_COMMAND_NOITEMSETFOUND);
2594 return true;
2597 bool ChatHandler::HandleLookupSkillCommand(const char* args)
2599 if(!*args)
2600 return false;
2602 // can be NULL in console call
2603 Player* target = getSelectedPlayer();
2605 std::string namepart = args;
2606 std::wstring wnamepart;
2608 if(!Utf8toWStr(namepart,wnamepart))
2609 return false;
2611 // converting string that we try to find to lower case
2612 wstrToLower( wnamepart );
2614 uint32 counter = 0; // Counter for figure out that we found smth.
2616 // Search in SkillLine.dbc
2617 for (uint32 id = 0; id < sSkillLineStore.GetNumRows(); id++)
2619 SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(id);
2620 if(skillInfo)
2622 int loc = m_session ? m_session->GetSessionDbcLocale() : sWorld.GetDefaultDbcLocale();
2623 std::string name = skillInfo->name[loc];
2624 if(name.empty())
2625 continue;
2627 if (!Utf8FitTo(name, wnamepart))
2629 loc = 0;
2630 for(; loc < MAX_LOCALE; ++loc)
2632 if(m_session && loc==m_session->GetSessionDbcLocale())
2633 continue;
2635 name = skillInfo->name[loc];
2636 if(name.empty())
2637 continue;
2639 if (Utf8FitTo(name, wnamepart))
2640 break;
2644 if(loc < MAX_LOCALE)
2646 char const* knownStr = "";
2647 if(target && target->HasSkill(id))
2648 knownStr = GetMangosString(LANG_KNOWN);
2650 // send skill in "id - [namedlink locale]" format
2651 if (m_session)
2652 PSendSysMessage(LANG_SKILL_LIST_CHAT,id,id,name.c_str(),localeNames[loc],knownStr);
2653 else
2654 PSendSysMessage(LANG_SKILL_LIST_CONSOLE,id,name.c_str(),localeNames[loc],knownStr);
2656 ++counter;
2660 if (counter == 0) // if counter == 0 then we found nth
2661 SendSysMessage(LANG_COMMAND_NOSKILLFOUND);
2662 return true;
2665 bool ChatHandler::HandleLookupSpellCommand(const char* args)
2667 if(!*args)
2668 return false;
2670 // can be NULL at console call
2671 Player* target = getSelectedPlayer();
2673 std::string namepart = args;
2674 std::wstring wnamepart;
2676 if(!Utf8toWStr(namepart,wnamepart))
2677 return false;
2679 // converting string that we try to find to lower case
2680 wstrToLower( wnamepart );
2682 uint32 counter = 0; // Counter for figure out that we found smth.
2684 // Search in Spell.dbc
2685 for (uint32 id = 0; id < sSpellStore.GetNumRows(); id++)
2687 SpellEntry const *spellInfo = sSpellStore.LookupEntry(id);
2688 if(spellInfo)
2690 int loc = m_session ? m_session->GetSessionDbcLocale() : sWorld.GetDefaultDbcLocale();
2691 std::string name = spellInfo->SpellName[loc];
2692 if(name.empty())
2693 continue;
2695 if (!Utf8FitTo(name, wnamepart))
2697 loc = 0;
2698 for(; loc < MAX_LOCALE; ++loc)
2700 if(m_session && loc==m_session->GetSessionDbcLocale())
2701 continue;
2703 name = spellInfo->SpellName[loc];
2704 if(name.empty())
2705 continue;
2707 if (Utf8FitTo(name, wnamepart))
2708 break;
2712 if(loc < MAX_LOCALE)
2714 bool known = target && target->HasSpell(id);
2715 bool learn = (spellInfo->Effect[0] == SPELL_EFFECT_LEARN_SPELL);
2717 uint32 talentCost = GetTalentSpellCost(id);
2719 bool talent = (talentCost > 0);
2720 bool passive = IsPassiveSpell(id);
2721 bool active = target && (target->HasAura(id,0) || target->HasAura(id,1) || target->HasAura(id,2));
2723 // unit32 used to prevent interpreting uint8 as char at output
2724 // find rank of learned spell for learning spell, or talent rank
2725 uint32 rank = talentCost ? talentCost : spellmgr.GetSpellRank(learn ? spellInfo->EffectTriggerSpell[0] : id);
2727 // send spell in "id - [name, rank N] [talent] [passive] [learn] [known]" format
2728 std::ostringstream ss;
2729 if (m_session)
2730 ss << id << " - |cffffffff|Hspell:" << id << "|h[" << name;
2731 else
2732 ss << id << " - " << name;
2734 // include rank in link name
2735 if(rank)
2736 ss << GetMangosString(LANG_SPELL_RANK) << rank;
2738 if (m_session)
2739 ss << " " << localeNames[loc] << "]|h|r";
2740 else
2741 ss << " " << localeNames[loc];
2743 if(talent)
2744 ss << GetMangosString(LANG_TALENT);
2745 if(passive)
2746 ss << GetMangosString(LANG_PASSIVE);
2747 if(learn)
2748 ss << GetMangosString(LANG_LEARN);
2749 if(known)
2750 ss << GetMangosString(LANG_KNOWN);
2751 if(active)
2752 ss << GetMangosString(LANG_ACTIVE);
2754 SendSysMessage(ss.str().c_str());
2756 ++counter;
2760 if (counter == 0) // if counter == 0 then we found nth
2761 SendSysMessage(LANG_COMMAND_NOSPELLFOUND);
2762 return true;
2765 bool ChatHandler::HandleLookupQuestCommand(const char* args)
2767 if(!*args)
2768 return false;
2770 // can be NULL at console call
2771 Player* target = getSelectedPlayer();
2773 std::string namepart = args;
2774 std::wstring wnamepart;
2776 // converting string that we try to find to lower case
2777 if(!Utf8toWStr(namepart,wnamepart))
2778 return false;
2780 wstrToLower(wnamepart);
2782 uint32 counter = 0 ;
2784 ObjectMgr::QuestMap const& qTemplates = objmgr.GetQuestTemplates();
2785 for (ObjectMgr::QuestMap::const_iterator iter = qTemplates.begin(); iter != qTemplates.end(); ++iter)
2787 Quest * qinfo = iter->second;
2789 int loc_idx = m_session ? m_session->GetSessionDbLocaleIndex() : objmgr.GetDBCLocaleIndex();
2790 if ( loc_idx >= 0 )
2792 QuestLocale const *il = objmgr.GetQuestLocale(qinfo->GetQuestId());
2793 if (il)
2795 if (il->Title.size() > loc_idx && !il->Title[loc_idx].empty())
2797 std::string title = il->Title[loc_idx];
2799 if (Utf8FitTo(title, wnamepart))
2801 char const* statusStr = "";
2803 if(target)
2805 QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId());
2807 if(status == QUEST_STATUS_COMPLETE)
2809 if(target->GetQuestRewardStatus(qinfo->GetQuestId()))
2810 statusStr = GetMangosString(LANG_COMMAND_QUEST_REWARDED);
2811 else
2812 statusStr = GetMangosString(LANG_COMMAND_QUEST_COMPLETE);
2814 else if(status == QUEST_STATUS_INCOMPLETE)
2815 statusStr = GetMangosString(LANG_COMMAND_QUEST_ACTIVE);
2818 if (m_session)
2819 PSendSysMessage(LANG_QUEST_LIST_CHAT,qinfo->GetQuestId(),qinfo->GetQuestId(),title.c_str(),statusStr);
2820 else
2821 PSendSysMessage(LANG_QUEST_LIST_CONSOLE,qinfo->GetQuestId(),title.c_str(),statusStr);
2822 ++counter;
2823 continue;
2829 std::string title = qinfo->GetTitle();
2830 if(title.empty())
2831 continue;
2833 if (Utf8FitTo(title, wnamepart))
2835 char const* statusStr = "";
2837 if(target)
2839 QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId());
2841 if(status == QUEST_STATUS_COMPLETE)
2843 if(target->GetQuestRewardStatus(qinfo->GetQuestId()))
2844 statusStr = GetMangosString(LANG_COMMAND_QUEST_REWARDED);
2845 else
2846 statusStr = GetMangosString(LANG_COMMAND_QUEST_COMPLETE);
2848 else if(status == QUEST_STATUS_INCOMPLETE)
2849 statusStr = GetMangosString(LANG_COMMAND_QUEST_ACTIVE);
2852 if (m_session)
2853 PSendSysMessage(LANG_QUEST_LIST_CHAT,qinfo->GetQuestId(),qinfo->GetQuestId(),title.c_str(),statusStr);
2854 else
2855 PSendSysMessage(LANG_QUEST_LIST_CONSOLE,qinfo->GetQuestId(),title.c_str(),statusStr);
2857 ++counter;
2861 if (counter==0)
2862 SendSysMessage(LANG_COMMAND_NOQUESTFOUND);
2864 return true;
2867 bool ChatHandler::HandleLookupCreatureCommand(const char* args)
2869 if (!*args)
2870 return false;
2872 std::string namepart = args;
2873 std::wstring wnamepart;
2875 // converting string that we try to find to lower case
2876 if (!Utf8toWStr (namepart,wnamepart))
2877 return false;
2879 wstrToLower (wnamepart);
2881 uint32 counter = 0;
2883 for (uint32 id = 0; id< sCreatureStorage.MaxEntry; ++id)
2885 CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo> (id);
2886 if(!cInfo)
2887 continue;
2889 int loc_idx = m_session ? m_session->GetSessionDbLocaleIndex() : objmgr.GetDBCLocaleIndex();
2890 if (loc_idx >= 0)
2892 CreatureLocale const *cl = objmgr.GetCreatureLocale (id);
2893 if (cl)
2895 if (cl->Name.size() > loc_idx && !cl->Name[loc_idx].empty ())
2897 std::string name = cl->Name[loc_idx];
2899 if (Utf8FitTo (name, wnamepart))
2901 if (m_session)
2902 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CHAT, id, id, name.c_str ());
2903 else
2904 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CONSOLE, id, name.c_str ());
2905 ++counter;
2906 continue;
2912 std::string name = cInfo->Name;
2913 if (name.empty ())
2914 continue;
2916 if (Utf8FitTo(name, wnamepart))
2918 if (m_session)
2919 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CHAT, id, id, name.c_str ());
2920 else
2921 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CONSOLE, id, name.c_str ());
2922 ++counter;
2926 if (counter==0)
2927 SendSysMessage (LANG_COMMAND_NOCREATUREFOUND);
2929 return true;
2932 bool ChatHandler::HandleLookupObjectCommand(const char* args)
2934 if(!*args)
2935 return false;
2937 std::string namepart = args;
2938 std::wstring wnamepart;
2940 // converting string that we try to find to lower case
2941 if(!Utf8toWStr(namepart,wnamepart))
2942 return false;
2944 wstrToLower(wnamepart);
2946 uint32 counter = 0;
2948 for (uint32 id = 0; id< sGOStorage.MaxEntry; id++ )
2950 GameObjectInfo const* gInfo = sGOStorage.LookupEntry<GameObjectInfo>(id);
2951 if(!gInfo)
2952 continue;
2954 int loc_idx = m_session ? m_session->GetSessionDbLocaleIndex() : objmgr.GetDBCLocaleIndex();
2955 if ( loc_idx >= 0 )
2957 GameObjectLocale const *gl = objmgr.GetGameObjectLocale(id);
2958 if (gl)
2960 if (gl->Name.size() > loc_idx && !gl->Name[loc_idx].empty())
2962 std::string name = gl->Name[loc_idx];
2964 if (Utf8FitTo(name, wnamepart))
2966 if (m_session)
2967 PSendSysMessage(LANG_GO_ENTRY_LIST_CHAT, id, id, name.c_str());
2968 else
2969 PSendSysMessage(LANG_GO_ENTRY_LIST_CONSOLE, id, name.c_str());
2970 ++counter;
2971 continue;
2977 std::string name = gInfo->name;
2978 if(name.empty())
2979 continue;
2981 if(Utf8FitTo(name, wnamepart))
2983 if (m_session)
2984 PSendSysMessage(LANG_GO_ENTRY_LIST_CHAT, id, id, name.c_str());
2985 else
2986 PSendSysMessage(LANG_GO_ENTRY_LIST_CONSOLE, id, name.c_str());
2987 ++counter;
2991 if(counter==0)
2992 SendSysMessage(LANG_COMMAND_NOGAMEOBJECTFOUND);
2994 return true;
2997 /** \brief GM command level 3 - Create a guild.
2999 * This command allows a GM (level 3) to create a guild.
3001 * The "args" parameter contains the name of the guild leader
3002 * and then the name of the guild.
3005 bool ChatHandler::HandleGuildCreateCommand(const char* args)
3008 if (!*args)
3009 return false;
3011 char *lname = strtok ((char*)args, " ");
3012 char *gname = strtok (NULL, "");
3014 if (!lname)
3015 return false;
3017 if (!gname)
3019 SendSysMessage (LANG_INSERT_GUILD_NAME);
3020 SetSentErrorMessage (true);
3021 return false;
3024 std::string guildname = gname;
3026 Player* player = ObjectAccessor::Instance ().FindPlayerByName (lname);
3027 if (!player)
3029 SendSysMessage (LANG_PLAYER_NOT_FOUND);
3030 SetSentErrorMessage (true);
3031 return false;
3034 if (player->GetGuildId())
3036 SendSysMessage (LANG_PLAYER_IN_GUILD);
3037 return true;
3040 Guild *guild = new Guild;
3041 if (!guild->create (player->GetGUID (),guildname))
3043 delete guild;
3044 SendSysMessage (LANG_GUILD_NOT_CREATED);
3045 SetSentErrorMessage (true);
3046 return false;
3049 objmgr.AddGuild (guild);
3050 return true;
3053 bool ChatHandler::HandleGuildInviteCommand(const char *args)
3055 if (!*args)
3056 return false;
3058 char* par1 = strtok ((char*)args, " ");
3059 char* par2 = strtok (NULL, "");
3060 if(!par1 || !par2)
3061 return false;
3063 std::string glName = par2;
3064 Guild* targetGuild = objmgr.GetGuildByName (glName);
3065 if (!targetGuild)
3066 return false;
3068 std::string plName = par1;
3069 if (!normalizePlayerName (plName))
3071 SendSysMessage (LANG_PLAYER_NOT_FOUND);
3072 SetSentErrorMessage (true);
3073 return false;
3076 uint64 plGuid = 0;
3077 if (Player* targetPlayer = ObjectAccessor::Instance ().FindPlayerByName (plName.c_str ()))
3078 plGuid = targetPlayer->GetGUID ();
3079 else
3080 plGuid = objmgr.GetPlayerGUIDByName (plName.c_str ());
3082 if (!plGuid)
3083 false;
3085 // player's guild membership checked in AddMember before add
3086 if (!targetGuild->AddMember (plGuid,targetGuild->GetLowestRank ()))
3087 return false;
3089 return true;
3092 bool ChatHandler::HandleGuildUninviteCommand(const char *args)
3094 if (!*args)
3095 return false;
3097 char* par1 = strtok ((char*)args, " ");
3098 if(!par1)
3099 return false;
3101 std::string plName = par1;
3102 if (!normalizePlayerName (plName))
3104 SendSysMessage (LANG_PLAYER_NOT_FOUND);
3105 SetSentErrorMessage (true);
3106 return false;
3109 uint64 plGuid = 0;
3110 uint32 glId = 0;
3111 if (Player* targetPlayer = ObjectAccessor::Instance ().FindPlayerByName (plName.c_str ()))
3113 plGuid = targetPlayer->GetGUID ();
3114 glId = targetPlayer->GetGuildId ();
3116 else
3118 plGuid = objmgr.GetPlayerGUIDByName (plName.c_str ());
3119 glId = Player::GetGuildIdFromDB (plGuid);
3122 if (!plGuid || !glId)
3123 return false;
3125 Guild* targetGuild = objmgr.GetGuildById (glId);
3126 if (!targetGuild)
3127 return false;
3129 targetGuild->DelMember (plGuid);
3131 return true;
3134 bool ChatHandler::HandleGuildRankCommand(const char *args)
3136 if (!*args)
3137 return false;
3139 char* par1 = strtok ((char*)args, " ");
3140 char* par2 = strtok (NULL, " ");
3141 if (!par1 || !par2)
3142 return false;
3143 std::string plName = par1;
3144 if (!normalizePlayerName (plName))
3146 SendSysMessage (LANG_PLAYER_NOT_FOUND);
3147 SetSentErrorMessage (true);
3148 return false;
3151 uint64 plGuid = 0;
3152 uint32 glId = 0;
3153 if (Player* targetPlayer = ObjectAccessor::Instance ().FindPlayerByName (plName.c_str ()))
3155 plGuid = targetPlayer->GetGUID ();
3156 glId = targetPlayer->GetGuildId ();
3158 else
3160 plGuid = objmgr.GetPlayerGUIDByName (plName.c_str ());
3161 glId = Player::GetGuildIdFromDB (plGuid);
3164 if (!plGuid || !glId)
3165 return false;
3167 Guild* targetGuild = objmgr.GetGuildById (glId);
3168 if (!targetGuild)
3169 return false;
3171 uint32 newrank = uint32 (atoi (par2));
3172 if (newrank > targetGuild->GetLowestRank ())
3173 return false;
3175 targetGuild->ChangeRank (plGuid,newrank);
3177 return true;
3180 bool ChatHandler::HandleGuildDeleteCommand(const char* args)
3182 if (!*args)
3183 return false;
3185 char* par1 = strtok ((char*)args, " ");
3186 if (!par1)
3187 return false;
3189 std::string gld = par1;
3191 Guild* targetGuild = objmgr.GetGuildByName (gld);
3192 if (!targetGuild)
3193 return false;
3195 targetGuild->Disband ();
3197 return true;
3200 bool ChatHandler::HandleGetDistanceCommand(const char* /*args*/)
3202 Unit* pUnit = getSelectedUnit();
3204 if(!pUnit)
3206 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3207 SetSentErrorMessage(true);
3208 return false;
3211 PSendSysMessage(LANG_DISTANCE, m_session->GetPlayer()->GetDistance(pUnit),m_session->GetPlayer()->GetDistance2d(pUnit));
3213 return true;
3216 // FIX-ME!!!
3218 bool ChatHandler::HandleAddWeaponCommand(const char* /*args*/)
3220 /*if (!*args)
3221 return false;
3223 uint64 guid = m_session->GetPlayer()->GetSelection();
3224 if (guid == 0)
3226 SendSysMessage(LANG_NO_SELECTION);
3227 return true;
3230 Creature *pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
3232 if(!pCreature)
3234 SendSysMessage(LANG_SELECT_CREATURE);
3235 return true;
3238 char* pSlotID = strtok((char*)args, " ");
3239 if (!pSlotID)
3240 return false;
3242 char* pItemID = strtok(NULL, " ");
3243 if (!pItemID)
3244 return false;
3246 uint32 ItemID = atoi(pItemID);
3247 uint32 SlotID = atoi(pSlotID);
3249 ItemPrototype* tmpItem = objmgr.GetItemPrototype(ItemID);
3251 bool added = false;
3252 if(tmpItem)
3254 switch(SlotID)
3256 case 1:
3257 pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, ItemID);
3258 added = true;
3259 break;
3260 case 2:
3261 pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_01, ItemID);
3262 added = true;
3263 break;
3264 case 3:
3265 pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_02, ItemID);
3266 added = true;
3267 break;
3268 default:
3269 PSendSysMessage(LANG_ITEM_SLOT_NOT_EXIST,SlotID);
3270 added = false;
3271 break;
3273 if(added)
3275 PSendSysMessage(LANG_ITEM_ADDED_TO_SLOT,ItemID,tmpItem->Name1,SlotID);
3278 else
3280 PSendSysMessage(LANG_ITEM_NOT_FOUND,ItemID);
3281 return true;
3284 return true;
3287 bool ChatHandler::HandleDieCommand(const char* /*args*/)
3289 Unit* target = getSelectedUnit();
3291 if(!target || !m_session->GetPlayer()->GetSelection())
3293 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3294 SetSentErrorMessage(true);
3295 return false;
3298 if( target->isAlive() )
3300 m_session->GetPlayer()->DealDamage(target, target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
3303 return true;
3306 bool ChatHandler::HandleDamageCommand(const char * args)
3308 if (!*args)
3309 return false;
3311 Unit* target = getSelectedUnit();
3313 if(!target || !m_session->GetPlayer()->GetSelection())
3315 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3316 SetSentErrorMessage(true);
3317 return false;
3320 if( !target->isAlive() )
3321 return true;
3323 char* damageStr = strtok((char*)args, " ");
3324 if(!damageStr)
3325 return false;
3327 int32 damage = atoi((char*)damageStr);
3328 if(damage <=0)
3329 return true;
3331 char* schoolStr = strtok((char*)NULL, " ");
3333 // flat melee damage without resistence/etc reduction
3334 if(!schoolStr)
3336 m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
3337 m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, SPELL_SCHOOL_MASK_NORMAL, damage, 0, 0, VICTIMSTATE_NORMAL, 0);
3338 return true;
3341 uint32 school = schoolStr ? atoi((char*)schoolStr) : SPELL_SCHOOL_NORMAL;
3342 if(school >= MAX_SPELL_SCHOOL)
3343 return false;
3345 SpellSchoolMask schoolmask = SpellSchoolMask(1 << school);
3347 if ( schoolmask & SPELL_SCHOOL_MASK_NORMAL )
3348 damage = m_session->GetPlayer()->CalcArmorReducedDamage(target, damage);
3350 char* spellStr = strtok((char*)NULL, " ");
3352 // melee damage by specific school
3353 if(!spellStr)
3355 uint32 absorb = 0;
3356 uint32 resist = 0;
3358 m_session->GetPlayer()->CalcAbsorbResist(target,schoolmask, SPELL_DIRECT_DAMAGE, damage, &absorb, &resist);
3360 if (damage <= absorb + resist)
3361 return true;
3363 damage -= absorb + resist;
3365 m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, schoolmask, NULL, false);
3366 m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, schoolmask, damage, absorb, resist, VICTIMSTATE_NORMAL, 0);
3367 return true;
3370 // non-melee damage
3372 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
3373 uint32 spellid = extractSpellIdFromLink((char*)args);
3374 if(!spellid || !sSpellStore.LookupEntry(spellid))
3375 return false;
3377 m_session->GetPlayer()->SpellNonMeleeDamageLog(target, spellid, damage, false);
3378 return true;
3381 bool ChatHandler::HandleModifyArenaCommand(const char * args)
3383 if (!*args)
3384 return false;
3386 Player *target = getSelectedPlayer();
3387 if(!target)
3389 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3390 SetSentErrorMessage(true);
3391 return false;
3394 int32 amount = (uint32)atoi(args);
3396 target->ModifyArenaPoints(amount);
3398 PSendSysMessage(LANG_COMMAND_MODIFY_ARENA, target->GetName(), target->GetArenaPoints());
3400 return true;
3403 bool ChatHandler::HandleReviveCommand(const char* args)
3405 Player* SelectedPlayer = NULL;
3407 if (*args)
3409 std::string name = args;
3410 if(!normalizePlayerName(name))
3412 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3413 SetSentErrorMessage(true);
3414 return false;
3417 SelectedPlayer = objmgr.GetPlayer(name.c_str());
3419 else
3420 SelectedPlayer = getSelectedPlayer();
3422 if(!SelectedPlayer)
3424 SendSysMessage(LANG_NO_CHAR_SELECTED);
3425 SetSentErrorMessage(true);
3426 return false;
3429 SelectedPlayer->ResurrectPlayer(0.5f);
3430 SelectedPlayer->SpawnCorpseBones();
3431 SelectedPlayer->SaveToDB();
3432 return true;
3435 bool ChatHandler::HandleAuraCommand(const char* args)
3437 char* px = strtok((char*)args, " ");
3438 if (!px)
3439 return false;
3441 Unit *target = getSelectedUnit();
3442 if(!target)
3444 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3445 SetSentErrorMessage(true);
3446 return false;
3449 uint32 spellID = (uint32)atoi(px);
3450 SpellEntry const *spellInfo = sSpellStore.LookupEntry( spellID );
3451 if(spellInfo)
3453 for(uint32 i = 0;i<3;i++)
3455 uint8 eff = spellInfo->Effect[i];
3456 if (eff>=TOTAL_SPELL_EFFECTS)
3457 continue;
3458 if( IsAreaAuraEffect(eff) ||
3459 eff == SPELL_EFFECT_APPLY_AURA ||
3460 eff == SPELL_EFFECT_PERSISTENT_AREA_AURA )
3462 Aura *Aur = CreateAura(spellInfo, i, NULL, target);
3463 target->AddAura(Aur);
3468 return true;
3471 bool ChatHandler::HandleUnAuraCommand(const char* args)
3473 char* px = strtok((char*)args, " ");
3474 if (!px)
3475 return false;
3477 Unit *target = getSelectedUnit();
3478 if(!target)
3480 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3481 SetSentErrorMessage(true);
3482 return false;
3485 std::string argstr = args;
3486 if (argstr == "all")
3488 target->RemoveAllAuras();
3489 return true;
3492 uint32 spellID = (uint32)atoi(px);
3493 target->RemoveAurasDueToSpell(spellID);
3495 return true;
3498 bool ChatHandler::HandleLinkGraveCommand(const char* args)
3500 if(!*args)
3501 return false;
3503 char* px = strtok((char*)args, " ");
3504 if (!px)
3505 return false;
3507 uint32 g_id = (uint32)atoi(px);
3509 uint32 g_team;
3511 char* px2 = strtok(NULL, " ");
3513 if (!px2)
3514 g_team = 0;
3515 else if (strncmp(px2,"horde",6)==0)
3516 g_team = HORDE;
3517 else if (strncmp(px2,"alliance",9)==0)
3518 g_team = ALLIANCE;
3519 else
3520 return false;
3522 WorldSafeLocsEntry const* graveyard = sWorldSafeLocsStore.LookupEntry(g_id);
3524 if(!graveyard )
3526 PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST, g_id);
3527 SetSentErrorMessage(true);
3528 return false;
3531 Player* player = m_session->GetPlayer();
3533 uint32 zoneId = player->GetZoneId();
3535 AreaTableEntry const *areaEntry = GetAreaEntryByAreaID(zoneId);
3536 if(!areaEntry || areaEntry->zone !=0 )
3538 PSendSysMessage(LANG_COMMAND_GRAVEYARDWRONGZONE, g_id,zoneId);
3539 SetSentErrorMessage(true);
3540 return false;
3543 if(objmgr.AddGraveYardLink(g_id,player->GetZoneId(),g_team))
3544 PSendSysMessage(LANG_COMMAND_GRAVEYARDLINKED, g_id,zoneId);
3545 else
3546 PSendSysMessage(LANG_COMMAND_GRAVEYARDALRLINKED, g_id,zoneId);
3548 return true;
3551 bool ChatHandler::HandleNearGraveCommand(const char* args)
3553 uint32 g_team;
3555 size_t argslen = strlen(args);
3557 if(!*args)
3558 g_team = 0;
3559 else if (strncmp((char*)args,"horde",argslen)==0)
3560 g_team = HORDE;
3561 else if (strncmp((char*)args,"alliance",argslen)==0)
3562 g_team = ALLIANCE;
3563 else
3564 return false;
3566 Player* player = m_session->GetPlayer();
3568 WorldSafeLocsEntry const* graveyard = objmgr.GetClosestGraveYard(
3569 player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(),player->GetMapId(),g_team);
3571 if(graveyard)
3573 uint32 g_id = graveyard->ID;
3575 GraveYardData const* data = objmgr.FindGraveYardData(g_id,player->GetZoneId());
3576 if (!data)
3578 PSendSysMessage(LANG_COMMAND_GRAVEYARDERROR,g_id);
3579 SetSentErrorMessage(true);
3580 return false;
3583 g_team = data->team;
3585 std::string team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_NOTEAM);
3587 if(g_team == 0)
3588 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ANY);
3589 else if(g_team == HORDE)
3590 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_HORDE);
3591 else if(g_team == ALLIANCE)
3592 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ALLIANCE);
3594 PSendSysMessage(LANG_COMMAND_GRAVEYARDNEAREST, g_id,team_name.c_str(),player->GetZoneId());
3596 else
3598 std::string team_name;
3600 if(g_team == 0)
3601 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ANY);
3602 else if(g_team == HORDE)
3603 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_HORDE);
3604 else if(g_team == ALLIANCE)
3605 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ALLIANCE);
3607 if(g_team == ~uint32(0))
3608 PSendSysMessage(LANG_COMMAND_ZONENOGRAVEYARDS, player->GetZoneId());
3609 else
3610 PSendSysMessage(LANG_COMMAND_ZONENOGRAFACTION, player->GetZoneId(),team_name.c_str());
3613 return true;
3616 //play npc emote
3617 bool ChatHandler::HandleNpcPlayEmoteCommand(const char* args)
3619 uint32 emote = atoi((char*)args);
3621 Creature* target = getSelectedCreature();
3622 if(!target)
3624 SendSysMessage(LANG_SELECT_CREATURE);
3625 SetSentErrorMessage(true);
3626 return false;
3629 target->SetUInt32Value(UNIT_NPC_EMOTESTATE,emote);
3631 return true;
3634 bool ChatHandler::HandleNpcInfoCommand(const char* /*args*/)
3636 Creature* target = getSelectedCreature();
3638 if(!target)
3640 SendSysMessage(LANG_SELECT_CREATURE);
3641 SetSentErrorMessage(true);
3642 return false;
3645 uint32 faction = target->getFaction();
3646 uint32 npcflags = target->GetUInt32Value(UNIT_NPC_FLAGS);
3647 uint32 displayid = target->GetDisplayId();
3648 uint32 nativeid = target->GetNativeDisplayId();
3649 uint32 Entry = target->GetEntry();
3650 CreatureInfo const* cInfo = target->GetCreatureInfo();
3652 int32 curRespawnDelay = target->GetRespawnTimeEx()-time(NULL);
3653 if(curRespawnDelay < 0)
3654 curRespawnDelay = 0;
3655 std::string curRespawnDelayStr = secsToTimeString(curRespawnDelay,true);
3656 std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(),true);
3658 PSendSysMessage(LANG_NPCINFO_CHAR, target->GetDBTableGUIDLow(), faction, npcflags, Entry, displayid, nativeid);
3659 PSendSysMessage(LANG_NPCINFO_LEVEL, target->getLevel());
3660 PSendSysMessage(LANG_NPCINFO_HEALTH,target->GetCreateHealth(), target->GetMaxHealth(), target->GetHealth());
3661 PSendSysMessage(LANG_NPCINFO_FLAGS, target->GetUInt32Value(UNIT_FIELD_FLAGS), target->GetUInt32Value(UNIT_DYNAMIC_FLAGS), target->getFaction());
3662 PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES, defRespawnDelayStr.c_str(),curRespawnDelayStr.c_str());
3663 PSendSysMessage(LANG_NPCINFO_LOOT, cInfo->lootid,cInfo->pickpocketLootId,cInfo->SkinLootId);
3664 PSendSysMessage(LANG_NPCINFO_DUNGEON_ID, target->GetInstanceId());
3665 PSendSysMessage(LANG_NPCINFO_POSITION,float(target->GetPositionX()), float(target->GetPositionY()), float(target->GetPositionZ()));
3667 if ((npcflags & UNIT_NPC_FLAG_VENDOR) )
3669 SendSysMessage(LANG_NPCINFO_VENDOR);
3671 if ((npcflags & UNIT_NPC_FLAG_TRAINER) )
3673 SendSysMessage(LANG_NPCINFO_TRAINER);
3676 return true;
3679 bool ChatHandler::HandleExploreCheatCommand(const char* args)
3681 if (!*args)
3682 return false;
3684 int flag = atoi((char*)args);
3686 Player *chr = getSelectedPlayer();
3687 if (chr == NULL)
3689 SendSysMessage(LANG_NO_CHAR_SELECTED);
3690 SetSentErrorMessage(true);
3691 return false;
3694 if (flag != 0)
3696 PSendSysMessage(LANG_YOU_SET_EXPLORE_ALL, chr->GetName());
3697 if (needReportToTarget(chr))
3698 ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_ALL,GetName());
3700 else
3702 PSendSysMessage(LANG_YOU_SET_EXPLORE_NOTHING, chr->GetName());
3703 if (needReportToTarget(chr))
3704 ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_NOTHING,GetName());
3707 for (uint8 i=0; i<128; i++)
3709 if (flag != 0)
3711 m_session->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i,0xFFFFFFFF);
3713 else
3715 m_session->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i,0);
3719 return true;
3722 bool ChatHandler::HandleHoverCommand(const char* args)
3724 char* px = strtok((char*)args, " ");
3725 uint32 flag;
3726 if (!px)
3727 flag = 1;
3728 else
3729 flag = atoi(px);
3731 m_session->GetPlayer()->SetHover(flag);
3733 if (flag)
3734 SendSysMessage(LANG_HOVER_ENABLED);
3735 else
3736 SendSysMessage(LANG_HOVER_DISABLED);
3738 return true;
3741 bool ChatHandler::HandleLevelUpCommand(const char* args)
3743 char* px = strtok((char*)args, " ");
3744 char* py = strtok((char*)NULL, " ");
3746 // command format parsing
3747 char* pname = (char*)NULL;
3748 int addlevel = 1;
3750 if(px && py) // .levelup name level
3752 addlevel = atoi(py);
3753 pname = px;
3755 else if(px && !py) // .levelup name OR .levelup level
3757 if(isalpha(px[0])) // .levelup name
3758 pname = px;
3759 else // .levelup level
3760 addlevel = atoi(px);
3762 // else .levelup - nothing do for preparing
3764 // player
3765 Player *chr = NULL;
3766 uint64 chr_guid = 0;
3768 std::string name;
3770 if(pname) // player by name
3772 name = pname;
3773 if(!normalizePlayerName(name))
3775 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3776 SetSentErrorMessage(true);
3777 return false;
3780 chr = objmgr.GetPlayer(name.c_str());
3781 if(!chr) // not in game
3783 chr_guid = objmgr.GetPlayerGUIDByName(name);
3784 if (chr_guid == 0)
3786 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3787 SetSentErrorMessage(true);
3788 return false;
3792 else // player by selection
3794 chr = getSelectedPlayer();
3796 if (chr == NULL)
3798 SendSysMessage(LANG_NO_CHAR_SELECTED);
3799 SetSentErrorMessage(true);
3800 return false;
3803 name = chr->GetName();
3806 assert(chr || chr_guid);
3808 int32 oldlevel = chr ? chr->getLevel() : Player::GetUInt32ValueFromDB(UNIT_FIELD_LEVEL,chr_guid);
3809 int32 newlevel = oldlevel + addlevel;
3810 if(newlevel < 1)
3811 newlevel = 1;
3812 if(newlevel > STRONG_MAX_LEVEL) // hardcoded maximum level
3813 newlevel = STRONG_MAX_LEVEL;
3815 if(chr)
3817 chr->GiveLevel(newlevel);
3818 chr->InitTalentForLevel();
3819 chr->SetUInt32Value(PLAYER_XP,0);
3821 if(oldlevel == newlevel)
3822 ChatHandler(chr).SendSysMessage(LANG_YOURS_LEVEL_PROGRESS_RESET);
3823 else
3824 if(oldlevel < newlevel)
3825 ChatHandler(chr).PSendSysMessage(LANG_YOURS_LEVEL_UP,newlevel-oldlevel);
3826 else
3827 if(oldlevel > newlevel)
3828 ChatHandler(chr).PSendSysMessage(LANG_YOURS_LEVEL_DOWN,newlevel-oldlevel);
3830 else
3832 // update level and XP at level, all other will be updated at loading
3833 Tokens values;
3834 Player::LoadValuesArrayFromDB(values,chr_guid);
3835 Player::SetUInt32ValueInArray(values,UNIT_FIELD_LEVEL,newlevel);
3836 Player::SetUInt32ValueInArray(values,PLAYER_XP,0);
3837 Player::SaveValuesArrayInDB(values,chr_guid);
3840 if(m_session->GetPlayer() != chr) // including chr==NULL
3841 PSendSysMessage(LANG_YOU_CHANGE_LVL,name.c_str(),newlevel);
3842 return true;
3845 bool ChatHandler::HandleShowAreaCommand(const char* args)
3847 if (!*args)
3848 return false;
3850 int area = atoi((char*)args);
3852 Player *chr = getSelectedPlayer();
3853 if (chr == NULL)
3855 SendSysMessage(LANG_NO_CHAR_SELECTED);
3856 SetSentErrorMessage(true);
3857 return false;
3860 int offset = area / 32;
3861 uint32 val = (uint32)(1 << (area % 32));
3863 if(offset >= 128)
3865 SendSysMessage(LANG_BAD_VALUE);
3866 SetSentErrorMessage(true);
3867 return false;
3870 uint32 currFields = chr->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset);
3871 chr->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields | val));
3873 SendSysMessage(LANG_EXPLORE_AREA);
3874 return true;
3877 bool ChatHandler::HandleHideAreaCommand(const char* args)
3879 if (!*args)
3880 return false;
3882 int area = atoi((char*)args);
3884 Player *chr = getSelectedPlayer();
3885 if (chr == NULL)
3887 SendSysMessage(LANG_NO_CHAR_SELECTED);
3888 SetSentErrorMessage(true);
3889 return false;
3892 int offset = area / 32;
3893 uint32 val = (uint32)(1 << (area % 32));
3895 if(offset >= 128)
3897 SendSysMessage(LANG_BAD_VALUE);
3898 SetSentErrorMessage(true);
3899 return false;
3902 uint32 currFields = chr->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset);
3903 chr->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields ^ val));
3905 SendSysMessage(LANG_UNEXPLORE_AREA);
3906 return true;
3909 bool ChatHandler::HandleUpdate(const char* args)
3911 if(!*args)
3912 return false;
3914 uint32 updateIndex;
3915 uint32 value;
3917 char* pUpdateIndex = strtok((char*)args, " ");
3919 Unit* chr = getSelectedUnit();
3920 if (chr == NULL)
3922 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3923 SetSentErrorMessage(true);
3924 return false;
3927 if(!pUpdateIndex)
3929 return true;
3931 updateIndex = atoi(pUpdateIndex);
3932 //check updateIndex
3933 if(chr->GetTypeId() == TYPEID_PLAYER)
3935 if (updateIndex>=PLAYER_END) return true;
3937 else
3939 if (updateIndex>=UNIT_END) return true;
3942 char* pvalue = strtok(NULL, " ");
3943 if (!pvalue)
3945 value=chr->GetUInt32Value(updateIndex);
3947 PSendSysMessage(LANG_UPDATE, chr->GetGUIDLow(),updateIndex,value);
3948 return true;
3951 value=atoi(pvalue);
3953 PSendSysMessage(LANG_UPDATE_CHANGE, chr->GetGUIDLow(),updateIndex,value);
3955 chr->SetUInt32Value(updateIndex,value);
3957 return true;
3960 bool ChatHandler::HandleBankCommand(const char* /*args*/)
3962 m_session->SendShowBank( m_session->GetPlayer()->GetGUID() );
3964 return true;
3967 bool ChatHandler::HandleChangeWeather(const char* args)
3969 if(!*args)
3970 return false;
3972 //Weather is OFF
3973 if (!sWorld.getConfig(CONFIG_WEATHER))
3975 SendSysMessage(LANG_WEATHER_DISABLED);
3976 SetSentErrorMessage(true);
3977 return false;
3980 //*Change the weather of a cell
3981 char* px = strtok((char*)args, " ");
3982 char* py = strtok(NULL, " ");
3984 if (!px || !py)
3985 return false;
3987 uint32 type = (uint32)atoi(px); //0 to 3, 0: fine, 1: rain, 2: snow, 3: sand
3988 float grade = (float)atof(py); //0 to 1, sending -1 is instand good weather
3990 Player *player = m_session->GetPlayer();
3991 uint32 zoneid = player->GetZoneId();
3993 Weather* wth = sWorld.FindWeather(zoneid);
3995 if(!wth)
3996 wth = sWorld.AddWeather(zoneid);
3997 if(!wth)
3999 SendSysMessage(LANG_NO_WEATHER);
4000 SetSentErrorMessage(true);
4001 return false;
4004 wth->SetWeather(WeatherType(type), grade);
4006 return true;
4009 bool ChatHandler::HandleSetValue(const char* args)
4011 if(!*args)
4012 return false;
4014 char* px = strtok((char*)args, " ");
4015 char* py = strtok(NULL, " ");
4016 char* pz = strtok(NULL, " ");
4018 if (!px || !py)
4019 return false;
4021 Unit* target = getSelectedUnit();
4022 if(!target)
4024 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
4025 SetSentErrorMessage(true);
4026 return false;
4029 uint64 guid = target->GetGUID();
4031 uint32 Opcode = (uint32)atoi(px);
4032 if(Opcode >= target->GetValuesCount())
4034 PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, GUID_LOPART(guid), target->GetValuesCount());
4035 return false;
4037 uint32 iValue;
4038 float fValue;
4039 bool isint32 = true;
4040 if(pz)
4041 isint32 = (bool)atoi(pz);
4042 if(isint32)
4044 iValue = (uint32)atoi(py);
4045 sLog.outDebug(GetMangosString(LANG_SET_UINT), GUID_LOPART(guid), Opcode, iValue);
4046 target->SetUInt32Value( Opcode , iValue );
4047 PSendSysMessage(LANG_SET_UINT_FIELD, GUID_LOPART(guid), Opcode,iValue);
4049 else
4051 fValue = (float)atof(py);
4052 sLog.outDebug(GetMangosString(LANG_SET_FLOAT), GUID_LOPART(guid), Opcode, fValue);
4053 target->SetFloatValue( Opcode , fValue );
4054 PSendSysMessage(LANG_SET_FLOAT_FIELD, GUID_LOPART(guid), Opcode,fValue);
4057 return true;
4060 bool ChatHandler::HandleGetValue(const char* args)
4062 if(!*args)
4063 return false;
4065 char* px = strtok((char*)args, " ");
4066 char* pz = strtok(NULL, " ");
4068 if (!px)
4069 return false;
4071 Unit* target = getSelectedUnit();
4072 if(!target)
4074 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
4075 SetSentErrorMessage(true);
4076 return false;
4079 uint64 guid = target->GetGUID();
4081 uint32 Opcode = (uint32)atoi(px);
4082 if(Opcode >= target->GetValuesCount())
4084 PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, GUID_LOPART(guid), target->GetValuesCount());
4085 return false;
4087 uint32 iValue;
4088 float fValue;
4089 bool isint32 = true;
4090 if(pz)
4091 isint32 = (bool)atoi(pz);
4093 if(isint32)
4095 iValue = target->GetUInt32Value( Opcode );
4096 sLog.outDebug(GetMangosString(LANG_GET_UINT), GUID_LOPART(guid), Opcode, iValue);
4097 PSendSysMessage(LANG_GET_UINT_FIELD, GUID_LOPART(guid), Opcode, iValue);
4099 else
4101 fValue = target->GetFloatValue( Opcode );
4102 sLog.outDebug(GetMangosString(LANG_GET_FLOAT), GUID_LOPART(guid), Opcode, fValue);
4103 PSendSysMessage(LANG_GET_FLOAT_FIELD, GUID_LOPART(guid), Opcode, fValue);
4106 return true;
4109 bool ChatHandler::HandleSet32Bit(const char* args)
4111 if(!*args)
4112 return false;
4114 char* px = strtok((char*)args, " ");
4115 char* py = strtok(NULL, " ");
4117 if (!px || !py)
4118 return false;
4120 uint32 Opcode = (uint32)atoi(px);
4121 uint32 Value = (uint32)atoi(py);
4122 if (Value > 32) //uint32 = 32 bits
4123 return false;
4125 sLog.outDebug(GetMangosString(LANG_SET_32BIT), Opcode, Value);
4127 m_session->GetPlayer( )->SetUInt32Value( Opcode , 2^Value );
4129 PSendSysMessage(LANG_SET_32BIT_FIELD, Opcode,1);
4130 return true;
4133 bool ChatHandler::HandleMod32Value(const char* args)
4135 if(!*args)
4136 return false;
4138 char* px = strtok((char*)args, " ");
4139 char* py = strtok(NULL, " ");
4141 if (!px || !py)
4142 return false;
4144 uint32 Opcode = (uint32)atoi(px);
4145 int Value = atoi(py);
4147 if(Opcode >= m_session->GetPlayer()->GetValuesCount())
4149 PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, m_session->GetPlayer()->GetGUIDLow(), m_session->GetPlayer( )->GetValuesCount());
4150 return false;
4153 sLog.outDebug(GetMangosString(LANG_CHANGE_32BIT), Opcode, Value);
4155 int CurrentValue = (int)m_session->GetPlayer( )->GetUInt32Value( Opcode );
4157 CurrentValue += Value;
4158 m_session->GetPlayer( )->SetUInt32Value( Opcode , (uint32)CurrentValue );
4160 PSendSysMessage(LANG_CHANGE_32BIT_FIELD, Opcode,CurrentValue);
4162 return true;
4165 bool ChatHandler::HandleAddTeleCommand(const char * args)
4167 if(!*args)
4168 return false;
4170 Player *player=m_session->GetPlayer();
4171 if (!player)
4172 return false;
4174 std::string name = args;
4176 if(objmgr.GetGameTele(name))
4178 SendSysMessage(LANG_COMMAND_TP_ALREADYEXIST);
4179 SetSentErrorMessage(true);
4180 return false;
4183 GameTele tele;
4184 tele.position_x = player->GetPositionX();
4185 tele.position_y = player->GetPositionY();
4186 tele.position_z = player->GetPositionZ();
4187 tele.orientation = player->GetOrientation();
4188 tele.mapId = player->GetMapId();
4189 tele.name = name;
4191 if(objmgr.AddGameTele(tele))
4193 SendSysMessage(LANG_COMMAND_TP_ADDED);
4195 else
4197 SendSysMessage(LANG_COMMAND_TP_ADDEDERR);
4198 SetSentErrorMessage(true);
4199 return false;
4202 return true;
4205 bool ChatHandler::HandleDelTeleCommand(const char * args)
4207 if(!*args)
4208 return false;
4210 std::string name = args;
4212 if(!objmgr.DeleteGameTele(name))
4214 SendSysMessage(LANG_COMMAND_TELE_NOTFOUND);
4215 SetSentErrorMessage(true);
4216 return false;
4219 SendSysMessage(LANG_COMMAND_TP_DELETED);
4220 return true;
4223 bool ChatHandler::HandleListAurasCommand (const char * /*args*/)
4225 Unit *unit = getSelectedUnit();
4226 if(!unit)
4228 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
4229 SetSentErrorMessage(true);
4230 return false;
4233 char const* talentStr = GetMangosString(LANG_TALENT);
4234 char const* passiveStr = GetMangosString(LANG_PASSIVE);
4236 Unit::AuraMap const& uAuras = unit->GetAuras();
4237 PSendSysMessage(LANG_COMMAND_TARGET_LISTAURAS, uAuras.size());
4238 for (Unit::AuraMap::const_iterator itr = uAuras.begin(); itr != uAuras.end(); ++itr)
4240 bool talent = GetTalentSpellCost(itr->second->GetId()) > 0;
4241 PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffIndex(),
4242 itr->second->GetModifier()->m_auraname, itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(),
4243 itr->second->GetSpellProto()->SpellName[m_session->GetSessionDbcLocale()],
4244 (itr->second->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
4245 IS_PLAYER_GUID(itr->second->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(itr->second->GetCasterGUID()));
4247 for (int i = 0; i < TOTAL_AURAS; i++)
4249 Unit::AuraList const& uAuraList = unit->GetAurasByType(AuraType(i));
4250 if (uAuraList.empty()) continue;
4251 PSendSysMessage(LANG_COMMAND_TARGET_LISTAURATYPE, uAuraList.size(), i);
4252 for (Unit::AuraList::const_iterator itr = uAuraList.begin(); itr != uAuraList.end(); ++itr)
4254 bool talent = GetTalentSpellCost((*itr)->GetId()) > 0;
4255 PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(),
4256 (*itr)->GetSpellProto()->SpellName[m_session->GetSessionDbcLocale()],((*itr)->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
4257 IS_PLAYER_GUID((*itr)->GetCasterGUID()) ? "player" : "creature",GUID_LOPART((*itr)->GetCasterGUID()));
4260 return true;
4263 bool ChatHandler::HandleResetHonorCommand (const char * args)
4265 char* pName = strtok((char*)args, "");
4266 Player *player = NULL;
4267 if (pName)
4269 std::string name = pName;
4270 if(!normalizePlayerName(name))
4272 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4273 SetSentErrorMessage(true);
4274 return false;
4277 uint64 guid = objmgr.GetPlayerGUIDByName(name.c_str());
4278 player = objmgr.GetPlayer(guid);
4280 else
4281 player = getSelectedPlayer();
4283 if(!player)
4285 SendSysMessage(LANG_NO_CHAR_SELECTED);
4286 return true;
4289 player->SetUInt32Value(PLAYER_FIELD_KILLS, 0);
4290 player->SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORBALE_KILLS, 0);
4291 player->SetUInt32Value(PLAYER_FIELD_HONOR_CURRENCY, 0);
4292 player->SetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, 0);
4293 player->SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, 0);
4295 return true;
4298 static bool HandleResetStatsOrLevelHelper(Player* player)
4300 PlayerInfo const *info = objmgr.GetPlayerInfo(player->getRace(), player->getClass());
4301 if(!info) return false;
4303 ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(player->getClass());
4304 if(!cEntry)
4306 sLog.outError("Class %u not found in DBC (Wrong DBC files?)",player->getClass());
4307 return false;
4310 uint8 powertype = cEntry->powerType;
4312 uint32 unitfield;
4313 if(powertype == POWER_RAGE)
4314 unitfield = 0x1100EE00;
4315 else if(powertype == POWER_ENERGY)
4316 unitfield = 0x00000000;
4317 else if(powertype == POWER_MANA)
4318 unitfield = 0x0000EE00;
4319 else
4321 sLog.outError("Invalid default powertype %u for player (class %u)",powertype,player->getClass());
4322 return false;
4325 // reset m_form if no aura
4326 if(!player->HasAuraType(SPELL_AURA_MOD_SHAPESHIFT))
4327 player->m_form = FORM_NONE;
4329 player->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE );
4330 player->SetFloatValue(UNIT_FIELD_COMBATREACH, 1.5f );
4332 player->setFactionForRace(player->getRace());
4334 player->SetUInt32Value(UNIT_FIELD_BYTES_0, ( ( player->getRace() ) | ( player->getClass() << 8 ) | ( player->getGender() << 16 ) | ( powertype << 24 ) ) );
4336 // reset only if player not in some form;
4337 if(player->m_form==FORM_NONE)
4339 switch(player->getGender())
4341 case GENDER_FEMALE:
4342 player->SetDisplayId(info->displayId_f);
4343 player->SetNativeDisplayId(info->displayId_f);
4344 break;
4345 case GENDER_MALE:
4346 player->SetDisplayId(info->displayId_m);
4347 player->SetNativeDisplayId(info->displayId_m);
4348 break;
4349 default:
4350 break;
4354 // set UNIT_FIELD_BYTES_1 to init state but preserve m_form value
4355 player->SetUInt32Value(UNIT_FIELD_BYTES_1, unitfield);
4356 player->SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP );
4357 player->SetByteValue(UNIT_FIELD_BYTES_2, 3, player->m_form);
4359 player->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
4361 //-1 is default value
4362 player->SetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, uint32(-1));
4364 //player->SetUInt32Value(PLAYER_FIELD_BYTES, 0xEEE00000 );
4365 return true;
4368 bool ChatHandler::HandleResetLevelCommand(const char * args)
4370 char* pName = strtok((char*)args, "");
4371 Player *player = NULL;
4372 if (pName)
4374 std::string name = pName;
4375 if(!normalizePlayerName(name))
4377 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4378 SetSentErrorMessage(true);
4379 return false;
4382 uint64 guid = objmgr.GetPlayerGUIDByName(name.c_str());
4383 player = objmgr.GetPlayer(guid);
4385 else
4386 player = getSelectedPlayer();
4388 if(!player)
4390 SendSysMessage(LANG_NO_CHAR_SELECTED);
4391 SetSentErrorMessage(true);
4392 return false;
4395 if(!HandleResetStatsOrLevelHelper(player))
4396 return false;
4398 player->SetLevel(1);
4399 player->InitStatsForLevel(true);
4400 player->InitTaxiNodesForLevel();
4401 player->InitGlyphsForLevel();
4402 player->InitTalentForLevel();
4403 player->SetUInt32Value(PLAYER_XP,0);
4405 // reset level to summoned pet
4406 Pet* pet = player->GetPet();
4407 if(pet && pet->getPetType()==SUMMON_PET)
4408 pet->InitStatsForLevel(1);
4410 return true;
4413 bool ChatHandler::HandleResetStatsCommand(const char * args)
4415 char* pName = strtok((char*)args, "");
4416 Player *player = NULL;
4417 if (pName)
4419 std::string name = pName;
4420 if(!normalizePlayerName(name))
4422 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4423 SetSentErrorMessage(true);
4424 return false;
4427 uint64 guid = objmgr.GetPlayerGUIDByName(name.c_str());
4428 player = objmgr.GetPlayer(guid);
4430 else
4431 player = getSelectedPlayer();
4433 if(!player)
4435 SendSysMessage(LANG_NO_CHAR_SELECTED);
4436 SetSentErrorMessage(true);
4437 return false;
4440 if(!HandleResetStatsOrLevelHelper(player))
4441 return false;
4443 player->InitStatsForLevel(true);
4444 player->InitTaxiNodesForLevel();
4445 player->InitGlyphsForLevel();
4446 player->InitTalentForLevel();
4448 return true;
4451 bool ChatHandler::HandleResetSpellsCommand(const char * args)
4453 char* pName = strtok((char*)args, "");
4454 Player *player = NULL;
4455 uint64 playerGUID = 0;
4456 if (pName)
4458 std::string name = pName;
4460 if(!normalizePlayerName(name))
4462 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4463 SetSentErrorMessage(true);
4464 return false;
4467 player = objmgr.GetPlayer(name.c_str());
4468 if(!player)
4469 playerGUID = objmgr.GetPlayerGUIDByName(name.c_str());
4471 else
4472 player = getSelectedPlayer();
4474 if(!player && !playerGUID)
4476 SendSysMessage(LANG_NO_CHAR_SELECTED);
4477 SetSentErrorMessage(true);
4478 return false;
4481 if(player)
4483 player->resetSpells();
4485 ChatHandler(player).SendSysMessage(LANG_RESET_SPELLS);
4487 if(m_session->GetPlayer()!=player)
4488 PSendSysMessage(LANG_RESET_SPELLS_ONLINE,player->GetName());
4490 else
4492 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",uint32(AT_LOGIN_RESET_SPELLS), GUID_LOPART(playerGUID));
4493 PSendSysMessage(LANG_RESET_SPELLS_OFFLINE,pName);
4496 return true;
4499 bool ChatHandler::HandleResetTalentsCommand(const char * args)
4501 char* pName = strtok((char*)args, "");
4502 Player *player = NULL;
4503 uint64 playerGUID = 0;
4504 if (pName)
4506 std::string name = pName;
4507 if(!normalizePlayerName(name))
4509 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4510 SetSentErrorMessage(true);
4511 return false;
4514 player = objmgr.GetPlayer(name.c_str());
4515 if(!player)
4516 playerGUID = objmgr.GetPlayerGUIDByName(name.c_str());
4518 else
4519 player = getSelectedPlayer();
4521 if(!player && !playerGUID)
4523 SendSysMessage(LANG_NO_CHAR_SELECTED);
4524 SetSentErrorMessage(true);
4525 return false;
4528 if(player)
4530 player->resetTalents(true);
4532 ChatHandler(player).SendSysMessage(LANG_RESET_TALENTS);
4534 if(m_session->GetPlayer()!=player)
4535 PSendSysMessage(LANG_RESET_TALENTS_ONLINE,player->GetName());
4537 else
4539 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",uint32(AT_LOGIN_RESET_TALENTS), GUID_LOPART(playerGUID) );
4540 PSendSysMessage(LANG_RESET_TALENTS_OFFLINE,pName);
4543 return true;
4546 bool ChatHandler::HandleResetAllCommand(const char * args)
4548 if(!*args)
4549 return false;
4551 std::string casename = args;
4553 AtLoginFlags atLogin;
4555 // Command specially created as single command to prevent using short case names
4556 if(casename=="spells")
4558 atLogin = AT_LOGIN_RESET_SPELLS;
4559 sWorld.SendWorldText(LANG_RESETALL_SPELLS);
4561 else if(casename=="talents")
4563 atLogin = AT_LOGIN_RESET_TALENTS;
4564 sWorld.SendWorldText(LANG_RESETALL_TALENTS);
4566 else
4568 PSendSysMessage(LANG_RESETALL_UNKNOWN_CASE,args);
4569 SetSentErrorMessage(true);
4570 return false;
4573 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE (at_login & '%u') = '0'",atLogin,atLogin);
4574 HashMapHolder<Player>::MapType const& plist = ObjectAccessor::Instance().GetPlayers();
4575 for(HashMapHolder<Player>::MapType::const_iterator itr = plist.begin(); itr != plist.end(); ++itr)
4576 itr->second->SetAtLoginFlag(atLogin);
4578 return true;
4581 bool ChatHandler::HandleServerShutDownCancelCommand(const char* args)
4583 sWorld.ShutdownCancel();
4584 return true;
4587 bool ChatHandler::HandleServerShutDownCommand(const char* args)
4589 if(!*args)
4590 return false;
4592 char* time_str = strtok ((char*) args, " ");
4593 char* exitcode_str = strtok (NULL, "");
4595 int32 time = atoi (time_str);
4597 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4598 if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0)
4599 return false;
4601 if (exitcode_str)
4603 int32 exitcode = atoi (exitcode_str);
4605 // Handle atoi() errors
4606 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4607 return false;
4609 // Exit code should be in range of 0-125, 126-255 is used
4610 // in many shells for their own return codes and code > 255
4611 // is not supported in many others
4612 if (exitcode < 0 || exitcode > 125)
4613 return false;
4615 sWorld.ShutdownServ (time, 0, exitcode);
4617 else
4618 sWorld.ShutdownServ(time,0,SHUTDOWN_EXIT_CODE);
4619 return true;
4622 bool ChatHandler::HandleServerRestartCommand(const char* args)
4624 if(!*args)
4625 return false;
4627 char* time_str = strtok ((char*) args, " ");
4628 char* exitcode_str = strtok (NULL, "");
4630 int32 time = atoi (time_str);
4632 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4633 if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0)
4634 return false;
4636 if (exitcode_str)
4638 int32 exitcode = atoi (exitcode_str);
4640 // Handle atoi() errors
4641 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4642 return false;
4644 // Exit code should be in range of 0-125, 126-255 is used
4645 // in many shells for their own return codes and code > 255
4646 // is not supported in many others
4647 if (exitcode < 0 || exitcode > 125)
4648 return false;
4650 sWorld.ShutdownServ (time, SHUTDOWN_MASK_RESTART, exitcode);
4652 else
4653 sWorld.ShutdownServ(time, SHUTDOWN_MASK_RESTART, RESTART_EXIT_CODE);
4654 return true;
4657 bool ChatHandler::HandleServerIdleRestartCommand(const char* args)
4659 if(!*args)
4660 return false;
4662 char* time_str = strtok ((char*) args, " ");
4663 char* exitcode_str = strtok (NULL, "");
4665 int32 time = atoi (time_str);
4667 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4668 if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0)
4669 return false;
4671 if (exitcode_str)
4673 int32 exitcode = atoi (exitcode_str);
4675 // Handle atoi() errors
4676 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4677 return false;
4679 // Exit code should be in range of 0-125, 126-255 is used
4680 // in many shells for their own return codes and code > 255
4681 // is not supported in many others
4682 if (exitcode < 0 || exitcode > 125)
4683 return false;
4685 sWorld.ShutdownServ (time, SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE, exitcode);
4687 else
4688 sWorld.ShutdownServ(time,SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE,RESTART_EXIT_CODE);
4689 return true;
4692 bool ChatHandler::HandleServerIdleShutDownCommand(const char* args)
4694 if(!*args)
4695 return false;
4697 char* time_str = strtok ((char*) args, " ");
4698 char* exitcode_str = strtok (NULL, "");
4700 int32 time = atoi (time_str);
4702 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4703 if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0)
4704 return false;
4706 if (exitcode_str)
4708 int32 exitcode = atoi (exitcode_str);
4710 // Handle atoi() errors
4711 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4712 return false;
4714 // Exit code should be in range of 0-125, 126-255 is used
4715 // in many shells for their own return codes and code > 255
4716 // is not supported in many others
4717 if (exitcode < 0 || exitcode > 125)
4718 return false;
4720 sWorld.ShutdownServ (time, SHUTDOWN_MASK_IDLE, exitcode);
4722 else
4723 sWorld.ShutdownServ(time,SHUTDOWN_MASK_IDLE,SHUTDOWN_EXIT_CODE);
4724 return true;
4727 bool ChatHandler::HandleAddQuest(const char* args)
4729 Player* player = getSelectedPlayer();
4730 if(!player)
4732 SendSysMessage(LANG_NO_CHAR_SELECTED);
4733 SetSentErrorMessage(true);
4734 return false;
4737 // .addquest #entry'
4738 // number or [name] Shift-click form |color|Hquest:quest_id|h[name]|h|r
4739 char* cId = extractKeyFromLink((char*)args,"Hquest");
4740 if(!cId)
4741 return false;
4743 uint32 entry = atol(cId);
4745 Quest const* pQuest = objmgr.GetQuestTemplate(entry);
4747 if(!pQuest)
4749 PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND,entry);
4750 SetSentErrorMessage(true);
4751 return false;
4754 // check item starting quest (it can work incorrectly if added without item in inventory)
4755 for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
4757 ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype>(id);
4758 if (!pProto)
4759 continue;
4761 if (pProto->StartQuest == entry)
4763 PSendSysMessage(LANG_COMMAND_QUEST_STARTFROMITEM, entry, pProto->ItemId);
4764 SetSentErrorMessage(true);
4765 return false;
4769 // ok, normal (creature/GO starting) quest
4770 if( player->CanAddQuest( pQuest, true ) )
4772 player->AddQuest( pQuest, NULL );
4774 if ( player->CanCompleteQuest( entry ) )
4775 player->CompleteQuest( entry );
4778 return true;
4781 bool ChatHandler::HandleRemoveQuest(const char* args)
4783 Player* player = getSelectedPlayer();
4784 if(!player)
4786 SendSysMessage(LANG_NO_CHAR_SELECTED);
4787 SetSentErrorMessage(true);
4788 return false;
4791 // .removequest #entry'
4792 // number or [name] Shift-click form |color|Hquest:quest_id|h[name]|h|r
4793 char* cId = extractKeyFromLink((char*)args,"Hquest");
4794 if(!cId)
4795 return false;
4797 uint32 entry = atol(cId);
4799 Quest const* pQuest = objmgr.GetQuestTemplate(entry);
4801 if(!pQuest)
4803 PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry);
4804 SetSentErrorMessage(true);
4805 return false;
4808 // remove all quest entries for 'entry' from quest log
4809 for(uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot )
4811 uint32 quest = player->GetQuestSlotQuestId(slot);
4812 if(quest==entry)
4814 player->SetQuestSlot(slot,0);
4816 // we ignore unequippable quest items in this case, its' still be equipped
4817 player->TakeQuestSourceItem( quest, false );
4821 // set quest status to not started (will updated in DB at next save)
4822 player->SetQuestStatus( entry, QUEST_STATUS_NONE);
4824 // reset rewarded for restart repeatable quest
4825 player->getQuestStatusMap()[entry].m_rewarded = false;
4827 SendSysMessage(LANG_COMMAND_QUEST_REMOVED);
4828 return true;
4831 bool ChatHandler::HandleCompleteQuest(const char* args)
4833 Player* player = getSelectedPlayer();
4834 if(!player)
4836 SendSysMessage(LANG_NO_CHAR_SELECTED);
4837 SetSentErrorMessage(true);
4838 return false;
4841 // .quest complete #entry
4842 // number or [name] Shift-click form |color|Hquest:quest_id|h[name]|h|r
4843 char* cId = extractKeyFromLink((char*)args,"Hquest");
4844 if(!cId)
4845 return false;
4847 uint32 entry = atol(cId);
4849 Quest const* pQuest = objmgr.GetQuestTemplate(entry);
4851 // If player doesn't have the quest
4852 if(!pQuest || player->GetQuestStatus(entry) == QUEST_STATUS_NONE)
4854 PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry);
4855 SetSentErrorMessage(true);
4856 return false;
4859 // Add quest items for quests that require items
4860 for(uint8 x = 0; x < QUEST_OBJECTIVES_COUNT; ++x)
4862 uint32 id = pQuest->ReqItemId[x];
4863 uint32 count = pQuest->ReqItemCount[x];
4864 if(!id || !count)
4865 continue;
4867 uint32 curItemCount = player->GetItemCount(id,true);
4869 ItemPosCountVec dest;
4870 uint8 msg = player->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, id, count-curItemCount );
4871 if( msg == EQUIP_ERR_OK )
4873 Item* item = player->StoreNewItem( dest, id, true);
4874 player->SendNewItem(item,count-curItemCount,true,false);
4878 // All creature/GO slain/casted (not required, but otherwise it will display "Creature slain 0/10")
4879 for(uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; i++)
4881 uint32 creature = pQuest->ReqCreatureOrGOId[i];
4882 uint32 creaturecount = pQuest->ReqCreatureOrGOCount[i];
4884 if(uint32 spell_id = pQuest->ReqSpell[i])
4886 for(uint16 z = 0; z < creaturecount; ++z)
4887 player->CastedCreatureOrGO(creature,0,spell_id);
4889 else if(creature > 0)
4891 for(uint16 z = 0; z < creaturecount; ++z)
4892 player->KilledMonster(creature,0);
4894 else if(creature < 0)
4896 for(uint16 z = 0; z < creaturecount; ++z)
4897 player->CastedCreatureOrGO(creature,0,0);
4901 // If the quest requires reputation to complete
4902 if(uint32 repFaction = pQuest->GetRepObjectiveFaction())
4904 uint32 repValue = pQuest->GetRepObjectiveValue();
4905 uint32 curRep = player->GetReputation(repFaction);
4906 if(curRep < repValue)
4908 FactionEntry const *factionEntry = sFactionStore.LookupEntry(repFaction);
4909 player->SetFactionReputation(factionEntry,repValue);
4913 // If the quest requires money
4914 int32 ReqOrRewMoney = pQuest->GetRewOrReqMoney();
4915 if(ReqOrRewMoney < 0)
4916 player->ModifyMoney(-ReqOrRewMoney);
4918 player->CompleteQuest(entry);
4919 return true;
4922 bool ChatHandler::HandleBanAccountCommand(const char* args)
4924 return HandleBanHelper(BAN_ACCOUNT,args);
4927 bool ChatHandler::HandleBanCharacterCommand(const char* args)
4929 return HandleBanHelper(BAN_CHARACTER,args);
4932 bool ChatHandler::HandleBanIPCommand(const char* args)
4934 return HandleBanHelper(BAN_IP,args);
4937 bool ChatHandler::HandleBanHelper(BanMode mode, const char* args)
4939 if(!args)
4940 return false;
4942 char* cnameOrIP = strtok ((char*)args, " ");
4943 if (!cnameOrIP)
4944 return false;
4946 std::string nameOrIP = cnameOrIP;
4948 char* duration = strtok (NULL," ");
4949 if(!duration || !atoi(duration))
4950 return false;
4952 char* reason = strtok (NULL,"");
4953 if(!reason)
4954 return false;
4956 switch(mode)
4958 case BAN_ACCOUNT:
4959 if(!AccountMgr::normilizeString(nameOrIP))
4961 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,nameOrIP.c_str());
4962 SetSentErrorMessage(true);
4963 return false;
4965 break;
4966 case BAN_CHARACTER:
4967 if(!normalizePlayerName(nameOrIP))
4969 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4970 SetSentErrorMessage(true);
4971 return false;
4973 break;
4974 case BAN_IP:
4975 if(!IsIPAddress(nameOrIP.c_str()))
4976 return false;
4977 break;
4980 switch(sWorld.BanAccount(mode, nameOrIP, duration, reason,m_session ? m_session->GetPlayerName() : ""))
4982 case BAN_SUCCESS:
4983 if(atoi(duration)>0)
4984 PSendSysMessage(LANG_BAN_YOUBANNED,nameOrIP.c_str(),secsToTimeString(TimeStringToSecs(duration),true).c_str(),reason);
4985 else
4986 PSendSysMessage(LANG_BAN_YOUPERMBANNED,nameOrIP.c_str(),reason);
4987 break;
4988 case BAN_SYNTAX_ERROR:
4989 return false;
4990 case BAN_NOTFOUND:
4991 switch(mode)
4993 default:
4994 PSendSysMessage(LANG_BAN_NOTFOUND,"account",nameOrIP.c_str());
4995 break;
4996 case BAN_CHARACTER:
4997 PSendSysMessage(LANG_BAN_NOTFOUND,"character",nameOrIP.c_str());
4998 break;
4999 case BAN_IP:
5000 PSendSysMessage(LANG_BAN_NOTFOUND,"ip",nameOrIP.c_str());
5001 break;
5003 SetSentErrorMessage(true);
5004 return false;
5007 return true;
5010 bool ChatHandler::HandleUnBanAccountCommand(const char* args)
5012 return HandleUnBanHelper(BAN_ACCOUNT,args);
5015 bool ChatHandler::HandleUnBanCharacterCommand(const char* args)
5017 return HandleUnBanHelper(BAN_CHARACTER,args);
5020 bool ChatHandler::HandleUnBanIPCommand(const char* args)
5022 return HandleUnBanHelper(BAN_IP,args);
5025 bool ChatHandler::HandleUnBanHelper(BanMode mode, const char* args)
5027 if(!args)
5028 return false;
5030 char* cnameOrIP = strtok ((char*)args, " ");
5031 if(!cnameOrIP)
5032 return false;
5034 std::string nameOrIP = cnameOrIP;
5036 switch(mode)
5038 case BAN_ACCOUNT:
5039 if(!AccountMgr::normilizeString(nameOrIP))
5041 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,nameOrIP.c_str());
5042 SetSentErrorMessage(true);
5043 return false;
5045 break;
5046 case BAN_CHARACTER:
5047 if(!normalizePlayerName(nameOrIP))
5049 SendSysMessage(LANG_PLAYER_NOT_FOUND);
5050 SetSentErrorMessage(true);
5051 return false;
5053 break;
5054 case BAN_IP:
5055 if(!IsIPAddress(nameOrIP.c_str()))
5056 return false;
5057 break;
5060 if(sWorld.RemoveBanAccount(mode,nameOrIP))
5061 PSendSysMessage(LANG_UNBAN_UNBANNED,nameOrIP.c_str());
5062 else
5063 PSendSysMessage(LANG_UNBAN_ERROR,nameOrIP.c_str());
5065 return true;
5068 bool ChatHandler::HandleBanInfoAccountCommand(const char* args)
5070 if(!args)
5071 return false;
5073 char* cname = strtok((char*)args, "");
5074 if(!cname)
5075 return false;
5077 std::string account_name = cname;
5078 if(!AccountMgr::normilizeString(account_name))
5080 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5081 SetSentErrorMessage(true);
5082 return false;
5085 uint32 accountid = accmgr.GetId(account_name);
5086 if(!accountid)
5088 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5089 return true;
5092 return HandleBanInfoHelper(accountid,account_name.c_str());
5095 bool ChatHandler::HandleBanInfoCharacterCommand(const char* args)
5097 if(!args)
5098 return false;
5100 char* cname = strtok ((char*)args, "");
5101 if(!cname)
5102 return false;
5104 std::string name = cname;
5105 if(!normalizePlayerName(name))
5107 SendSysMessage(LANG_PLAYER_NOT_FOUND);
5108 SetSentErrorMessage(true);
5109 return false;
5112 uint32 accountid = objmgr.GetPlayerAccountIdByPlayerName(name);
5113 if(!accountid)
5115 SendSysMessage(LANG_PLAYER_NOT_FOUND);
5116 SetSentErrorMessage(true);
5117 return false;
5120 std::string accountname;
5121 if(!accmgr.GetName(accountid,accountname))
5123 PSendSysMessage(LANG_BANINFO_NOCHARACTER);
5124 return true;
5127 return HandleBanInfoHelper(accountid,accountname.c_str());
5130 bool ChatHandler::HandleBanInfoHelper(uint32 accountid, char const* accountname)
5132 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);
5133 if(!result)
5135 PSendSysMessage(LANG_BANINFO_NOACCOUNTBAN, accountname);
5136 return true;
5139 PSendSysMessage(LANG_BANINFO_BANHISTORY,accountname);
5142 Field* fields = result->Fetch();
5144 time_t unbandate = time_t(fields[3].GetUInt64());
5145 bool active = false;
5146 if(fields[2].GetBool() && (fields[1].GetUInt64() == (uint64)0 ||unbandate >= time(NULL)) )
5147 active = true;
5148 bool permanent = (fields[1].GetUInt64() == (uint64)0);
5149 std::string bantime = permanent?GetMangosString(LANG_BANINFO_INFINITE):secsToTimeString(fields[1].GetUInt64(), true);
5150 PSendSysMessage(LANG_BANINFO_HISTORYENTRY,
5151 fields[0].GetString(), bantime.c_str(), active ? GetMangosString(LANG_BANINFO_YES):GetMangosString(LANG_BANINFO_NO), fields[4].GetString(), fields[5].GetString());
5152 }while (result->NextRow());
5154 delete result;
5155 return true;
5158 bool ChatHandler::HandleBanInfoIPCommand(const char* args)
5160 if(!args)
5161 return false;
5163 char* cIP = strtok ((char*)args, "");
5164 if(!cIP)
5165 return false;
5167 if (!IsIPAddress(cIP))
5168 return false;
5170 std::string IP = cIP;
5172 loginDatabase.escape_string(IP);
5173 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());
5174 if(!result)
5176 PSendSysMessage(LANG_BANINFO_NOIP);
5177 return true;
5180 Field *fields = result->Fetch();
5181 bool permanent = !fields[6].GetUInt64();
5182 PSendSysMessage(LANG_BANINFO_IPENTRY,
5183 fields[0].GetString(), fields[1].GetString(), permanent ? GetMangosString(LANG_BANINFO_NEVER):fields[2].GetString(),
5184 permanent ? GetMangosString(LANG_BANINFO_INFINITE):secsToTimeString(fields[3].GetUInt64(), true).c_str(), fields[4].GetString(), fields[5].GetString());
5185 delete result;
5186 return true;
5189 bool ChatHandler::HandleBanListCharacterCommand(const char* args)
5191 loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
5193 char* cFilter = strtok ((char*)args, " ");
5194 if(!cFilter)
5195 return false;
5197 std::string filter = cFilter;
5198 loginDatabase.escape_string(filter);
5199 QueryResult* result = CharacterDatabase.PQuery("SELECT account FROM characters WHERE name "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'"),filter.c_str());
5200 if (!result)
5202 PSendSysMessage(LANG_BANLIST_NOCHARACTER);
5203 return true;
5206 return HandleBanListHelper(result);
5209 bool ChatHandler::HandleBanListAccountCommand(const char* args)
5211 loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
5213 char* cFilter = strtok((char*)args, " ");
5214 std::string filter = cFilter ? cFilter : "";
5215 loginDatabase.escape_string(filter);
5217 QueryResult* result;
5219 if(filter.empty())
5221 result = loginDatabase.Query("SELECT account.id, username FROM account, account_banned"
5222 " WHERE account.id = account_banned.id AND active = 1 GROUP BY account.id");
5224 else
5226 result = loginDatabase.PQuery("SELECT account.id, username FROM account, account_banned"
5227 " WHERE account.id = account_banned.id AND active = 1 AND username "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")" GROUP BY account.id",
5228 filter.c_str());
5231 if (!result)
5233 PSendSysMessage(LANG_BANLIST_NOACCOUNT);
5234 return true;
5237 return HandleBanListHelper(result);
5240 bool ChatHandler::HandleBanListHelper(QueryResult* result)
5242 PSendSysMessage(LANG_BANLIST_MATCHINGACCOUNT);
5244 // Chat short output
5245 if(m_session)
5249 Field* fields = result->Fetch();
5250 uint32 accountid = fields[0].GetUInt32();
5252 QueryResult* banresult = loginDatabase.PQuery("SELECT account.username FROM account,account_banned WHERE account_banned.id='%u' AND account_banned.id=account.id",accountid);
5253 if(banresult)
5255 Field* fields2 = banresult->Fetch();
5256 PSendSysMessage("%s",fields2[0].GetString());
5257 delete banresult;
5259 } while (result->NextRow());
5261 // Console wide output
5262 else
5264 SendSysMessage(LANG_BANLIST_ACCOUNTS);
5265 SendSysMessage("===============================================================================");
5266 SendSysMessage(LANG_BANLIST_ACCOUNTS_HEADER);
5269 SendSysMessage("-------------------------------------------------------------------------------");
5270 Field *fields = result->Fetch();
5271 uint32 account_id = fields[0].GetUInt32 ();
5273 std::string account_name;
5275 // "account" case, name can be get in same query
5276 if(result->GetFieldCount() > 1)
5277 account_name = fields[1].GetCppString();
5278 // "character" case, name need extract from another DB
5279 else
5280 accmgr.GetName (account_id,account_name);
5282 // No SQL injection. id is uint32.
5283 QueryResult *banInfo = loginDatabase.PQuery("SELECT bandate,unbandate,bannedby,banreason FROM account_banned WHERE id = %u ORDER BY unbandate", account_id);
5284 if (banInfo)
5286 Field *fields2 = banInfo->Fetch();
5289 time_t t_ban = fields2[0].GetUInt64();
5290 tm* aTm_ban = localtime(&t_ban);
5292 if (fields2[0].GetUInt64() == fields2[1].GetUInt64())
5294 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|",
5295 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,
5296 fields2[2].GetString(),fields2[3].GetString());
5298 else
5300 time_t t_unban = fields2[1].GetUInt64();
5301 tm* aTm_unban = localtime(&t_unban);
5302 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|",
5303 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,
5304 aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min,
5305 fields2[2].GetString(),fields2[3].GetString());
5307 }while ( banInfo->NextRow() );
5308 delete banInfo;
5310 }while( result->NextRow() );
5311 SendSysMessage("===============================================================================");
5314 delete result;
5315 return true;
5318 bool ChatHandler::HandleBanListIPCommand(const char* args)
5320 loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
5322 char* cFilter = strtok((char*)args, " ");
5323 std::string filter = cFilter ? cFilter : "";
5324 loginDatabase.escape_string(filter);
5326 QueryResult* result;
5328 if(filter.empty())
5330 result = loginDatabase.Query ("SELECT ip,bandate,unbandate,bannedby,banreason FROM ip_banned"
5331 " WHERE (bandate=unbandate OR unbandate>UNIX_TIMESTAMP())"
5332 " ORDER BY unbandate" );
5334 else
5336 result = loginDatabase.PQuery( "SELECT ip,bandate,unbandate,bannedby,banreason FROM ip_banned"
5337 " WHERE (bandate=unbandate OR unbandate>UNIX_TIMESTAMP()) AND ip "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")
5338 " ORDER BY unbandate",filter.c_str() );
5341 if(!result)
5343 PSendSysMessage(LANG_BANLIST_NOIP);
5344 return true;
5347 PSendSysMessage(LANG_BANLIST_MATCHINGIP);
5348 // Chat short output
5349 if(m_session)
5353 Field* fields = result->Fetch();
5354 PSendSysMessage("%s",fields[0].GetString());
5355 } while (result->NextRow());
5357 // Console wide output
5358 else
5360 SendSysMessage(LANG_BANLIST_IPS);
5361 SendSysMessage("===============================================================================");
5362 SendSysMessage(LANG_BANLIST_IPS_HEADER);
5365 SendSysMessage("-------------------------------------------------------------------------------");
5366 Field *fields = result->Fetch();
5367 time_t t_ban = fields[1].GetUInt64();
5368 tm* aTm_ban = localtime(&t_ban);
5369 if ( fields[1].GetUInt64() == fields[2].GetUInt64() )
5371 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|",
5372 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,
5373 fields[3].GetString(), fields[4].GetString());
5375 else
5377 time_t t_unban = fields[2].GetUInt64();
5378 tm* aTm_unban = localtime(&t_unban);
5379 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|",
5380 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,
5381 aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min,
5382 fields[3].GetString(), fields[4].GetString());
5384 }while( result->NextRow() );
5385 SendSysMessage("===============================================================================");
5388 delete result;
5389 return true;
5392 bool ChatHandler::HandleRespawnCommand(const char* /*args*/)
5394 Player* pl = m_session->GetPlayer();
5396 // accept only explicitly selected target (not implicitly self targeting case)
5397 Unit* target = getSelectedUnit();
5398 if(pl->GetSelection() && target)
5400 if(target->GetTypeId()!=TYPEID_UNIT)
5402 SendSysMessage(LANG_SELECT_CREATURE);
5403 SetSentErrorMessage(true);
5404 return false;
5407 if(target->isDead())
5408 ((Creature*)target)->Respawn();
5409 return true;
5412 CellPair p(MaNGOS::ComputeCellPair(pl->GetPositionX(), pl->GetPositionY()));
5413 Cell cell(p);
5414 cell.data.Part.reserved = ALL_DISTRICT;
5415 cell.SetNoCreate();
5417 MaNGOS::RespawnDo u_do;
5418 MaNGOS::WorldObjectWorker<MaNGOS::RespawnDo> worker(u_do);
5420 TypeContainerVisitor<MaNGOS::WorldObjectWorker<MaNGOS::RespawnDo>, GridTypeMapContainer > obj_worker(worker);
5421 CellLock<GridReadGuard> cell_lock(cell, p);
5422 cell_lock->Visit(cell_lock, obj_worker, *pl->GetMap());
5424 return true;
5427 bool ChatHandler::HandleFlyModeCommand(const char* args)
5429 if(!args)
5430 return false;
5432 Unit *unit = getSelectedUnit();
5433 if (!unit || (unit->GetTypeId() != TYPEID_PLAYER))
5434 unit = m_session->GetPlayer();
5436 WorldPacket data(12);
5437 if (strncmp(args, "on", 3) == 0)
5438 data.SetOpcode(SMSG_MOVE_SET_CAN_FLY);
5439 else if (strncmp(args, "off", 4) == 0)
5440 data.SetOpcode(SMSG_MOVE_UNSET_CAN_FLY);
5441 else
5443 SendSysMessage(LANG_USE_BOL);
5444 return false;
5446 data.append(unit->GetPackGUID());
5447 data << uint32(0); // unknown
5448 unit->SendMessageToSet(&data, true);
5449 PSendSysMessage(LANG_COMMAND_FLYMODE_STATUS, unit->GetName(), args);
5450 return true;
5453 bool ChatHandler::HandleLoadPDumpCommand(const char *args)
5455 if(!args)
5456 return false;
5458 char * file = strtok((char*)args, " ");
5459 if(!file)
5460 return false;
5462 char * account = strtok(NULL, " ");
5463 if(!account)
5464 return false;
5466 std::string account_name = account;
5467 if(!AccountMgr::normilizeString(account_name))
5469 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5470 SetSentErrorMessage(true);
5471 return false;
5474 uint32 account_id = accmgr.GetId(account_name);
5475 if(!account_id)
5477 account_id = atoi(account); // use original string
5478 if(!account_id)
5480 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5481 SetSentErrorMessage(true);
5482 return false;
5486 if(!accmgr.GetName(account_id,account_name))
5488 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5489 SetSentErrorMessage(true);
5490 return false;
5493 char* guid_str = NULL;
5494 char* name_str = strtok(NULL, " ");
5496 std::string name;
5497 if(name_str)
5499 name = name_str;
5500 // normalize the name if specified and check if it exists
5501 if(!normalizePlayerName(name))
5503 PSendSysMessage(LANG_INVALID_CHARACTER_NAME);
5504 SetSentErrorMessage(true);
5505 return false;
5508 if(!ObjectMgr::IsValidName(name,true))
5510 PSendSysMessage(LANG_INVALID_CHARACTER_NAME);
5511 SetSentErrorMessage(true);
5512 return false;
5515 guid_str = strtok(NULL, " ");
5518 uint32 guid = 0;
5520 if(guid_str)
5522 guid = atoi(guid_str);
5523 if(!guid)
5525 PSendSysMessage(LANG_INVALID_CHARACTER_GUID);
5526 SetSentErrorMessage(true);
5527 return false;
5530 if(objmgr.GetPlayerAccountIdByGUID(guid))
5532 PSendSysMessage(LANG_CHARACTER_GUID_IN_USE,guid);
5533 SetSentErrorMessage(true);
5534 return false;
5538 switch(PlayerDumpReader().LoadDump(file, account_id, name, guid))
5540 case DUMP_SUCCESS:
5541 PSendSysMessage(LANG_COMMAND_IMPORT_SUCCESS);
5542 break;
5543 case DUMP_FILE_OPEN_ERROR:
5544 PSendSysMessage(LANG_FILE_OPEN_FAIL,file);
5545 SetSentErrorMessage(true);
5546 return false;
5547 case DUMP_FILE_BROKEN:
5548 PSendSysMessage(LANG_DUMP_BROKEN,file);
5549 SetSentErrorMessage(true);
5550 return false;
5551 case DUMP_TOO_MANY_CHARS:
5552 PSendSysMessage(LANG_ACCOUNT_CHARACTER_LIST_FULL,account_name.c_str(),account_id);
5553 SetSentErrorMessage(true);
5554 return false;
5555 default:
5556 PSendSysMessage(LANG_COMMAND_IMPORT_FAILED);
5557 SetSentErrorMessage(true);
5558 return false;
5561 return true;
5564 bool ChatHandler::HandleNpcChangeEntryCommand(const char *args)
5566 if(!args)
5567 return false;
5569 uint32 newEntryNum = atoi(args);
5570 if(!newEntryNum)
5571 return false;
5573 Unit* unit = getSelectedUnit();
5574 if(!unit || unit->GetTypeId() != TYPEID_UNIT)
5576 SendSysMessage(LANG_SELECT_CREATURE);
5577 SetSentErrorMessage(true);
5578 return false;
5580 Creature* creature = (Creature*)unit;
5581 if(creature->UpdateEntry(newEntryNum))
5582 SendSysMessage(LANG_DONE);
5583 else
5584 SendSysMessage(LANG_ERROR);
5585 return true;
5588 bool ChatHandler::HandleWritePDumpCommand(const char *args)
5590 if(!args)
5591 return false;
5593 char* file = strtok((char*)args, " ");
5594 char* p2 = strtok(NULL, " ");
5596 if(!file || !p2)
5597 return false;
5599 uint32 guid;
5600 // character name can't start from number
5601 if (isNumeric(p2[0]))
5602 guid = atoi(p2);
5603 else
5605 std::string name = p2;
5607 if (!normalizePlayerName (name))
5609 SendSysMessage (LANG_PLAYER_NOT_FOUND);
5610 SetSentErrorMessage (true);
5611 return false;
5614 guid = objmgr.GetPlayerGUIDByName(name);
5617 if(!objmgr.GetPlayerAccountIdByGUID(guid))
5619 PSendSysMessage(LANG_PLAYER_NOT_FOUND);
5620 SetSentErrorMessage(true);
5621 return false;
5624 switch(PlayerDumpWriter().WriteDump(file, guid))
5626 case DUMP_SUCCESS:
5627 PSendSysMessage(LANG_COMMAND_EXPORT_SUCCESS);
5628 break;
5629 case DUMP_FILE_OPEN_ERROR:
5630 PSendSysMessage(LANG_FILE_OPEN_FAIL,file);
5631 SetSentErrorMessage(true);
5632 return false;
5633 default:
5634 PSendSysMessage(LANG_COMMAND_EXPORT_FAILED);
5635 SetSentErrorMessage(true);
5636 return false;
5639 return true;
5642 bool ChatHandler::HandleMovegensCommand(const char* /*args*/)
5644 Unit* unit = getSelectedUnit();
5645 if(!unit)
5647 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5648 SetSentErrorMessage(true);
5649 return false;
5652 PSendSysMessage(LANG_MOVEGENS_LIST,(unit->GetTypeId()==TYPEID_PLAYER ? "Player" : "Creature" ),unit->GetGUIDLow());
5654 MotionMaster* mm = unit->GetMotionMaster();
5655 for(MotionMaster::const_iterator itr = mm->begin(); itr != mm->end(); ++itr)
5657 switch((*itr)->GetMovementGeneratorType())
5659 case IDLE_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_IDLE); break;
5660 case RANDOM_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_RANDOM); break;
5661 case WAYPOINT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_WAYPOINT); break;
5662 case ANIMAL_RANDOM_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_ANIMAL_RANDOM); break;
5663 case CONFUSED_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_CONFUSED); break;
5664 case TARGETED_MOTION_TYPE:
5666 if(unit->GetTypeId()==TYPEID_PLAYER)
5668 TargetedMovementGenerator<Player> const* mgen = static_cast<TargetedMovementGenerator<Player> const*>(*itr);
5669 Unit* target = mgen->GetTarget();
5670 if(target)
5671 PSendSysMessage(LANG_MOVEGENS_TARGETED_PLAYER,target->GetName(),target->GetGUIDLow());
5672 else
5673 SendSysMessage(LANG_MOVEGENS_TARGETED_NULL);
5675 else
5677 TargetedMovementGenerator<Creature> const* mgen = static_cast<TargetedMovementGenerator<Creature> const*>(*itr);
5678 Unit* target = mgen->GetTarget();
5679 if(target)
5680 PSendSysMessage(LANG_MOVEGENS_TARGETED_CREATURE,target->GetName(),target->GetGUIDLow());
5681 else
5682 SendSysMessage(LANG_MOVEGENS_TARGETED_NULL);
5684 break;
5686 case HOME_MOTION_TYPE:
5687 if(unit->GetTypeId()==TYPEID_UNIT)
5689 float x,y,z;
5690 (*itr)->GetDestination(x,y,z);
5691 PSendSysMessage(LANG_MOVEGENS_HOME_CREATURE,x,y,z);
5693 else
5694 SendSysMessage(LANG_MOVEGENS_HOME_PLAYER);
5695 break;
5696 case FLIGHT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_FLIGHT); break;
5697 case POINT_MOTION_TYPE:
5699 float x,y,z;
5700 (*itr)->GetDestination(x,y,z);
5701 PSendSysMessage(LANG_MOVEGENS_POINT,x,y,z);
5702 break;
5704 case FLEEING_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_FEAR); break;
5705 case DISTRACT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_DISTRACT); break;
5706 default:
5707 PSendSysMessage(LANG_MOVEGENS_UNKNOWN,(*itr)->GetMovementGeneratorType());
5708 break;
5711 return true;
5714 bool ChatHandler::HandlePLimitCommand(const char *args)
5716 if(*args)
5718 char* param = strtok((char*)args, " ");
5719 if(!param)
5720 return false;
5722 int l = strlen(param);
5724 if( strncmp(param,"player",l) == 0 )
5725 sWorld.SetPlayerLimit(-SEC_PLAYER);
5726 else if(strncmp(param,"moderator",l) == 0 )
5727 sWorld.SetPlayerLimit(-SEC_MODERATOR);
5728 else if(strncmp(param,"gamemaster",l) == 0 )
5729 sWorld.SetPlayerLimit(-SEC_GAMEMASTER);
5730 else if(strncmp(param,"administrator",l) == 0 )
5731 sWorld.SetPlayerLimit(-SEC_ADMINISTRATOR);
5732 else if(strncmp(param,"reset",l) == 0 )
5733 sWorld.SetPlayerLimit( sConfig.GetIntDefault("PlayerLimit", DEFAULT_PLAYER_LIMIT) );
5734 else
5736 int val = atoi(param);
5737 if(val < -SEC_ADMINISTRATOR) val = -SEC_ADMINISTRATOR;
5739 sWorld.SetPlayerLimit(val);
5742 // kick all low security level players
5743 if(sWorld.GetPlayerAmountLimit() > SEC_PLAYER)
5744 sWorld.KickAllLess(sWorld.GetPlayerSecurityLimit());
5747 uint32 pLimit = sWorld.GetPlayerAmountLimit();
5748 AccountTypes allowedAccountType = sWorld.GetPlayerSecurityLimit();
5749 char const* secName = "";
5750 switch(allowedAccountType)
5752 case SEC_PLAYER: secName = "Player"; break;
5753 case SEC_MODERATOR: secName = "Moderator"; break;
5754 case SEC_GAMEMASTER: secName = "Gamemaster"; break;
5755 case SEC_ADMINISTRATOR: secName = "Administrator"; break;
5756 default: secName = "<unknown>"; break;
5759 PSendSysMessage("Player limits: amount %u, min. security level %s.",pLimit,secName);
5761 return true;
5764 bool ChatHandler::HandleCastCommand(const char* args)
5766 if(!*args)
5767 return false;
5769 Unit* target = getSelectedUnit();
5771 if(!target)
5773 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5774 SetSentErrorMessage(true);
5775 return false;
5778 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5779 uint32 spell = extractSpellIdFromLink((char*)args);
5780 if(!spell)
5781 return false;
5783 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
5784 if(!spellInfo)
5785 return false;
5787 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
5789 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
5790 SetSentErrorMessage(true);
5791 return false;
5794 char* trig_str = strtok(NULL, " ");
5795 if(trig_str)
5797 int l = strlen(trig_str);
5798 if(strncmp(trig_str,"triggered",l) != 0 )
5799 return false;
5802 bool triggered = (trig_str != NULL);
5804 m_session->GetPlayer()->CastSpell(target,spell,triggered);
5806 return true;
5809 bool ChatHandler::HandleCastBackCommand(const char* args)
5811 Creature* caster = getSelectedCreature();
5813 if(!caster)
5815 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5816 SetSentErrorMessage(true);
5817 return false;
5820 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
5821 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5822 uint32 spell = extractSpellIdFromLink((char*)args);
5823 if(!spell || !sSpellStore.LookupEntry(spell))
5824 return false;
5826 char* trig_str = strtok(NULL, " ");
5827 if(trig_str)
5829 int l = strlen(trig_str);
5830 if(strncmp(trig_str,"triggered",l) != 0 )
5831 return false;
5834 bool triggered = (trig_str != NULL);
5836 // update orientation at server
5837 caster->SetOrientation(caster->GetAngle(m_session->GetPlayer()));
5839 // and client
5840 WorldPacket data;
5841 caster->BuildHeartBeatMsg(&data);
5842 caster->SendMessageToSet(&data,true);
5844 caster->CastSpell(m_session->GetPlayer(),spell,triggered);
5846 return true;
5849 bool ChatHandler::HandleCastDistCommand(const char* args)
5851 if(!*args)
5852 return false;
5854 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5855 uint32 spell = extractSpellIdFromLink((char*)args);
5856 if(!spell)
5857 return false;
5859 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
5860 if(!spellInfo)
5861 return false;
5863 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
5865 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
5866 SetSentErrorMessage(true);
5867 return false;
5870 char *distStr = strtok(NULL, " ");
5872 float dist = 0;
5874 if(distStr)
5875 sscanf(distStr, "%f", &dist);
5877 char* trig_str = strtok(NULL, " ");
5878 if(trig_str)
5880 int l = strlen(trig_str);
5881 if(strncmp(trig_str,"triggered",l) != 0 )
5882 return false;
5885 bool triggered = (trig_str != NULL);
5887 float x,y,z;
5888 m_session->GetPlayer()->GetClosePoint(x,y,z,dist);
5890 m_session->GetPlayer()->CastSpell(x,y,z,spell,triggered);
5891 return true;
5894 bool ChatHandler::HandleCastTargetCommand(const char* args)
5896 Creature* caster = getSelectedCreature();
5898 if(!caster)
5900 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5901 SetSentErrorMessage(true);
5902 return false;
5905 if(!caster->getVictim())
5907 SendSysMessage(LANG_SELECTED_TARGET_NOT_HAVE_VICTIM);
5908 SetSentErrorMessage(true);
5909 return false;
5912 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5913 uint32 spell = extractSpellIdFromLink((char*)args);
5914 if(!spell || !sSpellStore.LookupEntry(spell))
5915 return false;
5917 char* trig_str = strtok(NULL, " ");
5918 if(trig_str)
5920 int l = strlen(trig_str);
5921 if(strncmp(trig_str,"triggered",l) != 0 )
5922 return false;
5925 bool triggered = (trig_str != NULL);
5927 // update orientation at server
5928 caster->SetOrientation(caster->GetAngle(m_session->GetPlayer()));
5930 // and client
5931 WorldPacket data;
5932 caster->BuildHeartBeatMsg(&data);
5933 caster->SendMessageToSet(&data,true);
5935 caster->CastSpell(caster->getVictim(),spell,triggered);
5937 return true;
5941 ComeToMe command REQUIRED for 3rd party scripting library to have access to PointMovementGenerator
5942 Without this function 3rd party scripting library will get linking errors (unresolved external)
5943 when attempting to use the PointMovementGenerator
5945 bool ChatHandler::HandleComeToMeCommand(const char *args)
5947 Creature* caster = getSelectedCreature();
5949 if(!caster)
5951 SendSysMessage(LANG_SELECT_CREATURE);
5952 SetSentErrorMessage(true);
5953 return false;
5956 char* newFlagStr = strtok((char*)args, " ");
5958 if(!newFlagStr)
5959 return false;
5961 uint32 newFlags = atoi(newFlagStr);
5963 caster->SetUnitMovementFlags(newFlags);
5965 Player* pl = m_session->GetPlayer();
5967 caster->GetMotionMaster()->MovePoint(0, pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ());
5968 return true;
5971 bool ChatHandler::HandleCastSelfCommand(const char* args)
5973 if(!*args)
5974 return false;
5976 Unit* target = getSelectedUnit();
5978 if(!target)
5980 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5981 SetSentErrorMessage(true);
5982 return false;
5985 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5986 uint32 spell = extractSpellIdFromLink((char*)args);
5987 if(!spell)
5988 return false;
5990 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
5991 if(!spellInfo)
5992 return false;
5994 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
5996 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
5997 SetSentErrorMessage(true);
5998 return false;
6001 target->CastSpell(target,spell,false);
6003 return true;
6006 std::string GetTimeString(uint32 time)
6008 uint16 days = time / DAY, hours = (time % DAY) / HOUR, minute = (time % HOUR) / MINUTE;
6009 std::ostringstream ss;
6010 if(days) ss << days << "d ";
6011 if(hours) ss << hours << "h ";
6012 ss << minute << "m";
6013 return ss.str();
6016 bool ChatHandler::HandleInstanceListBindsCommand(const char* /*args*/)
6018 Player* player = getSelectedPlayer();
6019 if (!player) player = m_session->GetPlayer();
6020 uint32 counter = 0;
6021 for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++)
6023 Player::BoundInstancesMap &binds = player->GetBoundInstances(i);
6024 for(Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end(); ++itr)
6026 InstanceSave *save = itr->second.save;
6027 std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
6028 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());
6029 counter++;
6032 PSendSysMessage("player binds: %d", counter);
6033 counter = 0;
6034 Group *group = player->GetGroup();
6035 if(group)
6037 for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++)
6039 Group::BoundInstancesMap &binds = group->GetBoundInstances(i);
6040 for(Group::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end(); ++itr)
6042 InstanceSave *save = itr->second.save;
6043 std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
6044 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());
6045 counter++;
6049 PSendSysMessage("group binds: %d", counter);
6051 return true;
6054 bool ChatHandler::HandleInstanceUnbindCommand(const char* args)
6056 if(!*args)
6057 return false;
6059 std::string cmd = args;
6060 if(cmd == "all")
6062 Player* player = getSelectedPlayer();
6063 if (!player) player = m_session->GetPlayer();
6064 uint32 counter = 0;
6065 for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++)
6067 Player::BoundInstancesMap &binds = player->GetBoundInstances(i);
6068 for(Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end();)
6070 if(itr->first != player->GetMapId())
6072 InstanceSave *save = itr->second.save;
6073 std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
6074 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());
6075 player->UnbindInstance(itr, i);
6076 counter++;
6078 else
6079 ++itr;
6082 PSendSysMessage("instances unbound: %d", counter);
6084 return true;
6087 bool ChatHandler::HandleInstanceStatsCommand(const char* /*args*/)
6089 PSendSysMessage("instances loaded: %d", MapManager::Instance().GetNumInstances());
6090 PSendSysMessage("players in instances: %d", MapManager::Instance().GetNumPlayersInInstances());
6091 PSendSysMessage("instance saves: %d", sInstanceSaveManager.GetNumInstanceSaves());
6092 PSendSysMessage("players bound: %d", sInstanceSaveManager.GetNumBoundPlayersTotal());
6093 PSendSysMessage("groups bound: %d", sInstanceSaveManager.GetNumBoundGroupsTotal());
6094 return true;
6097 bool ChatHandler::HandleInstanceSaveDataCommand(const char * /*args*/)
6099 Player* pl = m_session->GetPlayer();
6101 Map* map = pl->GetMap();
6102 if (!map->IsDungeon())
6104 PSendSysMessage("Map is not a dungeon.");
6105 SetSentErrorMessage(true);
6106 return false;
6109 if (!((InstanceMap*)map)->GetInstanceData())
6111 PSendSysMessage("Map has no instance data.");
6112 SetSentErrorMessage(true);
6113 return false;
6116 ((InstanceMap*)map)->GetInstanceData()->SaveToDB();
6117 return true;
6120 /// Display the list of GMs
6121 bool ChatHandler::HandleGMListFullCommand(const char* /*args*/)
6123 ///- Get the accounts with GM Level >0
6124 QueryResult *result = loginDatabase.Query( "SELECT username,gmlevel FROM account WHERE gmlevel > 0" );
6125 if(result)
6127 SendSysMessage(LANG_GMLIST);
6128 SendSysMessage("========================");
6129 SendSysMessage(LANG_GMLIST_HEADER);
6130 SendSysMessage("========================");
6132 ///- Circle through them. Display username and GM level
6135 Field *fields = result->Fetch();
6136 PSendSysMessage("|%15s|%6s|", fields[0].GetString(),fields[1].GetString());
6137 }while( result->NextRow() );
6139 PSendSysMessage("========================");
6140 delete result;
6142 else
6143 PSendSysMessage(LANG_GMLIST_EMPTY);
6144 return true;
6147 /// Define the 'Message of the day' for the realm
6148 bool ChatHandler::HandleServerSetMotdCommand(const char* args)
6150 sWorld.SetMotd(args);
6151 PSendSysMessage(LANG_MOTD_NEW, args);
6152 return true;
6155 /// Set/Unset the expansion level for an account
6156 bool ChatHandler::HandleAccountSetAddonCommand(const char* args)
6158 ///- Get the command line arguments
6159 char *szAcc = strtok((char*)args," ");
6160 char *szExp = strtok(NULL," ");
6162 if(!szAcc)
6163 return false;
6165 std::string account_name;
6166 uint32 account_id;
6168 if(!szExp)
6170 Player* player = getSelectedPlayer();
6171 if(!player)
6172 return false;
6174 account_id = player->GetSession()->GetAccountId();
6175 accmgr.GetName(account_id,account_name);
6176 szExp = szAcc;
6178 else
6180 ///- Convert Account name to Upper Format
6181 account_name = szAcc;
6182 if(!AccountMgr::normilizeString(account_name))
6184 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
6185 SetSentErrorMessage(true);
6186 return false;
6189 account_id = accmgr.GetId(account_name);
6190 if(!account_id)
6192 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
6193 SetSentErrorMessage(true);
6194 return false;
6198 int lev=atoi(szExp); //get int anyway (0 if error)
6199 if(lev < 0)
6200 return false;
6202 // No SQL injection
6203 loginDatabase.PExecute("UPDATE account SET expansion = '%d' WHERE id = '%u'",lev,account_id);
6204 PSendSysMessage(LANG_ACCOUNT_SETADDON,account_name.c_str(),account_id,lev);
6205 return true;
6208 //Send items by mail
6209 bool ChatHandler::HandleSendItemsCommand(const char* args)
6211 if(!*args)
6212 return false;
6214 // format: name "subject text" "mail text" item1[:count1] item2[:count2] ... item12[:count12]
6216 char* pName = strtok((char*)args, " ");
6217 if(!pName)
6218 return false;
6220 char* tail1 = strtok(NULL, "");
6221 if(!tail1)
6222 return false;
6224 char* msgSubject;
6225 if(*tail1=='"')
6226 msgSubject = strtok(tail1+1, "\"");
6227 else
6229 char* space = strtok(tail1, "\"");
6230 if(!space)
6231 return false;
6232 msgSubject = strtok(NULL, "\"");
6235 if (!msgSubject)
6236 return false;
6238 char* tail2 = strtok(NULL, "");
6239 if(!tail2)
6240 return false;
6242 char* msgText;
6243 if(*tail2=='"')
6244 msgText = strtok(tail2+1, "\"");
6245 else
6247 char* space = strtok(tail2, "\"");
6248 if(!space)
6249 return false;
6250 msgText = strtok(NULL, "\"");
6253 if (!msgText)
6254 return false;
6256 // pName, msgSubject, msgText isn't NUL after prev. check
6257 std::string name = pName;
6258 std::string subject = msgSubject;
6259 std::string text = msgText;
6261 // extract items
6262 typedef std::pair<uint32,uint32> ItemPair;
6263 typedef std::list< ItemPair > ItemPairs;
6264 ItemPairs items;
6266 // get all tail string
6267 char* tail = strtok(NULL, "");
6269 // get from tail next item str
6270 while(char* itemStr = strtok(tail, " "))
6272 // and get new tail
6273 tail = strtok(NULL, "");
6275 // parse item str
6276 char* itemIdStr = strtok(itemStr, ":");
6277 char* itemCountStr = strtok(NULL, " ");
6279 uint32 item_id = atoi(itemIdStr);
6280 if(!item_id)
6281 return false;
6283 ItemPrototype const* item_proto = objmgr.GetItemPrototype(item_id);
6284 if(!item_proto)
6286 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
6287 SetSentErrorMessage(true);
6288 return false;
6291 uint32 item_count = itemCountStr ? atoi(itemCountStr) : 1;
6292 if(item_count < 1 || item_proto->MaxCount && item_count > item_proto->MaxCount)
6294 PSendSysMessage(LANG_COMMAND_INVALID_ITEM_COUNT, item_count,item_id);
6295 SetSentErrorMessage(true);
6296 return false;
6299 while(item_count > item_proto->Stackable)
6301 items.push_back(ItemPair(item_id,item_proto->Stackable));
6302 item_count -= item_proto->Stackable;
6305 items.push_back(ItemPair(item_id,item_count));
6307 if(items.size() > MAX_MAIL_ITEMS)
6309 PSendSysMessage(LANG_COMMAND_MAIL_ITEMS_LIMIT, MAX_MAIL_ITEMS);
6310 SetSentErrorMessage(true);
6311 return false;
6315 if(!normalizePlayerName(name))
6317 SendSysMessage(LANG_PLAYER_NOT_FOUND);
6318 SetSentErrorMessage(true);
6319 return false;
6322 uint64 receiver_guid = objmgr.GetPlayerGUIDByName(name);
6323 if(!receiver_guid)
6325 SendSysMessage(LANG_PLAYER_NOT_FOUND);
6326 SetSentErrorMessage(true);
6327 return false;
6330 // from console show not existed sender
6331 uint32 sender_guidlo = m_session ? m_session->GetPlayer()->GetGUIDLow() : 0;
6333 uint32 messagetype = MAIL_NORMAL;
6334 uint32 stationery = MAIL_STATIONERY_GM;
6335 uint32 itemTextId = !text.empty() ? objmgr.CreateItemText( text ) : 0;
6337 Player *receiver = objmgr.GetPlayer(receiver_guid);
6339 // fill mail
6340 MailItemsInfo mi; // item list preparing
6342 for(ItemPairs::const_iterator itr = items.begin(); itr != items.end(); ++itr)
6344 if(Item* item = Item::CreateItem(itr->first,itr->second,m_session ? m_session->GetPlayer() : 0))
6346 item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted
6347 mi.AddItem(item->GetGUIDLow(), item->GetEntry(), item);
6351 WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, &mi, 0, 0, MAIL_CHECK_MASK_NONE);
6353 PSendSysMessage(LANG_MAIL_SENT, name.c_str());
6354 return true;
6357 ///Send money by mail
6358 bool ChatHandler::HandleSendMoneyCommand(const char* args)
6360 if (!*args)
6361 return false;
6363 /// format: name "subject text" "mail text" money
6365 char* pName = strtok((char*)args, " ");
6366 if (!pName)
6367 return false;
6369 char* tail1 = strtok(NULL, "");
6370 if (!tail1)
6371 return false;
6373 char* msgSubject;
6374 if (*tail1=='"')
6375 msgSubject = strtok(tail1+1, "\"");
6376 else
6378 char* space = strtok(tail1, "\"");
6379 if (!space)
6380 return false;
6381 msgSubject = strtok(NULL, "\"");
6384 if (!msgSubject)
6385 return false;
6387 char* tail2 = strtok(NULL, "");
6388 if (!tail2)
6389 return false;
6391 char* msgText;
6392 if (*tail2=='"')
6393 msgText = strtok(tail2+1, "\"");
6394 else
6396 char* space = strtok(tail2, "\"");
6397 if (!space)
6398 return false;
6399 msgText = strtok(NULL, "\"");
6402 if (!msgText)
6403 return false;
6405 char* money_str = strtok(NULL, "");
6406 int32 money = money_str ? atoi(money_str) : 0;
6407 if (money <= 0)
6408 return false;
6410 // pName, msgSubject, msgText isn't NUL after prev. check
6411 std::string name = pName;
6412 std::string subject = msgSubject;
6413 std::string text = msgText;
6415 if (!normalizePlayerName(name))
6417 SendSysMessage(LANG_PLAYER_NOT_FOUND);
6418 SetSentErrorMessage(true);
6419 return false;
6422 uint64 receiver_guid = objmgr.GetPlayerGUIDByName(name);
6423 if (!receiver_guid)
6425 SendSysMessage(LANG_PLAYER_NOT_FOUND);
6426 SetSentErrorMessage(true);
6427 return false;
6430 uint32 mailId = objmgr.GenerateMailID();
6432 // from console show not existed sender
6433 uint32 sender_guidlo = m_session ? m_session->GetPlayer()->GetGUIDLow() : 0;
6435 uint32 messagetype = MAIL_NORMAL;
6436 uint32 stationery = MAIL_STATIONERY_GM;
6437 uint32 itemTextId = !text.empty() ? objmgr.CreateItemText( text ) : 0;
6439 Player *receiver = objmgr.GetPlayer(receiver_guid);
6441 WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, NULL, money, 0, MAIL_CHECK_MASK_NONE);
6443 PSendSysMessage(LANG_MAIL_SENT, name.c_str());
6444 return true;
6447 /// Send a message to a player in game
6448 bool ChatHandler::HandleSendMessageCommand(const char* args)
6450 ///- Get the command line arguments
6451 char* name_str = strtok((char*)args, " ");
6452 char* msg_str = strtok(NULL, "");
6454 if(!name_str || !msg_str)
6455 return false;
6457 std::string name = name_str;
6459 if(!normalizePlayerName(name))
6460 return false;
6462 ///- Find the player and check that he is not logging out.
6463 Player *rPlayer = objmgr.GetPlayer(name.c_str());
6464 if(!rPlayer)
6466 SendSysMessage(LANG_PLAYER_NOT_FOUND);
6467 SetSentErrorMessage(true);
6468 return false;
6471 if(rPlayer->GetSession()->isLogingOut())
6473 SendSysMessage(LANG_PLAYER_NOT_FOUND);
6474 SetSentErrorMessage(true);
6475 return false;
6478 ///- Send the message
6479 //Use SendAreaTriggerMessage for fastest delivery.
6480 rPlayer->GetSession()->SendAreaTriggerMessage("%s", msg_str);
6481 rPlayer->GetSession()->SendAreaTriggerMessage("|cffff0000[Message from administrator]:|r");
6483 //Confirmation message
6484 PSendSysMessage(LANG_SENDMESSAGE,name.c_str(),msg_str);
6485 return true;
6488 bool ChatHandler::HandleFlushArenaPointsCommand(const char * /*args*/)
6490 sBattleGroundMgr.DistributeArenaPoints();
6491 return true;
6494 bool ChatHandler::HandleModifyGenderCommand(const char *args)
6496 if(!*args)
6497 return false;
6499 Player *player = getSelectedPlayer();
6501 if(!player)
6503 PSendSysMessage(LANG_NO_PLAYER);
6504 SetSentErrorMessage(true);
6505 return false;
6508 PlayerInfo const* info = objmgr.GetPlayerInfo(player->getRace(), player->getClass());
6509 if(!info)
6510 return false;
6512 char const* gender_str = (char*)args;
6513 int gender_len = strlen(gender_str);
6515 Gender gender;
6517 if(!strncmp(gender_str, "male", gender_len)) // MALE
6519 if(player->getGender() == GENDER_MALE)
6520 return true;
6522 gender = GENDER_MALE;
6524 else if (!strncmp(gender_str, "female", gender_len)) // FEMALE
6526 if(player->getGender() == GENDER_FEMALE)
6527 return true;
6529 gender = GENDER_FEMALE;
6531 else
6533 SendSysMessage(LANG_MUST_MALE_OR_FEMALE);
6534 SetSentErrorMessage(true);
6535 return false;
6538 // Set gender
6539 player->SetByteValue(UNIT_FIELD_BYTES_0, 2, gender);
6540 player->SetByteValue(PLAYER_BYTES_3, 0, gender);
6542 // Change display ID
6543 player->SetDisplayId(gender ? info->displayId_f : info->displayId_m);
6544 player->SetNativeDisplayId(gender ? info->displayId_f : info->displayId_m);
6546 char const* gender_full = gender ? "female" : "male";
6548 PSendSysMessage(LANG_YOU_CHANGE_GENDER, player->GetName(), gender_full);
6550 if (needReportToTarget(player))
6551 ChatHandler(player).PSendSysMessage(LANG_YOUR_GENDER_CHANGED, gender_full, GetName());
6553 return true;