[7279] Allow equipped items loading at relogin to arena map.
[AHbot.git] / src / game / Level3.cpp
blob36fd8ab3a2e390fc1b47d857a43bc4056857d473
1 /*
2 * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include "Common.h"
20 #include "Database/DatabaseEnv.h"
21 #include "WorldPacket.h"
22 #include "WorldSession.h"
23 #include "World.h"
24 #include "ObjectMgr.h"
25 #include "AccountMgr.h"
26 #include "PlayerDump.h"
27 #include "SpellMgr.h"
28 #include "Player.h"
29 #include "Opcodes.h"
30 #include "GameObject.h"
31 #include "Chat.h"
32 #include "Log.h"
33 #include "Guild.h"
34 #include "ObjectAccessor.h"
35 #include "MapManager.h"
36 #include "SpellAuras.h"
37 #include "ScriptCalls.h"
38 #include "Language.h"
39 #include "GridNotifiersImpl.h"
40 #include "CellImpl.h"
41 #include "Weather.h"
42 #include "PointMovementGenerator.h"
43 #include "TargetedMovementGenerator.h"
44 #include "SkillDiscovery.h"
45 #include "SkillExtraItems.h"
46 #include "SystemConfig.h"
47 #include "Config/ConfigEnv.h"
48 #include "Util.h"
49 #include "ItemEnchantmentMgr.h"
50 #include "BattleGroundMgr.h"
51 #include "InstanceSaveMgr.h"
52 #include "InstanceData.h"
54 //reload commands
55 bool ChatHandler::HandleReloadAllCommand(const char*)
57 HandleReloadSkillFishingBaseLevelCommand("");
59 HandleReloadAllAreaCommand("");
60 HandleReloadAllLootCommand("");
61 HandleReloadAllNpcCommand("");
62 HandleReloadAllQuestCommand("");
63 HandleReloadAllSpellCommand("");
64 HandleReloadAllItemCommand("");
65 HandleReloadAllLocalesCommand("");
67 HandleReloadCommandCommand("");
68 HandleReloadReservedNameCommand("");
69 HandleReloadMangosStringCommand("");
70 HandleReloadGameTeleCommand("");
71 return true;
74 bool ChatHandler::HandleReloadAllAreaCommand(const char*)
76 //HandleReloadQuestAreaTriggersCommand(""); -- reloaded in HandleReloadAllQuestCommand
77 HandleReloadAreaTriggerTeleportCommand("");
78 HandleReloadAreaTriggerTavernCommand("");
79 HandleReloadGameGraveyardZoneCommand("");
80 return true;
83 bool ChatHandler::HandleReloadAllLootCommand(const char*)
85 sLog.outString( "Re-Loading Loot Tables..." );
86 LoadLootTables();
87 SendGlobalSysMessage("DB tables `*_loot_template` reloaded.");
88 return true;
91 bool ChatHandler::HandleReloadAllNpcCommand(const char* /*args*/)
93 HandleReloadNpcGossipCommand("a");
94 HandleReloadNpcOptionCommand("a");
95 HandleReloadNpcTrainerCommand("a");
96 HandleReloadNpcVendorCommand("a");
97 return true;
100 bool ChatHandler::HandleReloadAllQuestCommand(const char* /*args*/)
102 HandleReloadQuestAreaTriggersCommand("a");
103 HandleReloadQuestTemplateCommand("a");
105 sLog.outString( "Re-Loading Quests Relations..." );
106 objmgr.LoadQuestRelations();
107 SendGlobalSysMessage("DB tables `*_questrelation` and `*_involvedrelation` reloaded.");
108 return true;
111 bool ChatHandler::HandleReloadAllScriptsCommand(const char*)
113 if(sWorld.IsScriptScheduled())
115 PSendSysMessage("DB scripts used currently, please attempt reload later.");
116 SetSentErrorMessage(true);
117 return false;
120 sLog.outString( "Re-Loading Scripts..." );
121 HandleReloadGameObjectScriptsCommand("a");
122 HandleReloadEventScriptsCommand("a");
123 HandleReloadQuestEndScriptsCommand("a");
124 HandleReloadQuestStartScriptsCommand("a");
125 HandleReloadSpellScriptsCommand("a");
126 SendGlobalSysMessage("DB tables `*_scripts` reloaded.");
127 HandleReloadDbScriptStringCommand("a");
128 return true;
131 bool ChatHandler::HandleReloadAllSpellCommand(const char*)
133 HandleReloadSkillDiscoveryTemplateCommand("a");
134 HandleReloadSkillExtraItemTemplateCommand("a");
135 HandleReloadSpellAffectCommand("a");
136 HandleReloadSpellChainCommand("a");
137 HandleReloadSpellElixirCommand("a");
138 HandleReloadSpellLearnSpellCommand("a");
139 HandleReloadSpellProcEventCommand("a");
140 HandleReloadSpellBonusesCommand("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.");
243 /// dependent also from `gameobject` but this table not reloaded anyway
244 sLog.outString( "Re-Loading GameObjects for quests..." );
245 objmgr.LoadGameObjectForQuests();
246 SendGlobalSysMessage("Data GameObjects for quests reloaded.");
247 return true;
250 bool ChatHandler::HandleReloadLootTemplatesCreatureCommand(const char*)
252 sLog.outString( "Re-Loading Loot Tables... (`creature_loot_template`)" );
253 LoadLootTemplates_Creature();
254 LootTemplates_Creature.CheckLootRefs();
255 SendGlobalSysMessage("DB table `creature_loot_template` reloaded.");
256 return true;
259 bool ChatHandler::HandleReloadLootTemplatesDisenchantCommand(const char*)
261 sLog.outString( "Re-Loading Loot Tables... (`disenchant_loot_template`)" );
262 LoadLootTemplates_Disenchant();
263 LootTemplates_Disenchant.CheckLootRefs();
264 SendGlobalSysMessage("DB table `disenchant_loot_template` reloaded.");
265 return true;
268 bool ChatHandler::HandleReloadLootTemplatesFishingCommand(const char*)
270 sLog.outString( "Re-Loading Loot Tables... (`fishing_loot_template`)" );
271 LoadLootTemplates_Fishing();
272 LootTemplates_Fishing.CheckLootRefs();
273 SendGlobalSysMessage("DB table `fishing_loot_template` reloaded.");
274 return true;
277 bool ChatHandler::HandleReloadLootTemplatesGameobjectCommand(const char*)
279 sLog.outString( "Re-Loading Loot Tables... (`gameobject_loot_template`)" );
280 LoadLootTemplates_Gameobject();
281 LootTemplates_Gameobject.CheckLootRefs();
282 SendGlobalSysMessage("DB table `gameobject_loot_template` reloaded.");
283 return true;
286 bool ChatHandler::HandleReloadLootTemplatesItemCommand(const char*)
288 sLog.outString( "Re-Loading Loot Tables... (`item_loot_template`)" );
289 LoadLootTemplates_Item();
290 LootTemplates_Item.CheckLootRefs();
291 SendGlobalSysMessage("DB table `item_loot_template` reloaded.");
292 return true;
295 bool ChatHandler::HandleReloadLootTemplatesMillingCommand(const char*)
297 sLog.outString( "Re-Loading Loot Tables... (`milling_loot_template`)" );
298 LoadLootTemplates_Milling();
299 LootTemplates_Milling.CheckLootRefs();
300 SendGlobalSysMessage("DB table `milling_loot_template` reloaded.");
301 return true;
304 bool ChatHandler::HandleReloadLootTemplatesPickpocketingCommand(const char*)
306 sLog.outString( "Re-Loading Loot Tables... (`pickpocketing_loot_template`)" );
307 LoadLootTemplates_Pickpocketing();
308 LootTemplates_Pickpocketing.CheckLootRefs();
309 SendGlobalSysMessage("DB table `pickpocketing_loot_template` reloaded.");
310 return true;
313 bool ChatHandler::HandleReloadLootTemplatesProspectingCommand(const char*)
315 sLog.outString( "Re-Loading Loot Tables... (`prospecting_loot_template`)" );
316 LoadLootTemplates_Prospecting();
317 LootTemplates_Prospecting.CheckLootRefs();
318 SendGlobalSysMessage("DB table `prospecting_loot_template` reloaded.");
319 return true;
322 bool ChatHandler::HandleReloadLootTemplatesQuestMailCommand(const char*)
324 sLog.outString( "Re-Loading Loot Tables... (`quest_mail_loot_template`)" );
325 LoadLootTemplates_QuestMail();
326 LootTemplates_QuestMail.CheckLootRefs();
327 SendGlobalSysMessage("DB table `quest_mail_loot_template` reloaded.");
328 return true;
331 bool ChatHandler::HandleReloadLootTemplatesReferenceCommand(const char*)
333 sLog.outString( "Re-Loading Loot Tables... (`reference_loot_template`)" );
334 LoadLootTemplates_Reference();
335 SendGlobalSysMessage("DB table `reference_loot_template` reloaded.");
336 return true;
339 bool ChatHandler::HandleReloadLootTemplatesSkinningCommand(const char*)
341 sLog.outString( "Re-Loading Loot Tables... (`skinning_loot_template`)" );
342 LoadLootTemplates_Skinning();
343 LootTemplates_Skinning.CheckLootRefs();
344 SendGlobalSysMessage("DB table `skinning_loot_template` reloaded.");
345 return true;
348 bool ChatHandler::HandleReloadLootTemplatesSpellCommand(const char*)
350 sLog.outString( "Re-Loading Loot Tables... (`spell_loot_template`)" );
351 LoadLootTemplates_Spell();
352 LootTemplates_Spell.CheckLootRefs();
353 SendGlobalSysMessage("DB table `spell_loot_template` reloaded.");
354 return true;
357 bool ChatHandler::HandleReloadMangosStringCommand(const char*)
359 sLog.outString( "Re-Loading mangos_string Table!" );
360 objmgr.LoadMangosStrings();
361 SendGlobalSysMessage("DB table `mangos_string` reloaded.");
362 return true;
365 bool ChatHandler::HandleReloadNpcOptionCommand(const char*)
367 sLog.outString( "Re-Loading `npc_option` Table!" );
368 objmgr.LoadNpcOptions();
369 SendGlobalSysMessage("DB table `npc_option` reloaded.");
370 return true;
373 bool ChatHandler::HandleReloadNpcGossipCommand(const char*)
375 sLog.outString( "Re-Loading `npc_gossip` Table!" );
376 objmgr.LoadNpcTextId();
377 SendGlobalSysMessage("DB table `npc_gossip` reloaded.");
378 return true;
381 bool ChatHandler::HandleReloadNpcTrainerCommand(const char*)
383 sLog.outString( "Re-Loading `npc_trainer` Table!" );
384 objmgr.LoadTrainerSpell();
385 SendGlobalSysMessage("DB table `npc_trainer` reloaded.");
386 return true;
389 bool ChatHandler::HandleReloadNpcVendorCommand(const char*)
391 sLog.outString( "Re-Loading `npc_vendor` Table!" );
392 objmgr.LoadVendors();
393 SendGlobalSysMessage("DB table `npc_vendor` reloaded.");
394 return true;
397 bool ChatHandler::HandleReloadReservedNameCommand(const char*)
399 sLog.outString( "Loading ReservedNames... (`reserved_name`)" );
400 objmgr.LoadReservedPlayersNames();
401 SendGlobalSysMessage("DB table `reserved_name` (player reserved names) reloaded.");
402 return true;
405 bool ChatHandler::HandleReloadSkillDiscoveryTemplateCommand(const char* /*args*/)
407 sLog.outString( "Re-Loading Skill Discovery Table..." );
408 LoadSkillDiscoveryTable();
409 SendGlobalSysMessage("DB table `skill_discovery_template` (recipes discovered at crafting) reloaded.");
410 return true;
413 bool ChatHandler::HandleReloadSkillExtraItemTemplateCommand(const char* /*args*/)
415 sLog.outString( "Re-Loading Skill Extra Item Table..." );
416 LoadSkillExtraItemTable();
417 SendGlobalSysMessage("DB table `skill_extra_item_template` (extra item creation when crafting) reloaded.");
418 return true;
421 bool ChatHandler::HandleReloadSkillFishingBaseLevelCommand(const char* /*args*/)
423 sLog.outString( "Re-Loading Skill Fishing base level requirements..." );
424 objmgr.LoadFishingBaseSkillLevel();
425 SendGlobalSysMessage("DB table `skill_fishing_base_level` (fishing base level for zone/subzone) reloaded.");
426 return true;
429 bool ChatHandler::HandleReloadSpellAffectCommand(const char*)
431 sLog.outString( "Re-Loading SpellAffect definitions..." );
432 spellmgr.LoadSpellAffects();
433 SendGlobalSysMessage("DB table `spell_affect` (spell mods apply requirements) reloaded.");
434 return true;
437 bool ChatHandler::HandleReloadSpellChainCommand(const char*)
439 sLog.outString( "Re-Loading Spell Chain Data... " );
440 spellmgr.LoadSpellChains();
441 SendGlobalSysMessage("DB table `spell_chain` (spell ranks) reloaded.");
442 return true;
445 bool ChatHandler::HandleReloadSpellElixirCommand(const char*)
447 sLog.outString( "Re-Loading Spell Elixir types..." );
448 spellmgr.LoadSpellElixirs();
449 SendGlobalSysMessage("DB table `spell_elixir` (spell elixir types) reloaded.");
450 return true;
453 bool ChatHandler::HandleReloadSpellLearnSpellCommand(const char*)
455 sLog.outString( "Re-Loading Spell Learn Spells..." );
456 spellmgr.LoadSpellLearnSpells();
457 SendGlobalSysMessage("DB table `spell_learn_spell` reloaded.");
458 return true;
461 bool ChatHandler::HandleReloadSpellProcEventCommand(const char*)
463 sLog.outString( "Re-Loading Spell Proc Event conditions..." );
464 spellmgr.LoadSpellProcEvents();
465 SendGlobalSysMessage("DB table `spell_proc_event` (spell proc trigger requirements) reloaded.");
466 return true;
469 bool ChatHandler::HandleReloadSpellBonusesCommand(const char*)
471 sLog.outString( "Re-Loading Spell Bonus Data..." );
472 spellmgr.LoadSpellBonusess();
473 SendGlobalSysMessage("DB table `spell_bonus_data` (spell damage/healing coefficients) reloaded.");
474 return true;
477 bool ChatHandler::HandleReloadSpellScriptTargetCommand(const char*)
479 sLog.outString( "Re-Loading SpellsScriptTarget..." );
480 spellmgr.LoadSpellScriptTarget();
481 SendGlobalSysMessage("DB table `spell_script_target` (spell targets selection in case specific creature/GO requirements) reloaded.");
482 return true;
485 bool ChatHandler::HandleReloadSpellTargetPositionCommand(const char*)
487 sLog.outString( "Re-Loading Spell target coordinates..." );
488 spellmgr.LoadSpellTargetPositions();
489 SendGlobalSysMessage("DB table `spell_target_position` (destination coordinates for spell targets) reloaded.");
490 return true;
493 bool ChatHandler::HandleReloadSpellThreatsCommand(const char*)
495 sLog.outString( "Re-Loading Aggro Spells Definitions...");
496 spellmgr.LoadSpellThreats();
497 SendGlobalSysMessage("DB table `spell_threat` (spell aggro definitions) reloaded.");
498 return true;
501 bool ChatHandler::HandleReloadSpellPetAurasCommand(const char*)
503 sLog.outString( "Re-Loading Spell pet auras...");
504 spellmgr.LoadSpellPetAuras();
505 SendGlobalSysMessage("DB table `spell_pet_auras` reloaded.");
506 return true;
509 bool ChatHandler::HandleReloadPageTextsCommand(const char*)
511 sLog.outString( "Re-Loading Page Texts..." );
512 objmgr.LoadPageTexts();
513 SendGlobalSysMessage("DB table `page_texts` reloaded.");
514 return true;
517 bool ChatHandler::HandleReloadItemEnchantementsCommand(const char*)
519 sLog.outString( "Re-Loading Item Random Enchantments Table..." );
520 LoadRandomEnchantmentsTable();
521 SendGlobalSysMessage("DB table `item_enchantment_template` reloaded.");
522 return true;
525 bool ChatHandler::HandleReloadGameObjectScriptsCommand(const char* arg)
527 if(sWorld.IsScriptScheduled())
529 SendSysMessage("DB scripts used currently, please attempt reload later.");
530 SetSentErrorMessage(true);
531 return false;
534 if(*arg!='a')
535 sLog.outString( "Re-Loading Scripts from `gameobject_scripts`...");
537 objmgr.LoadGameObjectScripts();
539 if(*arg!='a')
540 SendGlobalSysMessage("DB table `gameobject_scripts` reloaded.");
542 return true;
545 bool ChatHandler::HandleReloadEventScriptsCommand(const char* arg)
547 if(sWorld.IsScriptScheduled())
549 SendSysMessage("DB scripts used currently, please attempt reload later.");
550 SetSentErrorMessage(true);
551 return false;
554 if(*arg!='a')
555 sLog.outString( "Re-Loading Scripts from `event_scripts`...");
557 objmgr.LoadEventScripts();
559 if(*arg!='a')
560 SendGlobalSysMessage("DB table `event_scripts` reloaded.");
562 return true;
565 bool ChatHandler::HandleReloadQuestEndScriptsCommand(const char* arg)
567 if(sWorld.IsScriptScheduled())
569 SendSysMessage("DB scripts used currently, please attempt reload later.");
570 SetSentErrorMessage(true);
571 return false;
574 if(*arg!='a')
575 sLog.outString( "Re-Loading Scripts from `quest_end_scripts`...");
577 objmgr.LoadQuestEndScripts();
579 if(*arg!='a')
580 SendGlobalSysMessage("DB table `quest_end_scripts` reloaded.");
582 return true;
585 bool ChatHandler::HandleReloadQuestStartScriptsCommand(const char* arg)
587 if(sWorld.IsScriptScheduled())
589 SendSysMessage("DB scripts used currently, please attempt reload later.");
590 SetSentErrorMessage(true);
591 return false;
594 if(*arg!='a')
595 sLog.outString( "Re-Loading Scripts from `quest_start_scripts`...");
597 objmgr.LoadQuestStartScripts();
599 if(*arg!='a')
600 SendGlobalSysMessage("DB table `quest_start_scripts` reloaded.");
602 return true;
605 bool ChatHandler::HandleReloadSpellScriptsCommand(const char* arg)
607 if(sWorld.IsScriptScheduled())
609 SendSysMessage("DB scripts used currently, please attempt reload later.");
610 SetSentErrorMessage(true);
611 return false;
614 if(*arg!='a')
615 sLog.outString( "Re-Loading Scripts from `spell_scripts`...");
617 objmgr.LoadSpellScripts();
619 if(*arg!='a')
620 SendGlobalSysMessage("DB table `spell_scripts` reloaded.");
622 return true;
625 bool ChatHandler::HandleReloadDbScriptStringCommand(const char* arg)
627 sLog.outString( "Re-Loading Script strings from `db_script_string`...");
628 objmgr.LoadDbScriptStrings();
629 SendGlobalSysMessage("DB table `db_script_string` reloaded.");
630 return true;
633 bool ChatHandler::HandleReloadGameGraveyardZoneCommand(const char* /*arg*/)
635 sLog.outString( "Re-Loading Graveyard-zone links...");
637 objmgr.LoadGraveyardZones();
639 SendGlobalSysMessage("DB table `game_graveyard_zone` reloaded.");
641 return true;
644 bool ChatHandler::HandleReloadGameTeleCommand(const char* /*arg*/)
646 sLog.outString( "Re-Loading Game Tele coordinates...");
648 objmgr.LoadGameTele();
650 SendGlobalSysMessage("DB table `game_tele` reloaded.");
652 return true;
655 bool ChatHandler::HandleReloadLocalesCreatureCommand(const char* /*arg*/)
657 sLog.outString( "Re-Loading Locales Creature ...");
658 objmgr.LoadCreatureLocales();
659 SendGlobalSysMessage("DB table `locales_creature` reloaded.");
660 return true;
663 bool ChatHandler::HandleReloadLocalesGameobjectCommand(const char* /*arg*/)
665 sLog.outString( "Re-Loading Locales Gameobject ... ");
666 objmgr.LoadGameObjectLocales();
667 SendGlobalSysMessage("DB table `locales_gameobject` reloaded.");
668 return true;
671 bool ChatHandler::HandleReloadLocalesItemCommand(const char* /*arg*/)
673 sLog.outString( "Re-Loading Locales Item ... ");
674 objmgr.LoadItemLocales();
675 SendGlobalSysMessage("DB table `locales_item` reloaded.");
676 return true;
679 bool ChatHandler::HandleReloadLocalesNpcTextCommand(const char* /*arg*/)
681 sLog.outString( "Re-Loading Locales NPC Text ... ");
682 objmgr.LoadNpcTextLocales();
683 SendGlobalSysMessage("DB table `locales_npc_text` reloaded.");
684 return true;
687 bool ChatHandler::HandleReloadLocalesPageTextCommand(const char* /*arg*/)
689 sLog.outString( "Re-Loading Locales Page Text ... ");
690 objmgr.LoadPageTextLocales();
691 SendGlobalSysMessage("DB table `locales_page_text` reloaded.");
692 return true;
695 bool ChatHandler::HandleReloadLocalesQuestCommand(const char* /*arg*/)
697 sLog.outString( "Re-Loading Locales Quest ... ");
698 objmgr.LoadQuestLocales();
699 SendGlobalSysMessage("DB table `locales_quest` reloaded.");
700 return true;
703 bool ChatHandler::HandleLoadScriptsCommand(const char* args)
705 if(!LoadScriptingModule(args)) return true;
707 sWorld.SendWorldText(LANG_SCRIPTS_RELOADED);
708 return true;
711 bool ChatHandler::HandleAccountSetGmLevelCommand(const char* args)
713 char* arg1 = strtok((char*)args, " ");
714 if( !arg1 )
715 return false;
717 /// must be NULL if targeted syntax and must be not nULL if not targeted
718 char* arg2 = strtok(NULL, " ");
720 std::string targetAccountName;
721 uint32 targetAccountId = 0;
723 /// only target player different from self allowed (if targetPlayer!=NULL then not console)
724 Player* targetPlayer = getSelectedPlayer();
725 if(targetPlayer && m_session->GetPlayer()!=targetPlayer)
727 /// wrong command syntax or unexpected targeting
728 if(arg2)
729 return false;
731 /// security level expected in arg2 after this if.
732 arg2 = arg1;
734 targetAccountId = targetPlayer->GetSession()->GetAccountId();
736 else
738 /// wrong command syntax (second arg expected)
739 if(!arg2)
740 return false;
742 targetAccountName = arg1;
743 if(!AccountMgr::normilizeString(targetAccountName))
745 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,targetAccountName.c_str());
746 SetSentErrorMessage(true);
747 return false;
750 targetAccountId = accmgr.GetId(targetAccountName);
751 if(!targetAccountId)
753 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,targetAccountName.c_str());
754 SetSentErrorMessage(true);
755 return false;
759 int32 gm = (int32)atoi(arg2);
760 if ( gm < SEC_PLAYER || gm > SEC_ADMINISTRATOR )
762 SendSysMessage(LANG_BAD_VALUE);
763 SetSentErrorMessage(true);
764 return false;
767 /// can set security level only for target with less security and to less security that we have
768 /// This is also reject self apply in fact
769 if(HasLowerSecurityAccount(NULL,targetAccountId,true))
770 return false;
772 /// account can't set security to same or grater level, need more power GM or console
773 uint32 plSecurity = m_session ? m_session->GetSecurity() : SEC_CONSOLE;
774 if (uint32(gm) >= plSecurity )
776 SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
777 SetSentErrorMessage(true);
778 return false;
781 if(targetPlayer)
783 ChatHandler(targetPlayer).PSendSysMessage(LANG_YOURS_SECURITY_CHANGED,GetNameLink().c_str(), gm);
784 targetPlayer->GetSession()->SetSecurity(gm);
787 PSendSysMessage(LANG_YOU_CHANGE_SECURITY, targetAccountName.c_str(), gm);
788 loginDatabase.PExecute("UPDATE account SET gmlevel = '%i' WHERE id = '%u'", gm, targetAccountId);
790 return true;
793 /// Set password for account
794 bool ChatHandler::HandleAccountSetPasswordCommand(const char* args)
796 if(!*args)
797 return false;
799 ///- Get the command line arguments
800 char *szAccount = strtok ((char*)args," ");
801 char *szPassword1 = strtok (NULL," ");
802 char *szPassword2 = strtok (NULL," ");
804 if (!szAccount||!szPassword1 || !szPassword2)
805 return false;
807 std::string account_name = szAccount;
808 if(!AccountMgr::normilizeString(account_name))
810 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
811 SetSentErrorMessage(true);
812 return false;
815 uint32 targetAccountId = accmgr.GetId(account_name);
816 if (!targetAccountId)
818 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
819 SetSentErrorMessage(true);
820 return false;
823 /// can set password only for target with less security
824 /// This is also reject self apply in fact
825 if(HasLowerSecurityAccount (NULL,targetAccountId,true))
826 return false;
828 if (strcmp(szPassword1,szPassword2))
830 SendSysMessage (LANG_NEW_PASSWORDS_NOT_MATCH);
831 SetSentErrorMessage (true);
832 return false;
835 AccountOpResult result = accmgr.ChangePassword(targetAccountId, szPassword1);
837 switch(result)
839 case AOR_OK:
840 SendSysMessage(LANG_COMMAND_PASSWORD);
841 break;
842 case AOR_NAME_NOT_EXIST:
843 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
844 SetSentErrorMessage(true);
845 return false;
846 case AOR_PASS_TOO_LONG:
847 SendSysMessage(LANG_PASSWORD_TOO_LONG);
848 SetSentErrorMessage(true);
849 return false;
850 default:
851 SendSysMessage(LANG_COMMAND_NOTCHANGEPASSWORD);
852 SetSentErrorMessage(true);
853 return false;
856 return true;
859 bool ChatHandler::HandleAllowMovementCommand(const char* /*args*/)
861 if(sWorld.getAllowMovement())
863 sWorld.SetAllowMovement(false);
864 SendSysMessage(LANG_CREATURE_MOVE_DISABLED);
866 else
868 sWorld.SetAllowMovement(true);
869 SendSysMessage(LANG_CREATURE_MOVE_ENABLED);
871 return true;
874 bool ChatHandler::HandleMaxSkillCommand(const char* /*args*/)
876 Player* SelectedPlayer = getSelectedPlayer();
877 if(!SelectedPlayer)
879 SendSysMessage(LANG_NO_CHAR_SELECTED);
880 SetSentErrorMessage(true);
881 return false;
884 // each skills that have max skill value dependent from level seted to current level max skill value
885 SelectedPlayer->UpdateSkillsToMaxSkillsForLevel();
886 return true;
889 bool ChatHandler::HandleSetSkillCommand(const char* args)
891 // number or [name] Shift-click form |color|Hskill:skill_id|h[name]|h|r
892 char* skill_p = extractKeyFromLink((char*)args,"Hskill");
893 if(!skill_p)
894 return false;
896 char *level_p = strtok (NULL, " ");
898 if( !level_p)
899 return false;
901 char *max_p = strtok (NULL, " ");
903 int32 skill = atoi(skill_p);
904 if (skill <= 0)
906 PSendSysMessage(LANG_INVALID_SKILL_ID, skill);
907 SetSentErrorMessage(true);
908 return false;
911 int32 level = atol (level_p);
913 Player * target = getSelectedPlayer();
914 if(!target)
916 SendSysMessage(LANG_NO_CHAR_SELECTED);
917 SetSentErrorMessage(true);
918 return false;
921 SkillLineEntry const* sl = sSkillLineStore.LookupEntry(skill);
922 if(!sl)
924 PSendSysMessage(LANG_INVALID_SKILL_ID, skill);
925 SetSentErrorMessage(true);
926 return false;
929 std::string tNameLink = GetNameLink(target);
931 if(!target->GetSkillValue(skill))
933 PSendSysMessage(LANG_SET_SKILL_ERROR, tNameLink.c_str(), skill, sl->name[0]);
934 SetSentErrorMessage(true);
935 return false;
938 int32 max = max_p ? atol (max_p) : target->GetPureMaxSkillValue(skill);
940 if( level <= 0 || level > max || max <= 0 )
941 return false;
943 target->SetSkill(skill, level, max);
944 PSendSysMessage(LANG_SET_SKILL, skill, sl->name[0], tNameLink.c_str(), level, max);
946 return true;
949 bool ChatHandler::HandleUnLearnCommand(const char* args)
951 if (!*args)
952 return false;
954 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
955 uint32 spell_id = extractSpellIdFromLink((char*)args);
956 if(!spell_id)
957 return false;
959 char const* allStr = strtok(NULL," ");
960 bool allRanks = allStr ? (strncmp(allStr, "all", strlen(allStr)) == 0) : false;
962 Player* target = getSelectedPlayer();
963 if(!target)
965 SendSysMessage(LANG_NO_CHAR_SELECTED);
966 SetSentErrorMessage(true);
967 return false;
970 if(allRanks)
971 spell_id = spellmgr.GetFirstSpellInChain (spell_id);
973 if (target->HasSpell(spell_id))
974 target->removeSpell(spell_id,false,!allRanks);
975 else
976 SendSysMessage(LANG_FORGET_SPELL);
978 return true;
981 bool ChatHandler::HandleCooldownCommand(const char* args)
983 Player* target = getSelectedPlayer();
984 if(!target)
986 SendSysMessage(LANG_PLAYER_NOT_FOUND);
987 SetSentErrorMessage(true);
988 return false;
991 std::string tNameLink = GetNameLink(target);
993 if (!*args)
995 target->RemoveAllSpellCooldown();
996 PSendSysMessage(LANG_REMOVEALL_COOLDOWN, tNameLink.c_str());
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) : tNameLink.c_str());
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) : tNameLink.c_str());
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,false);
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,false);
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,false);
1734 SendSysMessage(LANG_COMMAND_LEARN_CLASS_SPELLS);
1735 return true;
1738 bool ChatHandler::HandleLearnAllMyTalentsCommand(const char* /*args*/)
1740 Player* player = m_session->GetPlayer();
1741 uint32 classMask = player->getClassMask();
1743 for (uint32 i = 0; i < sTalentStore.GetNumRows(); i++)
1745 TalentEntry const *talentInfo = sTalentStore.LookupEntry(i);
1746 if(!talentInfo)
1747 continue;
1749 TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab );
1750 if(!talentTabInfo)
1751 continue;
1753 if( (classMask & talentTabInfo->ClassMask) == 0 )
1754 continue;
1756 // search highest talent rank
1757 uint32 spellid = 0;
1758 int rank = 4;
1759 for(; rank >= 0; --rank)
1761 if(talentInfo->RankID[rank]!=0)
1763 spellid = talentInfo->RankID[rank];
1764 break;
1768 if(!spellid) // ??? none spells in talent
1769 continue;
1771 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid);
1772 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
1773 continue;
1775 // learn highest rank of talent and learn all non-talent spell ranks (recursive by tree)
1776 player->learnSpellHighRank(spellid);
1779 SendSysMessage(LANG_COMMAND_LEARN_CLASS_TALENTS);
1780 return true;
1783 bool ChatHandler::HandleLearnAllLangCommand(const char* /*args*/)
1785 // skipping UNIVERSAL language (0)
1786 for(int i = 1; i < LANGUAGES_COUNT; ++i)
1787 m_session->GetPlayer()->learnSpell(lang_description[i].spell_id,false);
1789 SendSysMessage(LANG_COMMAND_LEARN_ALL_LANG);
1790 return true;
1793 bool ChatHandler::HandleLearnAllDefaultCommand(const char* args)
1795 Player *player = NULL;
1796 if (*args)
1798 std::string name = extractPlayerNameFromLink((char*)args);
1799 if(name.empty())
1801 SendSysMessage(LANG_PLAYER_NOT_FOUND);
1802 SetSentErrorMessage(true);
1803 return false;
1806 player = objmgr.GetPlayer(name.c_str());
1808 else
1809 player = getSelectedPlayer();
1811 if(!player)
1813 SendSysMessage(LANG_NO_CHAR_SELECTED);
1814 SetSentErrorMessage(true);
1815 return false;
1818 player->learnDefaultSpells();
1819 player->learnQuestRewardedSpells();
1821 PSendSysMessage(LANG_COMMAND_LEARN_ALL_DEFAULT_AND_QUEST,GetNameLink(player).c_str());
1822 return true;
1825 bool ChatHandler::HandleLearnCommand(const char* args)
1827 Player* targetPlayer = getSelectedPlayer();
1829 if(!targetPlayer)
1831 SendSysMessage(LANG_PLAYER_NOT_FOUND);
1832 SetSentErrorMessage(true);
1833 return false;
1836 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
1837 uint32 spell = extractSpellIdFromLink((char*)args);
1838 if(!spell || !sSpellStore.LookupEntry(spell))
1839 return false;
1841 char const* allStr = strtok(NULL," ");
1842 bool allRanks = allStr ? (strncmp(allStr, "all", strlen(allStr)) == 0) : false;
1844 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
1845 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
1847 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
1848 SetSentErrorMessage(true);
1849 return false;
1852 if (!allRanks && targetPlayer->HasSpell(spell))
1854 if(targetPlayer == m_session->GetPlayer())
1855 SendSysMessage(LANG_YOU_KNOWN_SPELL);
1856 else
1857 PSendSysMessage(LANG_TARGET_KNOWN_SPELL,GetNameLink(targetPlayer).c_str());
1858 SetSentErrorMessage(true);
1859 return false;
1862 if(allRanks)
1863 targetPlayer->learnSpellHighRank(spell);
1864 else
1865 targetPlayer->learnSpell(spell,false);
1867 return true;
1870 bool ChatHandler::HandleAddItemCommand(const char* args)
1872 if (!*args)
1873 return false;
1875 uint32 itemId = 0;
1877 if(args[0]=='[') // [name] manual form
1879 char* citemName = citemName = strtok((char*)args, "]");
1881 if(citemName && citemName[0])
1883 std::string itemName = citemName+1;
1884 WorldDatabase.escape_string(itemName);
1885 QueryResult *result = WorldDatabase.PQuery("SELECT entry FROM item_template WHERE name = '%s'", itemName.c_str());
1886 if (!result)
1888 PSendSysMessage(LANG_COMMAND_COULDNOTFIND, citemName+1);
1889 SetSentErrorMessage(true);
1890 return false;
1892 itemId = result->Fetch()->GetUInt16();
1893 delete result;
1895 else
1896 return false;
1898 else // item_id or [name] Shift-click form |color|Hitem:item_id:0:0:0|h[name]|h|r
1900 char* cId = extractKeyFromLink((char*)args,"Hitem");
1901 if(!cId)
1902 return false;
1903 itemId = atol(cId);
1906 char* ccount = strtok(NULL, " ");
1908 int32 count = 1;
1910 if (ccount)
1911 count = strtol(ccount, NULL, 10);
1913 if (count == 0)
1914 count = 1;
1916 Player* pl = m_session->GetPlayer();
1917 Player* plTarget = getSelectedPlayer();
1918 if(!plTarget)
1919 plTarget = pl;
1921 sLog.outDetail(GetMangosString(LANG_ADDITEM), itemId, count);
1923 ItemPrototype const *pProto = objmgr.GetItemPrototype(itemId);
1924 if(!pProto)
1926 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId);
1927 SetSentErrorMessage(true);
1928 return false;
1931 //Subtract
1932 if (count < 0)
1934 plTarget->DestroyItemCount(itemId, -count, true, false);
1935 PSendSysMessage(LANG_REMOVEITEM, itemId, -count, GetNameLink(plTarget).c_str());
1936 return true;
1939 //Adding items
1940 uint32 noSpaceForCount = 0;
1942 // check space and find places
1943 ItemPosCountVec dest;
1944 uint8 msg = plTarget->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, itemId, count, &noSpaceForCount );
1945 if( msg != EQUIP_ERR_OK ) // convert to possible store amount
1946 count -= noSpaceForCount;
1948 if( count == 0 || dest.empty()) // can't add any
1950 PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount );
1951 SetSentErrorMessage(true);
1952 return false;
1955 Item* item = plTarget->StoreNewItem( dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId));
1957 // remove binding (let GM give it to another player later)
1958 if(pl==plTarget)
1959 for(ItemPosCountVec::const_iterator itr = dest.begin(); itr != dest.end(); ++itr)
1960 if(Item* item1 = pl->GetItemByPos(itr->pos))
1961 item1->SetBinding( false );
1963 if(count > 0 && item)
1965 pl->SendNewItem(item,count,false,true);
1966 if(pl!=plTarget)
1967 plTarget->SendNewItem(item,count,true,false);
1970 if(noSpaceForCount > 0)
1971 PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount);
1973 return true;
1976 bool ChatHandler::HandleAddItemSetCommand(const char* args)
1978 if (!*args)
1979 return false;
1981 char* cId = extractKeyFromLink((char*)args,"Hitemset"); // number or [name] Shift-click form |color|Hitemset:itemset_id|h[name]|h|r
1982 if (!cId)
1983 return false;
1985 uint32 itemsetId = atol(cId);
1987 // prevent generation all items with itemset field value '0'
1988 if (itemsetId == 0)
1990 PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND,itemsetId);
1991 SetSentErrorMessage(true);
1992 return false;
1995 Player* pl = m_session->GetPlayer();
1996 Player* plTarget = getSelectedPlayer();
1997 if(!plTarget)
1998 plTarget = pl;
2000 sLog.outDetail(GetMangosString(LANG_ADDITEMSET), itemsetId);
2002 bool found = false;
2003 for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
2005 ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype>(id);
2006 if (!pProto)
2007 continue;
2009 if (pProto->ItemSet == itemsetId)
2011 found = true;
2012 ItemPosCountVec dest;
2013 uint8 msg = plTarget->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, pProto->ItemId, 1 );
2014 if (msg == EQUIP_ERR_OK)
2016 Item* item = plTarget->StoreNewItem( dest, pProto->ItemId, true);
2018 // remove binding (let GM give it to another player later)
2019 if (pl==plTarget)
2020 item->SetBinding( false );
2022 pl->SendNewItem(item,1,false,true);
2023 if (pl!=plTarget)
2024 plTarget->SendNewItem(item,1,true,false);
2026 else
2028 pl->SendEquipError( msg, NULL, NULL );
2029 PSendSysMessage(LANG_ITEM_CANNOT_CREATE, pProto->ItemId, 1);
2034 if (!found)
2036 PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND,itemsetId);
2038 SetSentErrorMessage(true);
2039 return false;
2042 return true;
2045 bool ChatHandler::HandleListItemCommand(const char* args)
2047 if(!*args)
2048 return false;
2050 char* cId = extractKeyFromLink((char*)args,"Hitem");
2051 if(!cId)
2052 return false;
2054 uint32 item_id = atol(cId);
2055 if(!item_id)
2057 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
2058 SetSentErrorMessage(true);
2059 return false;
2062 ItemPrototype const* itemProto = objmgr.GetItemPrototype(item_id);
2063 if(!itemProto)
2065 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
2066 SetSentErrorMessage(true);
2067 return false;
2070 char* c_count = strtok(NULL, " ");
2071 int count = c_count ? atol(c_count) : 10;
2073 if(count < 0)
2074 return false;
2076 QueryResult *result;
2078 // inventory case
2079 uint32 inv_count = 0;
2080 result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM character_inventory WHERE item_template='%u'",item_id);
2081 if(result)
2083 inv_count = (*result)[0].GetUInt32();
2084 delete result;
2087 result=CharacterDatabase.PQuery(
2088 // 0 1 2 3 4 5
2089 "SELECT ci.item, cibag.slot AS bag, ci.slot, ci.guid, characters.account,characters.name "
2090 "FROM character_inventory AS ci LEFT JOIN character_inventory AS cibag ON (cibag.item=ci.bag),characters "
2091 "WHERE ci.item_template='%u' AND ci.guid = characters.guid LIMIT %u ",
2092 item_id,uint32(count));
2094 if(result)
2098 Field *fields = result->Fetch();
2099 uint32 item_guid = fields[0].GetUInt32();
2100 uint32 item_bag = fields[1].GetUInt32();
2101 uint32 item_slot = fields[2].GetUInt32();
2102 uint32 owner_guid = fields[3].GetUInt32();
2103 uint32 owner_acc = fields[4].GetUInt32();
2104 std::string owner_name = fields[5].GetCppString();
2106 char const* item_pos = 0;
2107 if(Player::IsEquipmentPos(item_bag,item_slot))
2108 item_pos = "[equipped]";
2109 else if(Player::IsInventoryPos(item_bag,item_slot))
2110 item_pos = "[in inventory]";
2111 else if(Player::IsBankPos(item_bag,item_slot))
2112 item_pos = "[in bank]";
2113 else
2114 item_pos = "";
2116 PSendSysMessage(LANG_ITEMLIST_SLOT,
2117 item_guid,owner_name.c_str(),owner_guid,owner_acc,item_pos);
2118 } while (result->NextRow());
2120 int64 res_count = result->GetRowCount();
2122 delete result;
2124 if(count > res_count)
2125 count-=res_count;
2126 else if(count)
2127 count = 0;
2130 // mail case
2131 uint32 mail_count = 0;
2132 result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM mail_items WHERE item_template='%u'", item_id);
2133 if(result)
2135 mail_count = (*result)[0].GetUInt32();
2136 delete result;
2139 if(count > 0)
2141 result=CharacterDatabase.PQuery(
2142 // 0 1 2 3 4 5 6
2143 "SELECT mail_items.item_guid, mail.sender, mail.receiver, char_s.account, char_s.name, char_r.account, char_r.name "
2144 "FROM mail,mail_items,characters as char_s,characters as char_r "
2145 "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",
2146 item_id,uint32(count));
2148 else
2149 result = NULL;
2151 if(result)
2155 Field *fields = result->Fetch();
2156 uint32 item_guid = fields[0].GetUInt32();
2157 uint32 item_s = fields[1].GetUInt32();
2158 uint32 item_r = fields[2].GetUInt32();
2159 uint32 item_s_acc = fields[3].GetUInt32();
2160 std::string item_s_name = fields[4].GetCppString();
2161 uint32 item_r_acc = fields[5].GetUInt32();
2162 std::string item_r_name = fields[6].GetCppString();
2164 char const* item_pos = "[in mail]";
2166 PSendSysMessage(LANG_ITEMLIST_MAIL,
2167 item_guid,item_s_name.c_str(),item_s,item_s_acc,item_r_name.c_str(),item_r,item_r_acc,item_pos);
2168 } while (result->NextRow());
2170 int64 res_count = result->GetRowCount();
2172 delete result;
2174 if(count > res_count)
2175 count-=res_count;
2176 else if(count)
2177 count = 0;
2180 // auction case
2181 uint32 auc_count = 0;
2182 result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM auctionhouse WHERE item_template='%u'",item_id);
2183 if(result)
2185 auc_count = (*result)[0].GetUInt32();
2186 delete result;
2189 if(count > 0)
2191 result=CharacterDatabase.PQuery(
2192 // 0 1 2 3
2193 "SELECT auctionhouse.itemguid, auctionhouse.itemowner, characters.account, characters.name "
2194 "FROM auctionhouse,characters WHERE auctionhouse.item_template='%u' AND characters.guid = auctionhouse.itemowner LIMIT %u",
2195 item_id,uint32(count));
2197 else
2198 result = NULL;
2200 if(result)
2204 Field *fields = result->Fetch();
2205 uint32 item_guid = fields[0].GetUInt32();
2206 uint32 owner = fields[1].GetUInt32();
2207 uint32 owner_acc = fields[2].GetUInt32();
2208 std::string owner_name = fields[3].GetCppString();
2210 char const* item_pos = "[in auction]";
2212 PSendSysMessage(LANG_ITEMLIST_AUCTION, item_guid, owner_name.c_str(), owner, owner_acc,item_pos);
2213 } while (result->NextRow());
2215 delete result;
2218 // guild bank case
2219 uint32 guild_count = 0;
2220 result=CharacterDatabase.PQuery("SELECT COUNT(item_entry) FROM guild_bank_item WHERE item_entry='%u'",item_id);
2221 if(result)
2223 guild_count = (*result)[0].GetUInt32();
2224 delete result;
2227 result=CharacterDatabase.PQuery(
2228 // 0 1 2
2229 "SELECT gi.item_guid, gi.guildid, guild.name "
2230 "FROM guild_bank_item AS gi, guild WHERE gi.item_entry='%u' AND gi.guildid = guild.guildid LIMIT %u ",
2231 item_id,uint32(count));
2233 if(result)
2237 Field *fields = result->Fetch();
2238 uint32 item_guid = fields[0].GetUInt32();
2239 uint32 guild_guid = fields[1].GetUInt32();
2240 std::string guild_name = fields[2].GetCppString();
2242 char const* item_pos = "[in guild bank]";
2244 PSendSysMessage(LANG_ITEMLIST_GUILD,item_guid,guild_name.c_str(),guild_guid,item_pos);
2245 } while (result->NextRow());
2247 int64 res_count = result->GetRowCount();
2249 delete result;
2251 if(count > res_count)
2252 count-=res_count;
2253 else if(count)
2254 count = 0;
2257 if(inv_count+mail_count+auc_count+guild_count == 0)
2259 SendSysMessage(LANG_COMMAND_NOITEMFOUND);
2260 SetSentErrorMessage(true);
2261 return false;
2264 PSendSysMessage(LANG_COMMAND_LISTITEMMESSAGE,item_id,inv_count+mail_count+auc_count+guild_count,inv_count,mail_count,auc_count,guild_count);
2266 return true;
2269 bool ChatHandler::HandleListObjectCommand(const char* args)
2271 if(!*args)
2272 return false;
2274 // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r
2275 char* cId = extractKeyFromLink((char*)args,"Hgameobject_entry");
2276 if(!cId)
2277 return false;
2279 uint32 go_id = atol(cId);
2280 if(!go_id)
2282 PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id);
2283 SetSentErrorMessage(true);
2284 return false;
2287 GameObjectInfo const * gInfo = objmgr.GetGameObjectInfo(go_id);
2288 if(!gInfo)
2290 PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id);
2291 SetSentErrorMessage(true);
2292 return false;
2295 char* c_count = strtok(NULL, " ");
2296 int count = c_count ? atol(c_count) : 10;
2298 if(count < 0)
2299 return false;
2301 QueryResult *result;
2303 uint32 obj_count = 0;
2304 result=WorldDatabase.PQuery("SELECT COUNT(guid) FROM gameobject WHERE id='%u'",go_id);
2305 if(result)
2307 obj_count = (*result)[0].GetUInt32();
2308 delete result;
2311 if(m_session)
2313 Player* pl = m_session->GetPlayer();
2314 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",
2315 pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),go_id,uint32(count));
2317 else
2318 result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map FROM gameobject WHERE id = '%u' LIMIT %u",
2319 go_id,uint32(count));
2321 if (result)
2325 Field *fields = result->Fetch();
2326 uint32 guid = fields[0].GetUInt32();
2327 float x = fields[1].GetFloat();
2328 float y = fields[2].GetFloat();
2329 float z = fields[3].GetFloat();
2330 int mapid = fields[4].GetUInt16();
2332 if (m_session)
2333 PSendSysMessage(LANG_GO_LIST_CHAT, guid, guid, gInfo->name, x, y, z, mapid);
2334 else
2335 PSendSysMessage(LANG_GO_LIST_CONSOLE, guid, gInfo->name, x, y, z, mapid);
2336 } while (result->NextRow());
2338 delete result;
2341 PSendSysMessage(LANG_COMMAND_LISTOBJMESSAGE,go_id,obj_count);
2342 return true;
2345 bool ChatHandler::HandleNearObjectCommand(const char* args)
2347 float distance = (!*args) ? 10 : atol(args);
2348 uint32 count = 0;
2350 Player* pl = m_session->GetPlayer();
2351 QueryResult *result = WorldDatabase.PQuery("SELECT guid, id, position_x, position_y, position_z, map, "
2352 "(POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ "
2353 "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_",
2354 pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),
2355 pl->GetMapId(),pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),distance*distance);
2357 if (result)
2361 Field *fields = result->Fetch();
2362 uint32 guid = fields[0].GetUInt32();
2363 uint32 entry = fields[1].GetUInt32();
2364 float x = fields[2].GetFloat();
2365 float y = fields[3].GetFloat();
2366 float z = fields[4].GetFloat();
2367 int mapid = fields[5].GetUInt16();
2369 GameObjectInfo const * gInfo = objmgr.GetGameObjectInfo(entry);
2371 if(!gInfo)
2372 continue;
2374 PSendSysMessage(LANG_GO_LIST_CHAT, guid, guid, gInfo->name, x, y, z, mapid);
2376 ++count;
2377 } while (result->NextRow());
2379 delete result;
2382 PSendSysMessage(LANG_COMMAND_NEAROBJMESSAGE,distance,count);
2383 return true;
2386 bool ChatHandler::HandleListCreatureCommand(const char* args)
2388 if(!*args)
2389 return false;
2391 // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
2392 char* cId = extractKeyFromLink((char*)args,"Hcreature_entry");
2393 if(!cId)
2394 return false;
2396 uint32 cr_id = atol(cId);
2397 if(!cr_id)
2399 PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id);
2400 SetSentErrorMessage(true);
2401 return false;
2404 CreatureInfo const* cInfo = objmgr.GetCreatureTemplate(cr_id);
2405 if(!cInfo)
2407 PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id);
2408 SetSentErrorMessage(true);
2409 return false;
2412 char* c_count = strtok(NULL, " ");
2413 int count = c_count ? atol(c_count) : 10;
2415 if(count < 0)
2416 return false;
2418 QueryResult *result;
2420 uint32 cr_count = 0;
2421 result=WorldDatabase.PQuery("SELECT COUNT(guid) FROM creature WHERE id='%u'",cr_id);
2422 if(result)
2424 cr_count = (*result)[0].GetUInt32();
2425 delete result;
2428 if(m_session)
2430 Player* pl = m_session->GetPlayer();
2431 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",
2432 pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), cr_id,uint32(count));
2434 else
2435 result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map FROM creature WHERE id = '%u' LIMIT %u",
2436 cr_id,uint32(count));
2438 if (result)
2442 Field *fields = result->Fetch();
2443 uint32 guid = fields[0].GetUInt32();
2444 float x = fields[1].GetFloat();
2445 float y = fields[2].GetFloat();
2446 float z = fields[3].GetFloat();
2447 int mapid = fields[4].GetUInt16();
2449 if (m_session)
2450 PSendSysMessage(LANG_CREATURE_LIST_CHAT, guid, guid, cInfo->Name, x, y, z, mapid);
2451 else
2452 PSendSysMessage(LANG_CREATURE_LIST_CONSOLE, guid, cInfo->Name, x, y, z, mapid);
2453 } while (result->NextRow());
2455 delete result;
2458 PSendSysMessage(LANG_COMMAND_LISTCREATUREMESSAGE,cr_id,cr_count);
2459 return true;
2462 bool ChatHandler::HandleLookupItemCommand(const char* args)
2464 if(!*args)
2465 return false;
2467 std::string namepart = args;
2468 std::wstring wnamepart;
2470 // converting string that we try to find to lower case
2471 if(!Utf8toWStr(namepart,wnamepart))
2472 return false;
2474 wstrToLower(wnamepart);
2476 uint32 counter = 0;
2478 // Search in `item_template`
2479 for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
2481 ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype >(id);
2482 if(!pProto)
2483 continue;
2485 int loc_idx = m_session ? m_session->GetSessionDbLocaleIndex() : objmgr.GetDBCLocaleIndex();
2486 if ( loc_idx >= 0 )
2488 ItemLocale const *il = objmgr.GetItemLocale(pProto->ItemId);
2489 if (il)
2491 if (il->Name.size() > loc_idx && !il->Name[loc_idx].empty())
2493 std::string name = il->Name[loc_idx];
2495 if (Utf8FitTo(name, wnamepart))
2497 if (m_session)
2498 PSendSysMessage(LANG_ITEM_LIST_CHAT, id, id, name.c_str());
2499 else
2500 PSendSysMessage(LANG_ITEM_LIST_CONSOLE, id, name.c_str());
2501 ++counter;
2502 continue;
2508 std::string name = pProto->Name1;
2509 if(name.empty())
2510 continue;
2512 if (Utf8FitTo(name, wnamepart))
2514 if (m_session)
2515 PSendSysMessage(LANG_ITEM_LIST_CHAT, id, id, name.c_str());
2516 else
2517 PSendSysMessage(LANG_ITEM_LIST_CONSOLE, id, name.c_str());
2518 ++counter;
2522 if (counter==0)
2523 SendSysMessage(LANG_COMMAND_NOITEMFOUND);
2525 return true;
2528 bool ChatHandler::HandleLookupItemSetCommand(const char* args)
2530 if(!*args)
2531 return false;
2533 std::string namepart = args;
2534 std::wstring wnamepart;
2536 if(!Utf8toWStr(namepart,wnamepart))
2537 return false;
2539 // converting string that we try to find to lower case
2540 wstrToLower( wnamepart );
2542 uint32 counter = 0; // Counter for figure out that we found smth.
2544 // Search in ItemSet.dbc
2545 for (uint32 id = 0; id < sItemSetStore.GetNumRows(); id++)
2547 ItemSetEntry const *set = sItemSetStore.LookupEntry(id);
2548 if(set)
2550 int loc = m_session ? m_session->GetSessionDbcLocale() : sWorld.GetDefaultDbcLocale();
2551 std::string name = set->name[loc];
2552 if(name.empty())
2553 continue;
2555 if (!Utf8FitTo(name, wnamepart))
2557 loc = 0;
2558 for(; loc < MAX_LOCALE; ++loc)
2560 if(m_session && loc==m_session->GetSessionDbcLocale())
2561 continue;
2563 name = set->name[loc];
2564 if(name.empty())
2565 continue;
2567 if (Utf8FitTo(name, wnamepart))
2568 break;
2572 if(loc < MAX_LOCALE)
2574 // send item set in "id - [namedlink locale]" format
2575 if (m_session)
2576 PSendSysMessage(LANG_ITEMSET_LIST_CHAT,id,id,name.c_str(),localeNames[loc]);
2577 else
2578 PSendSysMessage(LANG_ITEMSET_LIST_CONSOLE,id,name.c_str(),localeNames[loc]);
2579 ++counter;
2583 if (counter == 0) // if counter == 0 then we found nth
2584 SendSysMessage(LANG_COMMAND_NOITEMSETFOUND);
2585 return true;
2588 bool ChatHandler::HandleLookupSkillCommand(const char* args)
2590 if(!*args)
2591 return false;
2593 // can be NULL in console call
2594 Player* target = getSelectedPlayer();
2596 std::string namepart = args;
2597 std::wstring wnamepart;
2599 if(!Utf8toWStr(namepart,wnamepart))
2600 return false;
2602 // converting string that we try to find to lower case
2603 wstrToLower( wnamepart );
2605 uint32 counter = 0; // Counter for figure out that we found smth.
2607 // Search in SkillLine.dbc
2608 for (uint32 id = 0; id < sSkillLineStore.GetNumRows(); id++)
2610 SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(id);
2611 if(skillInfo)
2613 int loc = m_session ? m_session->GetSessionDbcLocale() : sWorld.GetDefaultDbcLocale();
2614 std::string name = skillInfo->name[loc];
2615 if(name.empty())
2616 continue;
2618 if (!Utf8FitTo(name, wnamepart))
2620 loc = 0;
2621 for(; loc < MAX_LOCALE; ++loc)
2623 if(m_session && loc==m_session->GetSessionDbcLocale())
2624 continue;
2626 name = skillInfo->name[loc];
2627 if(name.empty())
2628 continue;
2630 if (Utf8FitTo(name, wnamepart))
2631 break;
2635 if(loc < MAX_LOCALE)
2637 char valStr[50] = "";
2638 char const* knownStr = "";
2639 if(target && target->HasSkill(id))
2641 knownStr = GetMangosString(LANG_KNOWN);
2642 uint32 curValue = target->GetPureSkillValue(id);
2643 uint32 maxValue = target->GetPureMaxSkillValue(id);
2644 uint32 permValue = target->GetSkillPermBonusValue(id);
2645 uint32 tempValue = target->GetSkillTempBonusValue(id);
2647 char const* valFormat = GetMangosString(LANG_SKILL_VALUES);
2648 snprintf(valStr,50,valFormat,curValue,maxValue,permValue,tempValue);
2651 // send skill in "id - [namedlink locale]" format
2652 if (m_session)
2653 PSendSysMessage(LANG_SKILL_LIST_CHAT,id,id,name.c_str(),localeNames[loc],knownStr,valStr);
2654 else
2655 PSendSysMessage(LANG_SKILL_LIST_CONSOLE,id,name.c_str(),localeNames[loc],knownStr,valStr);
2657 ++counter;
2661 if (counter == 0) // if counter == 0 then we found nth
2662 SendSysMessage(LANG_COMMAND_NOSKILLFOUND);
2663 return true;
2666 bool ChatHandler::HandleLookupSpellCommand(const char* args)
2668 if(!*args)
2669 return false;
2671 // can be NULL at console call
2672 Player* target = getSelectedPlayer();
2674 std::string namepart = args;
2675 std::wstring wnamepart;
2677 if(!Utf8toWStr(namepart,wnamepart))
2678 return false;
2680 // converting string that we try to find to lower case
2681 wstrToLower( wnamepart );
2683 uint32 counter = 0; // Counter for figure out that we found smth.
2685 // Search in Spell.dbc
2686 for (uint32 id = 0; id < sSpellStore.GetNumRows(); id++)
2688 SpellEntry const *spellInfo = sSpellStore.LookupEntry(id);
2689 if(spellInfo)
2691 int loc = m_session ? m_session->GetSessionDbcLocale() : sWorld.GetDefaultDbcLocale();
2692 std::string name = spellInfo->SpellName[loc];
2693 if(name.empty())
2694 continue;
2696 if (!Utf8FitTo(name, wnamepart))
2698 loc = 0;
2699 for(; loc < MAX_LOCALE; ++loc)
2701 if(m_session && loc==m_session->GetSessionDbcLocale())
2702 continue;
2704 name = spellInfo->SpellName[loc];
2705 if(name.empty())
2706 continue;
2708 if (Utf8FitTo(name, wnamepart))
2709 break;
2713 if(loc < MAX_LOCALE)
2715 bool known = target && target->HasSpell(id);
2716 bool learn = (spellInfo->Effect[0] == SPELL_EFFECT_LEARN_SPELL);
2718 uint32 talentCost = GetTalentSpellCost(id);
2720 bool talent = (talentCost > 0);
2721 bool passive = IsPassiveSpell(id);
2722 bool active = target && target->HasAura(id);
2724 // unit32 used to prevent interpreting uint8 as char at output
2725 // find rank of learned spell for learning spell, or talent rank
2726 uint32 rank = talentCost ? talentCost : spellmgr.GetSpellRank(learn ? spellInfo->EffectTriggerSpell[0] : id);
2728 // send spell in "id - [name, rank N] [talent] [passive] [learn] [known]" format
2729 std::ostringstream ss;
2730 if (m_session)
2731 ss << id << " - |cffffffff|Hspell:" << id << "|h[" << name;
2732 else
2733 ss << id << " - " << name;
2735 // include rank in link name
2736 if(rank)
2737 ss << GetMangosString(LANG_SPELL_RANK) << rank;
2739 if (m_session)
2740 ss << " " << localeNames[loc] << "]|h|r";
2741 else
2742 ss << " " << localeNames[loc];
2744 if(talent)
2745 ss << GetMangosString(LANG_TALENT);
2746 if(passive)
2747 ss << GetMangosString(LANG_PASSIVE);
2748 if(learn)
2749 ss << GetMangosString(LANG_LEARN);
2750 if(known)
2751 ss << GetMangosString(LANG_KNOWN);
2752 if(active)
2753 ss << GetMangosString(LANG_ACTIVE);
2755 SendSysMessage(ss.str().c_str());
2757 ++counter;
2761 if (counter == 0) // if counter == 0 then we found nth
2762 SendSysMessage(LANG_COMMAND_NOSPELLFOUND);
2763 return true;
2766 bool ChatHandler::HandleLookupQuestCommand(const char* args)
2768 if(!*args)
2769 return false;
2771 // can be NULL at console call
2772 Player* target = getSelectedPlayer();
2774 std::string namepart = args;
2775 std::wstring wnamepart;
2777 // converting string that we try to find to lower case
2778 if(!Utf8toWStr(namepart,wnamepart))
2779 return false;
2781 wstrToLower(wnamepart);
2783 uint32 counter = 0 ;
2785 ObjectMgr::QuestMap const& qTemplates = objmgr.GetQuestTemplates();
2786 for (ObjectMgr::QuestMap::const_iterator iter = qTemplates.begin(); iter != qTemplates.end(); ++iter)
2788 Quest * qinfo = iter->second;
2790 int loc_idx = m_session ? m_session->GetSessionDbLocaleIndex() : objmgr.GetDBCLocaleIndex();
2791 if ( loc_idx >= 0 )
2793 QuestLocale const *il = objmgr.GetQuestLocale(qinfo->GetQuestId());
2794 if (il)
2796 if (il->Title.size() > loc_idx && !il->Title[loc_idx].empty())
2798 std::string title = il->Title[loc_idx];
2800 if (Utf8FitTo(title, wnamepart))
2802 char const* statusStr = "";
2804 if(target)
2806 QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId());
2808 if(status == QUEST_STATUS_COMPLETE)
2810 if(target->GetQuestRewardStatus(qinfo->GetQuestId()))
2811 statusStr = GetMangosString(LANG_COMMAND_QUEST_REWARDED);
2812 else
2813 statusStr = GetMangosString(LANG_COMMAND_QUEST_COMPLETE);
2815 else if(status == QUEST_STATUS_INCOMPLETE)
2816 statusStr = GetMangosString(LANG_COMMAND_QUEST_ACTIVE);
2819 if (m_session)
2820 PSendSysMessage(LANG_QUEST_LIST_CHAT,qinfo->GetQuestId(),qinfo->GetQuestId(),title.c_str(),statusStr);
2821 else
2822 PSendSysMessage(LANG_QUEST_LIST_CONSOLE,qinfo->GetQuestId(),title.c_str(),statusStr);
2823 ++counter;
2824 continue;
2830 std::string title = qinfo->GetTitle();
2831 if(title.empty())
2832 continue;
2834 if (Utf8FitTo(title, wnamepart))
2836 char const* statusStr = "";
2838 if(target)
2840 QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId());
2842 if(status == QUEST_STATUS_COMPLETE)
2844 if(target->GetQuestRewardStatus(qinfo->GetQuestId()))
2845 statusStr = GetMangosString(LANG_COMMAND_QUEST_REWARDED);
2846 else
2847 statusStr = GetMangosString(LANG_COMMAND_QUEST_COMPLETE);
2849 else if(status == QUEST_STATUS_INCOMPLETE)
2850 statusStr = GetMangosString(LANG_COMMAND_QUEST_ACTIVE);
2853 if (m_session)
2854 PSendSysMessage(LANG_QUEST_LIST_CHAT,qinfo->GetQuestId(),qinfo->GetQuestId(),title.c_str(),statusStr);
2855 else
2856 PSendSysMessage(LANG_QUEST_LIST_CONSOLE,qinfo->GetQuestId(),title.c_str(),statusStr);
2858 ++counter;
2862 if (counter==0)
2863 SendSysMessage(LANG_COMMAND_NOQUESTFOUND);
2865 return true;
2868 bool ChatHandler::HandleLookupCreatureCommand(const char* args)
2870 if (!*args)
2871 return false;
2873 std::string namepart = args;
2874 std::wstring wnamepart;
2876 // converting string that we try to find to lower case
2877 if (!Utf8toWStr (namepart,wnamepart))
2878 return false;
2880 wstrToLower (wnamepart);
2882 uint32 counter = 0;
2884 for (uint32 id = 0; id< sCreatureStorage.MaxEntry; ++id)
2886 CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo> (id);
2887 if(!cInfo)
2888 continue;
2890 int loc_idx = m_session ? m_session->GetSessionDbLocaleIndex() : objmgr.GetDBCLocaleIndex();
2891 if (loc_idx >= 0)
2893 CreatureLocale const *cl = objmgr.GetCreatureLocale (id);
2894 if (cl)
2896 if (cl->Name.size() > loc_idx && !cl->Name[loc_idx].empty ())
2898 std::string name = cl->Name[loc_idx];
2900 if (Utf8FitTo (name, wnamepart))
2902 if (m_session)
2903 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CHAT, id, id, name.c_str ());
2904 else
2905 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CONSOLE, id, name.c_str ());
2906 ++counter;
2907 continue;
2913 std::string name = cInfo->Name;
2914 if (name.empty ())
2915 continue;
2917 if (Utf8FitTo(name, wnamepart))
2919 if (m_session)
2920 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CHAT, id, id, name.c_str ());
2921 else
2922 PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CONSOLE, id, name.c_str ());
2923 ++counter;
2927 if (counter==0)
2928 SendSysMessage (LANG_COMMAND_NOCREATUREFOUND);
2930 return true;
2933 bool ChatHandler::HandleLookupObjectCommand(const char* args)
2935 if(!*args)
2936 return false;
2938 std::string namepart = args;
2939 std::wstring wnamepart;
2941 // converting string that we try to find to lower case
2942 if(!Utf8toWStr(namepart,wnamepart))
2943 return false;
2945 wstrToLower(wnamepart);
2947 uint32 counter = 0;
2949 for (uint32 id = 0; id< sGOStorage.MaxEntry; id++ )
2951 GameObjectInfo const* gInfo = sGOStorage.LookupEntry<GameObjectInfo>(id);
2952 if(!gInfo)
2953 continue;
2955 int loc_idx = m_session ? m_session->GetSessionDbLocaleIndex() : objmgr.GetDBCLocaleIndex();
2956 if ( loc_idx >= 0 )
2958 GameObjectLocale const *gl = objmgr.GetGameObjectLocale(id);
2959 if (gl)
2961 if (gl->Name.size() > loc_idx && !gl->Name[loc_idx].empty())
2963 std::string name = gl->Name[loc_idx];
2965 if (Utf8FitTo(name, wnamepart))
2967 if (m_session)
2968 PSendSysMessage(LANG_GO_ENTRY_LIST_CHAT, id, id, name.c_str());
2969 else
2970 PSendSysMessage(LANG_GO_ENTRY_LIST_CONSOLE, id, name.c_str());
2971 ++counter;
2972 continue;
2978 std::string name = gInfo->name;
2979 if(name.empty())
2980 continue;
2982 if(Utf8FitTo(name, wnamepart))
2984 if (m_session)
2985 PSendSysMessage(LANG_GO_ENTRY_LIST_CHAT, id, id, name.c_str());
2986 else
2987 PSendSysMessage(LANG_GO_ENTRY_LIST_CONSOLE, id, name.c_str());
2988 ++counter;
2992 if(counter==0)
2993 SendSysMessage(LANG_COMMAND_NOGAMEOBJECTFOUND);
2995 return true;
2998 /** \brief GM command level 3 - Create a guild.
3000 * This command allows a GM (level 3) to create a guild.
3002 * The "args" parameter contains the name of the guild leader
3003 * and then the name of the guild.
3006 bool ChatHandler::HandleGuildCreateCommand(const char* args)
3009 if (!*args)
3010 return false;
3012 char *lname = strtok ((char*)args, " ");
3013 char *gname = strtok (NULL, "");
3015 if (!lname)
3016 return false;
3018 if (!gname)
3020 SendSysMessage (LANG_INSERT_GUILD_NAME);
3021 SetSentErrorMessage (true);
3022 return false;
3025 std::string guildname = gname;
3027 Player* player = ObjectAccessor::Instance ().FindPlayerByName (lname);
3028 if (!player)
3030 SendSysMessage (LANG_PLAYER_NOT_FOUND);
3031 SetSentErrorMessage (true);
3032 return false;
3035 if (player->GetGuildId())
3037 SendSysMessage (LANG_PLAYER_IN_GUILD);
3038 return true;
3041 Guild *guild = new Guild;
3042 if (!guild->create (player->GetGUID (),guildname))
3044 delete guild;
3045 SendSysMessage (LANG_GUILD_NOT_CREATED);
3046 SetSentErrorMessage (true);
3047 return false;
3050 objmgr.AddGuild (guild);
3051 return true;
3054 bool ChatHandler::HandleGuildInviteCommand(const char *args)
3056 if (!*args)
3057 return false;
3059 char* par1 = strtok ((char*)args, " ");
3060 char* par2 = strtok (NULL, "");
3061 if(!par1 || !par2)
3062 return false;
3064 std::string glName = par2;
3065 Guild* targetGuild = objmgr.GetGuildByName (glName);
3066 if (!targetGuild)
3067 return false;
3069 std::string plName = extractPlayerNameFromLink(par1);
3070 if(plName.empty())
3072 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3073 SetSentErrorMessage(true);
3074 return false;
3077 uint64 plGuid = 0;
3078 if (Player* targetPlayer = ObjectAccessor::Instance ().FindPlayerByName (plName.c_str ()))
3079 plGuid = targetPlayer->GetGUID ();
3080 else
3081 plGuid = objmgr.GetPlayerGUIDByName (plName);
3083 if (!plGuid)
3084 false;
3086 // player's guild membership checked in AddMember before add
3087 if (!targetGuild->AddMember (plGuid,targetGuild->GetLowestRank ()))
3088 return false;
3090 return true;
3093 bool ChatHandler::HandleGuildUninviteCommand(const char *args)
3095 if (!*args)
3096 return false;
3098 char* par1 = strtok ((char*)args, " ");
3099 if(!par1)
3100 return false;
3102 std::string plName = extractPlayerNameFromLink(par1);
3103 if(plName.empty())
3105 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3106 SetSentErrorMessage(true);
3107 return false;
3110 uint64 plGuid = 0;
3111 uint32 glId = 0;
3112 if (Player* targetPlayer = ObjectAccessor::Instance ().FindPlayerByName (plName.c_str ()))
3114 plGuid = targetPlayer->GetGUID ();
3115 glId = targetPlayer->GetGuildId ();
3117 else
3119 plGuid = objmgr.GetPlayerGUIDByName (plName);
3120 glId = Player::GetGuildIdFromDB (plGuid);
3123 if (!plGuid || !glId)
3124 return false;
3126 Guild* targetGuild = objmgr.GetGuildById (glId);
3127 if (!targetGuild)
3128 return false;
3130 targetGuild->DelMember (plGuid);
3132 return true;
3135 bool ChatHandler::HandleGuildRankCommand(const char *args)
3137 if (!*args)
3138 return false;
3140 char* par1 = strtok ((char*)args, " ");
3141 char* par2 = strtok (NULL, " ");
3142 if (!par1 || !par2)
3143 return false;
3145 std::string plName = extractPlayerNameFromLink(par1);
3146 if(plName.empty())
3148 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3149 SetSentErrorMessage(true);
3150 return false;
3154 uint64 plGuid = 0;
3155 uint32 glId = 0;
3156 if (Player* targetPlayer = ObjectAccessor::Instance ().FindPlayerByName (plName.c_str ()))
3158 plGuid = targetPlayer->GetGUID ();
3159 glId = targetPlayer->GetGuildId ();
3161 else
3163 plGuid = objmgr.GetPlayerGUIDByName (plName);
3164 glId = Player::GetGuildIdFromDB (plGuid);
3167 if (!plGuid || !glId)
3168 return false;
3170 Guild* targetGuild = objmgr.GetGuildById (glId);
3171 if (!targetGuild)
3172 return false;
3174 uint32 newrank = uint32 (atoi (par2));
3175 if (newrank > targetGuild->GetLowestRank ())
3176 return false;
3178 targetGuild->ChangeRank (plGuid,newrank);
3180 return true;
3183 bool ChatHandler::HandleGuildDeleteCommand(const char* args)
3185 if (!*args)
3186 return false;
3188 char* par1 = strtok ((char*)args, " ");
3189 if (!par1)
3190 return false;
3192 std::string gld = par1;
3194 Guild* targetGuild = objmgr.GetGuildByName (gld);
3195 if (!targetGuild)
3196 return false;
3198 targetGuild->Disband ();
3200 return true;
3203 bool ChatHandler::HandleGetDistanceCommand(const char* /*args*/)
3205 Unit* pUnit = getSelectedUnit();
3207 if(!pUnit)
3209 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3210 SetSentErrorMessage(true);
3211 return false;
3214 PSendSysMessage(LANG_DISTANCE, m_session->GetPlayer()->GetDistance(pUnit),m_session->GetPlayer()->GetDistance2d(pUnit));
3216 return true;
3219 // FIX-ME!!!
3221 bool ChatHandler::HandleAddWeaponCommand(const char* /*args*/)
3223 /*if (!*args)
3224 return false;
3226 uint64 guid = m_session->GetPlayer()->GetSelection();
3227 if (guid == 0)
3229 SendSysMessage(LANG_NO_SELECTION);
3230 return true;
3233 Creature *pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
3235 if(!pCreature)
3237 SendSysMessage(LANG_SELECT_CREATURE);
3238 return true;
3241 char* pSlotID = strtok((char*)args, " ");
3242 if (!pSlotID)
3243 return false;
3245 char* pItemID = strtok(NULL, " ");
3246 if (!pItemID)
3247 return false;
3249 uint32 ItemID = atoi(pItemID);
3250 uint32 SlotID = atoi(pSlotID);
3252 ItemPrototype* tmpItem = objmgr.GetItemPrototype(ItemID);
3254 bool added = false;
3255 if(tmpItem)
3257 switch(SlotID)
3259 case 1:
3260 pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, ItemID);
3261 added = true;
3262 break;
3263 case 2:
3264 pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_01, ItemID);
3265 added = true;
3266 break;
3267 case 3:
3268 pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_02, ItemID);
3269 added = true;
3270 break;
3271 default:
3272 PSendSysMessage(LANG_ITEM_SLOT_NOT_EXIST,SlotID);
3273 added = false;
3274 break;
3276 if(added)
3278 PSendSysMessage(LANG_ITEM_ADDED_TO_SLOT,ItemID,tmpItem->Name1,SlotID);
3281 else
3283 PSendSysMessage(LANG_ITEM_NOT_FOUND,ItemID);
3284 return true;
3287 return true;
3290 bool ChatHandler::HandleDieCommand(const char* /*args*/)
3292 Unit* target = getSelectedUnit();
3294 if(!target || !m_session->GetPlayer()->GetSelection())
3296 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3297 SetSentErrorMessage(true);
3298 return false;
3301 if(target->GetTypeId()==TYPEID_PLAYER)
3303 if(HasLowerSecurity((Player*)target,0,false))
3304 return false;
3307 if( target->isAlive() )
3309 m_session->GetPlayer()->DealDamage(target, target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
3312 return true;
3315 bool ChatHandler::HandleDamageCommand(const char * args)
3317 if (!*args)
3318 return false;
3320 Unit* target = getSelectedUnit();
3322 if(!target || !m_session->GetPlayer()->GetSelection())
3324 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3325 SetSentErrorMessage(true);
3326 return false;
3329 if( !target->isAlive() )
3330 return true;
3332 char* damageStr = strtok((char*)args, " ");
3333 if(!damageStr)
3334 return false;
3336 int32 damage = atoi((char*)damageStr);
3337 if(damage <=0)
3338 return true;
3340 char* schoolStr = strtok((char*)NULL, " ");
3342 // flat melee damage without resistence/etc reduction
3343 if(!schoolStr)
3345 m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
3346 m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, SPELL_SCHOOL_MASK_NORMAL, damage, 0, 0, VICTIMSTATE_NORMAL, 0);
3347 return true;
3350 uint32 school = schoolStr ? atoi((char*)schoolStr) : SPELL_SCHOOL_NORMAL;
3351 if(school >= MAX_SPELL_SCHOOL)
3352 return false;
3354 SpellSchoolMask schoolmask = SpellSchoolMask(1 << school);
3356 if ( schoolmask & SPELL_SCHOOL_MASK_NORMAL )
3357 damage = m_session->GetPlayer()->CalcArmorReducedDamage(target, damage);
3359 char* spellStr = strtok((char*)NULL, " ");
3361 // melee damage by specific school
3362 if(!spellStr)
3364 uint32 absorb = 0;
3365 uint32 resist = 0;
3367 m_session->GetPlayer()->CalcAbsorbResist(target,schoolmask, SPELL_DIRECT_DAMAGE, damage, &absorb, &resist);
3369 if (damage <= absorb + resist)
3370 return true;
3372 damage -= absorb + resist;
3374 m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, schoolmask, NULL, false);
3375 m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, schoolmask, damage, absorb, resist, VICTIMSTATE_NORMAL, 0);
3376 return true;
3379 // non-melee damage
3381 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
3382 uint32 spellid = extractSpellIdFromLink((char*)args);
3383 if(!spellid || !sSpellStore.LookupEntry(spellid))
3384 return false;
3386 m_session->GetPlayer()->SpellNonMeleeDamageLog(target, spellid, damage, false);
3387 return true;
3390 bool ChatHandler::HandleModifyArenaCommand(const char * args)
3392 if (!*args)
3393 return false;
3395 Player *target = getSelectedPlayer();
3396 if(!target)
3398 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3399 SetSentErrorMessage(true);
3400 return false;
3403 int32 amount = (uint32)atoi(args);
3405 target->ModifyArenaPoints(amount);
3407 PSendSysMessage(LANG_COMMAND_MODIFY_ARENA, GetNameLink(target).c_str(), target->GetArenaPoints());
3409 return true;
3412 bool ChatHandler::HandleReviveCommand(const char* args)
3414 Player* SelectedPlayer = NULL;
3416 if (*args)
3418 std::string name = extractPlayerNameFromLink((char*)args);
3419 if(name.empty())
3421 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3422 SetSentErrorMessage(true);
3423 return false;
3426 SelectedPlayer = objmgr.GetPlayer(name.c_str());
3428 else
3429 SelectedPlayer = getSelectedPlayer();
3431 if(!SelectedPlayer)
3433 SendSysMessage(LANG_NO_CHAR_SELECTED);
3434 SetSentErrorMessage(true);
3435 return false;
3438 SelectedPlayer->ResurrectPlayer(0.5f);
3439 SelectedPlayer->SpawnCorpseBones();
3440 SelectedPlayer->SaveToDB();
3441 return true;
3444 bool ChatHandler::HandleAuraCommand(const char* args)
3446 Unit *target = getSelectedUnit();
3447 if(!target)
3449 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3450 SetSentErrorMessage(true);
3451 return false;
3454 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
3455 uint32 spellID = extractSpellIdFromLink((char*)args);
3457 SpellEntry const *spellInfo = sSpellStore.LookupEntry( spellID );
3458 if(spellInfo)
3460 for(uint32 i = 0;i<3;i++)
3462 uint8 eff = spellInfo->Effect[i];
3463 if (eff>=TOTAL_SPELL_EFFECTS)
3464 continue;
3465 if( IsAreaAuraEffect(eff) ||
3466 eff == SPELL_EFFECT_APPLY_AURA ||
3467 eff == SPELL_EFFECT_PERSISTENT_AREA_AURA )
3469 Aura *Aur = CreateAura(spellInfo, i, NULL, target);
3470 target->AddAura(Aur);
3475 return true;
3478 bool ChatHandler::HandleUnAuraCommand(const char* args)
3480 Unit *target = getSelectedUnit();
3481 if(!target)
3483 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3484 SetSentErrorMessage(true);
3485 return false;
3488 std::string argstr = args;
3489 if (argstr == "all")
3491 target->RemoveAllAuras();
3492 return true;
3495 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
3496 uint32 spellID = extractSpellIdFromLink((char*)args);
3497 if(!spellID)
3498 return false;
3500 target->RemoveAurasDueToSpell(spellID);
3502 return true;
3505 bool ChatHandler::HandleLinkGraveCommand(const char* args)
3507 if(!*args)
3508 return false;
3510 char* px = strtok((char*)args, " ");
3511 if (!px)
3512 return false;
3514 uint32 g_id = (uint32)atoi(px);
3516 uint32 g_team;
3518 char* px2 = strtok(NULL, " ");
3520 if (!px2)
3521 g_team = 0;
3522 else if (strncmp(px2,"horde",6)==0)
3523 g_team = HORDE;
3524 else if (strncmp(px2,"alliance",9)==0)
3525 g_team = ALLIANCE;
3526 else
3527 return false;
3529 WorldSafeLocsEntry const* graveyard = sWorldSafeLocsStore.LookupEntry(g_id);
3531 if(!graveyard )
3533 PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST, g_id);
3534 SetSentErrorMessage(true);
3535 return false;
3538 Player* player = m_session->GetPlayer();
3540 uint32 zoneId = player->GetZoneId();
3542 AreaTableEntry const *areaEntry = GetAreaEntryByAreaID(zoneId);
3543 if(!areaEntry || areaEntry->zone !=0 )
3545 PSendSysMessage(LANG_COMMAND_GRAVEYARDWRONGZONE, g_id,zoneId);
3546 SetSentErrorMessage(true);
3547 return false;
3550 if(objmgr.AddGraveYardLink(g_id,player->GetZoneId(),g_team))
3551 PSendSysMessage(LANG_COMMAND_GRAVEYARDLINKED, g_id,zoneId);
3552 else
3553 PSendSysMessage(LANG_COMMAND_GRAVEYARDALRLINKED, g_id,zoneId);
3555 return true;
3558 bool ChatHandler::HandleNearGraveCommand(const char* args)
3560 uint32 g_team;
3562 size_t argslen = strlen(args);
3564 if(!*args)
3565 g_team = 0;
3566 else if (strncmp((char*)args,"horde",argslen)==0)
3567 g_team = HORDE;
3568 else if (strncmp((char*)args,"alliance",argslen)==0)
3569 g_team = ALLIANCE;
3570 else
3571 return false;
3573 Player* player = m_session->GetPlayer();
3575 WorldSafeLocsEntry const* graveyard = objmgr.GetClosestGraveYard(
3576 player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(),player->GetMapId(),g_team);
3578 if(graveyard)
3580 uint32 g_id = graveyard->ID;
3582 GraveYardData const* data = objmgr.FindGraveYardData(g_id,player->GetZoneId());
3583 if (!data)
3585 PSendSysMessage(LANG_COMMAND_GRAVEYARDERROR,g_id);
3586 SetSentErrorMessage(true);
3587 return false;
3590 g_team = data->team;
3592 std::string team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_NOTEAM);
3594 if(g_team == 0)
3595 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ANY);
3596 else if(g_team == HORDE)
3597 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_HORDE);
3598 else if(g_team == ALLIANCE)
3599 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ALLIANCE);
3601 PSendSysMessage(LANG_COMMAND_GRAVEYARDNEAREST, g_id,team_name.c_str(),player->GetZoneId());
3603 else
3605 std::string team_name;
3607 if(g_team == 0)
3608 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ANY);
3609 else if(g_team == HORDE)
3610 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_HORDE);
3611 else if(g_team == ALLIANCE)
3612 team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ALLIANCE);
3614 if(g_team == ~uint32(0))
3615 PSendSysMessage(LANG_COMMAND_ZONENOGRAVEYARDS, player->GetZoneId());
3616 else
3617 PSendSysMessage(LANG_COMMAND_ZONENOGRAFACTION, player->GetZoneId(),team_name.c_str());
3620 return true;
3623 //play npc emote
3624 bool ChatHandler::HandleNpcPlayEmoteCommand(const char* args)
3626 uint32 emote = atoi((char*)args);
3628 Creature* target = getSelectedCreature();
3629 if(!target)
3631 SendSysMessage(LANG_SELECT_CREATURE);
3632 SetSentErrorMessage(true);
3633 return false;
3636 target->SetUInt32Value(UNIT_NPC_EMOTESTATE,emote);
3638 return true;
3641 bool ChatHandler::HandleNpcInfoCommand(const char* /*args*/)
3643 Creature* target = getSelectedCreature();
3645 if(!target)
3647 SendSysMessage(LANG_SELECT_CREATURE);
3648 SetSentErrorMessage(true);
3649 return false;
3652 uint32 faction = target->getFaction();
3653 uint32 npcflags = target->GetUInt32Value(UNIT_NPC_FLAGS);
3654 uint32 displayid = target->GetDisplayId();
3655 uint32 nativeid = target->GetNativeDisplayId();
3656 uint32 Entry = target->GetEntry();
3657 CreatureInfo const* cInfo = target->GetCreatureInfo();
3659 int32 curRespawnDelay = target->GetRespawnTimeEx()-time(NULL);
3660 if(curRespawnDelay < 0)
3661 curRespawnDelay = 0;
3662 std::string curRespawnDelayStr = secsToTimeString(curRespawnDelay,true);
3663 std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(),true);
3665 PSendSysMessage(LANG_NPCINFO_CHAR, target->GetDBTableGUIDLow(), faction, npcflags, Entry, displayid, nativeid);
3666 PSendSysMessage(LANG_NPCINFO_LEVEL, target->getLevel());
3667 PSendSysMessage(LANG_NPCINFO_HEALTH,target->GetCreateHealth(), target->GetMaxHealth(), target->GetHealth());
3668 PSendSysMessage(LANG_NPCINFO_FLAGS, target->GetUInt32Value(UNIT_FIELD_FLAGS), target->GetUInt32Value(UNIT_DYNAMIC_FLAGS), target->getFaction());
3669 PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES, defRespawnDelayStr.c_str(),curRespawnDelayStr.c_str());
3670 PSendSysMessage(LANG_NPCINFO_LOOT, cInfo->lootid,cInfo->pickpocketLootId,cInfo->SkinLootId);
3671 PSendSysMessage(LANG_NPCINFO_DUNGEON_ID, target->GetInstanceId());
3672 PSendSysMessage(LANG_NPCINFO_POSITION,float(target->GetPositionX()), float(target->GetPositionY()), float(target->GetPositionZ()));
3674 if ((npcflags & UNIT_NPC_FLAG_VENDOR) )
3676 SendSysMessage(LANG_NPCINFO_VENDOR);
3678 if ((npcflags & UNIT_NPC_FLAG_TRAINER) )
3680 SendSysMessage(LANG_NPCINFO_TRAINER);
3683 return true;
3686 bool ChatHandler::HandleExploreCheatCommand(const char* args)
3688 if (!*args)
3689 return false;
3691 int flag = atoi((char*)args);
3693 Player *chr = getSelectedPlayer();
3694 if (chr == NULL)
3696 SendSysMessage(LANG_NO_CHAR_SELECTED);
3697 SetSentErrorMessage(true);
3698 return false;
3701 if (flag != 0)
3703 PSendSysMessage(LANG_YOU_SET_EXPLORE_ALL, GetNameLink(chr).c_str());
3704 if (needReportToTarget(chr))
3705 ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_ALL,GetNameLink().c_str());
3707 else
3709 PSendSysMessage(LANG_YOU_SET_EXPLORE_NOTHING, GetNameLink(chr).c_str());
3710 if (needReportToTarget(chr))
3711 ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_NOTHING,GetNameLink().c_str());
3714 for (uint8 i=0; i<128; i++)
3716 if (flag != 0)
3718 m_session->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i,0xFFFFFFFF);
3720 else
3722 m_session->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i,0);
3726 return true;
3729 bool ChatHandler::HandleHoverCommand(const char* args)
3731 char* px = strtok((char*)args, " ");
3732 uint32 flag;
3733 if (!px)
3734 flag = 1;
3735 else
3736 flag = atoi(px);
3738 m_session->GetPlayer()->SetHover(flag);
3740 if (flag)
3741 SendSysMessage(LANG_HOVER_ENABLED);
3742 else
3743 SendSysMessage(LANG_HOVER_DISABLED);
3745 return true;
3748 bool ChatHandler::HandleLevelUpCommand(const char* args)
3750 char* px = strtok((char*)args, " ");
3751 char* py = strtok((char*)NULL, " ");
3753 // command format parsing
3754 char* pname = (char*)NULL;
3755 int addlevel = 1;
3757 if(px && py) // .levelup name level
3759 addlevel = atoi(py);
3760 pname = px;
3762 else if(px && !py) // .levelup name OR .levelup level
3764 if(isalpha(px[0])) // .levelup name
3765 pname = px;
3766 else // .levelup level
3767 addlevel = atoi(px);
3769 // else .levelup - nothing do for preparing
3771 // player
3772 Player *chr = NULL;
3773 uint64 chr_guid = 0;
3775 std::string name;
3777 if(pname) // player by name
3779 name = extractPlayerNameFromLink(pname);
3780 if(name.empty())
3782 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3783 SetSentErrorMessage(true);
3784 return false;
3787 chr = objmgr.GetPlayer(name.c_str());
3788 if(!chr) // not in game
3790 chr_guid = objmgr.GetPlayerGUIDByName(name);
3791 if (chr_guid == 0)
3793 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3794 SetSentErrorMessage(true);
3795 return false;
3799 else // player by selection
3801 chr = getSelectedPlayer();
3803 if (chr == NULL)
3805 SendSysMessage(LANG_NO_CHAR_SELECTED);
3806 SetSentErrorMessage(true);
3807 return false;
3810 name = GetNameLink(chr);
3813 assert(chr || chr_guid);
3815 int32 oldlevel = chr ? chr->getLevel() : Player::GetUInt32ValueFromDB(UNIT_FIELD_LEVEL,chr_guid);
3816 int32 newlevel = oldlevel + addlevel;
3817 if(newlevel < 1)
3818 newlevel = 1;
3819 if(newlevel > STRONG_MAX_LEVEL) // hardcoded maximum level
3820 newlevel = STRONG_MAX_LEVEL;
3822 if(chr)
3824 chr->GiveLevel(newlevel);
3825 chr->InitTalentForLevel();
3826 chr->SetUInt32Value(PLAYER_XP,0);
3828 if(oldlevel == newlevel)
3829 ChatHandler(chr).SendSysMessage(LANG_YOURS_LEVEL_PROGRESS_RESET);
3830 else
3831 if(oldlevel < newlevel)
3832 ChatHandler(chr).PSendSysMessage(LANG_YOURS_LEVEL_UP,newlevel-oldlevel);
3833 else
3834 if(oldlevel > newlevel)
3835 ChatHandler(chr).PSendSysMessage(LANG_YOURS_LEVEL_DOWN,newlevel-oldlevel);
3837 else
3839 // update level and XP at level, all other will be updated at loading
3840 Tokens values;
3841 Player::LoadValuesArrayFromDB(values,chr_guid);
3842 Player::SetUInt32ValueInArray(values,UNIT_FIELD_LEVEL,newlevel);
3843 Player::SetUInt32ValueInArray(values,PLAYER_XP,0);
3844 Player::SaveValuesArrayInDB(values,chr_guid);
3847 if(m_session->GetPlayer() != chr) // including chr==NULL
3849 std::string nameLink = playerLink(name);
3850 PSendSysMessage(LANG_YOU_CHANGE_LVL,nameLink.c_str(),newlevel);
3852 return true;
3855 bool ChatHandler::HandleShowAreaCommand(const char* args)
3857 if (!*args)
3858 return false;
3860 Player *chr = getSelectedPlayer();
3861 if (chr == NULL)
3863 SendSysMessage(LANG_NO_CHAR_SELECTED);
3864 SetSentErrorMessage(true);
3865 return false;
3868 int area = GetAreaFlagByAreaID(atoi((char*)args));
3869 int offset = area / 32;
3870 uint32 val = (uint32)(1 << (area % 32));
3872 if(area<0 || offset >= 128)
3874 SendSysMessage(LANG_BAD_VALUE);
3875 SetSentErrorMessage(true);
3876 return false;
3879 uint32 currFields = chr->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset);
3880 chr->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields | val));
3882 SendSysMessage(LANG_EXPLORE_AREA);
3883 return true;
3886 bool ChatHandler::HandleHideAreaCommand(const char* args)
3888 if (!*args)
3889 return false;
3891 Player *chr = getSelectedPlayer();
3892 if (chr == NULL)
3894 SendSysMessage(LANG_NO_CHAR_SELECTED);
3895 SetSentErrorMessage(true);
3896 return false;
3899 int area = GetAreaFlagByAreaID(atoi((char*)args));
3900 int offset = area / 32;
3901 uint32 val = (uint32)(1 << (area % 32));
3903 if(area<0 || offset >= 128)
3905 SendSysMessage(LANG_BAD_VALUE);
3906 SetSentErrorMessage(true);
3907 return false;
3910 uint32 currFields = chr->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset);
3911 chr->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields ^ val));
3913 SendSysMessage(LANG_UNEXPLORE_AREA);
3914 return true;
3917 bool ChatHandler::HandleUpdate(const char* args)
3919 if(!*args)
3920 return false;
3922 uint32 updateIndex;
3923 uint32 value;
3925 char* pUpdateIndex = strtok((char*)args, " ");
3927 Unit* chr = getSelectedUnit();
3928 if (chr == NULL)
3930 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3931 SetSentErrorMessage(true);
3932 return false;
3935 if(!pUpdateIndex)
3937 return true;
3939 updateIndex = atoi(pUpdateIndex);
3940 //check updateIndex
3941 if(chr->GetTypeId() == TYPEID_PLAYER)
3943 if (updateIndex>=PLAYER_END) return true;
3945 else
3947 if (updateIndex>=UNIT_END) return true;
3950 char* pvalue = strtok(NULL, " ");
3951 if (!pvalue)
3953 value=chr->GetUInt32Value(updateIndex);
3955 PSendSysMessage(LANG_UPDATE, chr->GetGUIDLow(),updateIndex,value);
3956 return true;
3959 value=atoi(pvalue);
3961 PSendSysMessage(LANG_UPDATE_CHANGE, chr->GetGUIDLow(),updateIndex,value);
3963 chr->SetUInt32Value(updateIndex,value);
3965 return true;
3968 bool ChatHandler::HandleBankCommand(const char* /*args*/)
3970 m_session->SendShowBank( m_session->GetPlayer()->GetGUID() );
3972 return true;
3975 bool ChatHandler::HandleChangeWeather(const char* args)
3977 if(!*args)
3978 return false;
3980 //Weather is OFF
3981 if (!sWorld.getConfig(CONFIG_WEATHER))
3983 SendSysMessage(LANG_WEATHER_DISABLED);
3984 SetSentErrorMessage(true);
3985 return false;
3988 //*Change the weather of a cell
3989 char* px = strtok((char*)args, " ");
3990 char* py = strtok(NULL, " ");
3992 if (!px || !py)
3993 return false;
3995 uint32 type = (uint32)atoi(px); //0 to 3, 0: fine, 1: rain, 2: snow, 3: sand
3996 float grade = (float)atof(py); //0 to 1, sending -1 is instand good weather
3998 Player *player = m_session->GetPlayer();
3999 uint32 zoneid = player->GetZoneId();
4001 Weather* wth = sWorld.FindWeather(zoneid);
4003 if(!wth)
4004 wth = sWorld.AddWeather(zoneid);
4005 if(!wth)
4007 SendSysMessage(LANG_NO_WEATHER);
4008 SetSentErrorMessage(true);
4009 return false;
4012 wth->SetWeather(WeatherType(type), grade);
4014 return true;
4017 bool ChatHandler::HandleSetValue(const char* args)
4019 if(!*args)
4020 return false;
4022 char* px = strtok((char*)args, " ");
4023 char* py = strtok(NULL, " ");
4024 char* pz = strtok(NULL, " ");
4026 if (!px || !py)
4027 return false;
4029 Unit* target = getSelectedUnit();
4030 if(!target)
4032 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
4033 SetSentErrorMessage(true);
4034 return false;
4037 uint64 guid = target->GetGUID();
4039 uint32 Opcode = (uint32)atoi(px);
4040 if(Opcode >= target->GetValuesCount())
4042 PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, GUID_LOPART(guid), target->GetValuesCount());
4043 return false;
4045 uint32 iValue;
4046 float fValue;
4047 bool isint32 = true;
4048 if(pz)
4049 isint32 = (bool)atoi(pz);
4050 if(isint32)
4052 iValue = (uint32)atoi(py);
4053 sLog.outDebug(GetMangosString(LANG_SET_UINT), GUID_LOPART(guid), Opcode, iValue);
4054 target->SetUInt32Value( Opcode , iValue );
4055 PSendSysMessage(LANG_SET_UINT_FIELD, GUID_LOPART(guid), Opcode,iValue);
4057 else
4059 fValue = (float)atof(py);
4060 sLog.outDebug(GetMangosString(LANG_SET_FLOAT), GUID_LOPART(guid), Opcode, fValue);
4061 target->SetFloatValue( Opcode , fValue );
4062 PSendSysMessage(LANG_SET_FLOAT_FIELD, GUID_LOPART(guid), Opcode,fValue);
4065 return true;
4068 bool ChatHandler::HandleGetValue(const char* args)
4070 if(!*args)
4071 return false;
4073 char* px = strtok((char*)args, " ");
4074 char* pz = strtok(NULL, " ");
4076 if (!px)
4077 return false;
4079 Unit* target = getSelectedUnit();
4080 if(!target)
4082 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
4083 SetSentErrorMessage(true);
4084 return false;
4087 uint64 guid = target->GetGUID();
4089 uint32 Opcode = (uint32)atoi(px);
4090 if(Opcode >= target->GetValuesCount())
4092 PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, GUID_LOPART(guid), target->GetValuesCount());
4093 return false;
4095 uint32 iValue;
4096 float fValue;
4097 bool isint32 = true;
4098 if(pz)
4099 isint32 = (bool)atoi(pz);
4101 if(isint32)
4103 iValue = target->GetUInt32Value( Opcode );
4104 sLog.outDebug(GetMangosString(LANG_GET_UINT), GUID_LOPART(guid), Opcode, iValue);
4105 PSendSysMessage(LANG_GET_UINT_FIELD, GUID_LOPART(guid), Opcode, iValue);
4107 else
4109 fValue = target->GetFloatValue( Opcode );
4110 sLog.outDebug(GetMangosString(LANG_GET_FLOAT), GUID_LOPART(guid), Opcode, fValue);
4111 PSendSysMessage(LANG_GET_FLOAT_FIELD, GUID_LOPART(guid), Opcode, fValue);
4114 return true;
4117 bool ChatHandler::HandleSet32Bit(const char* args)
4119 if(!*args)
4120 return false;
4122 char* px = strtok((char*)args, " ");
4123 char* py = strtok(NULL, " ");
4125 if (!px || !py)
4126 return false;
4128 uint32 Opcode = (uint32)atoi(px);
4129 uint32 Value = (uint32)atoi(py);
4130 if (Value > 32) //uint32 = 32 bits
4131 return false;
4133 sLog.outDebug(GetMangosString(LANG_SET_32BIT), Opcode, Value);
4135 m_session->GetPlayer( )->SetUInt32Value( Opcode , 2^Value );
4137 PSendSysMessage(LANG_SET_32BIT_FIELD, Opcode,1);
4138 return true;
4141 bool ChatHandler::HandleMod32Value(const char* args)
4143 if(!*args)
4144 return false;
4146 char* px = strtok((char*)args, " ");
4147 char* py = strtok(NULL, " ");
4149 if (!px || !py)
4150 return false;
4152 uint32 Opcode = (uint32)atoi(px);
4153 int Value = atoi(py);
4155 if(Opcode >= m_session->GetPlayer()->GetValuesCount())
4157 PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, m_session->GetPlayer()->GetGUIDLow(), m_session->GetPlayer( )->GetValuesCount());
4158 return false;
4161 sLog.outDebug(GetMangosString(LANG_CHANGE_32BIT), Opcode, Value);
4163 int CurrentValue = (int)m_session->GetPlayer( )->GetUInt32Value( Opcode );
4165 CurrentValue += Value;
4166 m_session->GetPlayer( )->SetUInt32Value( Opcode , (uint32)CurrentValue );
4168 PSendSysMessage(LANG_CHANGE_32BIT_FIELD, Opcode,CurrentValue);
4170 return true;
4173 bool ChatHandler::HandleAddTeleCommand(const char * args)
4175 if(!*args)
4176 return false;
4178 Player *player=m_session->GetPlayer();
4179 if (!player)
4180 return false;
4182 std::string name = args;
4184 if(objmgr.GetGameTele(name))
4186 SendSysMessage(LANG_COMMAND_TP_ALREADYEXIST);
4187 SetSentErrorMessage(true);
4188 return false;
4191 GameTele tele;
4192 tele.position_x = player->GetPositionX();
4193 tele.position_y = player->GetPositionY();
4194 tele.position_z = player->GetPositionZ();
4195 tele.orientation = player->GetOrientation();
4196 tele.mapId = player->GetMapId();
4197 tele.name = name;
4199 if(objmgr.AddGameTele(tele))
4201 SendSysMessage(LANG_COMMAND_TP_ADDED);
4203 else
4205 SendSysMessage(LANG_COMMAND_TP_ADDEDERR);
4206 SetSentErrorMessage(true);
4207 return false;
4210 return true;
4213 bool ChatHandler::HandleDelTeleCommand(const char * args)
4215 if(!*args)
4216 return false;
4218 std::string name = args;
4220 if(!objmgr.DeleteGameTele(name))
4222 SendSysMessage(LANG_COMMAND_TELE_NOTFOUND);
4223 SetSentErrorMessage(true);
4224 return false;
4227 SendSysMessage(LANG_COMMAND_TP_DELETED);
4228 return true;
4231 bool ChatHandler::HandleListAurasCommand (const char * /*args*/)
4233 Unit *unit = getSelectedUnit();
4234 if(!unit)
4236 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
4237 SetSentErrorMessage(true);
4238 return false;
4241 char const* talentStr = GetMangosString(LANG_TALENT);
4242 char const* passiveStr = GetMangosString(LANG_PASSIVE);
4244 Unit::AuraMap const& uAuras = unit->GetAuras();
4245 PSendSysMessage(LANG_COMMAND_TARGET_LISTAURAS, uAuras.size());
4246 for (Unit::AuraMap::const_iterator itr = uAuras.begin(); itr != uAuras.end(); ++itr)
4248 bool talent = GetTalentSpellCost(itr->second->GetId()) > 0;
4250 char const* name = itr->second->GetSpellProto()->SpellName[m_session->GetSessionDbcLocale()];
4252 if (m_session)
4254 std::ostringstream ss_name;
4255 ss_name << "|cffffffff|Hspell:" << itr->second->GetId() << "|h[" << name << "]|h|r";
4257 PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffIndex(),
4258 itr->second->GetModifier()->m_auraname, itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(),
4259 ss_name.str().c_str(),
4260 (itr->second->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
4261 IS_PLAYER_GUID(itr->second->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(itr->second->GetCasterGUID()));
4263 else
4265 PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffIndex(),
4266 itr->second->GetModifier()->m_auraname, itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(),
4267 name,
4268 (itr->second->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
4269 IS_PLAYER_GUID(itr->second->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(itr->second->GetCasterGUID()));
4272 for (int i = 0; i < TOTAL_AURAS; i++)
4274 Unit::AuraList const& uAuraList = unit->GetAurasByType(AuraType(i));
4275 if (uAuraList.empty()) continue;
4276 PSendSysMessage(LANG_COMMAND_TARGET_LISTAURATYPE, uAuraList.size(), i);
4277 for (Unit::AuraList::const_iterator itr = uAuraList.begin(); itr != uAuraList.end(); ++itr)
4279 bool talent = GetTalentSpellCost((*itr)->GetId()) > 0;
4281 char const* name = (*itr)->GetSpellProto()->SpellName[m_session->GetSessionDbcLocale()];
4283 if (m_session)
4285 std::ostringstream ss_name;
4286 ss_name << "|cffffffff|Hspell:" << (*itr)->GetId() << "|h[" << name << "]|h|r";
4288 PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(),
4289 ss_name.str().c_str(),((*itr)->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
4290 IS_PLAYER_GUID((*itr)->GetCasterGUID()) ? "player" : "creature",GUID_LOPART((*itr)->GetCasterGUID()));
4292 else
4294 PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(),
4295 name,((*itr)->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
4296 IS_PLAYER_GUID((*itr)->GetCasterGUID()) ? "player" : "creature",GUID_LOPART((*itr)->GetCasterGUID()));
4300 return true;
4303 bool ChatHandler::HandleResetAchievementsCommand (const char * args)
4305 char* pName = strtok((char*)args, "");
4306 Player *player = NULL;
4307 uint64 guid = 0;
4308 if (pName)
4310 std::string name = extractPlayerNameFromLink(pName);
4311 if(name.empty())
4313 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4314 SetSentErrorMessage(true);
4315 return false;
4318 guid = objmgr.GetPlayerGUIDByName(name);
4319 player = objmgr.GetPlayer(guid);
4321 else
4323 player = getSelectedPlayer();
4324 if(player)
4325 guid = player->GetGUID();
4328 if(!player && !guid)
4330 SendSysMessage(LANG_NO_CHAR_SELECTED);
4331 return true;
4334 if(player)
4335 player->GetAchievementMgr().Reset();
4336 else if(guid)
4337 AchievementMgr::DeleteFromDB(GUID_LOPART(guid));
4339 return true;
4342 bool ChatHandler::HandleResetHonorCommand (const char * args)
4344 char* pName = strtok((char*)args, "");
4345 Player *player = NULL;
4346 if (pName)
4348 std::string name = extractPlayerNameFromLink(pName);
4349 if(name.empty())
4351 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4352 SetSentErrorMessage(true);
4353 return false;
4356 uint64 guid = objmgr.GetPlayerGUIDByName(name);
4357 player = objmgr.GetPlayer(guid);
4359 else
4360 player = getSelectedPlayer();
4362 if(!player)
4364 SendSysMessage(LANG_NO_CHAR_SELECTED);
4365 return true;
4368 player->SetUInt32Value(PLAYER_FIELD_KILLS, 0);
4369 player->SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORBALE_KILLS, 0);
4370 player->SetUInt32Value(PLAYER_FIELD_HONOR_CURRENCY, 0);
4371 player->SetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, 0);
4372 player->SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, 0);
4374 return true;
4377 static bool HandleResetStatsOrLevelHelper(Player* player)
4379 PlayerInfo const *info = objmgr.GetPlayerInfo(player->getRace(), player->getClass());
4380 if(!info) return false;
4382 ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(player->getClass());
4383 if(!cEntry)
4385 sLog.outError("Class %u not found in DBC (Wrong DBC files?)",player->getClass());
4386 return false;
4389 uint8 powertype = cEntry->powerType;
4391 // reset m_form if no aura
4392 if(!player->HasAuraType(SPELL_AURA_MOD_SHAPESHIFT))
4393 player->m_form = FORM_NONE;
4395 player->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE );
4396 player->SetFloatValue(UNIT_FIELD_COMBATREACH, 1.5f );
4398 player->setFactionForRace(player->getRace());
4400 player->SetUInt32Value(UNIT_FIELD_BYTES_0, ( ( player->getRace() ) | ( player->getClass() << 8 ) | ( player->getGender() << 16 ) | ( powertype << 24 ) ) );
4402 // reset only if player not in some form;
4403 if(player->m_form==FORM_NONE)
4405 switch(player->getGender())
4407 case GENDER_FEMALE:
4408 player->SetDisplayId(info->displayId_f);
4409 player->SetNativeDisplayId(info->displayId_f);
4410 break;
4411 case GENDER_MALE:
4412 player->SetDisplayId(info->displayId_m);
4413 player->SetNativeDisplayId(info->displayId_m);
4414 break;
4415 default:
4416 break;
4420 player->SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP );
4421 player->SetByteValue(UNIT_FIELD_BYTES_2, 3, player->m_form);
4423 player->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
4425 //-1 is default value
4426 player->SetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, uint32(-1));
4428 //player->SetUInt32Value(PLAYER_FIELD_BYTES, 0xEEE00000 );
4429 return true;
4432 bool ChatHandler::HandleResetLevelCommand(const char * args)
4434 char* pName = strtok((char*)args, "");
4435 Player *player = NULL;
4436 if (pName)
4438 std::string name = extractPlayerNameFromLink(pName);
4439 if(name.empty())
4441 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4442 SetSentErrorMessage(true);
4443 return false;
4446 uint64 guid = objmgr.GetPlayerGUIDByName(name);
4447 player = objmgr.GetPlayer(guid);
4449 else
4450 player = getSelectedPlayer();
4452 if(!player)
4454 SendSysMessage(LANG_NO_CHAR_SELECTED);
4455 SetSentErrorMessage(true);
4456 return false;
4459 if(!HandleResetStatsOrLevelHelper(player))
4460 return false;
4462 // set starting level
4463 uint32 start_level = player->getClass() != CLASS_DEATH_KNIGHT
4464 ? sWorld.getConfig(CONFIG_START_PLAYER_LEVEL)
4465 : sWorld.getConfig(CONFIG_START_HEROIC_PLAYER_LEVEL);
4467 player->SetLevel(start_level);
4468 player->InitRunes();
4469 player->InitStatsForLevel(true);
4470 player->InitTaxiNodesForLevel();
4471 player->InitGlyphsForLevel();
4472 player->InitTalentForLevel();
4473 player->SetUInt32Value(PLAYER_XP,0);
4475 // reset level to summoned pet
4476 Pet* pet = player->GetPet();
4477 if(pet && pet->getPetType()==SUMMON_PET)
4479 pet->InitStatsForLevel(1);
4480 pet->InitTalentForLevel();
4482 return true;
4485 bool ChatHandler::HandleResetStatsCommand(const char * args)
4487 char* pName = strtok((char*)args, "");
4488 Player *player = NULL;
4489 if (pName)
4491 std::string name = extractPlayerNameFromLink(pName);
4492 if(name.empty())
4494 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4495 SetSentErrorMessage(true);
4496 return false;
4499 uint64 guid = objmgr.GetPlayerGUIDByName(name);
4500 player = objmgr.GetPlayer(guid);
4502 else
4503 player = getSelectedPlayer();
4505 if(!player)
4507 SendSysMessage(LANG_NO_CHAR_SELECTED);
4508 SetSentErrorMessage(true);
4509 return false;
4512 if(!HandleResetStatsOrLevelHelper(player))
4513 return false;
4515 player->InitRunes();
4516 player->InitStatsForLevel(true);
4517 player->InitTaxiNodesForLevel();
4518 player->InitGlyphsForLevel();
4519 player->InitTalentForLevel();
4521 return true;
4524 bool ChatHandler::HandleResetSpellsCommand(const char * args)
4526 char* pName = strtok((char*)args, "");
4527 Player *player = NULL;
4528 uint64 playerGUID = 0;
4529 if (pName)
4531 std::string name = extractPlayerNameFromLink(pName);
4532 if(name.empty())
4534 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4535 SetSentErrorMessage(true);
4536 return false;
4539 player = objmgr.GetPlayer(name.c_str());
4540 if(!player)
4541 playerGUID = objmgr.GetPlayerGUIDByName(name);
4543 else
4544 player = getSelectedPlayer();
4546 if(!player && !playerGUID)
4548 SendSysMessage(LANG_NO_CHAR_SELECTED);
4549 SetSentErrorMessage(true);
4550 return false;
4553 if(player)
4555 player->resetSpells();
4557 ChatHandler(player).SendSysMessage(LANG_RESET_SPELLS);
4558 if(m_session->GetPlayer()!=player)
4559 PSendSysMessage(LANG_RESET_SPELLS_ONLINE,GetNameLink(player).c_str());
4561 else
4563 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",uint32(AT_LOGIN_RESET_SPELLS), GUID_LOPART(playerGUID));
4564 PSendSysMessage(LANG_RESET_SPELLS_OFFLINE,pName);
4567 return true;
4570 bool ChatHandler::HandleResetTalentsCommand(const char * args)
4572 char* pName = strtok((char*)args, "");
4573 Player *player = NULL;
4574 uint64 playerGUID = 0;
4575 if (pName)
4577 std::string name = extractPlayerNameFromLink(pName);
4578 if(name.empty())
4580 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4581 SetSentErrorMessage(true);
4582 return false;
4585 player = objmgr.GetPlayer(name.c_str());
4586 if(!player)
4587 playerGUID = objmgr.GetPlayerGUIDByName(name);
4589 else
4590 player = getSelectedPlayer();
4592 if(player)
4594 player->resetTalents(true);
4596 ChatHandler(player).SendSysMessage(LANG_RESET_TALENTS);
4597 if(m_session->GetPlayer()!=player)
4598 PSendSysMessage(LANG_RESET_TALENTS_ONLINE,GetNameLink(player).c_str());
4600 return true;
4602 else if (playerGUID)
4604 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",uint32(AT_LOGIN_RESET_TALENTS), GUID_LOPART(playerGUID) );
4605 std::string nameLink = playerLink(pName);
4606 PSendSysMessage(LANG_RESET_TALENTS_OFFLINE,nameLink.c_str());
4607 return true;
4609 // Try reset talenents as Hunter Pet
4610 Creature* creature = getSelectedCreature();
4611 if (creature && creature->isPet() && ((Pet *)creature)->getPetType() == HUNTER_PET)
4613 ((Pet *)creature)->resetTalents(true);
4614 Unit *owner = creature->GetOwner();
4615 if (owner && owner->GetTypeId() == TYPEID_PLAYER)
4617 player = (Player *)owner;
4618 ChatHandler(player).SendSysMessage(LANG_RESET_TALENTS);
4619 if(m_session->GetPlayer()!=player)
4620 PSendSysMessage(LANG_RESET_TALENTS_ONLINE,GetNameLink(player).c_str());
4622 return true;
4625 SendSysMessage(LANG_NO_CHAR_SELECTED);
4626 SetSentErrorMessage(true);
4627 return false;
4630 bool ChatHandler::HandleResetAllCommand(const char * args)
4632 if(!*args)
4633 return false;
4635 std::string casename = args;
4637 AtLoginFlags atLogin;
4639 // Command specially created as single command to prevent using short case names
4640 if(casename=="spells")
4642 atLogin = AT_LOGIN_RESET_SPELLS;
4643 sWorld.SendWorldText(LANG_RESETALL_SPELLS);
4645 else if(casename=="talents")
4647 atLogin = AT_LOGIN_RESET_TALENTS;
4648 sWorld.SendWorldText(LANG_RESETALL_TALENTS);
4650 else
4652 PSendSysMessage(LANG_RESETALL_UNKNOWN_CASE,args);
4653 SetSentErrorMessage(true);
4654 return false;
4657 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE (at_login & '%u') = '0'",atLogin,atLogin);
4658 HashMapHolder<Player>::MapType const& plist = ObjectAccessor::Instance().GetPlayers();
4659 for(HashMapHolder<Player>::MapType::const_iterator itr = plist.begin(); itr != plist.end(); ++itr)
4660 itr->second->SetAtLoginFlag(atLogin);
4662 return true;
4665 bool ChatHandler::HandleServerShutDownCancelCommand(const char* args)
4667 sWorld.ShutdownCancel();
4668 return true;
4671 bool ChatHandler::HandleServerShutDownCommand(const char* args)
4673 if(!*args)
4674 return false;
4676 char* time_str = strtok ((char*) args, " ");
4677 char* exitcode_str = strtok (NULL, "");
4679 int32 time = atoi (time_str);
4681 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4682 if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0)
4683 return false;
4685 if (exitcode_str)
4687 int32 exitcode = atoi (exitcode_str);
4689 // Handle atoi() errors
4690 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4691 return false;
4693 // Exit code should be in range of 0-125, 126-255 is used
4694 // in many shells for their own return codes and code > 255
4695 // is not supported in many others
4696 if (exitcode < 0 || exitcode > 125)
4697 return false;
4699 sWorld.ShutdownServ (time, 0, exitcode);
4701 else
4702 sWorld.ShutdownServ(time,0,SHUTDOWN_EXIT_CODE);
4703 return true;
4706 bool ChatHandler::HandleServerRestartCommand(const char* args)
4708 if(!*args)
4709 return false;
4711 char* time_str = strtok ((char*) args, " ");
4712 char* exitcode_str = strtok (NULL, "");
4714 int32 time = atoi (time_str);
4716 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4717 if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0)
4718 return false;
4720 if (exitcode_str)
4722 int32 exitcode = atoi (exitcode_str);
4724 // Handle atoi() errors
4725 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4726 return false;
4728 // Exit code should be in range of 0-125, 126-255 is used
4729 // in many shells for their own return codes and code > 255
4730 // is not supported in many others
4731 if (exitcode < 0 || exitcode > 125)
4732 return false;
4734 sWorld.ShutdownServ (time, SHUTDOWN_MASK_RESTART, exitcode);
4736 else
4737 sWorld.ShutdownServ(time, SHUTDOWN_MASK_RESTART, RESTART_EXIT_CODE);
4738 return true;
4741 bool ChatHandler::HandleServerIdleRestartCommand(const char* args)
4743 if(!*args)
4744 return false;
4746 char* time_str = strtok ((char*) args, " ");
4747 char* exitcode_str = strtok (NULL, "");
4749 int32 time = atoi (time_str);
4751 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4752 if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0)
4753 return false;
4755 if (exitcode_str)
4757 int32 exitcode = atoi (exitcode_str);
4759 // Handle atoi() errors
4760 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4761 return false;
4763 // Exit code should be in range of 0-125, 126-255 is used
4764 // in many shells for their own return codes and code > 255
4765 // is not supported in many others
4766 if (exitcode < 0 || exitcode > 125)
4767 return false;
4769 sWorld.ShutdownServ (time, SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE, exitcode);
4771 else
4772 sWorld.ShutdownServ(time,SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE,RESTART_EXIT_CODE);
4773 return true;
4776 bool ChatHandler::HandleServerIdleShutDownCommand(const char* args)
4778 if(!*args)
4779 return false;
4781 char* time_str = strtok ((char*) args, " ");
4782 char* exitcode_str = strtok (NULL, "");
4784 int32 time = atoi (time_str);
4786 ///- Prevent interpret wrong arg value as 0 secs shutdown time
4787 if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0)
4788 return false;
4790 if (exitcode_str)
4792 int32 exitcode = atoi (exitcode_str);
4794 // Handle atoi() errors
4795 if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4796 return false;
4798 // Exit code should be in range of 0-125, 126-255 is used
4799 // in many shells for their own return codes and code > 255
4800 // is not supported in many others
4801 if (exitcode < 0 || exitcode > 125)
4802 return false;
4804 sWorld.ShutdownServ (time, SHUTDOWN_MASK_IDLE, exitcode);
4806 else
4807 sWorld.ShutdownServ(time,SHUTDOWN_MASK_IDLE,SHUTDOWN_EXIT_CODE);
4808 return true;
4811 bool ChatHandler::HandleAddQuest(const char* args)
4813 Player* player = getSelectedPlayer();
4814 if(!player)
4816 SendSysMessage(LANG_NO_CHAR_SELECTED);
4817 SetSentErrorMessage(true);
4818 return false;
4821 // .addquest #entry'
4822 // number or [name] Shift-click form |color|Hquest:quest_id|h[name]|h|r
4823 char* cId = extractKeyFromLink((char*)args,"Hquest");
4824 if(!cId)
4825 return false;
4827 uint32 entry = atol(cId);
4829 Quest const* pQuest = objmgr.GetQuestTemplate(entry);
4831 if(!pQuest)
4833 PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND,entry);
4834 SetSentErrorMessage(true);
4835 return false;
4838 // check item starting quest (it can work incorrectly if added without item in inventory)
4839 for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
4841 ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype>(id);
4842 if (!pProto)
4843 continue;
4845 if (pProto->StartQuest == entry)
4847 PSendSysMessage(LANG_COMMAND_QUEST_STARTFROMITEM, entry, pProto->ItemId);
4848 SetSentErrorMessage(true);
4849 return false;
4853 // ok, normal (creature/GO starting) quest
4854 if( player->CanAddQuest( pQuest, true ) )
4856 player->AddQuest( pQuest, NULL );
4858 if ( player->CanCompleteQuest( entry ) )
4859 player->CompleteQuest( entry );
4862 return true;
4865 bool ChatHandler::HandleRemoveQuest(const char* args)
4867 Player* player = getSelectedPlayer();
4868 if(!player)
4870 SendSysMessage(LANG_NO_CHAR_SELECTED);
4871 SetSentErrorMessage(true);
4872 return false;
4875 // .removequest #entry'
4876 // number or [name] Shift-click form |color|Hquest:quest_id|h[name]|h|r
4877 char* cId = extractKeyFromLink((char*)args,"Hquest");
4878 if(!cId)
4879 return false;
4881 uint32 entry = atol(cId);
4883 Quest const* pQuest = objmgr.GetQuestTemplate(entry);
4885 if(!pQuest)
4887 PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry);
4888 SetSentErrorMessage(true);
4889 return false;
4892 // remove all quest entries for 'entry' from quest log
4893 for(uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot )
4895 uint32 quest = player->GetQuestSlotQuestId(slot);
4896 if(quest==entry)
4898 player->SetQuestSlot(slot,0);
4900 // we ignore unequippable quest items in this case, its' still be equipped
4901 player->TakeQuestSourceItem( quest, false );
4905 // set quest status to not started (will updated in DB at next save)
4906 player->SetQuestStatus( entry, QUEST_STATUS_NONE);
4908 // reset rewarded for restart repeatable quest
4909 player->getQuestStatusMap()[entry].m_rewarded = false;
4911 SendSysMessage(LANG_COMMAND_QUEST_REMOVED);
4912 return true;
4915 bool ChatHandler::HandleCompleteQuest(const char* args)
4917 Player* player = getSelectedPlayer();
4918 if(!player)
4920 SendSysMessage(LANG_NO_CHAR_SELECTED);
4921 SetSentErrorMessage(true);
4922 return false;
4925 // .quest complete #entry
4926 // number or [name] Shift-click form |color|Hquest:quest_id|h[name]|h|r
4927 char* cId = extractKeyFromLink((char*)args,"Hquest");
4928 if(!cId)
4929 return false;
4931 uint32 entry = atol(cId);
4933 Quest const* pQuest = objmgr.GetQuestTemplate(entry);
4935 // If player doesn't have the quest
4936 if(!pQuest || player->GetQuestStatus(entry) == QUEST_STATUS_NONE)
4938 PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry);
4939 SetSentErrorMessage(true);
4940 return false;
4943 // Add quest items for quests that require items
4944 for(uint8 x = 0; x < QUEST_OBJECTIVES_COUNT; ++x)
4946 uint32 id = pQuest->ReqItemId[x];
4947 uint32 count = pQuest->ReqItemCount[x];
4948 if(!id || !count)
4949 continue;
4951 uint32 curItemCount = player->GetItemCount(id,true);
4953 ItemPosCountVec dest;
4954 uint8 msg = player->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, id, count-curItemCount );
4955 if( msg == EQUIP_ERR_OK )
4957 Item* item = player->StoreNewItem( dest, id, true);
4958 player->SendNewItem(item,count-curItemCount,true,false);
4962 // All creature/GO slain/casted (not required, but otherwise it will display "Creature slain 0/10")
4963 for(uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; i++)
4965 uint32 creature = pQuest->ReqCreatureOrGOId[i];
4966 uint32 creaturecount = pQuest->ReqCreatureOrGOCount[i];
4968 if(uint32 spell_id = pQuest->ReqSpell[i])
4970 for(uint16 z = 0; z < creaturecount; ++z)
4971 player->CastedCreatureOrGO(creature,0,spell_id);
4973 else if(creature > 0)
4975 for(uint16 z = 0; z < creaturecount; ++z)
4976 player->KilledMonster(creature,0);
4978 else if(creature < 0)
4980 for(uint16 z = 0; z < creaturecount; ++z)
4981 player->CastedCreatureOrGO(creature,0,0);
4985 // If the quest requires reputation to complete
4986 if(uint32 repFaction = pQuest->GetRepObjectiveFaction())
4988 uint32 repValue = pQuest->GetRepObjectiveValue();
4989 uint32 curRep = player->GetReputation(repFaction);
4990 if(curRep < repValue)
4992 FactionEntry const *factionEntry = sFactionStore.LookupEntry(repFaction);
4993 player->SetFactionReputation(factionEntry,repValue);
4997 // If the quest requires money
4998 int32 ReqOrRewMoney = pQuest->GetRewOrReqMoney();
4999 if(ReqOrRewMoney < 0)
5000 player->ModifyMoney(-ReqOrRewMoney);
5002 player->CompleteQuest(entry);
5003 return true;
5006 bool ChatHandler::HandleBanAccountCommand(const char* args)
5008 return HandleBanHelper(BAN_ACCOUNT,args);
5011 bool ChatHandler::HandleBanCharacterCommand(const char* args)
5013 return HandleBanHelper(BAN_CHARACTER,args);
5016 bool ChatHandler::HandleBanIPCommand(const char* args)
5018 return HandleBanHelper(BAN_IP,args);
5021 bool ChatHandler::HandleBanHelper(BanMode mode, const char* args)
5023 if(!args)
5024 return false;
5026 char* cnameOrIP = strtok ((char*)args, " ");
5027 if (!cnameOrIP)
5028 return false;
5030 std::string nameOrIP = cnameOrIP;
5032 char* duration = strtok (NULL," ");
5033 if(!duration || !atoi(duration))
5034 return false;
5036 char* reason = strtok (NULL,"");
5037 if(!reason)
5038 return false;
5040 switch(mode)
5042 case BAN_ACCOUNT:
5043 if(!AccountMgr::normilizeString(nameOrIP))
5045 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,nameOrIP.c_str());
5046 SetSentErrorMessage(true);
5047 return false;
5049 break;
5050 case BAN_CHARACTER:
5051 if(!normalizePlayerName(nameOrIP))
5053 SendSysMessage(LANG_PLAYER_NOT_FOUND);
5054 SetSentErrorMessage(true);
5055 return false;
5057 break;
5058 case BAN_IP:
5059 if(!IsIPAddress(nameOrIP.c_str()))
5060 return false;
5061 break;
5064 switch(sWorld.BanAccount(mode, nameOrIP, duration, reason,m_session ? m_session->GetPlayerName() : ""))
5066 case BAN_SUCCESS:
5067 if(atoi(duration)>0)
5068 PSendSysMessage(LANG_BAN_YOUBANNED,nameOrIP.c_str(),secsToTimeString(TimeStringToSecs(duration),true).c_str(),reason);
5069 else
5070 PSendSysMessage(LANG_BAN_YOUPERMBANNED,nameOrIP.c_str(),reason);
5071 break;
5072 case BAN_SYNTAX_ERROR:
5073 return false;
5074 case BAN_NOTFOUND:
5075 switch(mode)
5077 default:
5078 PSendSysMessage(LANG_BAN_NOTFOUND,"account",nameOrIP.c_str());
5079 break;
5080 case BAN_CHARACTER:
5081 PSendSysMessage(LANG_BAN_NOTFOUND,"character",nameOrIP.c_str());
5082 break;
5083 case BAN_IP:
5084 PSendSysMessage(LANG_BAN_NOTFOUND,"ip",nameOrIP.c_str());
5085 break;
5087 SetSentErrorMessage(true);
5088 return false;
5091 return true;
5094 bool ChatHandler::HandleUnBanAccountCommand(const char* args)
5096 return HandleUnBanHelper(BAN_ACCOUNT,args);
5099 bool ChatHandler::HandleUnBanCharacterCommand(const char* args)
5101 return HandleUnBanHelper(BAN_CHARACTER,args);
5104 bool ChatHandler::HandleUnBanIPCommand(const char* args)
5106 return HandleUnBanHelper(BAN_IP,args);
5109 bool ChatHandler::HandleUnBanHelper(BanMode mode, const char* args)
5111 if(!args)
5112 return false;
5114 char* cnameOrIP = strtok ((char*)args, " ");
5115 if(!cnameOrIP)
5116 return false;
5118 std::string nameOrIP = cnameOrIP;
5120 switch(mode)
5122 case BAN_ACCOUNT:
5123 if(!AccountMgr::normilizeString(nameOrIP))
5125 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,nameOrIP.c_str());
5126 SetSentErrorMessage(true);
5127 return false;
5129 break;
5130 case BAN_CHARACTER:
5131 if(!normalizePlayerName(nameOrIP))
5133 SendSysMessage(LANG_PLAYER_NOT_FOUND);
5134 SetSentErrorMessage(true);
5135 return false;
5137 break;
5138 case BAN_IP:
5139 if(!IsIPAddress(nameOrIP.c_str()))
5140 return false;
5141 break;
5144 if(sWorld.RemoveBanAccount(mode,nameOrIP))
5145 PSendSysMessage(LANG_UNBAN_UNBANNED,nameOrIP.c_str());
5146 else
5147 PSendSysMessage(LANG_UNBAN_ERROR,nameOrIP.c_str());
5149 return true;
5152 bool ChatHandler::HandleBanInfoAccountCommand(const char* args)
5154 if(!args)
5155 return false;
5157 char* cname = strtok((char*)args, "");
5158 if(!cname)
5159 return false;
5161 std::string account_name = cname;
5162 if(!AccountMgr::normilizeString(account_name))
5164 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5165 SetSentErrorMessage(true);
5166 return false;
5169 uint32 accountid = accmgr.GetId(account_name);
5170 if(!accountid)
5172 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5173 return true;
5176 return HandleBanInfoHelper(accountid,account_name.c_str());
5179 bool ChatHandler::HandleBanInfoCharacterCommand(const char* args)
5181 if(!args)
5182 return false;
5184 std::string name = extractPlayerNameFromLink((char*)args);
5185 if(name.empty())
5187 SendSysMessage(LANG_PLAYER_NOT_FOUND);
5188 SetSentErrorMessage(true);
5189 return false;
5192 uint32 accountid = objmgr.GetPlayerAccountIdByPlayerName(name);
5193 if(!accountid)
5195 SendSysMessage(LANG_PLAYER_NOT_FOUND);
5196 SetSentErrorMessage(true);
5197 return false;
5200 std::string accountname;
5201 if(!accmgr.GetName(accountid,accountname))
5203 PSendSysMessage(LANG_BANINFO_NOCHARACTER);
5204 return true;
5207 return HandleBanInfoHelper(accountid,accountname.c_str());
5210 bool ChatHandler::HandleBanInfoHelper(uint32 accountid, char const* accountname)
5212 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);
5213 if(!result)
5215 PSendSysMessage(LANG_BANINFO_NOACCOUNTBAN, accountname);
5216 return true;
5219 PSendSysMessage(LANG_BANINFO_BANHISTORY,accountname);
5222 Field* fields = result->Fetch();
5224 time_t unbandate = time_t(fields[3].GetUInt64());
5225 bool active = false;
5226 if(fields[2].GetBool() && (fields[1].GetUInt64() == (uint64)0 ||unbandate >= time(NULL)) )
5227 active = true;
5228 bool permanent = (fields[1].GetUInt64() == (uint64)0);
5229 std::string bantime = permanent?GetMangosString(LANG_BANINFO_INFINITE):secsToTimeString(fields[1].GetUInt64(), true);
5230 PSendSysMessage(LANG_BANINFO_HISTORYENTRY,
5231 fields[0].GetString(), bantime.c_str(), active ? GetMangosString(LANG_BANINFO_YES):GetMangosString(LANG_BANINFO_NO), fields[4].GetString(), fields[5].GetString());
5232 }while (result->NextRow());
5234 delete result;
5235 return true;
5238 bool ChatHandler::HandleBanInfoIPCommand(const char* args)
5240 if(!args)
5241 return false;
5243 char* cIP = strtok ((char*)args, "");
5244 if(!cIP)
5245 return false;
5247 if (!IsIPAddress(cIP))
5248 return false;
5250 std::string IP = cIP;
5252 loginDatabase.escape_string(IP);
5253 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());
5254 if(!result)
5256 PSendSysMessage(LANG_BANINFO_NOIP);
5257 return true;
5260 Field *fields = result->Fetch();
5261 bool permanent = !fields[6].GetUInt64();
5262 PSendSysMessage(LANG_BANINFO_IPENTRY,
5263 fields[0].GetString(), fields[1].GetString(), permanent ? GetMangosString(LANG_BANINFO_NEVER):fields[2].GetString(),
5264 permanent ? GetMangosString(LANG_BANINFO_INFINITE):secsToTimeString(fields[3].GetUInt64(), true).c_str(), fields[4].GetString(), fields[5].GetString());
5265 delete result;
5266 return true;
5269 bool ChatHandler::HandleBanListCharacterCommand(const char* args)
5271 loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
5273 char* cFilter = strtok ((char*)args, " ");
5274 if(!cFilter)
5275 return false;
5277 std::string filter = cFilter;
5278 loginDatabase.escape_string(filter);
5279 QueryResult* result = CharacterDatabase.PQuery("SELECT account FROM characters WHERE name "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'"),filter.c_str());
5280 if (!result)
5282 PSendSysMessage(LANG_BANLIST_NOCHARACTER);
5283 return true;
5286 return HandleBanListHelper(result);
5289 bool ChatHandler::HandleBanListAccountCommand(const char* args)
5291 loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
5293 char* cFilter = strtok((char*)args, " ");
5294 std::string filter = cFilter ? cFilter : "";
5295 loginDatabase.escape_string(filter);
5297 QueryResult* result;
5299 if(filter.empty())
5301 result = loginDatabase.Query("SELECT account.id, username FROM account, account_banned"
5302 " WHERE account.id = account_banned.id AND active = 1 GROUP BY account.id");
5304 else
5306 result = loginDatabase.PQuery("SELECT account.id, username FROM account, account_banned"
5307 " WHERE account.id = account_banned.id AND active = 1 AND username "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")" GROUP BY account.id",
5308 filter.c_str());
5311 if (!result)
5313 PSendSysMessage(LANG_BANLIST_NOACCOUNT);
5314 return true;
5317 return HandleBanListHelper(result);
5320 bool ChatHandler::HandleBanListHelper(QueryResult* result)
5322 PSendSysMessage(LANG_BANLIST_MATCHINGACCOUNT);
5324 // Chat short output
5325 if(m_session)
5329 Field* fields = result->Fetch();
5330 uint32 accountid = fields[0].GetUInt32();
5332 QueryResult* banresult = loginDatabase.PQuery("SELECT account.username FROM account,account_banned WHERE account_banned.id='%u' AND account_banned.id=account.id",accountid);
5333 if(banresult)
5335 Field* fields2 = banresult->Fetch();
5336 PSendSysMessage("%s",fields2[0].GetString());
5337 delete banresult;
5339 } while (result->NextRow());
5341 // Console wide output
5342 else
5344 SendSysMessage(LANG_BANLIST_ACCOUNTS);
5345 SendSysMessage("===============================================================================");
5346 SendSysMessage(LANG_BANLIST_ACCOUNTS_HEADER);
5349 SendSysMessage("-------------------------------------------------------------------------------");
5350 Field *fields = result->Fetch();
5351 uint32 account_id = fields[0].GetUInt32 ();
5353 std::string account_name;
5355 // "account" case, name can be get in same query
5356 if(result->GetFieldCount() > 1)
5357 account_name = fields[1].GetCppString();
5358 // "character" case, name need extract from another DB
5359 else
5360 accmgr.GetName (account_id,account_name);
5362 // No SQL injection. id is uint32.
5363 QueryResult *banInfo = loginDatabase.PQuery("SELECT bandate,unbandate,bannedby,banreason FROM account_banned WHERE id = %u ORDER BY unbandate", account_id);
5364 if (banInfo)
5366 Field *fields2 = banInfo->Fetch();
5369 time_t t_ban = fields2[0].GetUInt64();
5370 tm* aTm_ban = localtime(&t_ban);
5372 if (fields2[0].GetUInt64() == fields2[1].GetUInt64())
5374 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|",
5375 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,
5376 fields2[2].GetString(),fields2[3].GetString());
5378 else
5380 time_t t_unban = fields2[1].GetUInt64();
5381 tm* aTm_unban = localtime(&t_unban);
5382 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|",
5383 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,
5384 aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min,
5385 fields2[2].GetString(),fields2[3].GetString());
5387 }while ( banInfo->NextRow() );
5388 delete banInfo;
5390 }while( result->NextRow() );
5391 SendSysMessage("===============================================================================");
5394 delete result;
5395 return true;
5398 bool ChatHandler::HandleBanListIPCommand(const char* args)
5400 loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
5402 char* cFilter = strtok((char*)args, " ");
5403 std::string filter = cFilter ? cFilter : "";
5404 loginDatabase.escape_string(filter);
5406 QueryResult* result;
5408 if(filter.empty())
5410 result = loginDatabase.Query ("SELECT ip,bandate,unbandate,bannedby,banreason FROM ip_banned"
5411 " WHERE (bandate=unbandate OR unbandate>UNIX_TIMESTAMP())"
5412 " ORDER BY unbandate" );
5414 else
5416 result = loginDatabase.PQuery( "SELECT ip,bandate,unbandate,bannedby,banreason FROM ip_banned"
5417 " WHERE (bandate=unbandate OR unbandate>UNIX_TIMESTAMP()) AND ip "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")
5418 " ORDER BY unbandate",filter.c_str() );
5421 if(!result)
5423 PSendSysMessage(LANG_BANLIST_NOIP);
5424 return true;
5427 PSendSysMessage(LANG_BANLIST_MATCHINGIP);
5428 // Chat short output
5429 if(m_session)
5433 Field* fields = result->Fetch();
5434 PSendSysMessage("%s",fields[0].GetString());
5435 } while (result->NextRow());
5437 // Console wide output
5438 else
5440 SendSysMessage(LANG_BANLIST_IPS);
5441 SendSysMessage("===============================================================================");
5442 SendSysMessage(LANG_BANLIST_IPS_HEADER);
5445 SendSysMessage("-------------------------------------------------------------------------------");
5446 Field *fields = result->Fetch();
5447 time_t t_ban = fields[1].GetUInt64();
5448 tm* aTm_ban = localtime(&t_ban);
5449 if ( fields[1].GetUInt64() == fields[2].GetUInt64() )
5451 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|",
5452 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,
5453 fields[3].GetString(), fields[4].GetString());
5455 else
5457 time_t t_unban = fields[2].GetUInt64();
5458 tm* aTm_unban = localtime(&t_unban);
5459 PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|",
5460 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,
5461 aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min,
5462 fields[3].GetString(), fields[4].GetString());
5464 }while( result->NextRow() );
5465 SendSysMessage("===============================================================================");
5468 delete result;
5469 return true;
5472 bool ChatHandler::HandleRespawnCommand(const char* /*args*/)
5474 Player* pl = m_session->GetPlayer();
5476 // accept only explicitly selected target (not implicitly self targeting case)
5477 Unit* target = getSelectedUnit();
5478 if(pl->GetSelection() && target)
5480 if(target->GetTypeId()!=TYPEID_UNIT)
5482 SendSysMessage(LANG_SELECT_CREATURE);
5483 SetSentErrorMessage(true);
5484 return false;
5487 if(target->isDead())
5488 ((Creature*)target)->Respawn();
5489 return true;
5492 CellPair p(MaNGOS::ComputeCellPair(pl->GetPositionX(), pl->GetPositionY()));
5493 Cell cell(p);
5494 cell.data.Part.reserved = ALL_DISTRICT;
5495 cell.SetNoCreate();
5497 MaNGOS::RespawnDo u_do;
5498 MaNGOS::WorldObjectWorker<MaNGOS::RespawnDo> worker(pl,u_do);
5500 TypeContainerVisitor<MaNGOS::WorldObjectWorker<MaNGOS::RespawnDo>, GridTypeMapContainer > obj_worker(worker);
5501 CellLock<GridReadGuard> cell_lock(cell, p);
5502 cell_lock->Visit(cell_lock, obj_worker, *pl->GetMap());
5504 return true;
5507 bool ChatHandler::HandleFlyModeCommand(const char* args)
5509 if(!args)
5510 return false;
5512 Player *target = getSelectedPlayer();
5513 if (!target)
5514 target = m_session->GetPlayer();
5516 WorldPacket data(12);
5517 if (strncmp(args, "on", 3) == 0)
5518 data.SetOpcode(SMSG_MOVE_SET_CAN_FLY);
5519 else if (strncmp(args, "off", 4) == 0)
5520 data.SetOpcode(SMSG_MOVE_UNSET_CAN_FLY);
5521 else
5523 SendSysMessage(LANG_USE_BOL);
5524 return false;
5526 data.append(target->GetPackGUID());
5527 data << uint32(0); // unknown
5528 target->SendMessageToSet(&data, true);
5529 PSendSysMessage(LANG_COMMAND_FLYMODE_STATUS, GetNameLink(target).c_str(), args);
5530 return true;
5533 bool ChatHandler::HandleLoadPDumpCommand(const char *args)
5535 if(!args)
5536 return false;
5538 char * file = strtok((char*)args, " ");
5539 if(!file)
5540 return false;
5542 char * account = strtok(NULL, " ");
5543 if(!account)
5544 return false;
5546 std::string account_name = account;
5547 if(!AccountMgr::normilizeString(account_name))
5549 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5550 SetSentErrorMessage(true);
5551 return false;
5554 uint32 account_id = accmgr.GetId(account_name);
5555 if(!account_id)
5557 account_id = atoi(account); // use original string
5558 if(!account_id)
5560 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5561 SetSentErrorMessage(true);
5562 return false;
5566 if(!accmgr.GetName(account_id,account_name))
5568 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5569 SetSentErrorMessage(true);
5570 return false;
5573 char* guid_str = NULL;
5574 char* name_str = strtok(NULL, " ");
5576 std::string name;
5577 if(name_str)
5579 name = name_str;
5580 // normalize the name if specified and check if it exists
5581 if(!normalizePlayerName(name))
5583 PSendSysMessage(LANG_INVALID_CHARACTER_NAME);
5584 SetSentErrorMessage(true);
5585 return false;
5588 if(!ObjectMgr::IsValidName(name,true))
5590 PSendSysMessage(LANG_INVALID_CHARACTER_NAME);
5591 SetSentErrorMessage(true);
5592 return false;
5595 guid_str = strtok(NULL, " ");
5598 uint32 guid = 0;
5600 if(guid_str)
5602 guid = atoi(guid_str);
5603 if(!guid)
5605 PSendSysMessage(LANG_INVALID_CHARACTER_GUID);
5606 SetSentErrorMessage(true);
5607 return false;
5610 if(objmgr.GetPlayerAccountIdByGUID(guid))
5612 PSendSysMessage(LANG_CHARACTER_GUID_IN_USE,guid);
5613 SetSentErrorMessage(true);
5614 return false;
5618 switch(PlayerDumpReader().LoadDump(file, account_id, name, guid))
5620 case DUMP_SUCCESS:
5621 PSendSysMessage(LANG_COMMAND_IMPORT_SUCCESS);
5622 break;
5623 case DUMP_FILE_OPEN_ERROR:
5624 PSendSysMessage(LANG_FILE_OPEN_FAIL,file);
5625 SetSentErrorMessage(true);
5626 return false;
5627 case DUMP_FILE_BROKEN:
5628 PSendSysMessage(LANG_DUMP_BROKEN,file);
5629 SetSentErrorMessage(true);
5630 return false;
5631 case DUMP_TOO_MANY_CHARS:
5632 PSendSysMessage(LANG_ACCOUNT_CHARACTER_LIST_FULL,account_name.c_str(),account_id);
5633 SetSentErrorMessage(true);
5634 return false;
5635 default:
5636 PSendSysMessage(LANG_COMMAND_IMPORT_FAILED);
5637 SetSentErrorMessage(true);
5638 return false;
5641 return true;
5644 bool ChatHandler::HandleNpcChangeEntryCommand(const char *args)
5646 if(!args)
5647 return false;
5649 uint32 newEntryNum = atoi(args);
5650 if(!newEntryNum)
5651 return false;
5653 Unit* unit = getSelectedUnit();
5654 if(!unit || unit->GetTypeId() != TYPEID_UNIT)
5656 SendSysMessage(LANG_SELECT_CREATURE);
5657 SetSentErrorMessage(true);
5658 return false;
5660 Creature* creature = (Creature*)unit;
5661 if(creature->UpdateEntry(newEntryNum))
5662 SendSysMessage(LANG_DONE);
5663 else
5664 SendSysMessage(LANG_ERROR);
5665 return true;
5668 bool ChatHandler::HandleWritePDumpCommand(const char *args)
5670 if(!args)
5671 return false;
5673 char* file = strtok((char*)args, " ");
5674 char* p2 = strtok(NULL, " ");
5676 if(!file || !p2)
5677 return false;
5679 uint32 guid;
5680 // character name can't start from number
5681 if (isNumeric(p2[0]))
5682 guid = atoi(p2);
5683 else
5685 std::string name = extractPlayerNameFromLink(p2);
5686 if(name.empty())
5688 SendSysMessage(LANG_PLAYER_NOT_FOUND);
5689 SetSentErrorMessage(true);
5690 return false;
5693 guid = objmgr.GetPlayerGUIDByName(name);
5696 if(!objmgr.GetPlayerAccountIdByGUID(guid))
5698 PSendSysMessage(LANG_PLAYER_NOT_FOUND);
5699 SetSentErrorMessage(true);
5700 return false;
5703 switch(PlayerDumpWriter().WriteDump(file, guid))
5705 case DUMP_SUCCESS:
5706 PSendSysMessage(LANG_COMMAND_EXPORT_SUCCESS);
5707 break;
5708 case DUMP_FILE_OPEN_ERROR:
5709 PSendSysMessage(LANG_FILE_OPEN_FAIL,file);
5710 SetSentErrorMessage(true);
5711 return false;
5712 default:
5713 PSendSysMessage(LANG_COMMAND_EXPORT_FAILED);
5714 SetSentErrorMessage(true);
5715 return false;
5718 return true;
5721 bool ChatHandler::HandleMovegensCommand(const char* /*args*/)
5723 Unit* unit = getSelectedUnit();
5724 if(!unit)
5726 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5727 SetSentErrorMessage(true);
5728 return false;
5731 PSendSysMessage(LANG_MOVEGENS_LIST,(unit->GetTypeId()==TYPEID_PLAYER ? "Player" : "Creature" ),unit->GetGUIDLow());
5733 MotionMaster* mm = unit->GetMotionMaster();
5734 for(MotionMaster::const_iterator itr = mm->begin(); itr != mm->end(); ++itr)
5736 switch((*itr)->GetMovementGeneratorType())
5738 case IDLE_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_IDLE); break;
5739 case RANDOM_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_RANDOM); break;
5740 case WAYPOINT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_WAYPOINT); break;
5741 case ANIMAL_RANDOM_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_ANIMAL_RANDOM); break;
5742 case CONFUSED_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_CONFUSED); break;
5743 case TARGETED_MOTION_TYPE:
5745 if(unit->GetTypeId()==TYPEID_PLAYER)
5747 TargetedMovementGenerator<Player> const* mgen = static_cast<TargetedMovementGenerator<Player> const*>(*itr);
5748 Unit* target = mgen->GetTarget();
5749 if(target)
5750 PSendSysMessage(LANG_MOVEGENS_TARGETED_PLAYER,target->GetName(),target->GetGUIDLow());
5751 else
5752 SendSysMessage(LANG_MOVEGENS_TARGETED_NULL);
5754 else
5756 TargetedMovementGenerator<Creature> const* mgen = static_cast<TargetedMovementGenerator<Creature> const*>(*itr);
5757 Unit* target = mgen->GetTarget();
5758 if(target)
5759 PSendSysMessage(LANG_MOVEGENS_TARGETED_CREATURE,target->GetName(),target->GetGUIDLow());
5760 else
5761 SendSysMessage(LANG_MOVEGENS_TARGETED_NULL);
5763 break;
5765 case HOME_MOTION_TYPE:
5766 if(unit->GetTypeId()==TYPEID_UNIT)
5768 float x,y,z;
5769 (*itr)->GetDestination(x,y,z);
5770 PSendSysMessage(LANG_MOVEGENS_HOME_CREATURE,x,y,z);
5772 else
5773 SendSysMessage(LANG_MOVEGENS_HOME_PLAYER);
5774 break;
5775 case FLIGHT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_FLIGHT); break;
5776 case POINT_MOTION_TYPE:
5778 float x,y,z;
5779 (*itr)->GetDestination(x,y,z);
5780 PSendSysMessage(LANG_MOVEGENS_POINT,x,y,z);
5781 break;
5783 case FLEEING_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_FEAR); break;
5784 case DISTRACT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_DISTRACT); break;
5785 default:
5786 PSendSysMessage(LANG_MOVEGENS_UNKNOWN,(*itr)->GetMovementGeneratorType());
5787 break;
5790 return true;
5793 bool ChatHandler::HandlePLimitCommand(const char *args)
5795 if(*args)
5797 char* param = strtok((char*)args, " ");
5798 if(!param)
5799 return false;
5801 int l = strlen(param);
5803 if( strncmp(param,"player",l) == 0 )
5804 sWorld.SetPlayerLimit(-SEC_PLAYER);
5805 else if(strncmp(param,"moderator",l) == 0 )
5806 sWorld.SetPlayerLimit(-SEC_MODERATOR);
5807 else if(strncmp(param,"gamemaster",l) == 0 )
5808 sWorld.SetPlayerLimit(-SEC_GAMEMASTER);
5809 else if(strncmp(param,"administrator",l) == 0 )
5810 sWorld.SetPlayerLimit(-SEC_ADMINISTRATOR);
5811 else if(strncmp(param,"reset",l) == 0 )
5812 sWorld.SetPlayerLimit( sConfig.GetIntDefault("PlayerLimit", DEFAULT_PLAYER_LIMIT) );
5813 else
5815 int val = atoi(param);
5816 if(val < -SEC_ADMINISTRATOR) val = -SEC_ADMINISTRATOR;
5818 sWorld.SetPlayerLimit(val);
5821 // kick all low security level players
5822 if(sWorld.GetPlayerAmountLimit() > SEC_PLAYER)
5823 sWorld.KickAllLess(sWorld.GetPlayerSecurityLimit());
5826 uint32 pLimit = sWorld.GetPlayerAmountLimit();
5827 AccountTypes allowedAccountType = sWorld.GetPlayerSecurityLimit();
5828 char const* secName = "";
5829 switch(allowedAccountType)
5831 case SEC_PLAYER: secName = "Player"; break;
5832 case SEC_MODERATOR: secName = "Moderator"; break;
5833 case SEC_GAMEMASTER: secName = "Gamemaster"; break;
5834 case SEC_ADMINISTRATOR: secName = "Administrator"; break;
5835 default: secName = "<unknown>"; break;
5838 PSendSysMessage("Player limits: amount %u, min. security level %s.",pLimit,secName);
5840 return true;
5843 bool ChatHandler::HandleCastCommand(const char* args)
5845 if(!*args)
5846 return false;
5848 Unit* target = getSelectedUnit();
5850 if(!target)
5852 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5853 SetSentErrorMessage(true);
5854 return false;
5857 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5858 uint32 spell = extractSpellIdFromLink((char*)args);
5859 if(!spell)
5860 return false;
5862 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
5863 if(!spellInfo)
5864 return false;
5866 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
5868 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
5869 SetSentErrorMessage(true);
5870 return false;
5873 char* trig_str = strtok(NULL, " ");
5874 if(trig_str)
5876 int l = strlen(trig_str);
5877 if(strncmp(trig_str,"triggered",l) != 0 )
5878 return false;
5881 bool triggered = (trig_str != NULL);
5883 m_session->GetPlayer()->CastSpell(target,spell,triggered);
5885 return true;
5888 bool ChatHandler::HandleCastBackCommand(const char* args)
5890 Creature* caster = getSelectedCreature();
5892 if(!caster)
5894 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5895 SetSentErrorMessage(true);
5896 return false;
5899 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
5900 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5901 uint32 spell = extractSpellIdFromLink((char*)args);
5902 if(!spell || !sSpellStore.LookupEntry(spell))
5903 return false;
5905 char* trig_str = strtok(NULL, " ");
5906 if(trig_str)
5908 int l = strlen(trig_str);
5909 if(strncmp(trig_str,"triggered",l) != 0 )
5910 return false;
5913 bool triggered = (trig_str != NULL);
5915 // update orientation at server
5916 caster->SetOrientation(caster->GetAngle(m_session->GetPlayer()));
5918 // and client
5919 WorldPacket data;
5920 caster->BuildHeartBeatMsg(&data);
5921 caster->SendMessageToSet(&data,true);
5923 caster->CastSpell(m_session->GetPlayer(),spell,triggered);
5925 return true;
5928 bool ChatHandler::HandleCastDistCommand(const char* args)
5930 if(!*args)
5931 return false;
5933 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5934 uint32 spell = extractSpellIdFromLink((char*)args);
5935 if(!spell)
5936 return false;
5938 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
5939 if(!spellInfo)
5940 return false;
5942 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
5944 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
5945 SetSentErrorMessage(true);
5946 return false;
5949 char *distStr = strtok(NULL, " ");
5951 float dist = 0;
5953 if(distStr)
5954 sscanf(distStr, "%f", &dist);
5956 char* trig_str = strtok(NULL, " ");
5957 if(trig_str)
5959 int l = strlen(trig_str);
5960 if(strncmp(trig_str,"triggered",l) != 0 )
5961 return false;
5964 bool triggered = (trig_str != NULL);
5966 float x,y,z;
5967 m_session->GetPlayer()->GetClosePoint(x,y,z,dist);
5969 m_session->GetPlayer()->CastSpell(x,y,z,spell,triggered);
5970 return true;
5973 bool ChatHandler::HandleCastTargetCommand(const char* args)
5975 Creature* caster = getSelectedCreature();
5977 if(!caster)
5979 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5980 SetSentErrorMessage(true);
5981 return false;
5984 if(!caster->getVictim())
5986 SendSysMessage(LANG_SELECTED_TARGET_NOT_HAVE_VICTIM);
5987 SetSentErrorMessage(true);
5988 return false;
5991 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5992 uint32 spell = extractSpellIdFromLink((char*)args);
5993 if(!spell || !sSpellStore.LookupEntry(spell))
5994 return false;
5996 char* trig_str = strtok(NULL, " ");
5997 if(trig_str)
5999 int l = strlen(trig_str);
6000 if(strncmp(trig_str,"triggered",l) != 0 )
6001 return false;
6004 bool triggered = (trig_str != NULL);
6006 // update orientation at server
6007 caster->SetOrientation(caster->GetAngle(m_session->GetPlayer()));
6009 // and client
6010 WorldPacket data;
6011 caster->BuildHeartBeatMsg(&data);
6012 caster->SendMessageToSet(&data,true);
6014 caster->CastSpell(caster->getVictim(),spell,triggered);
6016 return true;
6020 ComeToMe command REQUIRED for 3rd party scripting library to have access to PointMovementGenerator
6021 Without this function 3rd party scripting library will get linking errors (unresolved external)
6022 when attempting to use the PointMovementGenerator
6024 bool ChatHandler::HandleComeToMeCommand(const char *args)
6026 Creature* caster = getSelectedCreature();
6028 if(!caster)
6030 SendSysMessage(LANG_SELECT_CREATURE);
6031 SetSentErrorMessage(true);
6032 return false;
6035 char* newFlagStr = strtok((char*)args, " ");
6037 if(!newFlagStr)
6038 return false;
6040 uint32 newFlags = atoi(newFlagStr);
6042 caster->SetUnitMovementFlags(newFlags);
6044 Player* pl = m_session->GetPlayer();
6046 caster->GetMotionMaster()->MovePoint(0, pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ());
6047 return true;
6050 bool ChatHandler::HandleCastSelfCommand(const char* args)
6052 if(!*args)
6053 return false;
6055 Unit* target = getSelectedUnit();
6057 if(!target)
6059 SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
6060 SetSentErrorMessage(true);
6061 return false;
6064 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
6065 uint32 spell = extractSpellIdFromLink((char*)args);
6066 if(!spell)
6067 return false;
6069 SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
6070 if(!spellInfo)
6071 return false;
6073 if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
6075 PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
6076 SetSentErrorMessage(true);
6077 return false;
6080 target->CastSpell(target,spell,false);
6082 return true;
6085 std::string GetTimeString(uint32 time)
6087 uint16 days = time / DAY, hours = (time % DAY) / HOUR, minute = (time % HOUR) / MINUTE;
6088 std::ostringstream ss;
6089 if(days) ss << days << "d ";
6090 if(hours) ss << hours << "h ";
6091 ss << minute << "m";
6092 return ss.str();
6095 bool ChatHandler::HandleInstanceListBindsCommand(const char* /*args*/)
6097 Player* player = getSelectedPlayer();
6098 if (!player) player = m_session->GetPlayer();
6099 uint32 counter = 0;
6100 for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++)
6102 Player::BoundInstancesMap &binds = player->GetBoundInstances(i);
6103 for(Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end(); ++itr)
6105 InstanceSave *save = itr->second.save;
6106 std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
6107 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());
6108 counter++;
6111 PSendSysMessage("player binds: %d", counter);
6112 counter = 0;
6113 Group *group = player->GetGroup();
6114 if(group)
6116 for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++)
6118 Group::BoundInstancesMap &binds = group->GetBoundInstances(i);
6119 for(Group::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end(); ++itr)
6121 InstanceSave *save = itr->second.save;
6122 std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
6123 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());
6124 counter++;
6128 PSendSysMessage("group binds: %d", counter);
6130 return true;
6133 bool ChatHandler::HandleInstanceUnbindCommand(const char* args)
6135 if(!*args)
6136 return false;
6138 std::string cmd = args;
6139 if(cmd == "all")
6141 Player* player = getSelectedPlayer();
6142 if (!player) player = m_session->GetPlayer();
6143 uint32 counter = 0;
6144 for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++)
6146 Player::BoundInstancesMap &binds = player->GetBoundInstances(i);
6147 for(Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end();)
6149 if(itr->first != player->GetMapId())
6151 InstanceSave *save = itr->second.save;
6152 std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
6153 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());
6154 player->UnbindInstance(itr, i);
6155 counter++;
6157 else
6158 ++itr;
6161 PSendSysMessage("instances unbound: %d", counter);
6163 return true;
6166 bool ChatHandler::HandleInstanceStatsCommand(const char* /*args*/)
6168 PSendSysMessage("instances loaded: %d", MapManager::Instance().GetNumInstances());
6169 PSendSysMessage("players in instances: %d", MapManager::Instance().GetNumPlayersInInstances());
6170 PSendSysMessage("instance saves: %d", sInstanceSaveManager.GetNumInstanceSaves());
6171 PSendSysMessage("players bound: %d", sInstanceSaveManager.GetNumBoundPlayersTotal());
6172 PSendSysMessage("groups bound: %d", sInstanceSaveManager.GetNumBoundGroupsTotal());
6173 return true;
6176 bool ChatHandler::HandleInstanceSaveDataCommand(const char * /*args*/)
6178 Player* pl = m_session->GetPlayer();
6180 Map* map = pl->GetMap();
6181 if (!map->IsDungeon())
6183 PSendSysMessage("Map is not a dungeon.");
6184 SetSentErrorMessage(true);
6185 return false;
6188 if (!((InstanceMap*)map)->GetInstanceData())
6190 PSendSysMessage("Map has no instance data.");
6191 SetSentErrorMessage(true);
6192 return false;
6195 ((InstanceMap*)map)->GetInstanceData()->SaveToDB();
6196 return true;
6199 /// Display the list of GMs
6200 bool ChatHandler::HandleGMListFullCommand(const char* /*args*/)
6202 ///- Get the accounts with GM Level >0
6203 QueryResult *result = loginDatabase.Query( "SELECT username,gmlevel FROM account WHERE gmlevel > 0" );
6204 if(result)
6206 SendSysMessage(LANG_GMLIST);
6207 SendSysMessage("========================");
6208 SendSysMessage(LANG_GMLIST_HEADER);
6209 SendSysMessage("========================");
6211 ///- Circle through them. Display username and GM level
6214 Field *fields = result->Fetch();
6215 PSendSysMessage("|%15s|%6s|", fields[0].GetString(),fields[1].GetString());
6216 }while( result->NextRow() );
6218 PSendSysMessage("========================");
6219 delete result;
6221 else
6222 PSendSysMessage(LANG_GMLIST_EMPTY);
6223 return true;
6226 /// Define the 'Message of the day' for the realm
6227 bool ChatHandler::HandleServerSetMotdCommand(const char* args)
6229 sWorld.SetMotd(args);
6230 PSendSysMessage(LANG_MOTD_NEW, args);
6231 return true;
6234 /// Set/Unset the expansion level for an account
6235 bool ChatHandler::HandleAccountSetAddonCommand(const char* args)
6237 ///- Get the command line arguments
6238 char *szAcc = strtok((char*)args," ");
6239 char *szExp = strtok(NULL," ");
6241 if(!szAcc)
6242 return false;
6244 std::string account_name;
6245 uint32 account_id;
6247 if(!szExp)
6249 Player* player = getSelectedPlayer();
6250 if(!player)
6251 return false;
6253 account_id = player->GetSession()->GetAccountId();
6254 accmgr.GetName(account_id,account_name);
6255 szExp = szAcc;
6257 else
6259 ///- Convert Account name to Upper Format
6260 account_name = szAcc;
6261 if(!AccountMgr::normilizeString(account_name))
6263 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
6264 SetSentErrorMessage(true);
6265 return false;
6268 account_id = accmgr.GetId(account_name);
6269 if(!account_id)
6271 PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
6272 SetSentErrorMessage(true);
6273 return false;
6278 // Let set addon state only for lesser (strong) security level
6279 // or to self account
6280 if (m_session && m_session->GetAccountId () != account_id &&
6281 HasLowerSecurityAccount (NULL,account_id,true))
6282 return false;
6284 int lev=atoi(szExp); //get int anyway (0 if error)
6285 if(lev < 0)
6286 return false;
6288 // No SQL injection
6289 loginDatabase.PExecute("UPDATE account SET expansion = '%d' WHERE id = '%u'",lev,account_id);
6290 PSendSysMessage(LANG_ACCOUNT_SETADDON,account_name.c_str(),account_id,lev);
6291 return true;
6294 //Send items by mail
6295 bool ChatHandler::HandleSendItemsCommand(const char* args)
6297 if(!*args)
6298 return false;
6300 // format: name "subject text" "mail text" item1[:count1] item2[:count2] ... item12[:count12]
6302 std::string name = extractPlayerNameFromLink((char*)args);
6303 if(name.empty())
6305 SendSysMessage(LANG_PLAYER_NOT_FOUND);
6306 SetSentErrorMessage(true);
6307 return false;
6310 char* tail1 = strtok(NULL, "");
6311 if(!tail1)
6312 return false;
6314 char* msgSubject;
6315 if(*tail1=='"')
6316 msgSubject = strtok(tail1+1, "\"");
6317 else
6319 char* space = strtok(tail1, "\"");
6320 if(!space)
6321 return false;
6322 msgSubject = strtok(NULL, "\"");
6325 if (!msgSubject)
6326 return false;
6328 char* tail2 = strtok(NULL, "");
6329 if(!tail2)
6330 return false;
6332 char* msgText;
6333 if(*tail2=='"')
6334 msgText = strtok(tail2+1, "\"");
6335 else
6337 char* space = strtok(tail2, "\"");
6338 if(!space)
6339 return false;
6340 msgText = strtok(NULL, "\"");
6343 if (!msgText)
6344 return false;
6346 // msgSubject, msgText isn't NUL after prev. check
6347 std::string subject = msgSubject;
6348 std::string text = msgText;
6350 // extract items
6351 typedef std::pair<uint32,uint32> ItemPair;
6352 typedef std::list< ItemPair > ItemPairs;
6353 ItemPairs items;
6355 // get all tail string
6356 char* tail = strtok(NULL, "");
6358 // get from tail next item str
6359 while(char* itemStr = strtok(tail, " "))
6361 // and get new tail
6362 tail = strtok(NULL, "");
6364 // parse item str
6365 char* itemIdStr = strtok(itemStr, ":");
6366 char* itemCountStr = strtok(NULL, " ");
6368 uint32 item_id = atoi(itemIdStr);
6369 if(!item_id)
6370 return false;
6372 ItemPrototype const* item_proto = objmgr.GetItemPrototype(item_id);
6373 if(!item_proto)
6375 PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
6376 SetSentErrorMessage(true);
6377 return false;
6380 uint32 item_count = itemCountStr ? atoi(itemCountStr) : 1;
6381 if(item_count < 1 || item_proto->MaxCount > 0 && item_count > uint32(item_proto->MaxCount))
6383 PSendSysMessage(LANG_COMMAND_INVALID_ITEM_COUNT, item_count,item_id);
6384 SetSentErrorMessage(true);
6385 return false;
6388 while(item_count > item_proto->GetMaxStackSize())
6390 items.push_back(ItemPair(item_id,item_proto->GetMaxStackSize()));
6391 item_count -= item_proto->GetMaxStackSize();
6394 items.push_back(ItemPair(item_id,item_count));
6396 if(items.size() > MAX_MAIL_ITEMS)
6398 PSendSysMessage(LANG_COMMAND_MAIL_ITEMS_LIMIT, MAX_MAIL_ITEMS);
6399 SetSentErrorMessage(true);
6400 return false;
6404 uint64 receiver_guid = objmgr.GetPlayerGUIDByName(name);
6405 if(!receiver_guid)
6407 SendSysMessage(LANG_PLAYER_NOT_FOUND);
6408 SetSentErrorMessage(true);
6409 return false;
6412 // from console show not existed sender
6413 uint32 sender_guidlo = m_session ? m_session->GetPlayer()->GetGUIDLow() : 0;
6415 uint32 messagetype = MAIL_NORMAL;
6416 uint32 stationery = MAIL_STATIONERY_GM;
6417 uint32 itemTextId = !text.empty() ? objmgr.CreateItemText( text ) : 0;
6419 Player *receiver = objmgr.GetPlayer(receiver_guid);
6421 // fill mail
6422 MailItemsInfo mi; // item list preparing
6424 for(ItemPairs::const_iterator itr = items.begin(); itr != items.end(); ++itr)
6426 if(Item* item = Item::CreateItem(itr->first,itr->second,m_session ? m_session->GetPlayer() : 0))
6428 item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted
6429 mi.AddItem(item->GetGUIDLow(), item->GetEntry(), item);
6433 WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, &mi, 0, 0, MAIL_CHECK_MASK_NONE);
6435 std::string nameLink = playerLink(name);
6436 PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
6437 return true;
6440 ///Send money by mail
6441 bool ChatHandler::HandleSendMoneyCommand(const char* args)
6443 if (!*args)
6444 return false;
6446 /// format: name "subject text" "mail text" money
6448 std::string name = extractPlayerNameFromLink((char*)args);
6449 if(name.empty())
6451 SendSysMessage(LANG_PLAYER_NOT_FOUND);
6452 SetSentErrorMessage(true);
6453 return false;
6456 char* tail1 = strtok(NULL, "");
6457 if (!tail1)
6458 return false;
6460 char* msgSubject;
6461 if (*tail1=='"')
6462 msgSubject = strtok(tail1+1, "\"");
6463 else
6465 char* space = strtok(tail1, "\"");
6466 if (!space)
6467 return false;
6468 msgSubject = strtok(NULL, "\"");
6471 if (!msgSubject)
6472 return false;
6474 char* tail2 = strtok(NULL, "");
6475 if (!tail2)
6476 return false;
6478 char* msgText;
6479 if (*tail2=='"')
6480 msgText = strtok(tail2+1, "\"");
6481 else
6483 char* space = strtok(tail2, "\"");
6484 if (!space)
6485 return false;
6486 msgText = strtok(NULL, "\"");
6489 if (!msgText)
6490 return false;
6492 char* money_str = strtok(NULL, "");
6493 int32 money = money_str ? atoi(money_str) : 0;
6494 if (money <= 0)
6495 return false;
6497 // msgSubject, msgText isn't NUL after prev. check
6498 std::string subject = msgSubject;
6499 std::string text = msgText;
6501 uint64 receiver_guid = objmgr.GetPlayerGUIDByName(name);
6502 if (!receiver_guid)
6504 SendSysMessage(LANG_PLAYER_NOT_FOUND);
6505 SetSentErrorMessage(true);
6506 return false;
6509 uint32 mailId = objmgr.GenerateMailID();
6511 // from console show not existed sender
6512 uint32 sender_guidlo = m_session ? m_session->GetPlayer()->GetGUIDLow() : 0;
6514 uint32 messagetype = MAIL_NORMAL;
6515 uint32 stationery = MAIL_STATIONERY_GM;
6516 uint32 itemTextId = !text.empty() ? objmgr.CreateItemText( text ) : 0;
6518 Player *receiver = objmgr.GetPlayer(receiver_guid);
6520 WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, NULL, money, 0, MAIL_CHECK_MASK_NONE);
6522 std::string nameLink = playerLink(name);
6523 PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
6524 return true;
6527 /// Send a message to a player in game
6528 bool ChatHandler::HandleSendMessageCommand(const char* args)
6530 ///- Get the command line arguments
6531 std::string name = extractPlayerNameFromLink((char*)args);
6532 if(name.empty())
6534 SendSysMessage(LANG_PLAYER_NOT_FOUND);
6535 SetSentErrorMessage(true);
6536 return false;
6539 char* msg_str = strtok(NULL, "");
6540 if(!msg_str)
6541 return false;
6543 ///- Find the player and check that he is not logging out.
6544 Player *rPlayer = objmgr.GetPlayer(name.c_str());
6545 if(!rPlayer)
6547 SendSysMessage(LANG_PLAYER_NOT_FOUND);
6548 SetSentErrorMessage(true);
6549 return false;
6552 if(rPlayer->GetSession()->isLogingOut())
6554 SendSysMessage(LANG_PLAYER_NOT_FOUND);
6555 SetSentErrorMessage(true);
6556 return false;
6559 ///- Send the message
6560 //Use SendAreaTriggerMessage for fastest delivery.
6561 rPlayer->GetSession()->SendAreaTriggerMessage("%s", msg_str);
6562 rPlayer->GetSession()->SendAreaTriggerMessage("|cffff0000[Message from administrator]:|r");
6564 //Confirmation message
6565 std::string nameLink = playerLink(name);
6566 PSendSysMessage(LANG_SENDMESSAGE,nameLink.c_str(),msg_str);
6567 return true;
6570 bool ChatHandler::HandleFlushArenaPointsCommand(const char * /*args*/)
6572 sBattleGroundMgr.DistributeArenaPoints();
6573 return true;
6576 bool ChatHandler::HandleModifyGenderCommand(const char *args)
6578 if(!*args)
6579 return false;
6581 Player *player = getSelectedPlayer();
6583 if(!player)
6585 PSendSysMessage(LANG_NO_PLAYER);
6586 SetSentErrorMessage(true);
6587 return false;
6590 PlayerInfo const* info = objmgr.GetPlayerInfo(player->getRace(), player->getClass());
6591 if(!info)
6592 return false;
6594 char const* gender_str = (char*)args;
6595 int gender_len = strlen(gender_str);
6597 Gender gender;
6599 if(!strncmp(gender_str, "male", gender_len)) // MALE
6601 if(player->getGender() == GENDER_MALE)
6602 return true;
6604 gender = GENDER_MALE;
6606 else if (!strncmp(gender_str, "female", gender_len)) // FEMALE
6608 if(player->getGender() == GENDER_FEMALE)
6609 return true;
6611 gender = GENDER_FEMALE;
6613 else
6615 SendSysMessage(LANG_MUST_MALE_OR_FEMALE);
6616 SetSentErrorMessage(true);
6617 return false;
6620 // Set gender
6621 player->SetByteValue(UNIT_FIELD_BYTES_0, 2, gender);
6622 player->SetByteValue(PLAYER_BYTES_3, 0, gender);
6624 // Change display ID
6625 player->SetDisplayId(gender ? info->displayId_f : info->displayId_m);
6626 player->SetNativeDisplayId(gender ? info->displayId_f : info->displayId_m);
6628 char const* gender_full = gender ? "female" : "male";
6630 PSendSysMessage(LANG_YOU_CHANGE_GENDER, GetNameLink(player).c_str(), gender_full);
6632 if (needReportToTarget(player))
6633 ChatHandler(player).PSendSysMessage(LANG_YOUR_GENDER_CHANGED, gender_full, GetNameLink().c_str());
6635 return true;