root/trunk/src/game/Level3.cpp @ 37

Revision 37, 148.4 kB (checked in by yumileroy, 17 years ago)

[svn] * svn:eol-style native set on all files that need it

Original author: Neo2003
Date: 2008-10-11 14:16:25-05:00

Line 
1/*
2 * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
3 *
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.
8 *
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.
13 *
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
17 */
18
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 "PlayerDump.h"
26#include "SpellMgr.h"
27#include "Player.h"
28#include "Opcodes.h"
29#include "GameObject.h"
30#include "Chat.h"
31#include "Log.h"
32#include "Guild.h"
33#include "ObjectAccessor.h"
34#include "MapManager.h"
35#include "SpellAuras.h"
36#include "ScriptCalls.h"
37#include "Language.h"
38#include "GridNotifiersImpl.h"
39#include "CellImpl.h"
40#include "Weather.h"
41#include "PointMovementGenerator.h"
42#include "TargetedMovementGenerator.h"
43#include "SkillDiscovery.h"
44#include "SkillExtraItems.h"
45#include "SystemConfig.h"
46#include "Config/ConfigEnv.h"
47#include "Util.h"
48#include "ItemEnchantmentMgr.h"
49#include "BattleGroundMgr.h"
50#include "InstanceSaveMgr.h"
51#include "InstanceData.h"
52
53//reload commands
54bool ChatHandler::HandleReloadCommand(const char* arg)
55{
56    // this is error catcher for wrong table name in .reload commands
57    PSendSysMessage("Db table with name starting from '%s' not found and can't be reloaded.",arg);
58    SetSentErrorMessage(true);
59    return false;
60}
61
62bool ChatHandler::HandleReloadAllCommand(const char*)
63{
64    HandleReloadAreaTriggerTeleportCommand("");
65    HandleReloadSkillFishingBaseLevelCommand("");
66
67    HandleReloadAllAreaCommand("");
68    HandleReloadAllLootCommand("");
69    HandleReloadAllNpcCommand("");
70    HandleReloadAllQuestCommand("");
71    HandleReloadAllSpellCommand("");
72    HandleReloadAllItemCommand("");
73
74    HandleReloadCommandCommand("");
75    HandleReloadReservedNameCommand("");
76    HandleReloadMangosStringCommand("");
77    HandleReloadGameTeleCommand("");
78    return true;
79}
80
81bool ChatHandler::HandleReloadAllAreaCommand(const char*)
82{
83    //HandleReloadQuestAreaTriggersCommand(""); -- reloaded in HandleReloadAllQuestCommand
84    HandleReloadAreaTriggerTeleportCommand("");
85    HandleReloadAreaTriggerTavernCommand("");
86    HandleReloadGameGraveyardZoneCommand("");
87    return true;
88}
89
90bool ChatHandler::HandleReloadAllLootCommand(const char*)
91{
92    sLog.outString( "Re-Loading Loot Tables..." );
93    LoadLootTables();
94    SendGlobalSysMessage("DB tables `*_loot_template` reloaded.");
95    return true;
96}
97
98bool ChatHandler::HandleReloadAllNpcCommand(const char* /*args*/)
99{
100    HandleReloadNpcGossipCommand("a");
101    HandleReloadNpcTrainerCommand("a");
102    HandleReloadNpcVendorCommand("a");
103    return true;
104}
105
106bool ChatHandler::HandleReloadAllQuestCommand(const char* /*args*/)
107{
108    HandleReloadQuestAreaTriggersCommand("a");
109    HandleReloadQuestTemplateCommand("a");
110
111    sLog.outString( "Re-Loading Quests Relations..." );
112    objmgr.LoadQuestRelations();
113    SendGlobalSysMessage("DB tables `*_questrelation` and `*_involvedrelation` reloaded.");
114    return true;
115}
116
117bool ChatHandler::HandleReloadAllScriptsCommand(const char*)
118{
119    if(sWorld.IsScriptScheduled())
120    {
121        PSendSysMessage("DB scripts used currently, please attempt reload later.");
122        SetSentErrorMessage(true);
123        return false;
124    }
125
126    sLog.outString( "Re-Loading Scripts..." );
127    HandleReloadGameObjectScriptsCommand("a");
128    HandleReloadEventScriptsCommand("a");
129    HandleReloadQuestEndScriptsCommand("a");
130    HandleReloadQuestStartScriptsCommand("a");
131    HandleReloadSpellScriptsCommand("a");
132    SendGlobalSysMessage("DB tables `*_scripts` reloaded.");
133    return true;
134}
135
136bool ChatHandler::HandleReloadAllSpellCommand(const char*)
137{
138    HandleReloadSkillDiscoveryTemplateCommand("a");
139    HandleReloadSkillExtraItemTemplateCommand("a");
140    HandleReloadSpellAffectCommand("a");
141    HandleReloadSpellChainCommand("a");
142    HandleReloadSpellElixirCommand("a");
143    HandleReloadSpellLearnSpellCommand("a");
144    HandleReloadSpellProcEventCommand("a");
145    HandleReloadSpellScriptTargetCommand("a");
146    HandleReloadSpellTargetPositionCommand("a");
147    HandleReloadSpellThreatsCommand("a");
148    HandleReloadSpellPetAurasCommand("a");
149    return true;
150}
151
152bool ChatHandler::HandleReloadAllItemCommand(const char*)
153{
154    HandleReloadPageTextsCommand("a");
155    HandleReloadItemEnchantementsCommand("a");
156    return true;
157}
158
159bool ChatHandler::HandleReloadConfigCommand(const char* arg)
160{
161    sLog.outString( "Re-Loading config settings..." );
162    sWorld.LoadConfigSettings(true);
163    SendGlobalSysMessage("World config settings reloaded.");
164    return true;
165}
166
167bool ChatHandler::HandleReloadAreaTriggerTavernCommand(const char*)
168{
169    sLog.outString( "Re-Loading Tavern Area Triggers..." );
170    objmgr.LoadTavernAreaTriggers();
171    SendGlobalSysMessage("DB table `areatrigger_tavern` reloaded.");
172    return true;
173}
174
175bool ChatHandler::HandleReloadAreaTriggerTeleportCommand(const char*)
176{
177    sLog.outString( "Re-Loading AreaTrigger teleport definitions..." );
178    objmgr.LoadAreaTriggerTeleports();
179    SendGlobalSysMessage("DB table `areatrigger_teleport` reloaded.");
180    return true;
181}
182
183bool ChatHandler::HandleReloadCommandCommand(const char*)
184{
185    load_command_table = true;
186    SendGlobalSysMessage("DB table `command` will be reloaded at next chat command use.");
187    return true;
188}
189
190bool ChatHandler::HandleReloadCreatureQuestRelationsCommand(const char*)
191{
192    sLog.outString( "Loading Quests Relations... (`creature_questrelation`)" );
193    objmgr.LoadCreatureQuestRelations();
194    SendGlobalSysMessage("DB table `creature_questrelation` (creature quest givers) reloaded.");
195    return true;
196}
197
198bool ChatHandler::HandleReloadCreatureQuestInvRelationsCommand(const char*)
199{
200    sLog.outString( "Loading Quests Relations... (`creature_involvedrelation`)" );
201    objmgr.LoadCreatureInvolvedRelations();
202    SendGlobalSysMessage("DB table `creature_involvedrelation` (creature quest takers) reloaded.");
203    return true;
204}
205
206bool ChatHandler::HandleReloadGOQuestRelationsCommand(const char*)
207{
208    sLog.outString( "Loading Quests Relations... (`gameobject_questrelation`)" );
209    objmgr.LoadGameobjectQuestRelations();
210    SendGlobalSysMessage("DB table `gameobject_questrelation` (gameobject quest givers) reloaded.");
211    return true;
212}
213
214bool ChatHandler::HandleReloadGOQuestInvRelationsCommand(const char*)
215{
216    sLog.outString( "Loading Quests Relations... (`gameobject_involvedrelation`)" );
217    objmgr.LoadGameobjectInvolvedRelations();
218    SendGlobalSysMessage("DB table `gameobject_involvedrelation` (gameobject quest takers) reloaded.");
219    return true;
220}
221
222bool ChatHandler::HandleReloadQuestAreaTriggersCommand(const char*)
223{
224    sLog.outString( "Re-Loading Quest Area Triggers..." );
225    objmgr.LoadQuestAreaTriggers();
226    SendGlobalSysMessage("DB table `areatrigger_involvedrelation` (quest area triggers) reloaded.");
227    return true;
228}
229
230bool ChatHandler::HandleReloadQuestTemplateCommand(const char*)
231{
232    sLog.outString( "Re-Loading Quest Templates..." );
233    objmgr.LoadQuests();
234    SendGlobalSysMessage("DB table `quest_template` (quest definitions) reloaded.");
235    return true;
236}
237
238bool ChatHandler::HandleReloadLootTemplatesCreatureCommand(const char*)
239{
240    sLog.outString( "Re-Loading Loot Tables... (`creature_loot_template`)" );
241    LoadLootTemplates_Creature();
242    LootTemplates_Creature.CheckLootRefs();
243    SendGlobalSysMessage("DB table `creature_loot_template` reloaded.");
244    return true;
245}
246
247bool ChatHandler::HandleReloadLootTemplatesDisenchantCommand(const char*)
248{
249    sLog.outString( "Re-Loading Loot Tables... (`disenchant_loot_template`)" );
250    LoadLootTemplates_Disenchant();
251    LootTemplates_Disenchant.CheckLootRefs();
252    SendGlobalSysMessage("DB table `disenchant_loot_template` reloaded.");
253    return true;
254}
255
256bool ChatHandler::HandleReloadLootTemplatesFishingCommand(const char*)
257{
258    sLog.outString( "Re-Loading Loot Tables... (`fishing_loot_template`)" );
259    LoadLootTemplates_Fishing();
260    LootTemplates_Fishing.CheckLootRefs();
261    SendGlobalSysMessage("DB table `fishing_loot_template` reloaded.");
262    return true;
263}
264
265bool ChatHandler::HandleReloadLootTemplatesGameobjectCommand(const char*)
266{
267    sLog.outString( "Re-Loading Loot Tables... (`gameobject_loot_template`)" );
268    LoadLootTemplates_Gameobject();
269    LootTemplates_Gameobject.CheckLootRefs();
270    SendGlobalSysMessage("DB table `gameobject_loot_template` reloaded.");
271    return true;
272}
273
274bool ChatHandler::HandleReloadLootTemplatesItemCommand(const char*)
275{
276    sLog.outString( "Re-Loading Loot Tables... (`item_loot_template`)" );
277    LoadLootTemplates_Item();
278    LootTemplates_Item.CheckLootRefs();
279    SendGlobalSysMessage("DB table `item_loot_template` reloaded.");
280    return true;
281}
282
283bool ChatHandler::HandleReloadLootTemplatesPickpocketingCommand(const char*)
284{
285    sLog.outString( "Re-Loading Loot Tables... (`pickpocketing_loot_template`)" );
286    LoadLootTemplates_Pickpocketing();
287    LootTemplates_Pickpocketing.CheckLootRefs();
288    SendGlobalSysMessage("DB table `pickpocketing_loot_template` reloaded.");
289    return true;
290}
291
292bool ChatHandler::HandleReloadLootTemplatesProspectingCommand(const char*)
293{
294    sLog.outString( "Re-Loading Loot Tables... (`prospecting_loot_template`)" );
295    LoadLootTemplates_Prospecting();
296    LootTemplates_Prospecting.CheckLootRefs();
297    SendGlobalSysMessage("DB table `prospecting_loot_template` reloaded.");
298    return true;
299}
300
301bool ChatHandler::HandleReloadLootTemplatesQuestMailCommand(const char*)
302{
303    sLog.outString( "Re-Loading Loot Tables... (`quest_mail_loot_template`)" );
304    LoadLootTemplates_QuestMail();
305    LootTemplates_QuestMail.CheckLootRefs();
306    SendGlobalSysMessage("DB table `quest_mail_loot_template` reloaded.");
307    return true;
308}
309
310bool ChatHandler::HandleReloadLootTemplatesReferenceCommand(const char*)
311{
312    sLog.outString( "Re-Loading Loot Tables... (`reference_loot_template`)" );
313    LoadLootTemplates_Reference();
314    SendGlobalSysMessage("DB table `reference_loot_template` reloaded.");
315    return true;
316}
317
318bool ChatHandler::HandleReloadLootTemplatesSkinningCommand(const char*)
319{
320    sLog.outString( "Re-Loading Loot Tables... (`skinning_loot_template`)" );
321    LoadLootTemplates_Skinning();
322    LootTemplates_Skinning.CheckLootRefs();
323    SendGlobalSysMessage("DB table `skinning_loot_template` reloaded.");
324    return true;
325}
326
327bool ChatHandler::HandleReloadMangosStringCommand(const char*)
328{
329    sLog.outString( "Re-Loading mangos_string Table!" );
330    objmgr.LoadMangosStrings();
331    SendGlobalSysMessage("DB table `mangos_string` reloaded.");
332    return true;
333}
334
335bool ChatHandler::HandleReloadNpcGossipCommand(const char*)
336{
337    sLog.outString( "Re-Loading `npc_gossip` Table!" );
338    objmgr.LoadNpcTextId();
339    SendGlobalSysMessage("DB table `npc_gossip` reloaded.");
340    return true;
341}
342
343bool ChatHandler::HandleReloadNpcTrainerCommand(const char*)
344{
345    sLog.outString( "Re-Loading `npc_trainer` Table!" );
346    objmgr.LoadTrainerSpell();
347    SendGlobalSysMessage("DB table `npc_trainer` reloaded.");
348    return true;
349}
350
351bool ChatHandler::HandleReloadNpcVendorCommand(const char*)
352{
353    sLog.outString( "Re-Loading `npc_vendor` Table!" );
354    objmgr.LoadVendors();
355    SendGlobalSysMessage("DB table `npc_vendor` reloaded.");
356    return true;
357}
358
359bool ChatHandler::HandleReloadReservedNameCommand(const char*)
360{
361    sLog.outString( "Loading ReservedNames... (`reserved_name`)" );
362    objmgr.LoadReservedPlayersNames();
363    SendGlobalSysMessage("DB table `reserved_name` (player reserved names) reloaded.");
364    return true;
365}
366
367bool ChatHandler::HandleReloadSkillDiscoveryTemplateCommand(const char* /*args*/)
368{
369    sLog.outString( "Re-Loading Skill Discovery Table..." );
370    LoadSkillDiscoveryTable();
371    SendGlobalSysMessage("DB table `skill_discovery_template` (recipes discovered at crafting) reloaded.");
372    return true;
373}
374
375bool ChatHandler::HandleReloadSkillExtraItemTemplateCommand(const char* /*args*/)
376{
377    sLog.outString( "Re-Loading Skill Extra Item Table..." );
378    LoadSkillExtraItemTable();
379    SendGlobalSysMessage("DB table `skill_extra_item_template` (extra item creation when crafting) reloaded.");
380    return true;
381}
382
383bool ChatHandler::HandleReloadSkillFishingBaseLevelCommand(const char* /*args*/)
384{
385    sLog.outString( "Re-Loading Skill Fishing base level requirements..." );
386    objmgr.LoadFishingBaseSkillLevel();
387    SendGlobalSysMessage("DB table `skill_fishing_base_level` (fishing base level for zone/subzone) reloaded.");
388    return true;
389}
390
391bool ChatHandler::HandleReloadSpellAffectCommand(const char*)
392{
393    sLog.outString( "Re-Loading SpellAffect definitions..." );
394    spellmgr.LoadSpellAffects();
395    SendGlobalSysMessage("DB table `spell_affect` (spell mods apply requirements) reloaded.");
396    return true;
397}
398
399bool ChatHandler::HandleReloadSpellChainCommand(const char*)
400{
401    sLog.outString( "Re-Loading Spell Chain Data... " );
402    spellmgr.LoadSpellChains();
403    SendGlobalSysMessage("DB table `spell_chain` (spell ranks) reloaded.");
404    return true;
405}
406
407bool ChatHandler::HandleReloadSpellElixirCommand(const char*)
408{
409    sLog.outString( "Re-Loading Spell Elixir types..." );
410    spellmgr.LoadSpellElixirs();
411    SendGlobalSysMessage("DB table `spell_elixir` (spell exlixir types) reloaded.");
412    return true;
413}
414
415bool ChatHandler::HandleReloadSpellLearnSpellCommand(const char*)
416{
417    sLog.outString( "Re-Loading Spell Learn Spells..." );
418    spellmgr.LoadSpellLearnSpells();
419    SendGlobalSysMessage("DB table `spell_learn_spell` reloaded.");
420    return true;
421}
422
423bool ChatHandler::HandleReloadSpellProcEventCommand(const char*)
424{
425    sLog.outString( "Re-Loading Spell Proc Event conditions..." );
426    spellmgr.LoadSpellProcEvents();
427    SendGlobalSysMessage("DB table `spell_proc_event` (spell proc trigger requirements) reloaded.");
428    return true;
429}
430
431bool ChatHandler::HandleReloadSpellScriptTargetCommand(const char*)
432{
433    sLog.outString( "Re-Loading SpellsScriptTarget..." );
434    spellmgr.LoadSpellScriptTarget();
435    SendGlobalSysMessage("DB table `spell_script_target` (spell targets selection in case specific creature/GO requirements) reloaded.");
436    return true;
437}
438
439bool ChatHandler::HandleReloadSpellTargetPositionCommand(const char*)
440{
441    sLog.outString( "Re-Loading Spell target coordinates..." );
442    spellmgr.LoadSpellTargetPositions();
443    SendGlobalSysMessage("DB table `spell_target_position` (destination coordinates for spell targets) reloaded.");
444    return true;
445}
446
447bool ChatHandler::HandleReloadSpellThreatsCommand(const char*)
448{
449    sLog.outString( "Re-Loading Aggro Spells Definitions...");
450    spellmgr.LoadSpellThreats();
451    SendGlobalSysMessage("DB table `spell_threat` (spell aggro definitions) reloaded.");
452    return true;
453}
454
455bool ChatHandler::HandleReloadSpellPetAurasCommand(const char*)
456{
457    sLog.outString( "Re-Loading Spell pet auras...");
458    spellmgr.LoadSpellPetAuras();
459    SendGlobalSysMessage("DB table `spell_pet_auras` reloaded.");
460    return true;
461}
462
463bool ChatHandler::HandleReloadPageTextsCommand(const char*)
464{
465    sLog.outString( "Re-Loading Page Texts..." );
466    objmgr.LoadPageTexts();
467    SendGlobalSysMessage("DB table `page_texts` reloaded.");
468    return true;
469}
470
471bool ChatHandler::HandleReloadItemEnchantementsCommand(const char*)
472{
473    sLog.outString( "Re-Loading Item Random Enchantments Table..." );
474    LoadRandomEnchantmentsTable();
475    SendGlobalSysMessage("DB table `item_enchantment_template` reloaded.");
476    return true;
477}
478
479bool ChatHandler::HandleReloadGameObjectScriptsCommand(const char* arg)
480{
481    if(sWorld.IsScriptScheduled())
482    {
483        SendSysMessage("DB scripts used currently, please attempt reload later.");
484        SetSentErrorMessage(true);
485        return false;
486    }
487
488    if(*arg!='a')
489        sLog.outString( "Re-Loading Scripts from `gameobject_scripts`...");
490
491    objmgr.LoadGameObjectScripts();
492
493    if(*arg!='a')
494        SendGlobalSysMessage("DB table `gameobject_scripts` reloaded.");
495
496    return true;
497}
498
499bool ChatHandler::HandleReloadEventScriptsCommand(const char* arg)
500{
501    if(sWorld.IsScriptScheduled())
502    {
503        SendSysMessage("DB scripts used currently, please attempt reload later.");
504        SetSentErrorMessage(true);
505        return false;
506    }
507
508    if(*arg!='a')
509        sLog.outString( "Re-Loading Scripts from `event_scripts`...");
510
511    objmgr.LoadEventScripts();
512
513    if(*arg!='a')
514        SendGlobalSysMessage("DB table `event_scripts` reloaded.");
515
516    return true;
517}
518
519bool ChatHandler::HandleReloadQuestEndScriptsCommand(const char* arg)
520{
521    if(sWorld.IsScriptScheduled())
522    {
523        SendSysMessage("DB scripts used currently, please attempt reload later.");
524        SetSentErrorMessage(true);
525        return false;
526    }
527
528    if(*arg!='a')
529        sLog.outString( "Re-Loading Scripts from `quest_end_scripts`...");
530
531    objmgr.LoadQuestEndScripts();
532
533    if(*arg!='a')
534        SendGlobalSysMessage("DB table `quest_end_scripts` reloaded.");
535
536    return true;
537}
538
539bool ChatHandler::HandleReloadQuestStartScriptsCommand(const char* arg)
540{
541    if(sWorld.IsScriptScheduled())
542    {
543        SendSysMessage("DB scripts used currently, please attempt reload later.");
544        SetSentErrorMessage(true);
545        return false;
546    }
547
548    if(*arg!='a')
549        sLog.outString( "Re-Loading Scripts from `quest_start_scripts`...");
550
551    objmgr.LoadQuestStartScripts();
552
553    if(*arg!='a')
554        SendGlobalSysMessage("DB table `quest_start_scripts` reloaded.");
555
556    return true;
557}
558
559bool ChatHandler::HandleReloadSpellScriptsCommand(const char* arg)
560{
561    if(sWorld.IsScriptScheduled())
562    {
563        SendSysMessage("DB scripts used currently, please attempt reload later.");
564        SetSentErrorMessage(true);
565        return false;
566    }
567
568    if(*arg!='a')
569        sLog.outString( "Re-Loading Scripts from `spell_scripts`...");
570
571    objmgr.LoadSpellScripts();
572
573    if(*arg!='a')
574        SendGlobalSysMessage("DB table `spell_scripts` reloaded.");
575
576    return true;
577}
578
579bool ChatHandler::HandleReloadGameGraveyardZoneCommand(const char* /*arg*/)
580{
581    sLog.outString( "Re-Loading Graveyard-zone links...");
582
583    objmgr.LoadGraveyardZones();
584
585    SendGlobalSysMessage("DB table `game_graveyard_zone` reloaded.");
586
587    return true;
588}
589
590bool ChatHandler::HandleReloadGameTeleCommand(const char* /*arg*/)
591{
592    sLog.outString( "Re-Loading Game Tele coordinates...");
593
594    objmgr.LoadGameTele();
595
596    SendGlobalSysMessage("DB table `game_tele` reloaded.");
597
598    return true;
599}
600
601bool ChatHandler::HandleLoadScriptsCommand(const char* args)
602{
603    if(!LoadScriptingModule(args)) return true;
604
605    sWorld.SendWorldText(LANG_SCRIPTS_RELOADED);
606    return true;
607}
608
609bool ChatHandler::HandleSecurityCommand(const char* args)
610{
611    char* arg1 = strtok((char*)args, " ");
612    if( !arg1 )
613        return false;
614
615    char* arg2 = 0;
616
617    std::string targetName;
618    uint32 targetAccountId = 0;
619    uint32 targetSecurity = 0;
620
621    Player* targetPlayer = getSelectedPlayer();
622    if(targetPlayer)
623    {
624        targetName = targetPlayer->GetName();
625        targetAccountId = targetPlayer->GetSession()->GetAccountId();
626        targetSecurity = targetPlayer->GetSession()->GetSecurity();
627        arg2 = arg1;
628    }
629    else
630    {
631        targetName = arg1;
632        if(!normalizePlayerName(targetName))
633        {
634            SendSysMessage(LANG_PLAYER_NOT_FOUND);
635            SetSentErrorMessage(true);
636            return false;
637        }
638
639        targetPlayer = ObjectAccessor::Instance().FindPlayerByName(targetName.c_str());
640        if(targetPlayer)
641        {
642            targetAccountId = targetPlayer->GetSession()->GetAccountId();
643            targetSecurity = targetPlayer->GetSession()->GetSecurity();
644        }
645        else
646        {
647            uint64 targetGUID = objmgr.GetPlayerGUIDByName(targetName.c_str());
648            if(!targetGUID)
649            {
650                SendSysMessage(LANG_PLAYER_NOT_FOUND);
651                SetSentErrorMessage(true);
652                return false;
653            }
654            targetAccountId = objmgr.GetPlayerAccountIdByGUID(targetGUID);
655            targetSecurity = objmgr.GetSecurityByAccount(targetAccountId);
656        }
657
658        arg2 = strtok(NULL, " ");
659    }
660
661    int32 gm = (int32)atoi(arg2);
662    if ( gm < SEC_PLAYER || gm > SEC_ADMINISTRATOR )
663    {
664        SendSysMessage(LANG_BAD_VALUE);
665        SetSentErrorMessage(true);
666        return false;
667    }
668
669    // can set security level only for target with less security and to less security that we have
670    if(targetSecurity >= m_session->GetSecurity() || uint32(gm) >= m_session->GetSecurity() )
671    {
672        SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
673        SetSentErrorMessage(true);
674        return false;
675    }
676
677    if(targetPlayer)
678    {
679        if( targetPlayer != m_session->GetPlayer() )
680            ChatHandler(targetPlayer).PSendSysMessage(LANG_YOURS_SECURITY_CHANGED,m_session->GetPlayer()->GetName(), gm);
681
682        targetPlayer->GetSession()->SetSecurity(gm);
683    }
684
685    PSendSysMessage(LANG_YOU_CHANGE_SECURITY, targetName.c_str(), gm);
686    loginDatabase.PExecute("UPDATE account SET gmlevel = '%i' WHERE id = '%u'", gm, targetAccountId);
687
688    return true;
689}
690
691bool ChatHandler::HandleAllowMovementCommand(const char* /*args*/)
692{
693    if(sWorld.getAllowMovement())
694    {
695        sWorld.SetAllowMovement(false);
696        SendSysMessage(LANG_CREATURE_MOVE_DISABLED);
697    }
698    else
699    {
700        sWorld.SetAllowMovement(true);
701        SendSysMessage(LANG_CREATURE_MOVE_ENABLED);
702    }
703    return true;
704}
705
706bool ChatHandler::HandleMaxSkillCommand(const char* /*args*/)
707{
708    Player* SelectedPlayer = getSelectedPlayer();
709    if(!SelectedPlayer)
710    {
711        SendSysMessage(LANG_NO_CHAR_SELECTED);
712        SetSentErrorMessage(true);
713        return false;
714    }
715
716    // each skills that have max skill value dependent from level seted to current level max skill value
717    SelectedPlayer->UpdateSkillsToMaxSkillsForLevel();
718    return true;
719}
720
721bool ChatHandler::HandleSetSkillCommand(const char* args)
722{
723    // number or [name] Shift-click form |color|Hskill:skill_id|h[name]|h|r
724    char* skill_p = extractKeyFromLink((char*)args,"Hskill");
725    if(!skill_p)
726        return false;
727
728    char *level_p = strtok (NULL, " ");
729
730    if( !level_p)
731        return false;
732
733    char *max_p   = strtok (NULL, " ");
734
735    int32 skill = atoi(skill_p);
736
737    if (skill <= 0)
738    {
739        PSendSysMessage(LANG_INVALID_SKILL_ID, skill);
740        SetSentErrorMessage(true);
741        return false;
742    }
743
744    int32 level = atol (level_p);
745
746    Player * target = getSelectedPlayer();
747    if(!target)
748    {
749        SendSysMessage(LANG_NO_CHAR_SELECTED);
750        SetSentErrorMessage(true);
751        return false;
752    }
753
754    SkillLineEntry const* sl = sSkillLineStore.LookupEntry(skill);
755    if(!sl)
756    {
757        PSendSysMessage(LANG_INVALID_SKILL_ID, skill);
758        SetSentErrorMessage(true);
759        return false;
760    }
761
762    if(!target->GetSkillValue(skill))
763    {
764        PSendSysMessage(LANG_SET_SKILL_ERROR, target->GetName(), skill, sl->name[0]);
765        SetSentErrorMessage(true);
766        return false;
767    }
768
769    int32 max   = max_p ? atol (max_p) : target->GetPureMaxSkillValue(skill);
770
771    if( level <= 0 || level > max || max <= 0 )
772        return false;
773
774    target->SetSkill(skill, level, max);
775    PSendSysMessage(LANG_SET_SKILL, skill, sl->name[0], target->GetName(), level, max);
776
777    return true;
778}
779
780bool ChatHandler::HandleUnLearnCommand(const char* args)
781{
782    if (!*args)
783        return false;
784
785
786    // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
787    uint32 min_id = extractSpellIdFromLink((char*)args);
788    if(!min_id)
789        return false;
790
791    // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
792    char* tail = strtok(NULL,"");
793
794    uint32 max_id = extractSpellIdFromLink(tail);
795
796    if (!max_id)
797    {
798        // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
799        max_id =  min_id+1;
800    }
801    else
802    {
803        if (max_id < min_id)
804            std::swap(min_id,max_id);
805
806        max_id=max_id+1;
807    }
808
809    Player* target = getSelectedPlayer();
810    if(!target)
811    {
812        SendSysMessage(LANG_NO_CHAR_SELECTED);
813        SetSentErrorMessage(true);
814        return false;
815    }
816
817    for(uint32 spell=min_id;spell<max_id;spell++)
818    {
819        if (target->HasSpell(spell))
820            target->removeSpell(spell);
821        else
822            SendSysMessage(LANG_FORGET_SPELL);
823    }
824
825    return true;
826}
827
828bool ChatHandler::HandleCooldownCommand(const char* args)
829{
830    Player* target = getSelectedPlayer();
831    if(!target)
832    {
833        SendSysMessage(LANG_PLAYER_NOT_FOUND);
834        SetSentErrorMessage(true);
835        return false;
836    }
837
838    if (!*args)
839    {
840        target->RemoveAllSpellCooldown();
841        PSendSysMessage(LANG_REMOVEALL_COOLDOWN, target->GetName());
842    }
843    else
844    {
845        // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
846        uint32 spell_id = extractSpellIdFromLink((char*)args);
847        if(!spell_id)
848            return false;
849
850        if(!sSpellStore.LookupEntry(spell_id))
851        {
852            PSendSysMessage(LANG_UNKNOWN_SPELL, target==m_session->GetPlayer() ? GetMangosString(LANG_YOU) : target->GetName());
853            SetSentErrorMessage(true);
854            return false;
855        }
856
857        WorldPacket data( SMSG_CLEAR_COOLDOWN, (4+8) );
858        data << uint32(spell_id);
859        data << uint64(target->GetGUID());
860        target->GetSession()->SendPacket(&data);
861        target->RemoveSpellCooldown(spell_id);
862        PSendSysMessage(LANG_REMOVE_COOLDOWN, spell_id, target==m_session->GetPlayer() ? GetMangosString(LANG_YOU) : target->GetName());
863    }
864    return true;
865}
866
867bool ChatHandler::HandleLearnAllCommand(const char* /*args*/)
868{
869    static const char *allSpellList[] =
870    {
871        "3365",
872        "6233",
873        "6247",
874        "6246",
875        "6477",
876        "6478",
877        "22810",
878        "8386",
879        "21651",
880        "21652",
881        "522",
882        "7266",
883        "8597",
884        "2479",
885        "22027",
886        "6603",
887        "5019",
888        "133",
889        "168",
890        "227",
891        "5009",
892        "9078",
893        "668",
894        "203",
895        "20599",
896        "20600",
897        "81",
898        "20597",
899        "20598",
900        "20864",
901        "1459",
902        "5504",
903        "587",
904        "5143",
905        "118",
906        "5505",
907        "597",
908        "604",
909        "1449",
910        "1460",
911        "2855",
912        "1008",
913        "475",
914        "5506",
915        "1463",
916        "12824",
917        "8437",
918        "990",
919        "5145",
920        "8450",
921        "1461",
922        "759",
923        "8494",
924        "8455",
925        "8438",
926        "6127",
927        "8416",
928        "6129",
929        "8451",
930        "8495",
931        "8439",
932        "3552",
933        "8417",
934        "10138",
935        "12825",
936        "10169",
937        "10156",
938        "10144",
939        "10191",
940        "10201",
941        "10211",
942        "10053",
943        "10173",
944        "10139",
945        "10145",
946        "10192",
947        "10170",
948        "10202",
949        "10054",
950        "10174",
951        "10193",
952        "12826",
953        "2136",
954        "143",
955        "145",
956        "2137",
957        "2120",
958        "3140",
959        "543",
960        "2138",
961        "2948",
962        "8400",
963        "2121",
964        "8444",
965        "8412",
966        "8457",
967        "8401",
968        "8422",
969        "8445",
970        "8402",
971        "8413",
972        "8458",
973        "8423",
974        "8446",
975        "10148",
976        "10197",
977        "10205",
978        "10149",
979        "10215",
980        "10223",
981        "10206",
982        "10199",
983        "10150",
984        "10216",
985        "10207",
986        "10225",
987        "10151",
988        "116",
989        "205",
990        "7300",
991        "122",
992        "837",
993        "10",
994        "7301",
995        "7322",
996        "6143",
997        "120",
998        "865",
999        "8406",
1000        "6141",
1001        "7302",
1002        "8461",
1003        "8407",
1004        "8492",
1005        "8427",
1006        "8408",
1007        "6131",
1008        "7320",
1009        "10159",
1010        "8462",
1011        "10185",
1012        "10179",
1013        "10160",
1014        "10180",
1015        "10219",
1016        "10186",
1017        "10177",
1018        "10230",
1019        "10181",
1020        "10161",
1021        "10187",
1022        "10220",
1023        "2018",
1024        "2663",
1025        "12260",
1026        "2660",
1027        "3115",
1028        "3326",
1029        "2665",
1030        "3116",
1031        "2738",
1032        "3293",
1033        "2661",
1034        "3319",
1035        "2662",
1036        "9983",
1037        "8880",
1038        "2737",
1039        "2739",
1040        "7408",
1041        "3320",
1042        "2666",
1043        "3323",
1044        "3324",
1045        "3294",
1046        "22723",
1047        "23219",
1048        "23220",
1049        "23221",
1050        "23228",
1051        "23338",
1052        "10788",
1053        "10790",
1054        "5611",
1055        "5016",
1056        "5609",
1057        "2060",
1058        "10963",
1059        "10964",
1060        "10965",
1061        "22593",
1062        "22594",
1063        "596",
1064        "996",
1065        "499",
1066        "768",
1067        "17002",
1068        "1448",
1069        "1082",
1070        "16979",
1071        "1079",
1072        "5215",
1073        "20484",
1074        "5221",
1075        "15590",
1076        "17007",
1077        "6795",
1078        "6807",
1079        "5487",
1080        "1446",
1081        "1066",
1082        "5421",
1083        "3139",
1084        "779",
1085        "6811",
1086        "6808",
1087        "1445",
1088        "5216",
1089        "1737",
1090        "5222",
1091        "5217",
1092        "1432",
1093        "6812",
1094        "9492",
1095        "5210",
1096        "3030",
1097        "1441",
1098        "783",
1099        "6801",
1100        "20739",
1101        "8944",
1102        "9491",
1103        "22569",
1104        "5226",
1105        "6786",
1106        "1433",
1107        "8973",
1108        "1828",
1109        "9495",
1110        "9006",
1111        "6794",
1112        "8993",
1113        "5203",
1114        "16914",
1115        "6784",
1116        "9635",
1117        "22830",
1118        "20722",
1119        "9748",
1120        "6790",
1121        "9753",
1122        "9493",
1123        "9752",
1124        "9831",
1125        "9825",
1126        "9822",
1127        "5204",
1128        "5401",
1129        "22831",
1130        "6793",
1131        "9845",
1132        "17401",
1133        "9882",
1134        "9868",
1135        "20749",
1136        "9893",
1137        "9899",
1138        "9895",
1139        "9832",
1140        "9902",
1141        "9909",
1142        "22832",
1143        "9828",
1144        "9851",
1145        "9883",
1146        "9869",
1147        "17406",
1148        "17402",
1149        "9914",
1150        "20750",
1151        "9897",
1152        "9848",
1153        "3127",
1154        "107",
1155        "204",
1156        "9116",
1157        "2457",
1158        "78",
1159        "18848",
1160        "331",
1161        "403",
1162        "2098",
1163        "1752",
1164        "11278",
1165        "11288",
1166        "11284",
1167        "6461",
1168        "2344",
1169        "2345",
1170        "6463",
1171        "2346",
1172        "2352",
1173        "775",
1174        "1434",
1175        "1612",
1176        "71",
1177        "2468",
1178        "2458",
1179        "2467",
1180        "7164",
1181        "7178",
1182        "7367",
1183        "7376",
1184        "7381",
1185        "21156",
1186        "5209",
1187        "3029",
1188        "5201",
1189        "9849",
1190        "9850",
1191        "20719",
1192        "22568",
1193        "22827",
1194        "22828",
1195        "22829",
1196        "6809",
1197        "8972",
1198        "9005",
1199        "9823",
1200        "9827",
1201        "6783",
1202        "9913",
1203        "6785",
1204        "6787",
1205        "9866",
1206        "9867",
1207        "9894",
1208        "9896",
1209        "6800",
1210        "8992",
1211        "9829",
1212        "9830",
1213        "780",
1214        "769",
1215        "6749",
1216        "6750",
1217        "9755",
1218        "9754",
1219        "9908",
1220        "20745",
1221        "20742",
1222        "20747",
1223        "20748",
1224        "9746",
1225        "9745",
1226        "9880",
1227        "9881",
1228        "5391",
1229        "842",
1230        "3025",
1231        "3031",
1232        "3287",
1233        "3329",
1234        "1945",
1235        "3559",
1236        "4933",
1237        "4934",
1238        "4935",
1239        "4936",
1240        "5142",
1241        "5390",
1242        "5392",
1243        "5404",
1244        "5420",
1245        "6405",
1246        "7293",
1247        "7965",
1248        "8041",
1249        "8153",
1250        "9033",
1251        "9034",
1252        //"9036", problems with ghost state
1253        "16421",
1254        "21653",
1255        "22660",
1256        "5225",
1257        "9846",
1258        "2426",
1259        "5916",
1260        "6634",
1261        //"6718", phasing stealth, annoing for learn all case.
1262        "6719",
1263        "8822",
1264        "9591",
1265        "9590",
1266        "10032",
1267        "17746",
1268        "17747",
1269        "8203",
1270        "11392",
1271        "12495",
1272        "16380",
1273        "23452",
1274        "4079",
1275        "4996",
1276        "4997",
1277        "4998",
1278        "4999",
1279        "5000",
1280        "6348",
1281        "6349",
1282        "6481",
1283        "6482",
1284        "6483",
1285        "6484",
1286        "11362",
1287        "11410",
1288        "11409",
1289        "12510",
1290        "12509",
1291        "12885",
1292        "13142",
1293        "21463",
1294        "23460",
1295        "11421",
1296        "11416",
1297        "11418",
1298        "1851",
1299        "10059",
1300        "11423",
1301        "11417",
1302        "11422",
1303        "11419",
1304        "11424",
1305        "11420",
1306        "27",
1307        "31",
1308        "33",
1309        "34",
1310        "35",
1311        "15125",
1312        "21127",
1313        "22950",
1314        "1180",
1315        "201",
1316        "12593",
1317        "12842",
1318        "16770",
1319        "6057",
1320        "12051",
1321        "18468",
1322        "12606",
1323        "12605",
1324        "18466",
1325        "12502",
1326        "12043",
1327        "15060",
1328        "12042",
1329        "12341",
1330        "12848",
1331        "12344",
1332        "12353",
1333        "18460",
1334        "11366",
1335        "12350",
1336        "12352",
1337        "13043",
1338        "11368",
1339        "11113",
1340        "12400",
1341        "11129",
1342        "16766",
1343        "12573",
1344        "15053",
1345        "12580",
1346        "12475",
1347        "12472",
1348        "12953",
1349        "12488",
1350        "11189",
1351        "12985",
1352        "12519",
1353        "16758",
1354        "11958",
1355        "12490",
1356        "11426",
1357        "3565",
1358        "3562",
1359        "18960",
1360        "3567",
1361        "3561",
1362        "3566",
1363        "3563",
1364        "1953",
1365        "2139",
1366        "12505",
1367        "13018",
1368        "12522",
1369        "12523",
1370        "5146",
1371        "5144",
1372        "5148",
1373        "8419",
1374        "8418",
1375        "10213",
1376        "10212",
1377        "10157",
1378        "12524",
1379        "13019",
1380        "12525",
1381        "13020",
1382        "12526",
1383        "13021",
1384        "18809",
1385        "13031",
1386        "13032",
1387        "13033",
1388        "4036",
1389        "3920",
1390        "3919",
1391        "3918",
1392        "7430",
1393        "3922",
1394        "3923",
1395        "7411",
1396        "7418",
1397        "7421",
1398        "13262",
1399        "7412",
1400        "7415",
1401        "7413",
1402        "7416",
1403        "13920",
1404        "13921",
1405        "7745",
1406        "7779",
1407        "7428",
1408        "7457",
1409        "7857",
1410        "7748",
1411        "7426",
1412        "13421",
1413        "7454",
1414        "13378",
1415        "7788",
1416        "14807",
1417        "14293",
1418        "7795",
1419        "6296",
1420        "20608",
1421        "755",
1422        "444",
1423        "427",
1424        "428",
1425        "442",
1426        "447",
1427        "3578",
1428        "3581",
1429        "19027",
1430        "3580",
1431        "665",
1432        "3579",
1433        "3577",
1434        "6755",
1435        "3576",
1436        "2575",
1437        "2577",
1438        "2578",
1439        "2579",
1440        "2580",
1441        "2656",
1442        "2657",
1443        "2576",
1444        "3564",
1445        "10248",
1446        "8388",
1447        "2659",
1448        "14891",
1449        "3308",
1450        "3307",
1451        "10097",
1452        "2658",
1453        "3569",
1454        "16153",
1455        "3304",
1456        "10098",
1457        "4037",
1458        "3929",
1459        "3931",
1460        "3926",
1461        "3924",
1462        "3930",
1463        "3977",
1464        "3925",
1465        "136",
1466        "228",
1467        "5487",
1468        "43",
1469        "202",
1470        "0"
1471    };
1472
1473    int loop = 0;
1474    while(strcmp(allSpellList[loop], "0"))
1475    {
1476        uint32 spell = atol((char*)allSpellList[loop++]);
1477
1478        if (m_session->GetPlayer()->HasSpell(spell))
1479            continue;
1480
1481        SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
1482        if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
1483        {
1484            PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
1485            continue;
1486        }
1487
1488        m_session->GetPlayer()->learnSpell(spell);
1489    }
1490
1491    SendSysMessage(LANG_COMMAND_LEARN_MANY_SPELLS);
1492
1493    return true;
1494}
1495
1496bool ChatHandler::HandleLearnAllGMCommand(const char* /*args*/)
1497{
1498    static const char *gmSpellList[] =
1499    {
1500        "24347",                                            // Become A Fish, No Breath Bar
1501        "35132",                                            // Visual Boom
1502        "38488",                                            // Attack 4000-8000 AOE
1503        "38795",                                            // Attack 2000 AOE + Slow Down 90%
1504        "15712",                                            // Attack 200
1505        "1852",                                             // GM Spell Silence
1506        "31899",                                            // Kill
1507        "31924",                                            // Kill
1508        "29878",                                            // Kill My Self
1509        "26644",                                            // More Kill
1510
1511        "28550",                                            //Invisible 24
1512        "23452",                                            //Invisible + Target
1513        "0"
1514    };
1515
1516    uint16 gmSpellIter = 0;
1517    while( strcmp(gmSpellList[gmSpellIter], "0") )
1518    {
1519        uint32 spell = atol((char*)gmSpellList[gmSpellIter++]);
1520
1521        SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
1522        if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
1523        {
1524            PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
1525            continue;
1526        }
1527
1528        m_session->GetPlayer()->learnSpell(spell);
1529    }
1530
1531    SendSysMessage(LANG_LEARNING_GM_SKILLS);
1532    return true;
1533}
1534
1535bool ChatHandler::HandleLearnAllMyClassCommand(const char* /*args*/)
1536{
1537    HandleLearnAllMySpellsCommand("");
1538    HandleLearnAllMyTalentsCommand("");
1539    return true;
1540}
1541
1542bool ChatHandler::HandleLearnAllMySpellsCommand(const char* /*args*/)
1543{
1544    ChrClassesEntry const* clsEntry = sChrClassesStore.LookupEntry(m_session->GetPlayer()->getClass());
1545    if(!clsEntry)
1546        return true;
1547    uint32 family = clsEntry->spellfamily;
1548
1549    for (uint32 i = 0; i < sSpellStore.GetNumRows(); i++)
1550    {
1551        SpellEntry const *spellInfo = sSpellStore.LookupEntry(i);
1552        if(!spellInfo)
1553            continue;
1554
1555        // skip wrong class/race skills
1556        if(!m_session->GetPlayer()->IsSpellFitByClassAndRace(spellInfo->Id))
1557            continue;
1558
1559        // skip other spell families
1560        if( spellInfo->SpellFamilyName != family)
1561            continue;
1562
1563        //TODO: skip triggered spells
1564
1565        // skip spells with first rank learned as talent (and all talents then also)
1566        uint32 first_rank = spellmgr.GetFirstSpellInChain(spellInfo->Id);
1567        if(GetTalentSpellCost(first_rank) > 0 )
1568            continue;
1569
1570        // skip broken spells
1571        if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
1572            continue;
1573
1574        m_session->GetPlayer()->learnSpell(i);
1575    }
1576
1577    SendSysMessage(LANG_COMMAND_LEARN_CLASS_SPELLS);
1578    return true;
1579}
1580
1581static void learnAllHighRanks(Player* player, uint32 spellid)
1582{
1583    SpellChainMapNext const& nextMap = spellmgr.GetSpellChainNext();
1584    for(SpellChainMapNext::const_iterator itr = nextMap.lower_bound(spellid); itr != nextMap.upper_bound(spellid); ++itr)
1585    {
1586        player->learnSpell(itr->second);
1587        learnAllHighRanks(player,itr->second);
1588    }
1589}
1590
1591bool ChatHandler::HandleLearnAllMyTalentsCommand(const char* /*args*/)
1592{
1593    Player* player = m_session->GetPlayer();
1594    uint32 classMask = player->getClassMask();
1595
1596    for (uint32 i = 0; i < sTalentStore.GetNumRows(); i++)
1597    {
1598        TalentEntry const *talentInfo = sTalentStore.LookupEntry(i);
1599        if(!talentInfo)
1600            continue;
1601
1602        TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab );
1603        if(!talentTabInfo)
1604            continue;
1605
1606        if( (classMask & talentTabInfo->ClassMask) == 0 )
1607            continue;
1608
1609        // search highest talent rank
1610        uint32 spellid = 0;
1611        int rank = 4;
1612        for(; rank >= 0; --rank)
1613        {
1614            if(talentInfo->RankID[rank]!=0)
1615            {
1616                spellid = talentInfo->RankID[rank];
1617                break;
1618            }
1619        }
1620
1621        if(!spellid)                                        // ??? none spells in telent
1622            continue;
1623
1624        SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid);
1625        if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
1626            continue;
1627
1628        // learn highest rank of talent
1629        player->learnSpell(spellid);
1630
1631        // and learn all non-talent spell ranks (recursive by tree)
1632        learnAllHighRanks(player,spellid);
1633    }
1634
1635    SendSysMessage(LANG_COMMAND_LEARN_CLASS_TALENTS);
1636    return true;
1637}
1638
1639bool ChatHandler::HandleLearnAllLangCommand(const char* /*args*/)
1640{
1641    // skipping UNIVERSAL language (0)
1642    for(int i = 1; i < LANGUAGES_COUNT; ++i)
1643        m_session->GetPlayer()->learnSpell(lang_description[i].spell_id);
1644
1645    SendSysMessage(LANG_COMMAND_LEARN_ALL_LANG);
1646    return true;
1647}
1648
1649bool ChatHandler::HandleLearnAllDefaultCommand(const char* args)
1650{
1651    char* pName = strtok((char*)args, "");
1652    Player *player = NULL;
1653    if (pName)
1654    {
1655        std::string name = pName;
1656
1657        if(!normalizePlayerName(name))
1658        {
1659            SendSysMessage(LANG_PLAYER_NOT_FOUND);
1660            SetSentErrorMessage(true);
1661            return false;
1662        }
1663
1664        player = objmgr.GetPlayer(name.c_str());
1665    }
1666    else
1667        player = getSelectedPlayer();
1668
1669    if(!player)
1670    {
1671        SendSysMessage(LANG_NO_CHAR_SELECTED);
1672        SetSentErrorMessage(true);
1673        return false;
1674    }
1675
1676    player->learnDefaultSpells();
1677    player->learnQuestRewardedSpells();
1678
1679    PSendSysMessage(LANG_COMMAND_LEARN_ALL_DEFAULT_AND_QUEST,player->GetName());
1680    return true;
1681}
1682
1683bool ChatHandler::HandleLearnCommand(const char* args)
1684{
1685    Player* targetPlayer = getSelectedPlayer();
1686
1687    if(!targetPlayer)
1688    {
1689        SendSysMessage(LANG_PLAYER_NOT_FOUND);
1690        SetSentErrorMessage(true);
1691        return false;
1692    }
1693
1694    // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
1695    uint32 spell = extractSpellIdFromLink((char*)args);
1696    if(!spell || !sSpellStore.LookupEntry(spell))
1697        return false;
1698
1699    if (targetPlayer->HasSpell(spell))
1700    {
1701        if(targetPlayer == m_session->GetPlayer())
1702            SendSysMessage(LANG_YOU_KNOWN_SPELL);
1703        else
1704            PSendSysMessage(LANG_TARGET_KNOWN_SPELL,targetPlayer->GetName());
1705        SetSentErrorMessage(true);
1706        return false;
1707    }
1708
1709    SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
1710    if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
1711    {
1712        PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
1713        SetSentErrorMessage(true);
1714        return false;
1715    }
1716
1717    targetPlayer->learnSpell(spell);
1718
1719    return true;
1720}
1721
1722bool ChatHandler::HandleAddItemCommand(const char* args)
1723{
1724    if (!*args)
1725        return false;
1726
1727    uint32 itemId = 0;
1728
1729    if(args[0]=='[')                                        // [name] manual form
1730    {
1731        char* citemName = citemName = strtok((char*)args, "]");
1732
1733        if(citemName && citemName[0])
1734        {
1735            std::string itemName = citemName+1;
1736            WorldDatabase.escape_string(itemName);
1737            QueryResult *result = WorldDatabase.PQuery("SELECT entry FROM item_template WHERE name = '%s'", itemName.c_str());
1738            if (!result)
1739            {
1740                PSendSysMessage(LANG_COMMAND_COULDNOTFIND, citemName+1);
1741                SetSentErrorMessage(true);
1742                return false;
1743            }
1744            itemId = result->Fetch()->GetUInt16();
1745            delete result;
1746        }
1747        else
1748            return false;
1749    }
1750    else                                                    // item_id or [name] Shift-click form |color|Hitem:item_id:0:0:0|h[name]|h|r
1751    {
1752        char* cId = extractKeyFromLink((char*)args,"Hitem");
1753        if(!cId)
1754            return false;
1755        itemId = atol(cId);
1756    }
1757
1758    char* ccount = strtok(NULL, " ");
1759
1760    int32 count = 1;
1761
1762    if (ccount)
1763        count = strtol(ccount, NULL, 10);
1764
1765    if (count == 0)
1766        count = 1;
1767
1768    Player* pl = m_session->GetPlayer();
1769    Player* plTarget = getSelectedPlayer();
1770    if(!plTarget)
1771        plTarget = pl;
1772
1773    sLog.outDetail(GetMangosString(LANG_ADDITEM), itemId, count);
1774
1775    ItemPrototype const *pProto = objmgr.GetItemPrototype(itemId);
1776    if(!pProto)
1777    {
1778        PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId);
1779        SetSentErrorMessage(true);
1780        return false;
1781    }
1782
1783    //Subtract
1784    if (count < 0)
1785    {
1786        plTarget->DestroyItemCount(itemId, -count, true, false);
1787        PSendSysMessage(LANG_REMOVEITEM, itemId, -count, plTarget->GetName());
1788        return true;
1789    }
1790
1791    //Adding items
1792    uint32 noSpaceForCount = 0;
1793
1794    // check space and find places
1795    ItemPosCountVec dest;
1796    uint8 msg = plTarget->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, itemId, count, &noSpaceForCount );
1797    if( msg != EQUIP_ERR_OK )                               // convert to possible store amount
1798        count -= noSpaceForCount;
1799
1800    if( count == 0 || dest.empty())                         // can't add any
1801    {
1802        PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount );
1803        SetSentErrorMessage(true);
1804        return false;
1805    }
1806
1807    Item* item = plTarget->StoreNewItem( dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId));
1808
1809    // remove binding (let GM give it to another player later)
1810    if(pl==plTarget)
1811        for(ItemPosCountVec::const_iterator itr = dest.begin(); itr != dest.end(); ++itr)
1812            if(Item* item1 = pl->GetItemByPos(itr->pos))
1813                item1->SetBinding( false );
1814
1815    if(count > 0 && item)
1816    {
1817        pl->SendNewItem(item,count,false,true);
1818        if(pl!=plTarget)
1819            plTarget->SendNewItem(item,count,true,false);
1820    }
1821
1822    if(noSpaceForCount > 0)
1823        PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount);
1824
1825    return true;
1826}
1827
1828bool ChatHandler::HandleAddItemSetCommand(const char* args)
1829{
1830    if (!*args)
1831        return false;
1832
1833    char* cId = extractKeyFromLink((char*)args,"Hitemset"); // number or [name] Shift-click form |color|Hitemset:itemset_id|h[name]|h|r
1834    if (!cId)
1835        return false;
1836
1837    uint32 itemsetId = atol(cId);
1838
1839    // prevent generation all items with itemset field value '0'
1840    if (itemsetId == 0)
1841    {
1842        PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND,itemsetId);
1843        SetSentErrorMessage(true);
1844        return false;
1845    }
1846
1847    Player* pl = m_session->GetPlayer();
1848    Player* plTarget = getSelectedPlayer();
1849    if(!plTarget)
1850        plTarget = pl;
1851
1852    sLog.outDetail(GetMangosString(LANG_ADDITEMSET), itemsetId);
1853
1854    QueryResult *result = WorldDatabase.PQuery("SELECT entry FROM item_template WHERE itemset = %u",itemsetId);
1855
1856    if(!result)
1857    {
1858        PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND,itemsetId);
1859
1860        SetSentErrorMessage(true);
1861        return false;
1862    }
1863
1864    do
1865    {
1866        Field *fields = result->Fetch();
1867        uint32 itemId = fields[0].GetUInt32();
1868
1869        ItemPosCountVec dest;
1870        uint8 msg = plTarget->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, itemId, 1 );
1871        if( msg == EQUIP_ERR_OK )
1872        {
1873            Item* item = plTarget->StoreNewItem( dest, itemId, true);
1874
1875            // remove binding (let GM give it to another player later)
1876            if(pl==plTarget)
1877                item->SetBinding( false );
1878
1879            pl->SendNewItem(item,1,false,true);
1880            if(pl!=plTarget)
1881                plTarget->SendNewItem(item,1,true,false);
1882        }
1883        else
1884        {
1885            pl->SendEquipError( msg, NULL, NULL );
1886            PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, 1);
1887        }
1888
1889    }while( result->NextRow() );
1890
1891    delete result;
1892
1893    return true;
1894}
1895
1896bool ChatHandler::HandleListItemCommand(const char* args)
1897{
1898    if(!*args)
1899        return false;
1900
1901    char* cId = extractKeyFromLink((char*)args,"Hitem");
1902    if(!cId)
1903        return false;
1904    uint32 item_id = atol(cId);
1905
1906    ItemPrototype const* itemProto = item_id ? itemProto = objmgr.GetItemPrototype(item_id) : NULL;
1907
1908    if(!itemProto)
1909    {
1910        PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
1911        SetSentErrorMessage(true);
1912        return false;
1913    }
1914
1915    char* c_count = strtok(NULL, " ");
1916    int count = c_count ? atol(c_count) : 10;
1917
1918    if(count < 0)
1919        return false;
1920
1921    QueryResult *result;
1922
1923    // inventory case
1924    uint32 inv_count = 0;
1925    result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM character_inventory WHERE item_template='%u'",item_id);
1926    if(result)
1927    {
1928        inv_count = (*result)[0].GetUInt32();
1929        delete result;
1930    }
1931
1932    result=CharacterDatabase.PQuery(
1933    //          0        1             2             3        4                  5
1934        "SELECT ci.item, cibag.slot AS bag, ci.slot, ci.guid, characters.account,characters.name "
1935        "FROM character_inventory AS ci LEFT JOIN character_inventory AS cibag ON (cibag.item=ci.bag),characters "
1936        "WHERE ci.item_template='%u' AND ci.guid = characters.guid LIMIT %u ",
1937        item_id,uint32(count));
1938
1939    if(result)
1940    {
1941        do
1942        {
1943            Field *fields = result->Fetch();
1944            uint32 item_guid = fields[0].GetUInt32();
1945            uint32 item_bag = fields[1].GetUInt32();
1946            uint32 item_slot = fields[2].GetUInt32();
1947            uint32 owner_guid = fields[3].GetUInt32();
1948            uint32 owner_acc = fields[4].GetUInt32();
1949            std::string owner_name = fields[5].GetCppString();
1950
1951            char const* item_pos = 0;
1952            if(Player::IsEquipmentPos(item_bag,item_slot))
1953                item_pos = "[equipped]";
1954            else if(Player::IsInventoryPos(item_bag,item_slot))
1955                item_pos = "[in inventory]";
1956            else if(Player::IsBankPos(item_bag,item_slot))
1957                item_pos = "[in bank]";
1958            else
1959                item_pos = "";
1960
1961            PSendSysMessage(LANG_ITEMLIST_SLOT,
1962                item_guid,owner_name.c_str(),owner_guid,owner_acc,item_pos);
1963        } while (result->NextRow());
1964
1965        int64 res_count = result->GetRowCount();
1966
1967        delete result;
1968
1969        if(count > res_count)
1970            count-=res_count;
1971        else if(count)
1972            count = 0;
1973    }
1974
1975    // mail case
1976    uint32 mail_count = 0;
1977    result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM mail_items WHERE item_template='%u'", item_id);
1978    if(result)
1979    {
1980        mail_count = (*result)[0].GetUInt32();
1981        delete result;
1982    }
1983
1984    if(count > 0)
1985    {
1986        result=CharacterDatabase.PQuery(
1987        //          0                     1            2              3               4            5               6
1988            "SELECT mail_items.item_guid, mail.sender, mail.receiver, char_s.account, char_s.name, char_r.account, char_r.name "
1989            "FROM mail,mail_items,characters as char_s,characters as char_r "
1990            "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",
1991            item_id,uint32(count));
1992    }
1993    else
1994        result = NULL;
1995
1996    if(result)
1997    {
1998        do
1999        {
2000            Field *fields = result->Fetch();
2001            uint32 item_guid        = fields[0].GetUInt32();
2002            uint32 item_s           = fields[1].GetUInt32();
2003            uint32 item_r           = fields[2].GetUInt32();
2004            uint32 item_s_acc       = fields[3].GetUInt32();
2005            std::string item_s_name = fields[4].GetCppString();
2006            uint32 item_r_acc       = fields[5].GetUInt32();
2007            std::string item_r_name = fields[6].GetCppString();
2008
2009            char const* item_pos = "[in mail]";
2010
2011            PSendSysMessage(LANG_ITEMLIST_MAIL,
2012                item_guid,item_s_name.c_str(),item_s,item_s_acc,item_r_name.c_str(),item_r,item_r_acc,item_pos);
2013        } while (result->NextRow());
2014
2015        int64 res_count = result->GetRowCount();
2016
2017        delete result;
2018
2019        if(count > res_count)
2020            count-=res_count;
2021        else if(count)
2022            count = 0;
2023    }
2024
2025    // auction case
2026    uint32 auc_count = 0;
2027    result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM auctionhouse WHERE item_template='%u'",item_id);
2028    if(result)
2029    {
2030        auc_count = (*result)[0].GetUInt32();
2031        delete result;
2032    }
2033
2034    if(count > 0)
2035    {
2036        result=CharacterDatabase.PQuery(
2037        //           0                      1                       2                   3
2038            "SELECT  auctionhouse.itemguid, auctionhouse.itemowner, characters.account, characters.name "
2039            "FROM auctionhouse,characters WHERE auctionhouse.item_template='%u' AND characters.guid = auctionhouse.itemowner LIMIT %u",
2040            item_id,uint32(count));
2041    }
2042    else
2043        result = NULL;
2044
2045    if(result)
2046    {
2047        do
2048        {
2049            Field *fields = result->Fetch();
2050            uint32 item_guid       = fields[0].GetUInt32();
2051            uint32 owner           = fields[1].GetUInt32();
2052            uint32 owner_acc       = fields[2].GetUInt32();
2053            std::string owner_name = fields[3].GetCppString();
2054
2055            char const* item_pos = "[in auction]";
2056
2057            PSendSysMessage(LANG_ITEMLIST_AUCTION, item_guid, owner_name.c_str(), owner, owner_acc,item_pos);
2058        } while (result->NextRow());
2059
2060        delete result;
2061    }
2062
2063    if(inv_count+mail_count+auc_count == 0)
2064    {
2065        SendSysMessage(LANG_COMMAND_NOITEMFOUND);
2066        SetSentErrorMessage(true);
2067        return false;
2068    }
2069
2070    PSendSysMessage(LANG_COMMAND_LISTITEMMESSAGE,item_id,inv_count+mail_count+auc_count,inv_count,mail_count,auc_count);
2071
2072    return true;
2073}
2074
2075bool ChatHandler::HandleListObjectCommand(const char* args)
2076{
2077    if(!*args)
2078        return false;
2079
2080                                                            // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r
2081    char* cId = extractKeyFromLink((char*)args,"Hgameobject_entry");
2082    if(!cId)
2083        return false;
2084
2085    uint32 go_id = atol(cId);
2086
2087    GameObjectInfo const * gInfo = objmgr.GetGameObjectInfo(go_id);
2088
2089    if(!go_id || !gInfo)
2090    {
2091        PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id);
2092        SetSentErrorMessage(true);
2093        return false;
2094    }
2095
2096    char* c_count = strtok(NULL, " ");
2097    int count = c_count ? atol(c_count) : 10;
2098
2099    if(count < 0)
2100        return false;
2101
2102    Player* pl = m_session->GetPlayer();
2103    QueryResult *result;
2104
2105    uint32 obj_count = 0;
2106    result=WorldDatabase.PQuery("SELECT COUNT(guid) FROM gameobject WHERE id='%u'",go_id);
2107    if(result)
2108    {
2109        obj_count = (*result)[0].GetUInt32();
2110        delete result;
2111    }
2112
2113    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",
2114        pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),go_id,uint32(count));
2115
2116    if (result)
2117    {
2118        do
2119        {
2120            Field *fields = result->Fetch();
2121            uint32 guid = fields[0].GetUInt32();
2122            float x = fields[1].GetFloat();
2123            float y = fields[2].GetFloat();
2124            float z = fields[3].GetFloat();
2125            int mapid = fields[4].GetUInt16();
2126
2127            PSendSysMessage(LANG_GO_LIST, guid, guid, gInfo->name, x, y, z, mapid);
2128        } while (result->NextRow());
2129
2130        delete result;
2131    }
2132
2133    PSendSysMessage(LANG_COMMAND_LISTOBJMESSAGE,go_id,obj_count);
2134    return true;
2135}
2136
2137bool ChatHandler::HandleNearObjectCommand(const char* args)
2138{
2139    float distance = (!*args) ? 10 : atol(args);
2140    uint32 count = 0;
2141
2142    Player* pl = m_session->GetPlayer();
2143    QueryResult *result = WorldDatabase.PQuery("SELECT guid, id, position_x, position_y, position_z, map, "
2144        "(POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ "
2145        "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_",
2146        pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),
2147        pl->GetMapId(),pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),distance*distance);
2148
2149    if (result)
2150    {
2151        do
2152        {
2153            Field *fields = result->Fetch();
2154            uint32 guid = fields[0].GetUInt32();
2155            uint32 entry = fields[1].GetUInt32();
2156            float x = fields[2].GetFloat();
2157            float y = fields[3].GetFloat();
2158            float z = fields[4].GetFloat();
2159            int mapid = fields[5].GetUInt16();
2160
2161            GameObjectInfo const * gInfo = objmgr.GetGameObjectInfo(entry);
2162
2163            if(!gInfo)
2164                continue;
2165
2166            PSendSysMessage(LANG_GO_LIST, guid, guid, gInfo->name, x, y, z, mapid);
2167
2168            ++count;
2169        } while (result->NextRow());
2170
2171        delete result;
2172    }
2173
2174    PSendSysMessage(LANG_COMMAND_NEAROBJMESSAGE,distance,count);
2175    return true;
2176}
2177
2178bool ChatHandler::HandleListCreatureCommand(const char* args)
2179{
2180    if(!*args)
2181        return false;
2182
2183                                                            // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
2184    char* cId = extractKeyFromLink((char*)args,"Hcreature_entry");
2185    if(!cId)
2186        return false;
2187
2188    uint32 cr_id = atol(cId);
2189
2190    CreatureInfo const* cInfo = objmgr.GetCreatureTemplate(cr_id);
2191
2192    if(!cr_id || !cInfo)
2193    {
2194        PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id);
2195        SetSentErrorMessage(true);
2196        return false;
2197    }
2198
2199    char* c_count = strtok(NULL, " ");
2200    int count = c_count ? atol(c_count) : 10;
2201
2202    if(count < 0)
2203        return false;
2204
2205    Player* pl = m_session->GetPlayer();
2206    QueryResult *result;
2207
2208    uint32 cr_count = 0;
2209    result=WorldDatabase.PQuery("SELECT COUNT(guid) FROM creature WHERE id='%u'",cr_id);
2210    if(result)
2211    {
2212        cr_count = (*result)[0].GetUInt32();
2213        delete result;
2214    }
2215
2216    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",
2217        pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), cr_id,uint32(count));
2218
2219    if (result)
2220    {
2221        do
2222        {
2223            Field *fields = result->Fetch();
2224            uint32 guid = fields[0].GetUInt32();
2225            float x = fields[1].GetFloat();
2226            float y = fields[2].GetFloat();
2227            float z = fields[3].GetFloat();
2228            int mapid = fields[4].GetUInt16();
2229
2230            PSendSysMessage(LANG_CREATURE_LIST, guid, guid, cInfo->Name, x, y, z, mapid);
2231        } while (result->NextRow());
2232
2233        delete result;
2234    }
2235
2236    PSendSysMessage(LANG_COMMAND_LISTCREATUREMESSAGE,cr_id,cr_count);
2237    return true;
2238}
2239
2240bool ChatHandler::HandleLookupItemCommand(const char* args)
2241{
2242    if(!*args)
2243        return false;
2244
2245    std::string namepart = args;
2246    std::wstring wnamepart;
2247
2248    // converting string that we try to find to lower case
2249    if(!Utf8toWStr(namepart,wnamepart))
2250        return false;
2251
2252    wstrToLower(wnamepart);
2253
2254    uint32 counter = 0;
2255
2256    // Search in `item_template`
2257    for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
2258    {
2259        ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype >(id);
2260        if(!pProto)
2261            continue;
2262
2263        int loc_idx = m_session->GetSessionDbLocaleIndex();
2264        if ( loc_idx >= 0 )
2265        {
2266            ItemLocale const *il = objmgr.GetItemLocale(pProto->ItemId);
2267            if (il)
2268            {
2269                if (il->Name.size() > loc_idx && !il->Name[loc_idx].empty())
2270                {
2271                    std::string name = il->Name[loc_idx];
2272
2273                    if (Utf8FitTo(name, wnamepart))
2274                    {
2275                        PSendSysMessage(LANG_ITEM_LIST, id, id, name.c_str());
2276                        ++counter;
2277                        continue;
2278                    }
2279                }
2280            }
2281        }
2282
2283        std::string name = pProto->Name1;
2284        if(name.empty())
2285            continue;
2286
2287        if (Utf8FitTo(name, wnamepart))
2288        {
2289            PSendSysMessage(LANG_ITEM_LIST, id, id, name.c_str());
2290            ++counter;
2291        }
2292    }
2293
2294    if (counter==0)
2295        SendSysMessage(LANG_COMMAND_NOITEMFOUND);
2296
2297    return true;
2298}
2299
2300bool ChatHandler::HandleLookupItemSetCommand(const char* args)
2301{
2302    if(!*args)
2303        return false;
2304
2305    std::string namepart = args;
2306    std::wstring wnamepart;
2307
2308    if(!Utf8toWStr(namepart,wnamepart))
2309        return false;
2310
2311    // converting string that we try to find to lower case
2312    wstrToLower( wnamepart );
2313
2314    uint32 counter = 0;                                     // Counter for figure out that we found smth.
2315
2316    // Search in ItemSet.dbc
2317    for (uint32 id = 0; id < sItemSetStore.GetNumRows(); id++)
2318    {
2319        ItemSetEntry const *set = sItemSetStore.LookupEntry(id);
2320        if(set)
2321        {
2322            int loc = m_session->GetSessionDbcLocale();
2323            std::string name = set->name[m_session->GetSessionDbcLocale()];
2324            if(name.empty())
2325                continue;
2326
2327            if (!Utf8FitTo(name, wnamepart))
2328            {
2329                loc = 0;
2330                for(; loc < MAX_LOCALE; ++loc)
2331                {
2332                    if(loc==m_session->GetSessionDbcLocale())
2333                        continue;
2334
2335                    name = set->name[m_session->GetSessionDbcLocale()];
2336                    if(name.empty())
2337                        continue;
2338
2339                    if (Utf8FitTo(name, wnamepart))
2340                        break;
2341                }
2342            }
2343
2344            if(loc < MAX_LOCALE)
2345            {
2346                // send item set in "id - [namedlink locale]" format
2347                PSendSysMessage(LANG_ITEMSET_LIST,id,id,name.c_str(),localeNames[loc]);
2348                ++counter;
2349            }
2350        }
2351    }
2352    if (counter == 0)                                       // if counter == 0 then we found nth
2353        SendSysMessage(LANG_COMMAND_NOITEMSETFOUND);
2354    return true;
2355}
2356
2357bool ChatHandler::HandleLookupSkillCommand(const char* args)
2358{
2359    Player* target = getSelectedPlayer();
2360    if(!target)
2361    {
2362        SendSysMessage(LANG_PLAYER_NOT_FOUND);
2363        SetSentErrorMessage(true);
2364        return false;
2365    }
2366
2367    if(!*args)
2368        return false;
2369
2370    std::string namepart = args;
2371    std::wstring wnamepart;
2372
2373    if(!Utf8toWStr(namepart,wnamepart))
2374        return false;
2375
2376    // converting string that we try to find to lower case
2377    wstrToLower( wnamepart );
2378
2379    uint32 counter = 0;                                     // Counter for figure out that we found smth.
2380
2381    // Search in SkillLine.dbc
2382    for (uint32 id = 0; id < sSkillLineStore.GetNumRows(); id++)
2383    {
2384        SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(id);
2385        if(skillInfo)
2386        {
2387            int loc = m_session->GetSessionDbcLocale();
2388            std::string name = skillInfo->name[loc];
2389            if(name.empty())
2390                continue;
2391
2392            if (!Utf8FitTo(name, wnamepart))
2393            {
2394                loc = 0;
2395                for(; loc < MAX_LOCALE; ++loc)
2396                {
2397                    if(loc==m_session->GetSessionDbcLocale())
2398                        continue;
2399
2400                    name = skillInfo->name[loc];
2401                    if(name.empty())
2402                        continue;
2403
2404                    if (Utf8FitTo(name, wnamepart))
2405                        break;
2406                }
2407            }
2408
2409            if(loc < MAX_LOCALE)
2410            {
2411                // send skill in "id - [namedlink locale]" format
2412                PSendSysMessage(LANG_SKILL_LIST,id,id,name.c_str(),localeNames[loc],(target->HasSkill(id) ? m_session->GetMangosString(LANG_KNOWN) : ""));
2413
2414                ++counter;
2415            }
2416        }
2417    }
2418    if (counter == 0)                                       // if counter == 0 then we found nth
2419        SendSysMessage(LANG_COMMAND_NOSKILLFOUND);
2420    return true;
2421}
2422
2423bool ChatHandler::HandleLookupSpellCommand(const char* args)
2424{
2425    Player* target = getSelectedPlayer();
2426    if( !target )
2427    {
2428        SendSysMessage(LANG_PLAYER_NOT_FOUND);
2429        SetSentErrorMessage(true);
2430        return false;
2431    }
2432
2433    if(!*args)
2434        return false;
2435
2436    std::string namepart = args;
2437    std::wstring wnamepart;
2438
2439    if(!Utf8toWStr(namepart,wnamepart))
2440        return false;
2441
2442    // converting string that we try to find to lower case
2443    wstrToLower( wnamepart );
2444
2445    uint32 counter = 0;                                     // Counter for figure out that we found smth.
2446
2447    // Search in Spell.dbc
2448    for (uint32 id = 0; id < sSpellStore.GetNumRows(); id++)
2449    {
2450        SpellEntry const *spellInfo = sSpellStore.LookupEntry(id);
2451        if(spellInfo)
2452        {
2453            int loc = m_session->GetSessionDbcLocale();
2454            std::string name = spellInfo->SpellName[loc];
2455            if(name.empty())
2456                continue;
2457
2458            if (!Utf8FitTo(name, wnamepart))
2459            {
2460                loc = 0;
2461                for(; loc < MAX_LOCALE; ++loc)
2462                {
2463                    if(loc==m_session->GetSessionDbcLocale())
2464                        continue;
2465
2466                    name = spellInfo->SpellName[loc];
2467                    if(name.empty())
2468                        continue;
2469
2470                    if (Utf8FitTo(name, wnamepart))
2471                        break;
2472                }
2473            }
2474
2475            if(loc < MAX_LOCALE)
2476            {
2477                bool known = target->HasSpell(id);
2478                bool learn = (spellInfo->Effect[0] == SPELL_EFFECT_LEARN_SPELL);
2479
2480                uint32 telentCost = GetTalentSpellCost(id);
2481
2482                bool talent = (telentCost > 0);
2483                bool passive = IsPassiveSpell(id);
2484                bool active = target->HasAura(id,0) || target->HasAura(id,1) || target->HasAura(id,2);
2485
2486                // unit32 used to prevent interpreting uint8 as char at output
2487                // find rank of learned spell for learning spell, or talent rank
2488                uint32 rank = telentCost ? telentCost : spellmgr.GetSpellRank(learn ? spellInfo->EffectTriggerSpell[0] : id);
2489
2490                // send spell in "id - [name, rank N] [talent] [passive] [learn] [known]" format
2491                std::ostringstream ss;
2492                ss << id << " - |cffffffff|Hspell:" << id << "|h[" << name;
2493
2494                // include rank in link name
2495                if(rank)
2496                    ss << GetMangosString(LANG_SPELL_RANK) << rank;
2497
2498                ss << " " << localeNames[loc] << "]|h|r";
2499
2500                if(talent)
2501                    ss << GetMangosString(LANG_TALENT);
2502                if(passive)
2503                    ss << GetMangosString(LANG_PASSIVE);
2504                if(learn)
2505                    ss << GetMangosString(LANG_LEARN);
2506                if(known)
2507                    ss << GetMangosString(LANG_KNOWN);
2508                if(active)
2509                    ss << GetMangosString(LANG_ACTIVE);
2510
2511                SendSysMessage(ss.str().c_str());
2512
2513                ++counter;
2514            }
2515        }
2516    }
2517    if (counter == 0)                                       // if counter == 0 then we found nth
2518        SendSysMessage(LANG_COMMAND_NOSPELLFOUND);
2519    return true;
2520}
2521
2522bool ChatHandler::HandleLookupQuestCommand(const char* args)
2523{
2524    Player* target = getSelectedPlayer();
2525    if( !target )
2526    {
2527        SendSysMessage(LANG_PLAYER_NOT_FOUND);
2528        SetSentErrorMessage(true);
2529        return false;
2530    }
2531
2532    if(!*args)
2533        return false;
2534
2535    std::string namepart = args;
2536    std::wstring wnamepart;
2537
2538    // converting string that we try to find to lower case
2539    if(!Utf8toWStr(namepart,wnamepart))
2540        return false;
2541
2542    wstrToLower(wnamepart);
2543
2544    uint32 counter = 0 ;
2545
2546    ObjectMgr::QuestMap const& qTemplates = objmgr.GetQuestTemplates();
2547    for (ObjectMgr::QuestMap::const_iterator iter = qTemplates.begin(); iter != qTemplates.end(); ++iter)
2548    {
2549        Quest * qinfo = iter->second;
2550
2551        int loc_idx = m_session->GetSessionDbLocaleIndex();
2552        if ( loc_idx >= 0 )
2553        {
2554            QuestLocale const *il = objmgr.GetQuestLocale(qinfo->GetQuestId());
2555            if (il)
2556            {
2557                if (il->Title.size() > loc_idx && !il->Title[loc_idx].empty())
2558                {
2559                    std::string title = il->Title[loc_idx];
2560
2561                    if (Utf8FitTo(title, wnamepart))
2562                    {
2563                        QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId());
2564
2565                        char const* statusStr = "";
2566                        if(status == QUEST_STATUS_COMPLETE)
2567                        {
2568                            if(target->GetQuestRewardStatus(qinfo->GetQuestId()))
2569                                statusStr = GetMangosString(LANG_COMMAND_QUEST_REWARDED);
2570                            else
2571                                statusStr = GetMangosString(LANG_COMMAND_QUEST_COMPLETE);
2572                        }
2573                        else if(status == QUEST_STATUS_INCOMPLETE)
2574                            statusStr = GetMangosString(LANG_COMMAND_QUEST_ACTIVE);
2575
2576                        PSendSysMessage(LANG_QUEST_LIST,qinfo->GetQuestId(),qinfo->GetQuestId(),title.c_str(),(status == QUEST_STATUS_COMPLETE ? GetMangosString(LANG_COMPLETE) : (status == QUEST_STATUS_INCOMPLETE ? GetMangosString(LANG_ACTIVE) : "") ));
2577                        ++counter;
2578                        continue;
2579                    }
2580                }
2581            }
2582        }
2583
2584        std::string title = qinfo->GetTitle();
2585        if(title.empty())
2586            continue;
2587
2588        if (Utf8FitTo(title, wnamepart))
2589        {
2590            QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId());
2591
2592            char const* statusStr = "";
2593            if(status == QUEST_STATUS_COMPLETE)
2594            {
2595                if(target->GetQuestRewardStatus(qinfo->GetQuestId()))
2596                    statusStr = GetMangosString(LANG_COMMAND_QUEST_REWARDED);
2597                else
2598                    statusStr = GetMangosString(LANG_COMMAND_QUEST_COMPLETE);
2599            }
2600            else if(status == QUEST_STATUS_INCOMPLETE)
2601                statusStr = GetMangosString(LANG_COMMAND_QUEST_ACTIVE);
2602
2603            PSendSysMessage(LANG_QUEST_LIST,qinfo->GetQuestId(),qinfo->GetQuestId(), title.c_str(),(status == QUEST_STATUS_COMPLETE ? GetMangosString(LANG_COMPLETE) : (status == QUEST_STATUS_INCOMPLETE ? GetMangosString(LANG_ACTIVE) : "") ));
2604            ++counter;
2605        }
2606    }
2607
2608    if (counter==0)
2609        SendSysMessage(LANG_COMMAND_NOQUESTFOUND);
2610
2611    return true;
2612}
2613
2614bool ChatHandler::HandleLookupCreatureCommand(const char* args)
2615{
2616    if(!*args)
2617        return false;
2618
2619    std::string namepart = args;
2620    std::wstring wnamepart;
2621
2622    // converting string that we try to find to lower case
2623    if(!Utf8toWStr(namepart,wnamepart))
2624        return false;
2625
2626    wstrToLower(wnamepart);
2627
2628    uint32 counter = 0;
2629
2630    for (uint32 id = 0; id< sCreatureStorage.MaxEntry; id++ )
2631    {
2632        CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo>(id);
2633        if(!cInfo)
2634            continue;
2635
2636        int loc_idx = m_session->GetSessionDbLocaleIndex();
2637        if ( loc_idx >= 0 )
2638        {
2639            CreatureLocale const *cl = objmgr.GetCreatureLocale(id);
2640            if (cl)
2641            {
2642                if (cl->Name.size() > loc_idx && !cl->Name[loc_idx].empty())
2643                {
2644                    std::string name = cl->Name[loc_idx];
2645
2646                    if (Utf8FitTo(name, wnamepart))
2647                    {
2648                        PSendSysMessage(LANG_CREATURE_ENTRY_LIST, id, id, name.c_str());
2649                        ++counter;
2650                        continue;
2651                    }
2652                }
2653            }
2654        }
2655
2656        std::string name = cInfo->Name;
2657        if(name.empty())
2658            continue;
2659
2660        if (Utf8FitTo(name, wnamepart))
2661        {
2662            PSendSysMessage(LANG_CREATURE_ENTRY_LIST,id,id,name.c_str());
2663            ++counter;
2664        }
2665    }
2666
2667    if (counter==0)
2668        SendSysMessage(LANG_COMMAND_NOCREATUREFOUND);
2669
2670    return true;
2671}
2672
2673bool ChatHandler::HandleLookupObjectCommand(const char* args)
2674{
2675    if(!*args)
2676        return false;
2677
2678    std::string namepart = args;
2679    std::wstring wnamepart;
2680
2681    // converting string that we try to find to lower case
2682    if(!Utf8toWStr(namepart,wnamepart))
2683        return false;
2684
2685    wstrToLower(wnamepart);
2686
2687    uint32 counter = 0;
2688
2689    for (uint32 id = 0; id< sGOStorage.MaxEntry; id++ )
2690    {
2691        GameObjectInfo const* gInfo = sGOStorage.LookupEntry<GameObjectInfo>(id);
2692        if(!gInfo)
2693            continue;
2694
2695        int loc_idx = m_session->GetSessionDbLocaleIndex();
2696        if ( loc_idx >= 0 )
2697        {
2698            GameObjectLocale const *gl = objmgr.GetGameObjectLocale(id);
2699            if (gl)
2700            {
2701                if (gl->Name.size() > loc_idx && !gl->Name[loc_idx].empty())
2702                {
2703                    std::string name = gl->Name[loc_idx];
2704
2705                    if (Utf8FitTo(name, wnamepart))
2706                    {
2707                        PSendSysMessage(LANG_GO_ENTRY_LIST, id, id, name.c_str());
2708                        ++counter;
2709                        continue;
2710                    }
2711                }
2712            }
2713        }
2714
2715        std::string name = gInfo->name;
2716        if(name.empty())
2717            continue;
2718
2719        if(Utf8FitTo(name, wnamepart))
2720        {
2721            PSendSysMessage(LANG_GO_ENTRY_LIST, id, id, name.c_str());
2722            ++counter;
2723        }
2724    }
2725
2726    if(counter==0)
2727        SendSysMessage(LANG_COMMAND_NOGAMEOBJECTFOUND);
2728
2729    return true;
2730}
2731
2732/** \brief GM command level 3 - Create a guild.
2733 *
2734 * This command allows a GM (level 3) to create a guild.
2735 *
2736 * The "args" parameter contains the name of the guild leader
2737 * and then the name of the guild.
2738 *
2739 */
2740bool ChatHandler::HandleGuildCreateCommand(const char* args)
2741{
2742
2743    if (!*args)
2744        return false;
2745
2746    Guild *guild;
2747    Player * player;
2748    char *lname,*gname;
2749    std::string guildname;
2750
2751    lname = strtok((char*)args, " ");
2752    gname = strtok(NULL, "");
2753
2754    if(!lname)
2755        return false;
2756    else if(!gname)
2757    {
2758        SendSysMessage(LANG_INSERT_GUILD_NAME);
2759        SetSentErrorMessage(true);
2760        return false;
2761    }
2762
2763    guildname = gname;
2764    player = ObjectAccessor::Instance().FindPlayerByName(lname);
2765
2766    if(!player)
2767    {
2768        SendSysMessage(LANG_PLAYER_NOT_FOUND);
2769        SetSentErrorMessage(true);
2770        return false;
2771    }
2772
2773    if(!player->GetGuildId())
2774    {
2775        guild = new Guild;
2776        if(!guild->create(player->GetGUID(),guildname))
2777        {
2778            delete guild;
2779            SendSysMessage(LANG_GUILD_NOT_CREATED);
2780            SetSentErrorMessage(true);
2781            return false;
2782        }
2783
2784        objmgr.AddGuild(guild);
2785    }
2786    else
2787        SendSysMessage(LANG_PLAYER_IN_GUILD);
2788
2789    return true;
2790}
2791
2792bool ChatHandler::HandleGuildInviteCommand(const char *args)
2793{
2794    if(!*args)
2795        return false;
2796
2797    char* par1 = strtok((char*)args, " ");
2798    char* par2 = strtok (NULL, "");
2799    if(!par1 || !par2)
2800        return false;
2801
2802    std::string glName = par2;
2803    Guild* targetGuild = objmgr.GetGuildByName(glName);
2804    if(!targetGuild)
2805        return false;
2806
2807    std::string plName = par1;
2808    if(!normalizePlayerName(plName))
2809    {
2810        SendSysMessage(LANG_PLAYER_NOT_FOUND);
2811        SetSentErrorMessage(true);
2812        return false;
2813    }
2814
2815    uint64 plGuid = 0;
2816    if(Player* targetPlayer = ObjectAccessor::Instance().FindPlayerByName(plName.c_str()))
2817        plGuid = targetPlayer->GetGUID();
2818    else
2819        plGuid = objmgr.GetPlayerGUIDByName(plName.c_str());
2820
2821    if(!plGuid)
2822        false;
2823
2824    // players's guild membership checked in AddMember before add
2825    if(!targetGuild->AddMember(plGuid,targetGuild->GetLowestRank()))
2826        return false;
2827
2828    return true;
2829}
2830
2831bool ChatHandler::HandleGuildUninviteCommand(const char *args)
2832{
2833    if(!*args)
2834        return false;
2835
2836    char* par1 = strtok((char*)args, " ");
2837    if(!par1)
2838        return false;
2839    std::string plName = par1;
2840    if(!normalizePlayerName(plName))
2841    {
2842        SendSysMessage(LANG_PLAYER_NOT_FOUND);
2843        SetSentErrorMessage(true);
2844        return false;
2845    }
2846
2847    uint64 plGuid = 0;
2848    uint32 glId   = 0;
2849    if(Player* targetPlayer = ObjectAccessor::Instance().FindPlayerByName(plName.c_str()))
2850    {
2851        plGuid = targetPlayer->GetGUID();
2852        glId   = targetPlayer->GetGuildId();
2853    }
2854    else
2855    {
2856        plGuid = objmgr.GetPlayerGUIDByName(plName.c_str());
2857        glId = Player::GetGuildIdFromDB(plGuid);
2858    }
2859
2860    if(!plGuid || !glId)
2861        return false;
2862
2863    Guild* targetGuild = objmgr.GetGuildById(glId);
2864    if(!targetGuild)
2865        return false;
2866
2867    targetGuild->DelMember(plGuid);
2868
2869    return true;
2870}
2871
2872bool ChatHandler::HandleGuildRankCommand(const char *args)
2873{
2874    if(!*args)
2875        return false;
2876
2877    char* par1 = strtok((char*)args, " ");
2878    char* par2 = strtok(NULL, " ");
2879    if(!par1 || !par2)
2880        return false;
2881    std::string plName = par1;
2882    if(!normalizePlayerName(plName))
2883    {
2884        SendSysMessage(LANG_PLAYER_NOT_FOUND);
2885        SetSentErrorMessage(true);
2886        return false;
2887    }
2888
2889    uint64 plGuid = 0;
2890    uint32 glId   = 0;
2891    if(Player* targetPlayer = ObjectAccessor::Instance().FindPlayerByName(plName.c_str()))
2892    {
2893        plGuid = targetPlayer->GetGUID();
2894        glId   = targetPlayer->GetGuildId();
2895    }
2896    else
2897    {
2898        plGuid = objmgr.GetPlayerGUIDByName(plName.c_str());
2899        glId = Player::GetGuildIdFromDB(plGuid);
2900    }
2901
2902    if(!plGuid || !glId)
2903        return false;
2904
2905    Guild* targetGuild = objmgr.GetGuildById(glId);
2906    if(!targetGuild)
2907        return false;
2908
2909    uint32 newrank = uint32(atoi(par2));
2910    if(newrank > targetGuild->GetLowestRank())
2911        return false;
2912
2913    targetGuild->ChangeRank(plGuid,newrank);
2914
2915    return true;
2916}
2917
2918bool ChatHandler::HandleGuildDeleteCommand(const char* args)
2919{
2920    if(!*args)
2921        return false;
2922
2923    char* par1 = strtok((char*)args, " ");
2924    if(!par1)
2925        return false;
2926
2927    std::string gld = par1;
2928
2929    Guild* targetGuild = objmgr.GetGuildByName(gld);
2930    if(!targetGuild)
2931        return false;
2932
2933    targetGuild->Disband();
2934
2935    return true;
2936}
2937
2938bool ChatHandler::HandleGetDistanceCommand(const char* /*args*/)
2939{
2940    Unit* pUnit = getSelectedUnit();
2941
2942    if(!pUnit)
2943    {
2944        SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
2945        SetSentErrorMessage(true);
2946        return false;
2947    }
2948
2949    PSendSysMessage(LANG_DISTANCE, m_session->GetPlayer()->GetDistance(pUnit),m_session->GetPlayer()->GetDistance2d(pUnit));
2950
2951    return true;
2952}
2953
2954// FIX-ME!!!
2955
2956bool ChatHandler::HandleAddWeaponCommand(const char* /*args*/)
2957{
2958    /*if (!*args)
2959        return false;
2960
2961    uint64 guid = m_session->GetPlayer()->GetSelection();
2962    if (guid == 0)
2963    {
2964        SendSysMessage(LANG_NO_SELECTION);
2965        return true;
2966    }
2967
2968    Creature *pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
2969
2970    if(!pCreature)
2971    {
2972        SendSysMessage(LANG_SELECT_CREATURE);
2973        return true;
2974    }
2975
2976    char* pSlotID = strtok((char*)args, " ");
2977    if (!pSlotID)
2978        return false;
2979
2980    char* pItemID = strtok(NULL, " ");
2981    if (!pItemID)
2982        return false;
2983
2984    uint32 ItemID = atoi(pItemID);
2985    uint32 SlotID = atoi(pSlotID);
2986
2987    ItemPrototype* tmpItem = objmgr.GetItemPrototype(ItemID);
2988
2989    bool added = false;
2990    if(tmpItem)
2991    {
2992        switch(SlotID)
2993        {
2994            case 1:
2995                pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, ItemID);
2996                added = true;
2997                break;
2998            case 2:
2999                pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_01, ItemID);
3000                added = true;
3001                break;
3002            case 3:
3003                pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_02, ItemID);
3004                added = true;
3005                break;
3006            default:
3007                PSendSysMessage(LANG_ITEM_SLOT_NOT_EXIST,SlotID);
3008                added = false;
3009                break;
3010        }
3011        if(added)
3012        {
3013            PSendSysMessage(LANG_ITEM_ADDED_TO_SLOT,ItemID,tmpItem->Name1,SlotID);
3014        }
3015    }
3016    else
3017    {
3018        PSendSysMessage(LANG_ITEM_NOT_FOUND,ItemID);
3019        return true;
3020    }
3021    */
3022    return true;
3023}
3024
3025bool ChatHandler::HandleDieCommand(const char* /*args*/)
3026{
3027    Unit* target = getSelectedUnit();
3028
3029    if(!target || !m_session->GetPlayer()->GetSelection())
3030    {
3031        SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3032        SetSentErrorMessage(true);
3033        return false;
3034    }
3035
3036    if( target->isAlive() )
3037    {
3038        m_session->GetPlayer()->DealDamage(target, target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
3039    }
3040
3041    return true;
3042}
3043
3044bool ChatHandler::HandleDamageCommand(const char * args)
3045{
3046    if (!*args)
3047        return false;
3048
3049    Unit* target = getSelectedUnit();
3050
3051    if(!target || !m_session->GetPlayer()->GetSelection())
3052    {
3053        SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3054        SetSentErrorMessage(true);
3055        return false;
3056    }
3057
3058    if( !target->isAlive() )
3059        return true;
3060
3061    char* damageStr = strtok((char*)args, " ");
3062    if(!damageStr)
3063        return false;
3064
3065    int32 damage = atoi((char*)damageStr);
3066    if(damage <=0)
3067        return true;
3068
3069    char* schoolStr = strtok((char*)NULL, " ");
3070
3071    // flat melee damage without resistence/etc reduction
3072    if(!schoolStr)
3073    {
3074        m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
3075        m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, SPELL_SCHOOL_MASK_NORMAL, damage, 0, 0, VICTIMSTATE_NORMAL, 0);
3076        return true;
3077    }
3078
3079    uint32 school = schoolStr ? atoi((char*)schoolStr) : SPELL_SCHOOL_NORMAL;
3080    if(school >= MAX_SPELL_SCHOOL)
3081        return false;
3082
3083    SpellSchoolMask schoolmask = SpellSchoolMask(1 << school);
3084
3085    if ( schoolmask & SPELL_SCHOOL_MASK_NORMAL )
3086        damage = m_session->GetPlayer()->CalcArmorReducedDamage(target, damage);
3087
3088    char* spellStr = strtok((char*)NULL, " ");
3089
3090    // melee damage by specific school
3091    if(!spellStr)
3092    {
3093        uint32 absorb = 0;
3094        uint32 resist = 0;
3095
3096        m_session->GetPlayer()->CalcAbsorbResist(target,schoolmask, SPELL_DIRECT_DAMAGE, damage, &absorb, &resist);
3097
3098        if (damage <= absorb + resist)
3099            return true;
3100
3101        damage -= absorb + resist;
3102
3103        m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, schoolmask, NULL, false);
3104        m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, schoolmask, damage, absorb, resist, VICTIMSTATE_NORMAL, 0);
3105        return true;
3106    }
3107
3108    // non-melee damage
3109
3110    // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
3111    uint32 spellid = extractSpellIdFromLink((char*)args);
3112    if(!spellid || !sSpellStore.LookupEntry(spellid))
3113        return false;
3114
3115    m_session->GetPlayer()->SpellNonMeleeDamageLog(target, spellid, damage, false);
3116    return true;
3117}
3118
3119bool ChatHandler::HandleModifyArenaCommand(const char * args)
3120{
3121    if (!*args)
3122        return false;
3123
3124    Player *target = getSelectedPlayer();
3125    if(!target)
3126    {
3127        SendSysMessage(LANG_PLAYER_NOT_FOUND);
3128        SetSentErrorMessage(true);
3129        return false;
3130    }
3131
3132    int32 amount = (uint32)atoi(args);
3133
3134    target->ModifyArenaPoints(amount);
3135
3136    PSendSysMessage(LANG_COMMAND_MODIFY_ARENA, target->GetName(), target->GetArenaPoints());
3137
3138    return true;
3139}
3140
3141bool ChatHandler::HandleReviveCommand(const char* args)
3142{
3143    Player* SelectedPlayer = NULL;
3144
3145    if (*args)
3146    {
3147        std::string name = args;
3148        if(!normalizePlayerName(name))
3149        {
3150            SendSysMessage(LANG_PLAYER_NOT_FOUND);
3151            SetSentErrorMessage(true);
3152            return false;
3153        }
3154
3155        SelectedPlayer = objmgr.GetPlayer(name.c_str());
3156    }
3157    else
3158        SelectedPlayer = getSelectedPlayer();
3159
3160    if(!SelectedPlayer)
3161    {
3162        SendSysMessage(LANG_NO_CHAR_SELECTED);
3163        SetSentErrorMessage(true);
3164        return false;
3165    }
3166
3167    SelectedPlayer->ResurrectPlayer(0.5f);
3168    SelectedPlayer->SpawnCorpseBones();
3169    SelectedPlayer->SaveToDB();
3170    return true;
3171}
3172
3173bool ChatHandler::HandleAuraCommand(const char* args)
3174{
3175    char* px = strtok((char*)args, " ");
3176    if (!px)
3177        return false;
3178
3179    Unit *target = getSelectedUnit();
3180    if(!target)
3181    {
3182        SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3183        SetSentErrorMessage(true);
3184        return false;
3185    }
3186
3187    uint32 spellID = (uint32)atoi(px);
3188    SpellEntry const *spellInfo = sSpellStore.LookupEntry( spellID );
3189    if(spellInfo)
3190    {
3191        for(uint32 i = 0;i<3;i++)
3192        {
3193            uint8 eff = spellInfo->Effect[i];
3194            if (eff>=TOTAL_SPELL_EFFECTS)
3195                continue;
3196            if( IsAreaAuraEffect(eff)           ||
3197                eff == SPELL_EFFECT_APPLY_AURA  ||
3198                eff == SPELL_EFFECT_PERSISTENT_AREA_AURA )
3199            {
3200                Aura *Aur = CreateAura(spellInfo, i, NULL, target);
3201                target->AddAura(Aur);
3202            }
3203        }
3204    }
3205
3206    return true;
3207}
3208
3209bool ChatHandler::HandleUnAuraCommand(const char* args)
3210{
3211    char* px = strtok((char*)args, " ");
3212    if (!px)
3213        return false;
3214
3215    Unit *target = getSelectedUnit();
3216    if(!target)
3217    {
3218        SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3219        SetSentErrorMessage(true);
3220        return false;
3221    }
3222
3223    std::string argstr = args;
3224    if (argstr == "all")
3225    {
3226        target->RemoveAllAuras();
3227        return true;
3228    }
3229
3230    uint32 spellID = (uint32)atoi(px);
3231    target->RemoveAurasDueToSpell(spellID);
3232
3233    return true;
3234}
3235
3236bool ChatHandler::HandleLinkGraveCommand(const char* args)
3237{
3238    if(!*args)
3239        return false;
3240
3241    char* px = strtok((char*)args, " ");
3242    if (!px)
3243        return false;
3244
3245    uint32 g_id = (uint32)atoi(px);
3246
3247    uint32 g_team;
3248
3249    char* px2 = strtok(NULL, " ");
3250
3251    if (!px2)
3252        g_team = 0;
3253    else if (strncmp(px2,"horde",6)==0)
3254        g_team = HORDE;
3255    else if (strncmp(px2,"alliance",9)==0)
3256        g_team = ALLIANCE;
3257    else
3258        return false;
3259
3260    WorldSafeLocsEntry const* graveyard =  sWorldSafeLocsStore.LookupEntry(g_id);
3261
3262    if(!graveyard )
3263    {
3264        PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST, g_id);
3265        SetSentErrorMessage(true);
3266        return false;
3267    }
3268
3269    Player* player = m_session->GetPlayer();
3270
3271    uint32 zoneId = player->GetZoneId();
3272
3273    AreaTableEntry const *areaEntry = GetAreaEntryByAreaID(zoneId);
3274    if(!areaEntry || areaEntry->zone !=0 )
3275    {
3276        PSendSysMessage(LANG_COMMAND_GRAVEYARDWRONGZONE, g_id,zoneId);
3277        SetSentErrorMessage(true);
3278        return false;
3279    }
3280
3281    if(graveyard->map_id != areaEntry->mapid && g_team != 0)
3282    {
3283        SendSysMessage(LANG_COMMAND_GRAVEYARDWRONGTEAM);
3284        SetSentErrorMessage(true);
3285        return false;
3286    }
3287
3288    if(objmgr.AddGraveYardLink(g_id,player->GetZoneId(),g_team))
3289        PSendSysMessage(LANG_COMMAND_GRAVEYARDLINKED, g_id,zoneId);
3290    else
3291        PSendSysMessage(LANG_COMMAND_GRAVEYARDALRLINKED, g_id,zoneId);
3292
3293    return true;
3294}
3295
3296bool ChatHandler::HandleNearGraveCommand(const char* args)
3297{
3298    uint32 g_team;
3299
3300    size_t argslen = strlen(args);
3301
3302    if(!*args)
3303        g_team = 0;
3304    else if (strncmp((char*)args,"horde",argslen)==0)
3305        g_team = HORDE;
3306    else if (strncmp((char*)args,"alliance",argslen)==0)
3307        g_team = ALLIANCE;
3308    else
3309        return false;
3310
3311    Player* player = m_session->GetPlayer();
3312
3313    WorldSafeLocsEntry const* graveyard = objmgr.GetClosestGraveYard(
3314        player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(),player->GetMapId(),g_team);
3315
3316    if(graveyard)
3317    {
3318        uint32 g_id = graveyard->ID;
3319
3320        GraveYardData const* data = objmgr.FindGraveYardData(g_id,player->GetZoneId());
3321        if (!data)
3322        {
3323            PSendSysMessage(LANG_COMMAND_GRAVEYARDERROR,g_id);
3324            SetSentErrorMessage(true);
3325            return false;
3326        }
3327
3328        g_team = data->team;
3329
3330        std::string team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_NOTEAM);
3331
3332        if(g_team == 0)
3333            team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ANY);
3334        else if(g_team == HORDE)
3335            team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_HORDE);
3336        else if(g_team == ALLIANCE)
3337            team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ALLIANCE);
3338
3339        PSendSysMessage(LANG_COMMAND_GRAVEYARDNEAREST, g_id,team_name.c_str(),player->GetZoneId());
3340    }
3341    else
3342    {
3343        std::string team_name;
3344
3345        if(g_team == 0)
3346            team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ANY);
3347        else if(g_team == HORDE)
3348            team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_HORDE);
3349        else if(g_team == ALLIANCE)
3350            team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ALLIANCE);
3351
3352        if(g_team == ~uint32(0))
3353            PSendSysMessage(LANG_COMMAND_ZONENOGRAVEYARDS, player->GetZoneId());
3354        else
3355            PSendSysMessage(LANG_COMMAND_ZONENOGRAFACTION, player->GetZoneId(),team_name.c_str());
3356    }
3357
3358    return true;
3359}
3360
3361bool ChatHandler::HandleSpawnTransportCommand(const char* /*args*/)
3362{
3363    return true;
3364}
3365
3366//play npc emote
3367bool ChatHandler::HandlePlayEmoteCommand(const char* args)
3368{
3369    uint32 emote = atoi((char*)args);
3370
3371    Creature* target = getSelectedCreature();
3372    if(!target)
3373    {
3374        SendSysMessage(LANG_SELECT_CREATURE);
3375        SetSentErrorMessage(true);
3376        return false;
3377    }
3378
3379    target->SetUInt32Value(UNIT_NPC_EMOTESTATE,emote);
3380
3381    return true;
3382}
3383
3384bool ChatHandler::HandleNpcInfoCommand(const char* /*args*/)
3385{
3386    Creature* target = getSelectedCreature();
3387
3388    if(!target)
3389    {
3390        SendSysMessage(LANG_SELECT_CREATURE);
3391        SetSentErrorMessage(true);
3392        return false;
3393    }
3394
3395    uint32 faction = target->getFaction();
3396    uint32 npcflags = target->GetUInt32Value(UNIT_NPC_FLAGS);
3397    uint32 displayid = target->GetDisplayId();
3398    uint32 nativeid = target->GetNativeDisplayId();
3399    uint32 Entry = target->GetEntry();
3400    CreatureInfo const* cInfo = target->GetCreatureInfo();
3401
3402    int32 curRespawnDelay = target->GetRespawnTimeEx()-time(NULL);
3403    if(curRespawnDelay < 0)
3404        curRespawnDelay = 0;
3405    std::string curRespawnDelayStr = secsToTimeString(curRespawnDelay,true);
3406    std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(),true);
3407
3408    PSendSysMessage(LANG_NPCINFO_CHAR,  target->GetDBTableGUIDLow(), faction, npcflags, Entry, displayid, nativeid);
3409    PSendSysMessage(LANG_NPCINFO_LEVEL, target->getLevel());
3410    PSendSysMessage(LANG_NPCINFO_HEALTH,target->GetCreateHealth(), target->GetMaxHealth(), target->GetHealth());
3411    PSendSysMessage(LANG_NPCINFO_FLAGS, target->GetUInt32Value(UNIT_FIELD_FLAGS), target->GetUInt32Value(UNIT_DYNAMIC_FLAGS), target->getFaction());
3412    PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES, defRespawnDelayStr.c_str(),curRespawnDelayStr.c_str());
3413    PSendSysMessage(LANG_NPCINFO_LOOT,  cInfo->lootid,cInfo->pickpocketLootId,cInfo->SkinLootId);
3414    PSendSysMessage(LANG_NPCINFO_DUNGEON_ID, target->GetInstanceId());
3415    PSendSysMessage(LANG_NPCINFO_POSITION,float(target->GetPositionX()), float(target->GetPositionY()), float(target->GetPositionZ()));
3416
3417    if ((npcflags & UNIT_NPC_FLAG_VENDOR) )
3418    {
3419        SendSysMessage(LANG_NPCINFO_VENDOR);
3420    }
3421    if ((npcflags & UNIT_NPC_FLAG_TRAINER) )
3422    {
3423        SendSysMessage(LANG_NPCINFO_TRAINER);
3424    }
3425
3426    return true;
3427}
3428
3429bool ChatHandler::HandleExploreCheatCommand(const char* args)
3430{
3431    if (!*args)
3432        return false;
3433
3434    int flag = atoi((char*)args);
3435
3436    Player *chr = getSelectedPlayer();
3437    if (chr == NULL)
3438    {
3439        SendSysMessage(LANG_NO_CHAR_SELECTED);
3440        SetSentErrorMessage(true);
3441        return false;
3442    }
3443
3444    if (flag != 0)
3445    {
3446        PSendSysMessage(LANG_YOU_SET_EXPLORE_ALL, chr->GetName());
3447        if(chr!=m_session->GetPlayer())
3448            ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_ALL,m_session->GetPlayer()->GetName());
3449    }
3450    else
3451    {
3452        PSendSysMessage(LANG_YOU_SET_EXPLORE_NOTHING, chr->GetName());
3453        if(chr!=m_session->GetPlayer())
3454            ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_NOTHING,m_session->GetPlayer()->GetName());
3455    }
3456
3457    for (uint8 i=0; i<128; i++)
3458    {
3459        if (flag != 0)
3460        {
3461            m_session->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i,0xFFFFFFFF);
3462        }
3463        else
3464        {
3465            m_session->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i,0);
3466        }
3467    }
3468
3469    return true;
3470}
3471
3472bool ChatHandler::HandleHoverCommand(const char* args)
3473{
3474    char* px = strtok((char*)args, " ");
3475    uint32 flag;
3476    if (!px)
3477        flag = 1;
3478    else
3479        flag = atoi(px);
3480
3481    m_session->GetPlayer()->SetHover(flag);
3482
3483    if (flag)
3484        SendSysMessage(LANG_HOVER_ENABLED);
3485    else
3486        SendSysMessage(LANG_HOVER_DISABLED);
3487
3488    return true;
3489}
3490
3491bool ChatHandler::HandleLevelUpCommand(const char* args)
3492{
3493    char* px = strtok((char*)args, " ");
3494    char* py = strtok((char*)NULL, " ");
3495
3496    // command format parsing
3497    char* pname = (char*)NULL;
3498    int addlevel = 1;
3499
3500    if(px && py)                                            // .levelup name level
3501    {
3502        addlevel = atoi(py);
3503        pname = px;
3504    }
3505    else if(px && !py)                                      // .levelup name OR .levelup level
3506    {
3507        if(isalpha(px[0]))                                  // .levelup name
3508            pname = px;
3509        else                                                // .levelup level
3510            addlevel = atoi(px);
3511    }
3512    // else .levelup - nothing do for prepering
3513
3514    // player
3515    Player *chr = NULL;
3516    uint64 chr_guid = 0;
3517
3518    std::string name;
3519
3520    if(pname)                                               // player by name
3521    {
3522        name = pname;
3523        if(!normalizePlayerName(name))
3524        {
3525            SendSysMessage(LANG_PLAYER_NOT_FOUND);
3526            SetSentErrorMessage(true);
3527            return false;
3528        }
3529
3530        chr = objmgr.GetPlayer(name.c_str());
3531        if(!chr)                                            // not in game
3532        {
3533            chr_guid = objmgr.GetPlayerGUIDByName(name);
3534            if (chr_guid == 0)
3535            {
3536                SendSysMessage(LANG_PLAYER_NOT_FOUND);
3537                SetSentErrorMessage(true);
3538                return false;
3539            }
3540        }
3541    }
3542    else                                                    // player by selection
3543    {
3544        chr = getSelectedPlayer();
3545
3546        if (chr == NULL)
3547        {
3548            SendSysMessage(LANG_NO_CHAR_SELECTED);
3549            SetSentErrorMessage(true);
3550            return false;
3551        }
3552
3553        name = chr->GetName();
3554    }
3555
3556    assert(chr || chr_guid);
3557
3558    int32 oldlevel = chr ? chr->getLevel() : Player::GetUInt32ValueFromDB(UNIT_FIELD_LEVEL,chr_guid);
3559    int32 newlevel = oldlevel + addlevel;
3560    if(newlevel < 1)
3561        newlevel = 1;
3562    if(newlevel > 255)                                      // hardcoded maximum level
3563        newlevel = 255;
3564
3565    if(chr)
3566    {
3567        chr->GiveLevel(newlevel);
3568        chr->InitTalentForLevel();
3569        chr->SetUInt32Value(PLAYER_XP,0);
3570
3571        if(oldlevel == newlevel)
3572            ChatHandler(chr).SendSysMessage(LANG_YOURS_LEVEL_PROGRESS_RESET);
3573        else
3574        if(oldlevel < newlevel)
3575            ChatHandler(chr).PSendSysMessage(LANG_YOURS_LEVEL_UP,newlevel-oldlevel);
3576        else
3577        if(oldlevel > newlevel)
3578            ChatHandler(chr).PSendSysMessage(LANG_YOURS_LEVEL_DOWN,newlevel-oldlevel);
3579    }
3580    else
3581    {
3582        // update levle and XP at level, all other will be updated at loading
3583        Tokens values;
3584        Player::LoadValuesArrayFromDB(values,chr_guid);
3585        Player::SetUInt32ValueInArray(values,UNIT_FIELD_LEVEL,newlevel);
3586        Player::SetUInt32ValueInArray(values,PLAYER_XP,0);
3587        Player::SaveValuesArrayInDB(values,chr_guid);
3588    }
3589
3590    if(m_session->GetPlayer() != chr)                       // including chr==NULL
3591        PSendSysMessage(LANG_YOU_CHANGE_LVL,name.c_str(),newlevel);
3592    return true;
3593}
3594
3595bool ChatHandler::HandleShowAreaCommand(const char* args)
3596{
3597    if (!*args)
3598        return false;
3599
3600    int area = atoi((char*)args);
3601
3602    Player *chr = getSelectedPlayer();
3603    if (chr == NULL)
3604    {
3605        SendSysMessage(LANG_NO_CHAR_SELECTED);
3606        SetSentErrorMessage(true);
3607        return false;
3608    }
3609
3610    int offset = area / 32;
3611    uint32 val = (uint32)(1 << (area % 32));
3612
3613    if(offset >= 128)
3614    {
3615        SendSysMessage(LANG_BAD_VALUE);
3616        SetSentErrorMessage(true);
3617        return false;
3618    }
3619
3620    uint32 currFields = chr->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset);
3621    chr->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields | val));
3622
3623    SendSysMessage(LANG_EXPLORE_AREA);
3624    return true;
3625}
3626
3627bool ChatHandler::HandleHideAreaCommand(const char* args)
3628{
3629    if (!*args)
3630        return false;
3631
3632    int area = atoi((char*)args);
3633
3634    Player *chr = getSelectedPlayer();
3635    if (chr == NULL)
3636    {
3637        SendSysMessage(LANG_NO_CHAR_SELECTED);
3638        SetSentErrorMessage(true);
3639        return false;
3640    }
3641
3642    int offset = area / 32;
3643    uint32 val = (uint32)(1 << (area % 32));
3644
3645    if(offset >= 128)
3646    {
3647        SendSysMessage(LANG_BAD_VALUE);
3648        SetSentErrorMessage(true);
3649        return false;
3650    }
3651
3652    uint32 currFields = chr->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset);
3653    chr->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields ^ val));
3654
3655    SendSysMessage(LANG_UNEXPLORE_AREA);
3656    return true;
3657}
3658
3659bool ChatHandler::HandleUpdate(const char* args)
3660{
3661    if(!*args)
3662        return false;
3663
3664    uint32 updateIndex;
3665    uint32 value;
3666
3667    char* pUpdateIndex = strtok((char*)args, " ");
3668
3669    Unit* chr = getSelectedUnit();
3670    if (chr == NULL)
3671    {
3672        SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3673        SetSentErrorMessage(true);
3674        return false;
3675    }
3676
3677    if(!pUpdateIndex)
3678    {
3679        return true;
3680    }
3681    updateIndex = atoi(pUpdateIndex);
3682    //check updateIndex
3683    if(chr->GetTypeId() == TYPEID_PLAYER)
3684    {
3685        if (updateIndex>=PLAYER_END) return true;
3686    }
3687    else
3688    {
3689        if (updateIndex>=UNIT_END) return true;
3690    }
3691
3692    char*  pvalue = strtok(NULL, " ");
3693    if (!pvalue)
3694    {
3695        value=chr->GetUInt32Value(updateIndex);
3696
3697        PSendSysMessage(LANG_UPDATE, chr->GetGUIDLow(),updateIndex,value);
3698        return true;
3699    }
3700
3701    value=atoi(pvalue);
3702
3703    PSendSysMessage(LANG_UPDATE_CHANGE, chr->GetGUIDLow(),updateIndex,value);
3704
3705    chr->SetUInt32Value(updateIndex,value);
3706
3707    return true;
3708}
3709
3710bool ChatHandler::HandleBankCommand(const char* /*args*/)
3711{
3712    m_session->SendShowBank( m_session->GetPlayer()->GetGUID() );
3713
3714    return true;
3715}
3716
3717bool ChatHandler::HandleChangeWeather(const char* args)
3718{
3719    if(!*args)
3720        return false;
3721
3722    //Weather is OFF
3723    if (!sWorld.getConfig(CONFIG_WEATHER))
3724    {
3725        SendSysMessage(LANG_WEATHER_DISABLED);
3726        SetSentErrorMessage(true);
3727        return false;
3728    }
3729
3730    //*Change the weather of a cell
3731    char* px = strtok((char*)args, " ");
3732    char* py = strtok(NULL, " ");
3733
3734    if (!px || !py)
3735        return false;
3736
3737    uint32 type = (uint32)atoi(px);                         //0 to 3, 0: fine, 1: rain, 2: snow, 3: sand
3738    float grade = (float)atof(py);                          //0 to 1, sending -1 is instand good weather
3739
3740    Player *player = m_session->GetPlayer();
3741    uint32 zoneid = player->GetZoneId();
3742
3743    Weather* wth = sWorld.FindWeather(zoneid);
3744
3745    if(!wth)
3746        wth = sWorld.AddWeather(zoneid);
3747    if(!wth)
3748    {
3749        SendSysMessage(LANG_NO_WEATHER);
3750        SetSentErrorMessage(true);
3751        return false;
3752    }
3753
3754    wth->SetWeather(WeatherType(type), grade);
3755
3756    return true;
3757}
3758
3759bool ChatHandler::HandleSetValue(const char* args)
3760{
3761    if(!*args)
3762        return false;
3763
3764    char* px = strtok((char*)args, " ");
3765    char* py = strtok(NULL, " ");
3766    char* pz = strtok(NULL, " ");
3767
3768    if (!px || !py)
3769        return false;
3770
3771    Unit* target = getSelectedUnit();
3772    if(!target)
3773    {
3774        SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3775        SetSentErrorMessage(true);
3776        return false;
3777    }
3778
3779    uint64 guid = target->GetGUID();
3780
3781    uint32 Opcode = (uint32)atoi(px);
3782    if(Opcode >= target->GetValuesCount())
3783    {
3784        PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, GUID_LOPART(guid), target->GetValuesCount());
3785        return false;
3786    }
3787    uint32 iValue;
3788    float fValue;
3789    bool isint32 = true;
3790    if(pz)
3791        isint32 = (bool)atoi(pz);
3792    if(isint32)
3793    {
3794        iValue = (uint32)atoi(py);
3795        sLog.outDebug(GetMangosString(LANG_SET_UINT), GUID_LOPART(guid), Opcode, iValue);
3796        target->SetUInt32Value( Opcode , iValue );
3797        PSendSysMessage(LANG_SET_UINT_FIELD, GUID_LOPART(guid), Opcode,iValue);
3798    }
3799    else
3800    {
3801        fValue = (float)atof(py);
3802        sLog.outDebug(GetMangosString(LANG_SET_FLOAT), GUID_LOPART(guid), Opcode, fValue);
3803        target->SetFloatValue( Opcode , fValue );
3804        PSendSysMessage(LANG_SET_FLOAT_FIELD, GUID_LOPART(guid), Opcode,fValue);
3805    }
3806
3807    return true;
3808}
3809
3810bool ChatHandler::HandleGetValue(const char* args)
3811{
3812    if(!*args)
3813        return false;
3814
3815    char* px = strtok((char*)args, " ");
3816    char* pz = strtok(NULL, " ");
3817
3818    if (!px)
3819        return false;
3820
3821    Unit* target = getSelectedUnit();
3822    if(!target)
3823    {
3824        SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3825        SetSentErrorMessage(true);
3826        return false;
3827    }
3828
3829    uint64 guid = target->GetGUID();
3830
3831    uint32 Opcode = (uint32)atoi(px);
3832    if(Opcode >= target->GetValuesCount())
3833    {
3834        PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, GUID_LOPART(guid), target->GetValuesCount());
3835        return false;
3836    }
3837    uint32 iValue;
3838    float fValue;
3839    bool isint32 = true;
3840    if(pz)
3841        isint32 = (bool)atoi(pz);
3842
3843    if(isint32)
3844    {
3845        iValue = target->GetUInt32Value( Opcode );
3846        sLog.outDebug(GetMangosString(LANG_GET_UINT), GUID_LOPART(guid), Opcode, iValue);
3847        PSendSysMessage(LANG_GET_UINT_FIELD, GUID_LOPART(guid), Opcode,    iValue);
3848    }
3849    else
3850    {
3851        fValue = target->GetFloatValue( Opcode );
3852        sLog.outDebug(GetMangosString(LANG_GET_FLOAT), GUID_LOPART(guid), Opcode, fValue);
3853        PSendSysMessage(LANG_GET_FLOAT_FIELD, GUID_LOPART(guid), Opcode, fValue);
3854    }
3855
3856    return true;
3857}
3858
3859bool ChatHandler::HandleSet32Bit(const char* args)
3860{
3861    if(!*args)
3862        return false;
3863
3864    char* px = strtok((char*)args, " ");
3865    char* py = strtok(NULL, " ");
3866
3867    if (!px || !py)
3868        return false;
3869
3870    uint32 Opcode = (uint32)atoi(px);
3871    uint32 Value = (uint32)atoi(py);
3872    if (Value > 32)                                         //uint32 = 32 bits
3873        return false;
3874
3875    sLog.outDebug(GetMangosString(LANG_SET_32BIT), Opcode, Value);
3876
3877    m_session->GetPlayer( )->SetUInt32Value( Opcode , 2^Value );
3878
3879    PSendSysMessage(LANG_SET_32BIT_FIELD, Opcode,1);
3880    return true;
3881}
3882
3883bool ChatHandler::HandleMod32Value(const char* args)
3884{
3885    if(!*args)
3886        return false;
3887
3888    char* px = strtok((char*)args, " ");
3889    char* py = strtok(NULL, " ");
3890
3891    if (!px || !py)
3892        return false;
3893
3894    uint32 Opcode = (uint32)atoi(px);
3895    int Value = atoi(py);
3896
3897    if(Opcode >= m_session->GetPlayer()->GetValuesCount())
3898    {
3899        PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, m_session->GetPlayer()->GetGUIDLow(), m_session->GetPlayer( )->GetValuesCount());
3900        return false;
3901    }
3902
3903    sLog.outDebug(GetMangosString(LANG_CHANGE_32BIT), Opcode, Value);
3904
3905    int CurrentValue = (int)m_session->GetPlayer( )->GetUInt32Value( Opcode );
3906
3907    CurrentValue += Value;
3908    m_session->GetPlayer( )->SetUInt32Value( Opcode , (uint32)CurrentValue );
3909
3910    PSendSysMessage(LANG_CHANGE_32BIT_FIELD, Opcode,CurrentValue);
3911
3912    return true;
3913}
3914
3915bool ChatHandler::HandleAddTeleCommand(const char * args)
3916{
3917    if(!*args)
3918        return false;
3919
3920    Player *player=m_session->GetPlayer();
3921    if (!player)
3922        return false;
3923
3924    std::string name = args;
3925
3926    if(objmgr.GetGameTele(name))
3927    {
3928        SendSysMessage(LANG_COMMAND_TP_ALREADYEXIST);
3929        SetSentErrorMessage(true);
3930        return false;
3931    }
3932
3933    GameTele tele;
3934    tele.position_x  = player->GetPositionX();
3935    tele.position_y  = player->GetPositionY();
3936    tele.position_z  = player->GetPositionZ();
3937    tele.orientation = player->GetOrientation();
3938    tele.mapId       = player->GetMapId();
3939    tele.name        = name;
3940
3941    if(objmgr.AddGameTele(tele))
3942    {
3943        SendSysMessage(LANG_COMMAND_TP_ADDED);
3944    }
3945    else
3946    {
3947        SendSysMessage(LANG_COMMAND_TP_ADDEDERR);
3948        SetSentErrorMessage(true);
3949        return false;
3950    }
3951
3952    return true;
3953}
3954
3955bool ChatHandler::HandleDelTeleCommand(const char * args)
3956{
3957    if(!*args)
3958        return false;
3959
3960    std::string name = args;
3961
3962    if(!objmgr.DeleteGameTele(name))
3963    {
3964        SendSysMessage(LANG_COMMAND_TELE_NOTFOUND);
3965        SetSentErrorMessage(true);
3966        return false;
3967    }
3968
3969    SendSysMessage(LANG_COMMAND_TP_DELETED);
3970    return true;
3971}
3972
3973bool ChatHandler::HandleListAurasCommand (const char * /*args*/)
3974{
3975    Unit *unit = getSelectedUnit();
3976    if(!unit)
3977    {
3978        SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3979        SetSentErrorMessage(true);
3980        return false;
3981    }
3982
3983    char const* talentStr = GetMangosString(LANG_TALENT);
3984    char const* passiveStr = GetMangosString(LANG_PASSIVE);
3985
3986    Unit::AuraMap const& uAuras = unit->GetAuras();
3987    PSendSysMessage(LANG_COMMAND_TARGET_LISTAURAS, uAuras.size());
3988    for (Unit::AuraMap::const_iterator itr = uAuras.begin(); itr != uAuras.end(); ++itr)
3989    {
3990        bool talent = GetTalentSpellCost(itr->second->GetId()) > 0;
3991        PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffIndex(),
3992            itr->second->GetModifier()->m_auraname, itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(),
3993            itr->second->GetSpellProto()->SpellName[m_session->GetSessionDbcLocale()],
3994            (itr->second->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
3995            IS_PLAYER_GUID(itr->second->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(itr->second->GetCasterGUID()));
3996    }
3997    for (int i = 0; i < TOTAL_AURAS; i++)
3998    {
3999        Unit::AuraList const& uAuraList = unit->GetAurasByType(AuraType(i));
4000        if (uAuraList.empty()) continue;
4001        PSendSysMessage(LANG_COMMAND_TARGET_LISTAURATYPE, uAuraList.size(), i);
4002        for (Unit::AuraList::const_iterator itr = uAuraList.begin(); itr != uAuraList.end(); ++itr)
4003        {
4004            bool talent = GetTalentSpellCost((*itr)->GetId()) > 0;
4005            PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(),
4006                (*itr)->GetSpellProto()->SpellName[m_session->GetSessionDbcLocale()],((*itr)->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
4007                IS_PLAYER_GUID((*itr)->GetCasterGUID()) ? "player" : "creature",GUID_LOPART((*itr)->GetCasterGUID()));
4008        }
4009    }
4010    return true;
4011}
4012
4013bool ChatHandler::HandleResetHonorCommand (const char * args)
4014{
4015    char* pName = strtok((char*)args, "");
4016    Player *player = NULL;
4017    if (pName)
4018    {
4019        std::string name = pName;
4020        if(!normalizePlayerName(name))
4021        {
4022            SendSysMessage(LANG_PLAYER_NOT_FOUND);
4023            SetSentErrorMessage(true);
4024            return false;
4025        }
4026
4027        uint64 guid = objmgr.GetPlayerGUIDByName(name.c_str());
4028        player = objmgr.GetPlayer(guid);
4029    }
4030    else
4031        player = getSelectedPlayer();
4032
4033    if(!player)
4034    {
4035        SendSysMessage(LANG_NO_CHAR_SELECTED);
4036        return true;
4037    }
4038
4039    player->SetUInt32Value(PLAYER_FIELD_KILLS, 0);
4040    player->SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORBALE_KILLS, 0);
4041    player->SetUInt32Value(PLAYER_FIELD_HONOR_CURRENCY, 0);
4042    player->SetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, 0);
4043    player->SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, 0);
4044
4045    return true;
4046}
4047
4048static bool HandleResetStatsOrLevelHelper(Player* player)
4049{
4050    PlayerInfo const *info = objmgr.GetPlayerInfo(player->getRace(), player->getClass());
4051    if(!info) return false;
4052
4053    ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(player->getClass());
4054    if(!cEntry)
4055    {
4056        sLog.outError("Class %u not found in DBC (Wrong DBC files?)",player->getClass());
4057        return false;
4058    }
4059
4060    uint8 powertype = cEntry->powerType;
4061
4062    uint32 unitfield;
4063    if(powertype == POWER_RAGE)
4064        unitfield = 0x1100EE00;
4065    else if(powertype == POWER_ENERGY)
4066        unitfield = 0x00000000;
4067    else if(powertype == POWER_MANA)
4068        unitfield = 0x0000EE00;
4069    else
4070    {
4071        sLog.outError("Invalid default powertype %u for player (class %u)",powertype,player->getClass());
4072        return false;
4073    }
4074
4075    // reset m_form if no aura
4076    if(!player->HasAuraType(SPELL_AURA_MOD_SHAPESHIFT))
4077        player->m_form = FORM_NONE;
4078
4079    player->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE );
4080    player->SetFloatValue(UNIT_FIELD_COMBATREACH, 1.5f   );
4081
4082    player->setFactionForRace(player->getRace());
4083
4084    player->SetUInt32Value(UNIT_FIELD_BYTES_0, ( ( player->getRace() ) | ( player->getClass() << 8 ) | ( player->getGender() << 16 ) | ( powertype << 24 ) ) );
4085
4086    // reset only if player not in some form;
4087    if(player->m_form==FORM_NONE)
4088    {
4089        switch(player->getGender())
4090        {
4091            case GENDER_FEMALE:
4092                player->SetDisplayId(info->displayId_f);
4093                player->SetNativeDisplayId(info->displayId_f);
4094                break;
4095            case GENDER_MALE:
4096                player->SetDisplayId(info->displayId_m);
4097                player->SetNativeDisplayId(info->displayId_m);
4098                break;
4099            default:
4100                break;
4101        }
4102    }
4103
4104    // set UNIT_FIELD_BYTES_1 to init state but preserve m_form value
4105    player->SetUInt32Value(UNIT_FIELD_BYTES_1, unitfield);
4106    player->SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_UNK3 | UNIT_BYTE2_FLAG_UNK5 );
4107    player->SetByteValue(UNIT_FIELD_BYTES_2, 3, player->m_form);
4108
4109    player->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
4110
4111    //-1 is default value
4112    player->SetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, uint32(-1));
4113
4114    //player->SetUInt32Value(PLAYER_FIELD_BYTES, 0xEEE00000 );
4115    return true;
4116}
4117
4118bool ChatHandler::HandleResetLevelCommand(const char * args)
4119{
4120    char* pName = strtok((char*)args, "");
4121    Player *player = NULL;
4122    if (pName)
4123    {
4124        std::string name = pName;
4125        if(!normalizePlayerName(name))
4126        {
4127            SendSysMessage(LANG_PLAYER_NOT_FOUND);
4128            SetSentErrorMessage(true);
4129            return false;
4130        }
4131
4132        uint64 guid = objmgr.GetPlayerGUIDByName(name.c_str());
4133        player = objmgr.GetPlayer(guid);
4134    }
4135    else
4136        player = getSelectedPlayer();
4137
4138    if(!player)
4139    {
4140        SendSysMessage(LANG_NO_CHAR_SELECTED);
4141        SetSentErrorMessage(true);
4142        return false;
4143    }
4144
4145    if(!HandleResetStatsOrLevelHelper(player))
4146        return false;
4147
4148    player->SetLevel(1);
4149    player->InitStatsForLevel(true);
4150    player->InitTaxiNodesForLevel();
4151    player->InitTalentForLevel();
4152    player->SetUInt32Value(PLAYER_XP,0);
4153
4154    // reset level to summoned pet
4155    Pet* pet = player->GetPet();
4156    if(pet && pet->getPetType()==SUMMON_PET)
4157        pet->InitStatsForLevel(1);
4158
4159    return true;
4160}
4161
4162bool ChatHandler::HandleResetStatsCommand(const char * args)
4163{
4164    char* pName = strtok((char*)args, "");
4165    Player *player = NULL;
4166    if (pName)
4167    {
4168        std::string name = pName;
4169        if(!normalizePlayerName(name))
4170        {
4171            SendSysMessage(LANG_PLAYER_NOT_FOUND);
4172            SetSentErrorMessage(true);
4173            return false;
4174        }
4175
4176        uint64 guid = objmgr.GetPlayerGUIDByName(name.c_str());
4177        player = objmgr.GetPlayer(guid);
4178    }
4179    else
4180        player = getSelectedPlayer();
4181
4182    if(!player)
4183    {
4184        SendSysMessage(LANG_NO_CHAR_SELECTED);
4185        SetSentErrorMessage(true);
4186        return false;
4187    }
4188
4189    if(!HandleResetStatsOrLevelHelper(player))
4190        return false;
4191
4192    player->InitStatsForLevel(true);
4193    player->InitTaxiNodesForLevel();
4194    player->InitTalentForLevel();
4195
4196    return true;
4197}
4198
4199bool ChatHandler::HandleResetSpellsCommand(const char * args)
4200{
4201    char* pName = strtok((char*)args, "");
4202    Player *player = NULL;
4203    uint64 playerGUID = 0;
4204    if (pName)
4205    {
4206        std::string name = pName;
4207
4208        if(!normalizePlayerName(name))
4209        {
4210            SendSysMessage(LANG_PLAYER_NOT_FOUND);
4211            SetSentErrorMessage(true);
4212            return false;
4213        }
4214
4215        player = objmgr.GetPlayer(name.c_str());
4216        if(!player)
4217            playerGUID = objmgr.GetPlayerGUIDByName(name.c_str());
4218    }
4219    else
4220        player = getSelectedPlayer();
4221
4222    if(!player && !playerGUID)
4223    {
4224        SendSysMessage(LANG_NO_CHAR_SELECTED);
4225        SetSentErrorMessage(true);
4226        return false;
4227    }
4228
4229    if(player)
4230    {
4231        player->resetSpells();
4232
4233        ChatHandler(player).SendSysMessage(LANG_RESET_SPELLS);
4234
4235        if(m_session->GetPlayer()!=player)
4236            PSendSysMessage(LANG_RESET_SPELLS_ONLINE,player->GetName());
4237    }
4238    else
4239    {
4240        CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",uint32(AT_LOGIN_RESET_SPELLS), GUID_LOPART(playerGUID));
4241        PSendSysMessage(LANG_RESET_SPELLS_OFFLINE,pName);
4242    }
4243
4244    return true;
4245}
4246
4247bool ChatHandler::HandleResetTalentsCommand(const char * args)
4248{
4249    char* pName = strtok((char*)args, "");
4250    Player *player = NULL;
4251    uint64 playerGUID = 0;
4252    if (pName)
4253    {
4254        std::string name = pName;
4255        if(!normalizePlayerName(name))
4256        {
4257            SendSysMessage(LANG_PLAYER_NOT_FOUND);
4258            SetSentErrorMessage(true);
4259            return false;
4260        }
4261
4262        player = objmgr.GetPlayer(name.c_str());
4263        if(!player)
4264            playerGUID = objmgr.GetPlayerGUIDByName(name.c_str());
4265    }
4266    else
4267        player = getSelectedPlayer();
4268
4269    if(!player && !playerGUID)
4270    {
4271        SendSysMessage(LANG_NO_CHAR_SELECTED);
4272        SetSentErrorMessage(true);
4273        return false;
4274    }
4275
4276    if(player)
4277    {
4278        player->resetTalents(true);
4279
4280        ChatHandler(player).SendSysMessage(LANG_RESET_TALENTS);
4281
4282        if(m_session->GetPlayer()!=player)
4283            PSendSysMessage(LANG_RESET_TALENTS_ONLINE,player->GetName());
4284    }
4285    else
4286    {
4287        CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",uint32(AT_LOGIN_RESET_TALENTS), GUID_LOPART(playerGUID) );
4288        PSendSysMessage(LANG_RESET_TALENTS_OFFLINE,pName);
4289    }
4290
4291    return true;
4292}
4293
4294bool ChatHandler::HandleResetAllCommand(const char * args)
4295{
4296    if(!*args)
4297        return false;
4298
4299    std::string casename = args;
4300
4301    AtLoginFlags atLogin;
4302
4303    // Command specially created as single command to prevent using short case names
4304    if(casename=="spells")
4305    {
4306        atLogin = AT_LOGIN_RESET_SPELLS;
4307        sWorld.SendWorldText(LANG_RESETALL_SPELLS);
4308    }
4309    else if(casename=="talents")
4310    {
4311        atLogin = AT_LOGIN_RESET_TALENTS;
4312        sWorld.SendWorldText(LANG_RESETALL_TALENTS);
4313    }
4314    else
4315    {
4316        PSendSysMessage(LANG_RESETALL_UNKNOWN_CASE,args);
4317        SetSentErrorMessage(true);
4318        return false;
4319    }
4320
4321    CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u'",atLogin);
4322    HashMapHolder<Player>::MapType const& plist = ObjectAccessor::Instance().GetPlayers();
4323    for(HashMapHolder<Player>::MapType::const_iterator itr = plist.begin(); itr != plist.end(); ++itr)
4324        itr->second->SetAtLoginFlag(atLogin);
4325
4326    return true;
4327}
4328
4329bool ChatHandler::HandleShutDownCommand(const char* args)
4330{
4331    if(!*args)
4332        return false;
4333
4334    if(std::string(args)=="cancel")
4335    {
4336        sWorld.ShutdownCancel();
4337    }
4338    else
4339    {
4340        int32 time = atoi(args);
4341
4342        ///- Prevent interpret wrong arg value as 0 secs shutdown time
4343        if(time == 0 && (args[0]!='0' || args[1]!='\0') || time < 0)
4344            return false;
4345
4346        sWorld.ShutdownServ(time);
4347    }
4348    return true;
4349}
4350
4351bool ChatHandler::HandleRestartCommand(const char* args)
4352{
4353    if(!*args)
4354        return false;
4355
4356    if(std::string(args)=="cancel")
4357    {
4358        sWorld.ShutdownCancel();
4359    }
4360    else
4361    {
4362        int32 time = atoi(args);
4363
4364        ///- Prevent interpret wrong arg value as 0 secs shutdown time
4365        if(time == 0 && (args[0]!='0' || args[1]!='\0') || time < 0)
4366            return false;
4367
4368        sWorld.ShutdownServ(time, SHUTDOWN_MASK_RESTART);
4369    }
4370    return true;
4371}
4372
4373bool ChatHandler::HandleIdleRestartCommand(const char* args)
4374{
4375    if(!*args)
4376        return false;
4377
4378    if(std::string(args)=="cancel")
4379    {
4380        sWorld.ShutdownCancel();
4381    }
4382    else
4383    {
4384        int32 time = atoi(args);
4385
4386        ///- Prevent interpret wrong arg value as 0 secs shutdown time
4387        if(time == 0 && (args[0]!='0' || args[1]!='\0') || time < 0)
4388            return false;
4389
4390        sWorld.ShutdownServ(time,SHUTDOWN_MASK_RESTART+SHUTDOWN_MASK_IDLE);
4391    }
4392    return true;
4393}
4394
4395bool ChatHandler::HandleIdleShutDownCommand(const char* args)
4396{
4397    if(!*args)
4398        return false;
4399
4400    if(std::string(args)=="cancel")
4401    {
4402        sWorld.ShutdownCancel();
4403    }
4404    else
4405    {
4406        int32 time = atoi(args);
4407
4408        ///- Prevent interpret wrong arg value as 0 secs shutdown time
4409        if(time == 0 && (args[0]!='0' || args[1]!='\0') || time < 0)
4410            return false;
4411
4412        sWorld.ShutdownServ(time,SHUTDOWN_MASK_IDLE);
4413    }
4414    return true;
4415}
4416
4417bool ChatHandler::HandleAddQuest(const char* args)
4418{
4419    Player* player = getSelectedPlayer();
4420    if(!player)
4421    {
4422        SendSysMessage(LANG_NO_CHAR_SELECTED);
4423        SetSentErrorMessage(true);
4424        return false;
4425    }
4426
4427    // .addquest #entry'
4428    // number or [name] Shift-click form |color|Hquest:quest_id|h[name]|h|r
4429    char* cId = extractKeyFromLink((char*)args,"Hquest");
4430    if(!cId)
4431        return false;
4432
4433    uint32 entry = atol(cId);
4434
4435    Quest const* pQuest = objmgr.GetQuestTemplate(entry);
4436
4437    if(!pQuest)
4438    {
4439        PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND,entry);
4440        SetSentErrorMessage(true);
4441        return false;
4442    }
4443
4444    // check item starting quest (it can work incorrectly if added without item in inventory)
4445    QueryResult *result = WorldDatabase.PQuery("SELECT entry FROM item_template WHERE startquest = '%u' LIMIT 1",entry);
4446    if(result)
4447    {
4448        Field* fields = result->Fetch();
4449        uint32 item_id = fields[0].GetUInt32();
4450        delete result;
4451
4452        PSendSysMessage(LANG_COMMAND_QUEST_STARTFROMITEM, entry,item_id);
4453        SetSentErrorMessage(true);
4454        return false;
4455    }
4456
4457    // ok, normal (creature/GO starting) quest
4458    if( player->CanAddQuest( pQuest, true ) )
4459    {
4460        player->AddQuest( pQuest, NULL );
4461
4462        if ( player->CanCompleteQuest( entry ) )
4463            player->CompleteQuest( entry );
4464    }
4465
4466    return true;
4467}
4468
4469bool ChatHandler::HandleRemoveQuest(const char* args)
4470{
4471    Player* player = getSelectedPlayer();
4472    if(!player)
4473    {
4474        SendSysMessage(LANG_NO_CHAR_SELECTED);
4475        SetSentErrorMessage(true);
4476        return false;
4477    }
4478
4479    // .removequest #entry'
4480    // number or [name] Shift-click form |color|Hquest:quest_id|h[name]|h|r
4481    char* cId = extractKeyFromLink((char*)args,"Hquest");
4482    if(!cId)
4483        return false;
4484
4485    uint32 entry = atol(cId);
4486
4487    Quest const* pQuest = objmgr.GetQuestTemplate(entry);
4488
4489    if(!pQuest)
4490    {
4491        PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry);
4492        SetSentErrorMessage(true);
4493        return false;
4494    }
4495
4496    // remove all quest entries for 'entry' from quest log
4497    for(uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot )
4498    {
4499        uint32 quest = player->GetQuestSlotQuestId(slot);
4500        if(quest==entry)
4501        {
4502            player->SetQuestSlot(slot,0);
4503
4504            // we ignore unequippable quest items in this case, its' still be equipped
4505            player->TakeQuestSourceItem( quest, false );
4506        }
4507    }
4508
4509    // set quest status to not started (will updated in DB at next save)
4510    player->SetQuestStatus( entry, QUEST_STATUS_NONE);
4511
4512    // reset rewarded for restart repeatable quest
4513    player->getQuestStatusMap()[entry].m_rewarded = false;
4514
4515    SendSysMessage(LANG_COMMAND_QUEST_REMOVED);
4516    return true;
4517}
4518
4519bool ChatHandler::HandleCompleteQuest(const char* args)
4520{
4521    Player* player = getSelectedPlayer();
4522    if(!player)
4523    {
4524        SendSysMessage(LANG_NO_CHAR_SELECTED);
4525        SetSentErrorMessage(true);
4526        return false;
4527    }
4528
4529    // .quest complete #entry
4530    // number or [name] Shift-click form |color|Hquest:quest_id|h[name]|h|r
4531    char* cId = extractKeyFromLink((char*)args,"Hquest");
4532    if(!cId)
4533        return false;
4534
4535    uint32 entry = atol(cId);
4536
4537    Quest const* pQuest = objmgr.GetQuestTemplate(entry);
4538
4539    // If player doesn't have the quest
4540    if(!pQuest || player->GetQuestStatus(entry) == QUEST_STATUS_NONE)
4541    {
4542        PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry);
4543        SetSentErrorMessage(true);
4544        return false;
4545    }
4546
4547    // Add quest items for quests that require items
4548    for(uint8 x = 0; x < QUEST_OBJECTIVES_COUNT; ++x)
4549    {
4550        uint32 id = pQuest->ReqItemId[x];
4551        uint32 count = pQuest->ReqItemCount[x];
4552        if(!id || !count)
4553            continue;
4554
4555        uint32 curItemCount = player->GetItemCount(id,true);
4556
4557        ItemPosCountVec dest;
4558        uint8 msg = player->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, id, count-curItemCount );
4559        if( msg == EQUIP_ERR_OK )
4560        {
4561            Item* item = player->StoreNewItem( dest, id, true);
4562            player->SendNewItem(item,count-curItemCount,true,false);
4563        }
4564    }
4565
4566    // All creature/GO slain/casted (not required, but otherwise it will display "Creature slain 0/10")
4567    for(uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; i++)
4568    {
4569        uint32 creature = pQuest->ReqCreatureOrGOId[i];
4570        uint32 creaturecount = pQuest->ReqCreatureOrGOCount[i];
4571
4572        if(uint32 spell_id = pQuest->ReqSpell[i])
4573        {
4574            for(uint16 z = 0; z < creaturecount; ++z)
4575                player->CastedCreatureOrGO(creature,0,spell_id);
4576        }
4577        else if(creature > 0)
4578        {
4579            for(uint16 z = 0; z < creaturecount; ++z)
4580                player->KilledMonster(creature,0);
4581        }
4582        else if(creature < 0)
4583        {
4584            for(uint16 z = 0; z < creaturecount; ++z)
4585                player->CastedCreatureOrGO(creature,0,0);
4586        }
4587    }
4588
4589    // If the quest requires reputation to complete
4590    if(uint32 repFaction = pQuest->GetRepObjectiveFaction())
4591    {
4592        uint32 repValue = pQuest->GetRepObjectiveValue();
4593        uint32 curRep = player->GetReputation(repFaction);
4594        if(curRep < repValue)
4595        {
4596            FactionEntry const *factionEntry = sFactionStore.LookupEntry(repFaction);
4597            player->SetFactionReputation(factionEntry,repValue);
4598        }
4599    }
4600
4601    // If the quest requires money
4602    int32 ReqOrRewMoney = pQuest->GetRewOrReqMoney();
4603    if(ReqOrRewMoney < 0)
4604        player->ModifyMoney(-ReqOrRewMoney);
4605
4606    player->CompleteQuest(entry);
4607    return true;
4608}
4609
4610bool ChatHandler::HandleBanCommand(const char* args)
4611{
4612    if(!args)
4613        return false;
4614
4615    char* type = strtok((char*)args, " ");
4616
4617    if(!type)
4618        return false;
4619    char* nameOrIP = strtok(NULL, " ");
4620
4621    if(!nameOrIP)
4622        return false;
4623
4624    char* duration = strtok(NULL," ");
4625    if(!duration || !atoi(duration))
4626        return false;
4627
4628    char* reason = strtok(NULL,"");
4629    if(!reason)
4630        return false;
4631
4632    switch(sWorld.BanAccount(type, nameOrIP, duration, reason,m_session->GetPlayerName()))
4633    {
4634        case BAN_SUCCESS:
4635            if(atoi(duration)>0)
4636                PSendSysMessage(LANG_BAN_YOUBANNED,nameOrIP,secsToTimeString(TimeStringToSecs(duration),true).c_str(),reason);
4637            else
4638                PSendSysMessage(LANG_BAN_YOUPERMBANNED,nameOrIP,reason);
4639            break;
4640        case BAN_SYNTAX_ERROR:
4641            return false;
4642        case BAN_NOTFOUND:
4643            PSendSysMessage(LANG_BAN_NOTFOUND,type,nameOrIP);
4644            break;
4645    }
4646
4647    return true;
4648}
4649
4650bool ChatHandler::HandleUnBanCommand(const char* args)
4651{
4652    if(!args)
4653        return false;
4654    char* type = strtok((char*)args, " ");
4655    if(!type)
4656        return false;
4657    char* nameOrIP = strtok(NULL, " ");
4658
4659    if(!nameOrIP)
4660        return false;
4661
4662    if(sWorld.RemoveBanAccount(type,nameOrIP))
4663        PSendSysMessage(LANG_UNBAN_UNBANNED,nameOrIP);
4664    else
4665        PSendSysMessage(LANG_UNBAN_ERROR,nameOrIP);
4666
4667    return true;
4668}
4669
4670bool ChatHandler::HandleBanInfoCommand(const char* args)
4671{
4672    if(!args)
4673        return false;
4674
4675    char* cType = strtok((char*)args, " ");
4676    char* cnameOrIP = strtok(NULL, "");
4677    if(!cType || !cnameOrIP)
4678        return false;
4679
4680    std::string nameOrIP = cnameOrIP;
4681    std::string type = cType;
4682    if (!IsIPAddress(cnameOrIP) && type=="ip")
4683        return false;
4684
4685    Field *fields;
4686    if(type != "ip")
4687    {
4688        //look the accountid up
4689        uint32 accountid;
4690        std::string accountname;
4691        if(type == "account")
4692        {
4693            loginDatabase.escape_string(nameOrIP);
4694            QueryResult *result = loginDatabase.PQuery("SELECT id, username FROM account WHERE username = '%s'",nameOrIP.c_str());
4695            if (!result)
4696            {
4697                PSendSysMessage(LANG_BANINFO_NOACCOUNT);
4698                return true;
4699            }
4700            fields = result->Fetch();
4701            accountid = fields[0].GetUInt32();
4702            accountname = fields[1].GetCppString();
4703            delete result;
4704        }
4705        else if(type == "character")
4706        {
4707            if(!normalizePlayerName(nameOrIP))
4708            {
4709                SendSysMessage(LANG_PLAYER_NOT_FOUND);
4710                SetSentErrorMessage(true);
4711                return false;
4712            }
4713
4714            loginDatabase.escape_string(nameOrIP);
4715            QueryResult *result = CharacterDatabase.PQuery("SELECT account FROM characters WHERE name = '%s'", nameOrIP.c_str());
4716            if (!result)
4717            {
4718                PSendSysMessage(LANG_BANINFO_NOCHARACTER);
4719                return true;
4720            }
4721            fields = result->Fetch();
4722            accountid = fields[0].GetUInt32();
4723            delete result;
4724            result = loginDatabase.PQuery("SELECT username FROM account WHERE id = '%u'", accountid);
4725            if (!result)
4726            {
4727                PSendSysMessage(LANG_BANINFO_NOCHARACTER);
4728                return true;
4729            }
4730            fields = result->Fetch();
4731            accountname = fields[0].GetCppString();
4732            delete result;
4733        }
4734        else
4735            return false;
4736
4737        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);
4738        if(!result)
4739        {
4740            PSendSysMessage(LANG_BANINFO_NOACCOUNTBAN, accountname.c_str());
4741            return true;
4742        }
4743
4744        PSendSysMessage(LANG_BANINFO_BANHISTORY,accountname.c_str());
4745        do
4746        {
4747            fields = result->Fetch();
4748
4749            time_t unbandate = time_t(fields[3].GetUInt64());
4750            bool active = false;
4751            if(fields[2].GetBool() && (fields[1].GetUInt64() == (uint64)0 ||unbandate >= time(NULL)) )
4752                active = true;
4753            bool permanent = (fields[1].GetUInt64() == (uint64)0);
4754            std::string bantime = permanent?GetMangosString(LANG_BANINFO_INFINITE):secsToTimeString(fields[1].GetUInt64(), true);
4755            PSendSysMessage(LANG_BANINFO_HISTORYENTRY,
4756                fields[0].GetString(), bantime.c_str(), active ? GetMangosString(LANG_BANINFO_YES):GetMangosString(LANG_BANINFO_NO), fields[4].GetString(), fields[5].GetString());
4757        }while (result->NextRow());
4758
4759        delete result;
4760    }
4761    else
4762    {
4763        loginDatabase.escape_string(nameOrIP);
4764        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'",nameOrIP.c_str());
4765        if(!result)
4766        {
4767            PSendSysMessage(LANG_BANINFO_NOIP);
4768            return true;
4769        }
4770        fields = result->Fetch();
4771        bool permanent = (fields[6].GetUInt64()==(uint64)0);
4772        PSendSysMessage(LANG_BANINFO_IPENTRY,
4773            fields[0].GetString(), fields[1].GetString(), permanent ? GetMangosString(LANG_BANINFO_NEVER):fields[2].GetString(),
4774            permanent ? GetMangosString(LANG_BANINFO_INFINITE):secsToTimeString(fields[3].GetUInt64(), true).c_str(), fields[4].GetString(), fields[5].GetString());
4775        delete result;
4776    }
4777    return true;
4778}
4779
4780bool ChatHandler::HandleBanListCommand(const char* args)
4781{
4782    loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
4783    if(!*args)
4784        return false;
4785    char* cType = strtok((char*)args, " ");
4786    char* cFilter = strtok(NULL, "");
4787    if(!cType || !cFilter)
4788        return false;
4789    std::string Filter = cFilter;
4790    std::string Type = cType;
4791    loginDatabase.escape_string(Filter);
4792
4793    QueryResult* result  = NULL;
4794    Field *fields = NULL;
4795    if(Type == "ip")
4796    {
4797        result = loginDatabase.PQuery("SELECT ip FROM ip_banned WHERE ip "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'"),Filter.c_str());
4798        if(!result)
4799        {
4800            PSendSysMessage(LANG_BANLIST_NOIP);
4801            return true;
4802        }
4803        PSendSysMessage(LANG_BANLIST_MATCHINGIP);
4804        do
4805        {
4806            fields = result->Fetch();
4807            PSendSysMessage("%s",fields[0].GetString());
4808        } while (result->NextRow());
4809
4810        delete result;
4811        return true;
4812    }
4813    //lookup accountid
4814    if(Type == "account")
4815    {
4816        result = loginDatabase.PQuery("SELECT id FROM account WHERE username "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'"),Filter.c_str());
4817        if (!result)
4818        {
4819            PSendSysMessage(LANG_BANLIST_NOACCOUNT);
4820            return true;
4821        }
4822        //do not delete result
4823    }
4824    else if(Type == "characters")
4825    {
4826        result = CharacterDatabase.PQuery("SELECT account FROM characters, WHERE name "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'"),Filter.c_str());
4827        if (!result)
4828        {
4829            PSendSysMessage(LANG_BANLIST_NOCHARACTER);
4830            return true;
4831        }
4832    }
4833    else
4834        return false;
4835
4836    PSendSysMessage(LANG_BANLIST_MATCHINGACCOUNT);
4837    do
4838    {
4839        fields = result->Fetch();
4840        uint32 accountid = fields[0].GetUInt32();
4841        QueryResult* banresult = loginDatabase.PQuery("SELECT account.username FROM account,account_banned WHERE account_banned.id='%u' AND account_banned.active = '1' AND account_banned.id=account.id",accountid);
4842        if(banresult)
4843        {
4844            Field* fields2 = banresult->Fetch();
4845            PSendSysMessage("%s",fields2[0].GetString());
4846            delete banresult;
4847        }
4848    } while (result->NextRow());
4849
4850    delete result;
4851    return true;
4852}
4853
4854bool ChatHandler::HandleRespawnCommand(const char* /*args*/)
4855{
4856    Player* pl = m_session->GetPlayer();
4857
4858    CellPair p(MaNGOS::ComputeCellPair(pl->GetPositionX(), pl->GetPositionY()));
4859    Cell cell(p);
4860    cell.data.Part.reserved = ALL_DISTRICT;
4861    cell.SetNoCreate();
4862
4863    MaNGOS::RespawnDo u_do;
4864    MaNGOS::WorldObjectWorker<MaNGOS::RespawnDo> worker(u_do);
4865
4866    TypeContainerVisitor<MaNGOS::WorldObjectWorker<MaNGOS::RespawnDo>, GridTypeMapContainer > obj_worker(worker);
4867    CellLock<GridReadGuard> cell_lock(cell, p);
4868    cell_lock->Visit(cell_lock, obj_worker, *MapManager::Instance().GetMap(pl->GetMapId(), pl));
4869
4870    return true;
4871}
4872
4873bool ChatHandler::HandleFlyModeCommand(const char* args)
4874{
4875    if(!args)
4876        return false;
4877
4878    Unit *unit = getSelectedUnit();
4879    if (!unit || (unit->GetTypeId() != TYPEID_PLAYER))
4880        unit = m_session->GetPlayer();
4881
4882    WorldPacket data(12);
4883    if (strncmp(args, "on", 3) == 0)
4884        data.SetOpcode(SMSG_MOVE_SET_CAN_FLY);
4885    else if (strncmp(args, "off", 4) == 0)
4886        data.SetOpcode(SMSG_MOVE_UNSET_CAN_FLY);
4887    else
4888    {
4889        SendSysMessage(LANG_USE_BOL);
4890        return false;
4891    }
4892    data.append(unit->GetPackGUID());
4893    data << uint32(0);                                      // unknown
4894    unit->SendMessageToSet(&data, true);
4895    PSendSysMessage(LANG_COMMAND_FLYMODE_STATUS, unit->GetName(), args);
4896    return true;
4897}
4898
4899bool ChatHandler::HandleLoadPDumpCommand(const char *args)
4900{
4901    if(!args)
4902        return false;
4903
4904    char * file = strtok((char*)args, " "); if(!file) return false;
4905    char * acc = strtok(NULL, " "); if(!acc) return false;
4906    if(!file || !acc)
4907        return false;
4908
4909    uint32 account_id = objmgr.GetAccountByAccountName(acc);
4910    if(!account_id)
4911    {
4912        account_id = atoi(acc);
4913        if(account_id)
4914        {
4915            std::string acc_name;
4916            if(!objmgr.GetAccountNameByAccount(account_id,acc_name))
4917                return false;
4918        }
4919        else
4920            return false;
4921    }
4922
4923    char * name = strtok(NULL, " ");
4924    char * guid_str = name ? strtok(NULL, " ") : NULL;
4925
4926    uint32 guid = guid_str ? atoi(guid_str) : 0;
4927
4928    if(PlayerDumpReader().LoadDump(file, account_id, name ? name : "", guid))
4929        PSendSysMessage(LANG_COMMAND_IMPORT_SUCCESS);
4930    else
4931        PSendSysMessage(LANG_COMMAND_IMPORT_FAILED);
4932
4933    return true;
4934}
4935
4936bool ChatHandler::HandleChangeEntryCommand(const char *args)
4937{
4938    if(!args)
4939        return false;
4940
4941    uint32 newEntryNum = atoi(args);
4942    if(!newEntryNum)
4943        return false;
4944
4945    Unit* unit = getSelectedUnit();
4946    if(!unit || unit->GetTypeId() != TYPEID_UNIT)
4947    {
4948        SendSysMessage(LANG_SELECT_CREATURE);
4949        SetSentErrorMessage(true);
4950        return false;
4951    }
4952    Creature* creature = (Creature*)unit;
4953    if(creature->UpdateEntry(newEntryNum))
4954        SendSysMessage(LANG_DONE);
4955    else
4956        SendSysMessage(LANG_ERROR);
4957    return true;
4958}
4959
4960bool ChatHandler::HandleWritePDumpCommand(const char *args)
4961{
4962    if(!args)
4963        return false;
4964
4965    char* file = strtok((char*)args, " ");
4966    char* p2 = strtok(NULL, " ");
4967
4968    if(!file || !p2)
4969        return false;
4970
4971    uint32 guid = objmgr.GetPlayerGUIDByName(p2);
4972    if(!guid)
4973        guid = atoi(p2);
4974
4975    if (PlayerDumpWriter().WriteDump(file, guid))
4976        PSendSysMessage(LANG_COMMAND_EXPORT_SUCCESS);
4977    else
4978        PSendSysMessage(LANG_COMMAND_EXPORT_FAILED);
4979
4980    return true;
4981}
4982
4983bool ChatHandler::HandleMovegensCommand(const char* /*args*/)
4984{
4985    Unit* unit = getSelectedUnit();
4986    if(!unit)
4987    {
4988        SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
4989        SetSentErrorMessage(true);
4990        return false;
4991    }
4992
4993    PSendSysMessage(LANG_MOVEGENS_LIST,(unit->GetTypeId()==TYPEID_PLAYER ? "Player" : "Creature" ),unit->GetGUIDLow());
4994
4995    MotionMaster* mm = unit->GetMotionMaster();
4996    for(MotionMaster::const_iterator itr = mm->begin(); itr != mm->end(); ++itr)
4997    {
4998        switch((*itr)->GetMovementGeneratorType())
4999        {
5000            case IDLE_MOTION_TYPE:          SendSysMessage(LANG_MOVEGENS_IDLE);          break;
5001            case RANDOM_MOTION_TYPE:        SendSysMessage(LANG_MOVEGENS_RANDOM);        break;
5002            case WAYPOINT_MOTION_TYPE:      SendSysMessage(LANG_MOVEGENS_WAYPOINT);      break;
5003            case ANIMAL_RANDOM_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_ANIMAL_RANDOM); break;
5004            case CONFUSED_MOTION_TYPE:      SendSysMessage(LANG_MOVEGENS_CONFUSED);      break;
5005            case TARGETED_MOTION_TYPE:
5006            {
5007                if(unit->GetTypeId()==TYPEID_PLAYER)
5008                {
5009                    TargetedMovementGenerator<Player> const* mgen = static_cast<TargetedMovementGenerator<Player> const*>(*itr);
5010                    Unit* target = mgen->GetTarget();
5011                    if(target)
5012                        PSendSysMessage(LANG_MOVEGENS_TARGETED_PLAYER,target->GetName(),target->GetGUIDLow());
5013                    else
5014                        SendSysMessage(LANG_MOVEGENS_TARGETED_NULL);
5015                }
5016                else
5017                {
5018                    TargetedMovementGenerator<Creature> const* mgen = static_cast<TargetedMovementGenerator<Creature> const*>(*itr);
5019                    Unit* target = mgen->GetTarget();
5020                    if(target)
5021                        PSendSysMessage(LANG_MOVEGENS_TARGETED_CREATURE,target->GetName(),target->GetGUIDLow());
5022                    else
5023                        SendSysMessage(LANG_MOVEGENS_TARGETED_NULL);
5024                }
5025                break;
5026            }
5027            case HOME_MOTION_TYPE:
5028                if(unit->GetTypeId()==TYPEID_UNIT)
5029                {
5030                    float x,y,z;
5031                    (*itr)->GetDestination(x,y,z);
5032                    PSendSysMessage(LANG_MOVEGENS_HOME_CREATURE,x,y,z);
5033                }
5034                else
5035                    SendSysMessage(LANG_MOVEGENS_HOME_PLAYER);
5036                break;
5037            case FLIGHT_MOTION_TYPE:   SendSysMessage(LANG_MOVEGENS_FLIGHT);  break;
5038            case POINT_MOTION_TYPE:
5039            {
5040                float x,y,z;
5041                (*itr)->GetDestination(x,y,z);
5042                PSendSysMessage(LANG_MOVEGENS_POINT,x,y,z);
5043                break;
5044            }
5045            case FLEEING_MOTION_TYPE:  SendSysMessage(LANG_MOVEGENS_FEAR);    break;
5046            case DISTRACT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_DISTRACT);  break;
5047            default:
5048                PSendSysMessage(LANG_MOVEGENS_UNKNOWN,(*itr)->GetMovementGeneratorType());
5049                break;
5050        }
5051    }
5052    return true;
5053}
5054
5055bool ChatHandler::HandlePLimitCommand(const char *args)
5056{
5057    if(*args)
5058    {
5059        char* param = strtok((char*)args, " ");
5060        if(!param)
5061            return false;
5062
5063        int l = strlen(param);
5064
5065        if(     strncmp(param,"player",l) == 0 )
5066            sWorld.SetPlayerLimit(-SEC_PLAYER);
5067        else if(strncmp(param,"moderator",l) == 0 )
5068            sWorld.SetPlayerLimit(-SEC_MODERATOR);
5069        else if(strncmp(param,"gamemaster",l) == 0 )
5070            sWorld.SetPlayerLimit(-SEC_GAMEMASTER);
5071        else if(strncmp(param,"administrator",l) == 0 )
5072            sWorld.SetPlayerLimit(-SEC_ADMINISTRATOR);
5073        else if(strncmp(param,"reset",l) == 0 )
5074            sWorld.SetPlayerLimit( sConfig.GetIntDefault("PlayerLimit", DEFAULT_PLAYER_LIMIT) );
5075        else
5076        {
5077            int val = atoi(param);
5078            if(val < -SEC_ADMINISTRATOR) val = -SEC_ADMINISTRATOR;
5079
5080            sWorld.SetPlayerLimit(val);
5081        }
5082
5083        // kick all low security level players
5084        if(sWorld.GetPlayerAmountLimit() > SEC_PLAYER)
5085            sWorld.KickAllLess(sWorld.GetPlayerSecurityLimit());
5086    }
5087
5088    uint32 pLimit = sWorld.GetPlayerAmountLimit();
5089    AccountTypes allowedAccountType = sWorld.GetPlayerSecurityLimit();
5090    char const* secName = "";
5091    switch(allowedAccountType)
5092    {
5093        case SEC_PLAYER:        secName = "Player";        break;
5094        case SEC_MODERATOR:     secName = "Moderator";     break;
5095        case SEC_GAMEMASTER:    secName = "Gamemaster";    break;
5096        case SEC_ADMINISTRATOR: secName = "Administrator"; break;
5097        default:                secName = "<unknown>";     break;
5098    }
5099
5100    PSendSysMessage("Player limits: amount %u, min. security level %s.",pLimit,secName);
5101
5102    return true;
5103}
5104
5105bool ChatHandler::HandleCastCommand(const char* args)
5106{
5107    if(!*args)
5108        return false;
5109
5110    Unit* target = getSelectedUnit();
5111
5112    if(!target)
5113    {
5114        SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5115        SetSentErrorMessage(true);
5116        return false;
5117    }
5118
5119    // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5120    uint32 spell = extractSpellIdFromLink((char*)args);
5121    if(!spell)
5122        return false;
5123
5124    SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
5125    if(!spellInfo)
5126        return false;
5127
5128    if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
5129    {
5130        PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
5131        SetSentErrorMessage(true);
5132        return false;
5133    }
5134
5135    char* trig_str = strtok(NULL, " ");
5136    if(trig_str)
5137    {
5138        int l = strlen(trig_str);
5139        if(strncmp(trig_str,"triggered",l) != 0 )
5140            return false;
5141    }
5142
5143    bool triggered = (trig_str != NULL);
5144
5145    m_session->GetPlayer()->CastSpell(target,spell,triggered);
5146
5147    return true;
5148}
5149
5150bool ChatHandler::HandleCastBackCommand(const char* args)
5151{
5152    Creature* caster = getSelectedCreature();
5153
5154    if(!caster)
5155    {
5156        SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5157        SetSentErrorMessage(true);
5158        return false;
5159    }
5160
5161    // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
5162    // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5163    uint32 spell = extractSpellIdFromLink((char*)args);
5164    if(!spell || !sSpellStore.LookupEntry(spell))
5165        return false;
5166
5167    char* trig_str = strtok(NULL, " ");
5168    if(trig_str)
5169    {
5170        int l = strlen(trig_str);
5171        if(strncmp(trig_str,"triggered",l) != 0 )
5172            return false;
5173    }
5174
5175    bool triggered = (trig_str != NULL);
5176
5177    // update orientation at server
5178    caster->SetOrientation(caster->GetAngle(m_session->GetPlayer()));
5179
5180    // and client
5181    WorldPacket data;
5182    caster->BuildHeartBeatMsg(&data);
5183    caster->SendMessageToSet(&data,true);
5184
5185    caster->CastSpell(m_session->GetPlayer(),spell,false);
5186
5187    return true;
5188}
5189
5190bool ChatHandler::HandleCastDistCommand(const char* args)
5191{
5192    if(!*args)
5193        return false;
5194
5195
5196    // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5197    uint32 spell = extractSpellIdFromLink((char*)args);
5198    if(!spell)
5199        return false;
5200
5201    SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
5202    if(!spellInfo)
5203        return false;
5204
5205    if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
5206    {
5207        PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
5208        SetSentErrorMessage(true);
5209        return false;
5210    }
5211
5212    char *distStr = strtok(NULL, " ");
5213
5214    float dist = 0;
5215
5216    if(distStr)
5217        sscanf(distStr, "%f", &dist);
5218
5219    char* trig_str = strtok(NULL, " ");
5220    if(trig_str)
5221    {
5222        int l = strlen(trig_str);
5223        if(strncmp(trig_str,"triggered",l) != 0 )
5224            return false;
5225    }
5226
5227    bool triggered = (trig_str != NULL);
5228
5229    float x,y,z;
5230    m_session->GetPlayer()->GetClosePoint(x,y,z,dist);
5231
5232    m_session->GetPlayer()->CastSpell(x,y,z,spell,triggered);
5233    return true;
5234}
5235
5236bool ChatHandler::HandleCastTargetCommand(const char* args)
5237{
5238    Creature* caster = getSelectedCreature();
5239
5240    if(!caster)
5241    {
5242        SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5243        SetSentErrorMessage(true);
5244        return false;
5245    }
5246
5247    if(!caster->getVictim())
5248    {
5249        SendSysMessage(LANG_SELECTED_TARGET_NOT_HAVE_VICTIM);
5250        SetSentErrorMessage(true);
5251        return false;
5252    }
5253
5254    // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5255    uint32 spell = extractSpellIdFromLink((char*)args);
5256    if(!spell || !sSpellStore.LookupEntry(spell))
5257        return false;
5258
5259    char* trig_str = strtok(NULL, " ");
5260    if(trig_str)
5261    {
5262        int l = strlen(trig_str);
5263        if(strncmp(trig_str,"triggered",l) != 0 )
5264            return false;
5265    }
5266
5267    bool triggered = (trig_str != NULL);
5268
5269    // update orientation at server
5270    caster->SetOrientation(caster->GetAngle(m_session->GetPlayer()));
5271
5272    // and client
5273    WorldPacket data;
5274    caster->BuildHeartBeatMsg(&data);
5275    caster->SendMessageToSet(&data,true);
5276
5277    caster->CastSpell(caster->getVictim(),spell,false);
5278
5279    return true;
5280}
5281
5282/*
5283ComeToMe command REQUIRED for 3rd party scripting library to have access to PointMovementGenerator
5284Without this function 3rd party scripting library will get linking errors (unresolved external)
5285when attempting to use the PointMovementGenerator
5286*/
5287bool ChatHandler::HandleComeToMeCommand(const char *args)
5288{
5289    Creature* caster = getSelectedCreature();
5290
5291    if(!caster)
5292    {
5293        SendSysMessage(LANG_SELECT_CREATURE);
5294        SetSentErrorMessage(true);
5295        return false;
5296    }
5297
5298    char* newFlagStr = strtok((char*)args, " ");
5299
5300    if(!newFlagStr)
5301        return false;
5302
5303    uint32 newFlags = atoi(newFlagStr);
5304
5305    caster->SetUnitMovementFlags(newFlags);
5306
5307    Player* pl = m_session->GetPlayer();
5308
5309    caster->GetMotionMaster()->MovePoint(0, pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ());
5310    return true;
5311}
5312
5313bool ChatHandler::HandleCastSelfCommand(const char* args)
5314{
5315    if(!*args)
5316        return false;
5317
5318    Unit* target = getSelectedUnit();
5319
5320    if(!target)
5321    {
5322        SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5323        SetSentErrorMessage(true);
5324        return false;
5325    }
5326
5327    // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5328    uint32 spell = extractSpellIdFromLink((char*)args);
5329    if(!spell)
5330        return false;
5331
5332    SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
5333    if(!spellInfo)
5334        return false;
5335
5336    if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
5337    {
5338        PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
5339        SetSentErrorMessage(true);
5340        return false;
5341    }
5342
5343    target->CastSpell(target,spell,false);
5344
5345    return true;
5346}
5347
5348std::string GetTimeString(uint32 time)
5349{
5350    uint16 days = time / DAY, hours = (time % DAY) / HOUR, minute = (time % HOUR) / MINUTE;
5351    std::ostringstream ss;
5352    if(days) ss << days << "d ";
5353    if(hours) ss << hours << "h ";
5354    ss << minute << "m";
5355    return ss.str();
5356}
5357
5358bool ChatHandler::HandleInstanceListBindsCommand(const char* /*args*/)
5359{
5360    Player* player = getSelectedPlayer();
5361    if (!player) player = m_session->GetPlayer();
5362    uint32 counter = 0;
5363    for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++)
5364    {
5365        Player::BoundInstancesMap &binds = player->GetBoundInstances(i);
5366        for(Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end(); ++itr)
5367        {
5368            InstanceSave *save = itr->second.save;
5369            std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
5370            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());
5371            counter++;
5372        }
5373    }
5374    PSendSysMessage("player binds: %d", counter);
5375    counter = 0;
5376    Group *group = player->GetGroup();
5377    if(group)
5378    {
5379        for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++)
5380        {
5381            Group::BoundInstancesMap &binds = group->GetBoundInstances(i);
5382            for(Group::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end(); ++itr)
5383            {
5384                InstanceSave *save = itr->second.save;
5385                std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
5386                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());
5387                counter++;
5388            }
5389        }
5390    }
5391    PSendSysMessage("group binds: %d", counter);
5392
5393    return true;
5394}
5395
5396bool ChatHandler::HandleInstanceUnbindCommand(const char* args)
5397{
5398    if(!*args)
5399        return false;
5400
5401    std::string cmd = args;
5402    if(cmd == "all")
5403    {
5404        Player* player = getSelectedPlayer();
5405        if (!player) player = m_session->GetPlayer();
5406        uint32 counter = 0;
5407        for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++)
5408        {
5409            Player::BoundInstancesMap &binds = player->GetBoundInstances(i);
5410            for(Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end();)
5411            {
5412                if(itr->first != player->GetMapId())
5413                {
5414                    InstanceSave *save = itr->second.save;
5415                    std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
5416                    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());
5417                    player->UnbindInstance(itr, i);
5418                    counter++;
5419                }
5420                else
5421                    ++itr;
5422            }
5423        }
5424        PSendSysMessage("instances unbound: %d", counter);
5425    }
5426    return true;
5427}
5428
5429bool ChatHandler::HandleInstanceStatsCommand(const char* /*args*/)
5430{
5431    PSendSysMessage("instances loaded: %d", MapManager::Instance().GetNumInstances());
5432    PSendSysMessage("players in instances: %d", MapManager::Instance().GetNumPlayersInInstances());
5433    PSendSysMessage("instance saves: %d", sInstanceSaveManager.GetNumInstanceSaves());
5434    PSendSysMessage("players bound: %d", sInstanceSaveManager.GetNumBoundPlayersTotal());
5435    PSendSysMessage("groups bound: %d", sInstanceSaveManager.GetNumBoundGroupsTotal());
5436    return true;
5437}
5438
5439bool ChatHandler::HandleInstanceSaveDataCommand(const char * /*args*/)
5440{
5441    Player* pl = m_session->GetPlayer();
5442
5443    Map* map = pl->GetMap();
5444    if (!map->IsDungeon())
5445    {
5446        PSendSysMessage("Map is not a dungeon.");
5447        SetSentErrorMessage(true);
5448        return false;
5449    }
5450
5451    if (!((InstanceMap*)map)->GetInstanceData())
5452    {
5453        PSendSysMessage("Map has no instance data.");
5454        SetSentErrorMessage(true);
5455        return false;
5456    }
5457
5458    ((InstanceMap*)map)->GetInstanceData()->SaveToDB();
5459    return true;
5460}
5461
5462bool ChatHandler::HandleFlushArenaPointsCommand(const char * /*args*/)
5463{
5464    sBattleGroundMgr.DistributeArenaPoints();
5465    return true;
5466}
Note: See TracBrowser for help on using the browser.