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

Revision 2, 147.7 kB (checked in by yumileroy, 17 years ago)

[svn] * Proper SVN structure

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