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

Revision 260, 191.4 kB (checked in by yumileroy, 17 years ago)

*DB script table stucture change. Source Mangos. Also fix some bugs. Hopefully this rev will make program usable again.

Original author: megamage
Date: 2008-11-20 10:43:20-06:00

Line 
1/*
2* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
3*
4* Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
5*
6* This program is free software; you can redistribute it and/or modify
7* it under the terms of the GNU General Public License as published by
8* the Free Software Foundation; either version 2 of the License, or
9* (at your option) any later version.
10*
11* This program is distributed in the hope that it will be useful,
12* but WITHOUT ANY WARRANTY; without even the implied warranty of
13* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14* GNU General Public License for more details.
15*
16* You should have received a copy of the GNU General Public License
17* along with this program; if not, write to the Free Software
18* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19*/
20
21#include "Common.h"
22#include "Database/DatabaseEnv.h"
23#include "WorldPacket.h"
24#include "WorldSession.h"
25#include "World.h"
26#include "ObjectMgr.h"
27#include "AccountMgr.h"
28#include "PlayerDump.h"
29#include "SpellMgr.h"
30#include "Player.h"
31#include "Opcodes.h"
32#include "GameObject.h"
33#include "Chat.h"
34#include "Log.h"
35#include "Guild.h"
36#include "ObjectAccessor.h"
37#include "MapManager.h"
38#include "SpellAuras.h"
39#include "ScriptCalls.h"
40#include "Language.h"
41#include "GridNotifiersImpl.h"
42#include "CellImpl.h"
43#include "Weather.h"
44#include "PointMovementGenerator.h"
45#include "TargetedMovementGenerator.h"
46#include "SkillDiscovery.h"
47#include "SkillExtraItems.h"
48#include "SystemConfig.h"
49#include "Config/ConfigEnv.h"
50#include "Util.h"
51#include "ItemEnchantmentMgr.h"
52#include "BattleGroundMgr.h"
53#include "InstanceSaveMgr.h"
54#include "InstanceData.h"
55
56//reload commands
57bool ChatHandler::HandleReloadCommand(const char* arg)
58{
59    // this is error catcher for wrong table name in .reload commands
60    PSendSysMessage("Db table with name starting from '%s' not found and can't be reloaded.",arg);
61    SetSentErrorMessage(true);
62    return false;
63}
64
65bool ChatHandler::HandleReloadAllCommand(const char*)
66{
67    HandleReloadAreaTriggerTeleportCommand("");
68    HandleReloadSkillFishingBaseLevelCommand("");
69
70    HandleReloadAllAreaCommand("");
71    HandleReloadAllLootCommand("");
72    HandleReloadAllNpcCommand("");
73    HandleReloadAllQuestCommand("");
74    HandleReloadAllSpellCommand("");
75    HandleReloadAllItemCommand("");
76    HandleReloadAllLocalesCommand("");
77
78    HandleReloadCommandCommand("");
79    HandleReloadReservedNameCommand("");
80    HandleReloadTrinityStringCommand("");
81    HandleReloadGameTeleCommand("");
82    return true;
83}
84
85bool ChatHandler::HandleReloadAllAreaCommand(const char*)
86{
87    //HandleReloadQuestAreaTriggersCommand(""); -- reloaded in HandleReloadAllQuestCommand
88    HandleReloadAreaTriggerTeleportCommand("");
89    HandleReloadAreaTriggerTavernCommand("");
90    HandleReloadGameGraveyardZoneCommand("");
91    return true;
92}
93
94bool ChatHandler::HandleReloadAllLootCommand(const char*)
95{
96    sLog.outString( "Re-Loading Loot Tables..." );
97    LoadLootTables();
98    SendGlobalSysMessage("DB tables `*_loot_template` reloaded.");
99    return true;
100}
101
102bool ChatHandler::HandleReloadAllNpcCommand(const char* /*args*/)
103{
104    HandleReloadNpcGossipCommand("a");
105    HandleReloadNpcOptionCommand("a");
106    HandleReloadNpcTrainerCommand("a");
107    HandleReloadNpcVendorCommand("a");
108    return true;
109}
110
111bool ChatHandler::HandleReloadAllQuestCommand(const char* /*args*/)
112{
113    HandleReloadQuestAreaTriggersCommand("a");
114    HandleReloadQuestTemplateCommand("a");
115
116    sLog.outString( "Re-Loading Quests Relations..." );
117    objmgr.LoadQuestRelations();
118    SendGlobalSysMessage("DB tables `*_questrelation` and `*_involvedrelation` reloaded.");
119    return true;
120}
121
122bool ChatHandler::HandleReloadAllScriptsCommand(const char*)
123{
124    if(sWorld.IsScriptScheduled())
125    {
126        PSendSysMessage("DB scripts used currently, please attempt reload later.");
127        SetSentErrorMessage(true);
128        return false;
129    }
130
131    sLog.outString( "Re-Loading Scripts..." );
132    HandleReloadGameObjectScriptsCommand("a");
133    HandleReloadEventScriptsCommand("a");
134    HandleReloadQuestEndScriptsCommand("a");
135    HandleReloadQuestStartScriptsCommand("a");
136    HandleReloadSpellScriptsCommand("a");
137    SendGlobalSysMessage("DB tables `*_scripts` reloaded.");
138    HandleReloadDbScriptStringCommand("a");
139    return true;
140}
141
142bool ChatHandler::HandleReloadAllSpellCommand(const char*)
143{
144    HandleReloadSkillDiscoveryTemplateCommand("a");
145    HandleReloadSkillExtraItemTemplateCommand("a");
146    HandleReloadSpellAffectCommand("a");
147    HandleReloadSpellChainCommand("a");
148    HandleReloadSpellElixirCommand("a");
149    HandleReloadSpellLearnSpellCommand("a");
150    HandleReloadSpellProcEventCommand("a");
151    HandleReloadSpellScriptTargetCommand("a");
152    HandleReloadSpellTargetPositionCommand("a");
153    HandleReloadSpellThreatsCommand("a");
154    HandleReloadSpellPetAurasCommand("a");
155    HandleReloadSpellDisabledCommand("a");
156    return true;
157}
158
159bool ChatHandler::HandleReloadAllItemCommand(const char*)
160{
161    HandleReloadPageTextsCommand("a");
162    HandleReloadItemEnchantementsCommand("a");
163    return true;
164}
165
166bool ChatHandler::HandleReloadAllLocalesCommand(const char* /*args*/)
167{
168    HandleReloadLocalesCreatureCommand("a");
169    HandleReloadLocalesGameobjectCommand("a");
170    HandleReloadLocalesItemCommand("a");
171    HandleReloadLocalesNpcTextCommand("a");
172    HandleReloadLocalesPageTextCommand("a");
173    HandleReloadLocalesQuestCommand("a");
174    return true;
175}
176
177bool ChatHandler::HandleReloadConfigCommand(const char* /*args*/)
178{
179    sLog.outString( "Re-Loading config settings..." );
180    sWorld.LoadConfigSettings(true);
181    SendGlobalSysMessage("World config settings reloaded.");
182    return true;
183}
184
185bool ChatHandler::HandleReloadAreaTriggerTavernCommand(const char*)
186{
187    sLog.outString( "Re-Loading Tavern Area Triggers..." );
188    objmgr.LoadTavernAreaTriggers();
189    SendGlobalSysMessage("DB table `areatrigger_tavern` reloaded.");
190    return true;
191}
192
193bool ChatHandler::HandleReloadAreaTriggerTeleportCommand(const char*)
194{
195    sLog.outString( "Re-Loading AreaTrigger teleport definitions..." );
196    objmgr.LoadAreaTriggerTeleports();
197    SendGlobalSysMessage("DB table `areatrigger_teleport` reloaded.");
198    return true;
199}
200
201bool ChatHandler::HandleReloadCommandCommand(const char*)
202{
203    load_command_table = true;
204    SendGlobalSysMessage("DB table `command` will be reloaded at next chat command use.");
205    return true;
206}
207
208bool ChatHandler::HandleReloadCreatureQuestRelationsCommand(const char*)
209{
210    sLog.outString( "Loading Quests Relations... (`creature_questrelation`)" );
211    objmgr.LoadCreatureQuestRelations();
212    SendGlobalSysMessage("DB table `creature_questrelation` (creature quest givers) reloaded.");
213    return true;
214}
215
216bool ChatHandler::HandleReloadCreatureQuestInvRelationsCommand(const char*)
217{
218    sLog.outString( "Loading Quests Relations... (`creature_involvedrelation`)" );
219    objmgr.LoadCreatureInvolvedRelations();
220    SendGlobalSysMessage("DB table `creature_involvedrelation` (creature quest takers) reloaded.");
221    return true;
222}
223
224bool ChatHandler::HandleReloadGOQuestRelationsCommand(const char*)
225{
226    sLog.outString( "Loading Quests Relations... (`gameobject_questrelation`)" );
227    objmgr.LoadGameobjectQuestRelations();
228    SendGlobalSysMessage("DB table `gameobject_questrelation` (gameobject quest givers) reloaded.");
229    return true;
230}
231
232bool ChatHandler::HandleReloadGOQuestInvRelationsCommand(const char*)
233{
234    sLog.outString( "Loading Quests Relations... (`gameobject_involvedrelation`)" );
235    objmgr.LoadGameobjectInvolvedRelations();
236    SendGlobalSysMessage("DB table `gameobject_involvedrelation` (gameobject quest takers) reloaded.");
237    return true;
238}
239
240bool ChatHandler::HandleReloadQuestAreaTriggersCommand(const char*)
241{
242    sLog.outString( "Re-Loading Quest Area Triggers..." );
243    objmgr.LoadQuestAreaTriggers();
244    SendGlobalSysMessage("DB table `areatrigger_involvedrelation` (quest area triggers) reloaded.");
245    return true;
246}
247
248bool ChatHandler::HandleReloadQuestTemplateCommand(const char*)
249{
250    sLog.outString( "Re-Loading Quest Templates..." );
251    objmgr.LoadQuests();
252    SendGlobalSysMessage("DB table `quest_template` (quest definitions) reloaded.");
253    return true;
254}
255
256bool ChatHandler::HandleReloadLootTemplatesCreatureCommand(const char*)
257{
258    sLog.outString( "Re-Loading Loot Tables... (`creature_loot_template`)" );
259    LoadLootTemplates_Creature();
260    LootTemplates_Creature.CheckLootRefs();
261    SendGlobalSysMessage("DB table `creature_loot_template` reloaded.");
262    return true;
263}
264
265bool ChatHandler::HandleReloadLootTemplatesDisenchantCommand(const char*)
266{
267    sLog.outString( "Re-Loading Loot Tables... (`disenchant_loot_template`)" );
268    LoadLootTemplates_Disenchant();
269    LootTemplates_Disenchant.CheckLootRefs();
270    SendGlobalSysMessage("DB table `disenchant_loot_template` reloaded.");
271    return true;
272}
273
274bool ChatHandler::HandleReloadLootTemplatesFishingCommand(const char*)
275{
276    sLog.outString( "Re-Loading Loot Tables... (`fishing_loot_template`)" );
277    LoadLootTemplates_Fishing();
278    LootTemplates_Fishing.CheckLootRefs();
279    SendGlobalSysMessage("DB table `fishing_loot_template` reloaded.");
280    return true;
281}
282
283bool ChatHandler::HandleReloadLootTemplatesGameobjectCommand(const char*)
284{
285    sLog.outString( "Re-Loading Loot Tables... (`gameobject_loot_template`)" );
286    LoadLootTemplates_Gameobject();
287    LootTemplates_Gameobject.CheckLootRefs();
288    SendGlobalSysMessage("DB table `gameobject_loot_template` reloaded.");
289    return true;
290}
291
292bool ChatHandler::HandleReloadLootTemplatesItemCommand(const char*)
293{
294    sLog.outString( "Re-Loading Loot Tables... (`item_loot_template`)" );
295    LoadLootTemplates_Item();
296    LootTemplates_Item.CheckLootRefs();
297    SendGlobalSysMessage("DB table `item_loot_template` reloaded.");
298    return true;
299}
300
301bool ChatHandler::HandleReloadLootTemplatesPickpocketingCommand(const char*)
302{
303    sLog.outString( "Re-Loading Loot Tables... (`pickpocketing_loot_template`)" );
304    LoadLootTemplates_Pickpocketing();
305    LootTemplates_Pickpocketing.CheckLootRefs();
306    SendGlobalSysMessage("DB table `pickpocketing_loot_template` reloaded.");
307    return true;
308}
309
310bool ChatHandler::HandleReloadLootTemplatesProspectingCommand(const char*)
311{
312    sLog.outString( "Re-Loading Loot Tables... (`prospecting_loot_template`)" );
313    LoadLootTemplates_Prospecting();
314    LootTemplates_Prospecting.CheckLootRefs();
315    SendGlobalSysMessage("DB table `prospecting_loot_template` reloaded.");
316    return true;
317}
318
319bool ChatHandler::HandleReloadLootTemplatesQuestMailCommand(const char*)
320{
321    sLog.outString( "Re-Loading Loot Tables... (`quest_mail_loot_template`)" );
322    LoadLootTemplates_QuestMail();
323    LootTemplates_QuestMail.CheckLootRefs();
324    SendGlobalSysMessage("DB table `quest_mail_loot_template` reloaded.");
325    return true;
326}
327
328bool ChatHandler::HandleReloadLootTemplatesReferenceCommand(const char*)
329{
330    sLog.outString( "Re-Loading Loot Tables... (`reference_loot_template`)" );
331    LoadLootTemplates_Reference();
332    SendGlobalSysMessage("DB table `reference_loot_template` reloaded.");
333    return true;
334}
335
336bool ChatHandler::HandleReloadLootTemplatesSkinningCommand(const char*)
337{
338    sLog.outString( "Re-Loading Loot Tables... (`skinning_loot_template`)" );
339    LoadLootTemplates_Skinning();
340    LootTemplates_Skinning.CheckLootRefs();
341    SendGlobalSysMessage("DB table `skinning_loot_template` reloaded.");
342    return true;
343}
344
345bool ChatHandler::HandleReloadTrinityStringCommand(const char*)
346{
347    sLog.outString( "Re-Loading trinity_string Table!" );
348    objmgr.LoadTrinityStrings();
349    SendGlobalSysMessage("DB table `trinity_string` reloaded.");
350    return true;
351}
352
353bool ChatHandler::HandleReloadNpcOptionCommand(const char*)
354{
355    sLog.outString( "Re-Loading `npc_option` Table!" );
356    objmgr.LoadNpcOptions();
357    SendGlobalSysMessage("DB table `npc_option` reloaded.");
358    return true;
359}
360
361bool ChatHandler::HandleReloadNpcGossipCommand(const char*)
362{
363    sLog.outString( "Re-Loading `npc_gossip` Table!" );
364    objmgr.LoadNpcTextId();
365    SendGlobalSysMessage("DB table `npc_gossip` reloaded.");
366    return true;
367}
368
369bool ChatHandler::HandleReloadNpcTrainerCommand(const char*)
370{
371    sLog.outString( "Re-Loading `npc_trainer` Table!" );
372    objmgr.LoadTrainerSpell();
373    SendGlobalSysMessage("DB table `npc_trainer` reloaded.");
374    return true;
375}
376
377bool ChatHandler::HandleReloadNpcVendorCommand(const char*)
378{
379    sLog.outString( "Re-Loading `npc_vendor` Table!" );
380    objmgr.LoadVendors();
381    SendGlobalSysMessage("DB table `npc_vendor` reloaded.");
382    return true;
383}
384
385bool ChatHandler::HandleReloadReservedNameCommand(const char*)
386{
387    sLog.outString( "Loading ReservedNames... (`reserved_name`)" );
388    objmgr.LoadReservedPlayersNames();
389    SendGlobalSysMessage("DB table `reserved_name` (player reserved names) reloaded.");
390    return true;
391}
392
393bool ChatHandler::HandleReloadSkillDiscoveryTemplateCommand(const char* /*args*/)
394{
395    sLog.outString( "Re-Loading Skill Discovery Table..." );
396    LoadSkillDiscoveryTable();
397    SendGlobalSysMessage("DB table `skill_discovery_template` (recipes discovered at crafting) reloaded.");
398    return true;
399}
400
401bool ChatHandler::HandleReloadSkillExtraItemTemplateCommand(const char* /*args*/)
402{
403    sLog.outString( "Re-Loading Skill Extra Item Table..." );
404    LoadSkillExtraItemTable();
405    SendGlobalSysMessage("DB table `skill_extra_item_template` (extra item creation when crafting) reloaded.");
406    return true;
407}
408
409bool ChatHandler::HandleReloadSkillFishingBaseLevelCommand(const char* /*args*/)
410{
411    sLog.outString( "Re-Loading Skill Fishing base level requirements..." );
412    objmgr.LoadFishingBaseSkillLevel();
413    SendGlobalSysMessage("DB table `skill_fishing_base_level` (fishing base level for zone/subzone) reloaded.");
414    return true;
415}
416
417bool ChatHandler::HandleReloadSpellAffectCommand(const char*)
418{
419    sLog.outString( "Re-Loading SpellAffect definitions..." );
420    spellmgr.LoadSpellAffects();
421    SendGlobalSysMessage("DB table `spell_affect` (spell mods apply requirements) reloaded.");
422    return true;
423}
424
425bool ChatHandler::HandleReloadSpellChainCommand(const char*)
426{
427    sLog.outString( "Re-Loading Spell Chain Data... " );
428    spellmgr.LoadSpellChains();
429    SendGlobalSysMessage("DB table `spell_chain` (spell ranks) reloaded.");
430    return true;
431}
432
433bool ChatHandler::HandleReloadSpellElixirCommand(const char*)
434{
435    sLog.outString( "Re-Loading Spell Elixir types..." );
436    spellmgr.LoadSpellElixirs();
437    SendGlobalSysMessage("DB table `spell_elixir` (spell elixir types) reloaded.");
438    return true;
439}
440
441bool ChatHandler::HandleReloadSpellLearnSpellCommand(const char*)
442{
443    sLog.outString( "Re-Loading Spell Learn Spells..." );
444    spellmgr.LoadSpellLearnSpells();
445    SendGlobalSysMessage("DB table `spell_learn_spell` reloaded.");
446    return true;
447}
448
449bool ChatHandler::HandleReloadSpellProcEventCommand(const char*)
450{
451    sLog.outString( "Re-Loading Spell Proc Event conditions..." );
452    spellmgr.LoadSpellProcEvents();
453    SendGlobalSysMessage("DB table `spell_proc_event` (spell proc trigger requirements) reloaded.");
454    return true;
455}
456
457bool ChatHandler::HandleReloadSpellScriptTargetCommand(const char*)
458{
459    sLog.outString( "Re-Loading SpellsScriptTarget..." );
460    spellmgr.LoadSpellScriptTarget();
461    SendGlobalSysMessage("DB table `spell_script_target` (spell targets selection in case specific creature/GO requirements) reloaded.");
462    return true;
463}
464
465bool ChatHandler::HandleReloadSpellTargetPositionCommand(const char*)
466{
467    sLog.outString( "Re-Loading Spell target coordinates..." );
468    spellmgr.LoadSpellTargetPositions();
469    SendGlobalSysMessage("DB table `spell_target_position` (destination coordinates for spell targets) reloaded.");
470    return true;
471}
472
473bool ChatHandler::HandleReloadSpellThreatsCommand(const char*)
474{
475    sLog.outString( "Re-Loading Aggro Spells Definitions...");
476    spellmgr.LoadSpellThreats();
477    SendGlobalSysMessage("DB table `spell_threat` (spell aggro definitions) reloaded.");
478    return true;
479}
480
481bool ChatHandler::HandleReloadSpellPetAurasCommand(const char*)
482{
483    sLog.outString( "Re-Loading Spell pet auras...");
484    spellmgr.LoadSpellPetAuras();
485    SendGlobalSysMessage("DB table `spell_pet_auras` reloaded.");
486    return true;
487}
488
489bool ChatHandler::HandleReloadPageTextsCommand(const char*)
490{
491    sLog.outString( "Re-Loading Page Texts..." );
492    objmgr.LoadPageTexts();
493    SendGlobalSysMessage("DB table `page_texts` reloaded.");
494    return true;
495}
496
497bool ChatHandler::HandleReloadItemEnchantementsCommand(const char*)
498{
499    sLog.outString( "Re-Loading Item Random Enchantments Table..." );
500    LoadRandomEnchantmentsTable();
501    SendGlobalSysMessage("DB table `item_enchantment_template` reloaded.");
502    return true;
503}
504
505bool ChatHandler::HandleReloadGameObjectScriptsCommand(const char* arg)
506{
507    if(sWorld.IsScriptScheduled())
508    {
509        SendSysMessage("DB scripts used currently, please attempt reload later.");
510        SetSentErrorMessage(true);
511        return false;
512    }
513
514    if(*arg!='a')
515        sLog.outString( "Re-Loading Scripts from `gameobject_scripts`...");
516
517    objmgr.LoadGameObjectScripts();
518
519    if(*arg!='a')
520        SendGlobalSysMessage("DB table `gameobject_scripts` reloaded.");
521
522    return true;
523}
524
525bool ChatHandler::HandleReloadEventScriptsCommand(const char* arg)
526{
527    if(sWorld.IsScriptScheduled())
528    {
529        SendSysMessage("DB scripts used currently, please attempt reload later.");
530        SetSentErrorMessage(true);
531        return false;
532    }
533
534    if(*arg!='a')
535        sLog.outString( "Re-Loading Scripts from `event_scripts`...");
536
537    objmgr.LoadEventScripts();
538
539    if(*arg!='a')
540        SendGlobalSysMessage("DB table `event_scripts` reloaded.");
541
542    return true;
543}
544
545bool ChatHandler::HandleReloadQuestEndScriptsCommand(const char* arg)
546{
547    if(sWorld.IsScriptScheduled())
548    {
549        SendSysMessage("DB scripts used currently, please attempt reload later.");
550        SetSentErrorMessage(true);
551        return false;
552    }
553
554    if(*arg!='a')
555        sLog.outString( "Re-Loading Scripts from `quest_end_scripts`...");
556
557    objmgr.LoadQuestEndScripts();
558
559    if(*arg!='a')
560        SendGlobalSysMessage("DB table `quest_end_scripts` reloaded.");
561
562    return true;
563}
564
565bool ChatHandler::HandleReloadQuestStartScriptsCommand(const char* arg)
566{
567    if(sWorld.IsScriptScheduled())
568    {
569        SendSysMessage("DB scripts used currently, please attempt reload later.");
570        SetSentErrorMessage(true);
571        return false;
572    }
573
574    if(*arg!='a')
575        sLog.outString( "Re-Loading Scripts from `quest_start_scripts`...");
576
577    objmgr.LoadQuestStartScripts();
578
579    if(*arg!='a')
580        SendGlobalSysMessage("DB table `quest_start_scripts` reloaded.");
581
582    return true;
583}
584
585bool ChatHandler::HandleReloadSpellScriptsCommand(const char* arg)
586{
587    if(sWorld.IsScriptScheduled())
588    {
589        SendSysMessage("DB scripts used currently, please attempt reload later.");
590        SetSentErrorMessage(true);
591        return false;
592    }
593
594    if(*arg!='a')
595        sLog.outString( "Re-Loading Scripts from `spell_scripts`...");
596
597    objmgr.LoadSpellScripts();
598
599    if(*arg!='a')
600        SendGlobalSysMessage("DB table `spell_scripts` reloaded.");
601
602    return true;
603}
604
605bool ChatHandler::HandleReloadDbScriptStringCommand(const char* arg)
606{
607    sLog.outString( "Re-Loading Script strings from `db_script_string`...");
608    objmgr.LoadDbScriptStrings();
609    SendGlobalSysMessage("DB table `db_script_string` reloaded.");
610    return true;
611}
612
613bool ChatHandler::HandleReloadGameGraveyardZoneCommand(const char* /*arg*/)
614{
615    sLog.outString( "Re-Loading Graveyard-zone links...");
616
617    objmgr.LoadGraveyardZones();
618
619    SendGlobalSysMessage("DB table `game_graveyard_zone` reloaded.");
620
621    return true;
622}
623
624bool ChatHandler::HandleReloadGameTeleCommand(const char* /*arg*/)
625{
626    sLog.outString( "Re-Loading Game Tele coordinates...");
627
628    objmgr.LoadGameTele();
629
630    SendGlobalSysMessage("DB table `game_tele` reloaded.");
631
632    return true;
633}
634
635bool ChatHandler::HandleReloadSpellDisabledCommand(const char* /*arg*/)
636{
637    sLog.outString( "Re-Loading spell disabled table...");
638
639    objmgr.LoadSpellDisabledEntrys();
640
641    SendGlobalSysMessage("DB table `spell_disabled` reloaded.");
642
643    return true;
644}
645
646bool ChatHandler::HandleReloadLocalesCreatureCommand(const char* /*arg*/)
647{
648    sLog.outString( "Re-Loading Locales Creature ...");
649    objmgr.LoadCreatureLocales();
650    SendGlobalSysMessage("DB table `locales_creature` reloaded.");
651    return true;
652}
653
654bool ChatHandler::HandleReloadLocalesGameobjectCommand(const char* /*arg*/)
655{
656    sLog.outString( "Re-Loading Locales Gameobject ... ");
657    objmgr.LoadGameObjectLocales();
658    SendGlobalSysMessage("DB table `locales_gameobject` reloaded.");
659    return true;
660}
661
662bool ChatHandler::HandleReloadLocalesItemCommand(const char* /*arg*/)
663{
664    sLog.outString( "Re-Loading Locales Item ... ");
665    objmgr.LoadItemLocales();
666    SendGlobalSysMessage("DB table `locales_item` reloaded.");
667    return true;
668}
669
670bool ChatHandler::HandleReloadLocalesNpcTextCommand(const char* /*arg*/)
671{
672    sLog.outString( "Re-Loading Locales NPC Text ... ");
673    objmgr.LoadNpcTextLocales();
674    SendGlobalSysMessage("DB table `locales_npc_text` reloaded.");
675    return true;
676}
677
678bool ChatHandler::HandleReloadLocalesPageTextCommand(const char* /*arg*/)
679{
680    sLog.outString( "Re-Loading Locales Page Text ... ");
681    objmgr.LoadPageTextLocales();
682    SendGlobalSysMessage("DB table `locales_page_text` reloaded.");
683    return true;
684}
685
686bool ChatHandler::HandleReloadLocalesQuestCommand(const char* /*arg*/)
687{
688    sLog.outString( "Re-Loading Locales Quest ... ");
689    objmgr.LoadQuestLocales();
690    SendGlobalSysMessage("DB table `locales_quest` reloaded.");
691    return true;
692}
693
694bool ChatHandler::HandleLoadScriptsCommand(const char* args)
695{
696    if(!LoadScriptingModule(args)) return true;
697
698    sWorld.SendWorldText(LANG_SCRIPTS_RELOADED);
699    return true;
700}
701
702bool ChatHandler::HandleAccountSetGmLevelCommand(const char* args)
703{
704    char* arg1 = strtok((char*)args, " ");
705    if( !arg1 )
706        return false;
707
708    /// must be NULL if targeted syntax and must be not nULL if not targeted
709    char* arg2 = strtok(NULL, " ");
710
711    std::string targetAccountName;
712    uint32 targetAccountId = 0;
713    uint32 targetSecurity = 0;
714
715    /// only target player different from self allowed (if targetPlayer!=NULL then not console)
716    Player* targetPlayer = getSelectedPlayer();
717    if(targetPlayer && m_session->GetPlayer()!=targetPlayer)
718    {
719        /// wrong command syntax or unexpected targeting
720        if(arg2)
721            return false;
722
723        /// security level expected in arg2 after this if.
724        arg2 = arg1;
725
726        targetAccountId = targetPlayer->GetSession()->GetAccountId();
727        targetSecurity = targetPlayer->GetSession()->GetSecurity();
728        if(!accmgr.GetName(targetAccountId,targetAccountName))
729        {
730            PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,targetAccountName.c_str());
731            SetSentErrorMessage(true);
732            return false;
733        }
734    }
735    else
736    {
737        /// wrong command syntax (second arg expected)
738        if(!arg2)
739            return false;
740
741        targetAccountName = arg1;
742        if(!AccountMgr::normilizeString(targetAccountName))
743        {
744            PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,targetAccountName.c_str());
745            SetSentErrorMessage(true);
746            return false;
747        }
748
749        targetAccountId = accmgr.GetId(targetAccountName);
750        targetSecurity = accmgr.GetSecurity(targetAccountId);
751    }
752
753    int32 gm = (int32)atoi(arg2);
754    if ( gm < SEC_PLAYER || gm > SEC_ADMINISTRATOR )
755    {
756        SendSysMessage(LANG_BAD_VALUE);
757        SetSentErrorMessage(true);
758        return false;
759    }
760
761    /// m_session==NULL only for console
762    uint32 plSecurity = m_session ? m_session->GetSecurity() : SEC_CONSOLE;
763
764    /// can set security level only for target with less security and to less security that we have
765    /// This is also reject self apply in fact
766    if(targetSecurity >= plSecurity || uint32(gm) >= plSecurity )
767    {
768        SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
769        SetSentErrorMessage(true);
770        return false;
771    }
772
773    if(targetPlayer)
774    {
775        ChatHandler(targetPlayer).PSendSysMessage(LANG_YOURS_SECURITY_CHANGED,GetName(), gm);
776        targetPlayer->GetSession()->SetSecurity(gm);
777    }
778
779    PSendSysMessage(LANG_YOU_CHANGE_SECURITY, targetAccountName.c_str(), gm);
780    loginDatabase.PExecute("UPDATE account SET gmlevel = '%i' WHERE id = '%u'", gm, targetAccountId);
781
782    return true;
783}
784
785/// Set password for account
786bool ChatHandler::HandleAccountSetPasswordCommand(const char* args)
787{
788    if(!*args)
789        return false;
790
791    ///- Get the command line arguments
792    char *szAccount = strtok ((char*)args," ");
793    char *szPassword1 =  strtok (NULL," ");
794    char *szPassword2 =  strtok (NULL," ");
795
796    if (!szAccount||!szPassword1 || !szPassword2)
797        return false;
798
799    std::string account_name = szAccount;
800    if(!AccountMgr::normilizeString(account_name))
801    {
802        PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
803        SetSentErrorMessage(true);
804        return false;
805    }
806
807    uint32 targetAccountId = accmgr.GetId(account_name);
808    if (!targetAccountId)
809    {
810        PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
811        SetSentErrorMessage(true);
812        return false;
813    }
814
815    uint32 targetSecurity = accmgr.GetSecurity(targetAccountId);
816
817    /// m_session==NULL only for console
818    uint32 plSecurity = m_session ? m_session->GetSecurity() : SEC_CONSOLE;
819
820    /// can set password only for target with less security
821    /// This is also reject self apply in fact
822    if (targetSecurity >= plSecurity)
823    {
824        SendSysMessage (LANG_YOURS_SECURITY_IS_LOW);
825        SetSentErrorMessage (true);
826        return false;
827    }
828
829    if (strcmp(szPassword1,szPassword2))
830    {
831        SendSysMessage (LANG_NEW_PASSWORDS_NOT_MATCH);
832        SetSentErrorMessage (true);
833        return false;
834    }
835
836    AccountOpResult result = accmgr.ChangePassword(targetAccountId, szPassword1);
837
838    switch(result)
839    {
840        case AOR_OK:
841            SendSysMessage(LANG_COMMAND_PASSWORD);
842            break;
843        case AOR_NAME_NOT_EXIST:
844            PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
845            SetSentErrorMessage(true);
846            return false;
847        case AOR_PASS_TOO_LONG:
848            SendSysMessage(LANG_PASSWORD_TOO_LONG);
849            SetSentErrorMessage(true);
850            return false;
851        default:
852            SendSysMessage(LANG_COMMAND_NOTCHANGEPASSWORD);
853            SetSentErrorMessage(true);
854            return false;
855    }
856
857    return true;
858}
859
860bool ChatHandler::HandleAllowMovementCommand(const char* /*args*/)
861{
862    if(sWorld.getAllowMovement())
863    {
864        sWorld.SetAllowMovement(false);
865        SendSysMessage(LANG_CREATURE_MOVE_DISABLED);
866    }
867    else
868    {
869        sWorld.SetAllowMovement(true);
870        SendSysMessage(LANG_CREATURE_MOVE_ENABLED);
871    }
872    return true;
873}
874
875bool ChatHandler::HandleMaxSkillCommand(const char* /*args*/)
876{
877    Player* SelectedPlayer = getSelectedPlayer();
878    if(!SelectedPlayer)
879    {
880        SendSysMessage(LANG_NO_CHAR_SELECTED);
881        SetSentErrorMessage(true);
882        return false;
883    }
884
885    // each skills that have max skill value dependent from level seted to current level max skill value
886    SelectedPlayer->UpdateSkillsToMaxSkillsForLevel();
887    return true;
888}
889
890bool ChatHandler::HandleSetSkillCommand(const char* args)
891{
892    // number or [name] Shift-click form |color|Hskill:skill_id|h[name]|h|r
893    char* skill_p = extractKeyFromLink((char*)args,"Hskill");
894    if(!skill_p)
895        return false;
896
897    char *level_p = strtok (NULL, " ");
898
899    if( !level_p)
900        return false;
901
902    char *max_p   = strtok (NULL, " ");
903
904    int32 skill = atoi(skill_p);
905
906    if (skill <= 0)
907    {
908        PSendSysMessage(LANG_INVALID_SKILL_ID, skill);
909        SetSentErrorMessage(true);
910        return false;
911    }
912
913    int32 level = atol (level_p);
914
915    Player * target = getSelectedPlayer();
916    if(!target)
917    {
918        SendSysMessage(LANG_NO_CHAR_SELECTED);
919        SetSentErrorMessage(true);
920        return false;
921    }
922
923    SkillLineEntry const* sl = sSkillLineStore.LookupEntry(skill);
924    if(!sl)
925    {
926        PSendSysMessage(LANG_INVALID_SKILL_ID, skill);
927        SetSentErrorMessage(true);
928        return false;
929    }
930
931    if(!target->GetSkillValue(skill))
932    {
933        PSendSysMessage(LANG_SET_SKILL_ERROR, target->GetName(), skill, sl->name[0]);
934        SetSentErrorMessage(true);
935        return false;
936    }
937
938    int32 max   = max_p ? atol (max_p) : target->GetPureMaxSkillValue(skill);
939
940    if( level <= 0 || level > max || max <= 0 )
941        return false;
942
943    target->SetSkill(skill, level, max);
944    PSendSysMessage(LANG_SET_SKILL, skill, sl->name[0], target->GetName(), level, max);
945
946    return true;
947}
948
949bool ChatHandler::HandleUnLearnCommand(const char* args)
950{
951    if (!*args)
952        return false;
953
954    // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
955    uint32 min_id = extractSpellIdFromLink((char*)args);
956    if(!min_id)
957        return false;
958
959    // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
960    char* tail = strtok(NULL,"");
961
962    uint32 max_id = extractSpellIdFromLink(tail);
963
964    if (!max_id)
965    {
966        // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
967        max_id =  min_id+1;
968    }
969    else
970    {
971        if (max_id < min_id)
972            std::swap(min_id,max_id);
973
974        max_id=max_id+1;
975    }
976
977    Player* target = getSelectedPlayer();
978    if(!target)
979    {
980        SendSysMessage(LANG_NO_CHAR_SELECTED);
981        SetSentErrorMessage(true);
982        return false;
983    }
984
985    for(uint32 spell=min_id;spell<max_id;spell++)
986    {
987        if (target->HasSpell(spell))
988            target->removeSpell(spell);
989        else
990            SendSysMessage(LANG_FORGET_SPELL);
991    }
992
993    return true;
994}
995
996bool ChatHandler::HandleCooldownCommand(const char* args)
997{
998    Player* target = getSelectedPlayer();
999    if(!target)
1000    {
1001        SendSysMessage(LANG_PLAYER_NOT_FOUND);
1002        SetSentErrorMessage(true);
1003        return false;
1004    }
1005
1006    if (!*args)
1007    {
1008        target->RemoveAllSpellCooldown();
1009        PSendSysMessage(LANG_REMOVEALL_COOLDOWN, target->GetName());
1010    }
1011    else
1012    {
1013        // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
1014        uint32 spell_id = extractSpellIdFromLink((char*)args);
1015        if(!spell_id)
1016            return false;
1017
1018        if(!sSpellStore.LookupEntry(spell_id))
1019        {
1020            PSendSysMessage(LANG_UNKNOWN_SPELL, target==m_session->GetPlayer() ? GetTrinityString(LANG_YOU) : target->GetName());
1021            SetSentErrorMessage(true);
1022            return false;
1023        }
1024
1025        WorldPacket data( SMSG_CLEAR_COOLDOWN, (4+8) );
1026        data << uint32(spell_id);
1027        data << uint64(target->GetGUID());
1028        target->GetSession()->SendPacket(&data);
1029        target->RemoveSpellCooldown(spell_id);
1030        PSendSysMessage(LANG_REMOVE_COOLDOWN, spell_id, target==m_session->GetPlayer() ? GetTrinityString(LANG_YOU) : target->GetName());
1031    }
1032    return true;
1033}
1034
1035bool ChatHandler::HandleLearnAllCommand(const char* /*args*/)
1036{
1037    static const char *allSpellList[] =
1038    {
1039        "3365",
1040        "6233",
1041        "6247",
1042        "6246",
1043        "6477",
1044        "6478",
1045        "22810",
1046        "8386",
1047        "21651",
1048        "21652",
1049        "522",
1050        "7266",
1051        "8597",
1052        "2479",
1053        "22027",
1054        "6603",
1055        "5019",
1056        "133",
1057        "168",
1058        "227",
1059        "5009",
1060        "9078",
1061        "668",
1062        "203",
1063        "20599",
1064        "20600",
1065        "81",
1066        "20597",
1067        "20598",
1068        "20864",
1069        "1459",
1070        "5504",
1071        "587",
1072        "5143",
1073        "118",
1074        "5505",
1075        "597",
1076        "604",
1077        "1449",
1078        "1460",
1079        "2855",
1080        "1008",
1081        "475",
1082        "5506",
1083        "1463",
1084        "12824",
1085        "8437",
1086        "990",
1087        "5145",
1088        "8450",
1089        "1461",
1090        "759",
1091        "8494",
1092        "8455",
1093        "8438",
1094        "6127",
1095        "8416",
1096        "6129",
1097        "8451",
1098        "8495",
1099        "8439",
1100        "3552",
1101        "8417",
1102        "10138",
1103        "12825",
1104        "10169",
1105        "10156",
1106        "10144",
1107        "10191",
1108        "10201",
1109        "10211",
1110        "10053",
1111        "10173",
1112        "10139",
1113        "10145",
1114        "10192",
1115        "10170",
1116        "10202",
1117        "10054",
1118        "10174",
1119        "10193",
1120        "12826",
1121        "2136",
1122        "143",
1123        "145",
1124        "2137",
1125        "2120",
1126        "3140",
1127        "543",
1128        "2138",
1129        "2948",
1130        "8400",
1131        "2121",
1132        "8444",
1133        "8412",
1134        "8457",
1135        "8401",
1136        "8422",
1137        "8445",
1138        "8402",
1139        "8413",
1140        "8458",
1141        "8423",
1142        "8446",
1143        "10148",
1144        "10197",
1145        "10205",
1146        "10149",
1147        "10215",
1148        "10223",
1149        "10206",
1150        "10199",
1151        "10150",
1152        "10216",
1153        "10207",
1154        "10225",
1155        "10151",
1156        "116",
1157        "205",
1158        "7300",
1159        "122",
1160        "837",
1161        "10",
1162        "7301",
1163        "7322",
1164        "6143",
1165        "120",
1166        "865",
1167        "8406",
1168        "6141",
1169        "7302",
1170        "8461",
1171        "8407",
1172        "8492",
1173        "8427",
1174        "8408",
1175        "6131",
1176        "7320",
1177        "10159",
1178        "8462",
1179        "10185",
1180        "10179",
1181        "10160",
1182        "10180",
1183        "10219",
1184        "10186",
1185        "10177",
1186        "10230",
1187        "10181",
1188        "10161",
1189        "10187",
1190        "10220",
1191        "2018",
1192        "2663",
1193        "12260",
1194        "2660",
1195        "3115",
1196        "3326",
1197        "2665",
1198        "3116",
1199        "2738",
1200        "3293",
1201        "2661",
1202        "3319",
1203        "2662",
1204        "9983",
1205        "8880",
1206        "2737",
1207        "2739",
1208        "7408",
1209        "3320",
1210        "2666",
1211        "3323",
1212        "3324",
1213        "3294",
1214        "22723",
1215        "23219",
1216        "23220",
1217        "23221",
1218        "23228",
1219        "23338",
1220        "10788",
1221        "10790",
1222        "5611",
1223        "5016",
1224        "5609",
1225        "2060",
1226        "10963",
1227        "10964",
1228        "10965",
1229        "22593",
1230        "22594",
1231        "596",
1232        "996",
1233        "499",
1234        "768",
1235        "17002",
1236        "1448",
1237        "1082",
1238        "16979",
1239        "1079",
1240        "5215",
1241        "20484",
1242        "5221",
1243        "15590",
1244        "17007",
1245        "6795",
1246        "6807",
1247        "5487",
1248        "1446",
1249        "1066",
1250        "5421",
1251        "3139",
1252        "779",
1253        "6811",
1254        "6808",
1255        "1445",
1256        "5216",
1257        "1737",
1258        "5222",
1259        "5217",
1260        "1432",
1261        "6812",
1262        "9492",
1263        "5210",
1264        "3030",
1265        "1441",
1266        "783",
1267        "6801",
1268        "20739",
1269        "8944",
1270        "9491",
1271        "22569",
1272        "5226",
1273        "6786",
1274        "1433",
1275        "8973",
1276        "1828",
1277        "9495",
1278        "9006",
1279        "6794",
1280        "8993",
1281        "5203",
1282        "16914",
1283        "6784",
1284        "9635",
1285        "22830",
1286        "20722",
1287        "9748",
1288        "6790",
1289        "9753",
1290        "9493",
1291        "9752",
1292        "9831",
1293        "9825",
1294        "9822",
1295        "5204",
1296        "5401",
1297        "22831",
1298        "6793",
1299        "9845",
1300        "17401",
1301        "9882",
1302        "9868",
1303        "20749",
1304        "9893",
1305        "9899",
1306        "9895",
1307        "9832",
1308        "9902",
1309        "9909",
1310        "22832",
1311        "9828",
1312        "9851",
1313        "9883",
1314        "9869",
1315        "17406",
1316        "17402",
1317        "9914",
1318        "20750",
1319        "9897",
1320        "9848",
1321        "3127",
1322        "107",
1323        "204",
1324        "9116",
1325        "2457",
1326        "78",
1327        "18848",
1328        "331",
1329        "403",
1330        "2098",
1331        "1752",
1332        "11278",
1333        "11288",
1334        "11284",
1335        "6461",
1336        "2344",
1337        "2345",
1338        "6463",
1339        "2346",
1340        "2352",
1341        "775",
1342        "1434",
1343        "1612",
1344        "71",
1345        "2468",
1346        "2458",
1347        "2467",
1348        "7164",
1349        "7178",
1350        "7367",
1351        "7376",
1352        "7381",
1353        "21156",
1354        "5209",
1355        "3029",
1356        "5201",
1357        "9849",
1358        "9850",
1359        "20719",
1360        "22568",
1361        "22827",
1362        "22828",
1363        "22829",
1364        "6809",
1365        "8972",
1366        "9005",
1367        "9823",
1368        "9827",
1369        "6783",
1370        "9913",
1371        "6785",
1372        "6787",
1373        "9866",
1374        "9867",
1375        "9894",
1376        "9896",
1377        "6800",
1378        "8992",
1379        "9829",
1380        "9830",
1381        "780",
1382        "769",
1383        "6749",
1384        "6750",
1385        "9755",
1386        "9754",
1387        "9908",
1388        "20745",
1389        "20742",
1390        "20747",
1391        "20748",
1392        "9746",
1393        "9745",
1394        "9880",
1395        "9881",
1396        "5391",
1397        "842",
1398        "3025",
1399        "3031",
1400        "3287",
1401        "3329",
1402        "1945",
1403        "3559",
1404        "4933",
1405        "4934",
1406        "4935",
1407        "4936",
1408        "5142",
1409        "5390",
1410        "5392",
1411        "5404",
1412        "5420",
1413        "6405",
1414        "7293",
1415        "7965",
1416        "8041",
1417        "8153",
1418        "9033",
1419        "9034",
1420        //"9036", problems with ghost state
1421        "16421",
1422        "21653",
1423        "22660",
1424        "5225",
1425        "9846",
1426        "2426",
1427        "5916",
1428        "6634",
1429        //"6718", phasing stealth, annoying for learn all case.
1430        "6719",
1431        "8822",
1432        "9591",
1433        "9590",
1434        "10032",
1435        "17746",
1436        "17747",
1437        "8203",
1438        "11392",
1439        "12495",
1440        "16380",
1441        "23452",
1442        "4079",
1443        "4996",
1444        "4997",
1445        "4998",
1446        "4999",
1447        "5000",
1448        "6348",
1449        "6349",
1450        "6481",
1451        "6482",
1452        "6483",
1453        "6484",
1454        "11362",
1455        "11410",
1456        "11409",
1457        "12510",
1458        "12509",
1459        "12885",
1460        "13142",
1461        "21463",
1462        "23460",
1463        "11421",
1464        "11416",
1465        "11418",
1466        "1851",
1467        "10059",
1468        "11423",
1469        "11417",
1470        "11422",
1471        "11419",
1472        "11424",
1473        "11420",
1474        "27",
1475        "31",
1476        "33",
1477        "34",
1478        "35",
1479        "15125",
1480        "21127",
1481        "22950",
1482        "1180",
1483        "201",
1484        "12593",
1485        "12842",
1486        "16770",
1487        "6057",
1488        "12051",
1489        "18468",
1490        "12606",
1491        "12605",
1492        "18466",
1493        "12502",
1494        "12043",
1495        "15060",
1496        "12042",
1497        "12341",
1498        "12848",
1499        "12344",
1500        "12353",
1501        "18460",
1502        "11366",
1503        "12350",
1504        "12352",
1505        "13043",
1506        "11368",
1507        "11113",
1508        "12400",
1509        "11129",
1510        "16766",
1511        "12573",
1512        "15053",
1513        "12580",
1514        "12475",
1515        "12472",
1516        "12953",
1517        "12488",
1518        "11189",
1519        "12985",
1520        "12519",
1521        "16758",
1522        "11958",
1523        "12490",
1524        "11426",
1525        "3565",
1526        "3562",
1527        "18960",
1528        "3567",
1529        "3561",
1530        "3566",
1531        "3563",
1532        "1953",
1533        "2139",
1534        "12505",
1535        "13018",
1536        "12522",
1537        "12523",
1538        "5146",
1539        "5144",
1540        "5148",
1541        "8419",
1542        "8418",
1543        "10213",
1544        "10212",
1545        "10157",
1546        "12524",
1547        "13019",
1548        "12525",
1549        "13020",
1550        "12526",
1551        "13021",
1552        "18809",
1553        "13031",
1554        "13032",
1555        "13033",
1556        "4036",
1557        "3920",
1558        "3919",
1559        "3918",
1560        "7430",
1561        "3922",
1562        "3923",
1563        "7411",
1564        "7418",
1565        "7421",
1566        "13262",
1567        "7412",
1568        "7415",
1569        "7413",
1570        "7416",
1571        "13920",
1572        "13921",
1573        "7745",
1574        "7779",
1575        "7428",
1576        "7457",
1577        "7857",
1578        "7748",
1579        "7426",
1580        "13421",
1581        "7454",
1582        "13378",
1583        "7788",
1584        "14807",
1585        "14293",
1586        "7795",
1587        "6296",
1588        "20608",
1589        "755",
1590        "444",
1591        "427",
1592        "428",
1593        "442",
1594        "447",
1595        "3578",
1596        "3581",
1597        "19027",
1598        "3580",
1599        "665",
1600        "3579",
1601        "3577",
1602        "6755",
1603        "3576",
1604        "2575",
1605        "2577",
1606        "2578",
1607        "2579",
1608        "2580",
1609        "2656",
1610        "2657",
1611        "2576",
1612        "3564",
1613        "10248",
1614        "8388",
1615        "2659",
1616        "14891",
1617        "3308",
1618        "3307",
1619        "10097",
1620        "2658",
1621        "3569",
1622        "16153",
1623        "3304",
1624        "10098",
1625        "4037",
1626        "3929",
1627        "3931",
1628        "3926",
1629        "3924",
1630        "3930",
1631        "3977",
1632        "3925",
1633        "136",
1634        "228",
1635        "5487",
1636        "43",
1637        "202",
1638        "0"
1639    };
1640
1641    int loop = 0;
1642    while(strcmp(allSpellList[loop], "0"))
1643    {
1644        uint32 spell = atol((char*)allSpellList[loop++]);
1645
1646        if (m_session->GetPlayer()->HasSpell(spell))
1647            continue;
1648
1649        SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
1650        if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
1651        {
1652            PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
1653            continue;
1654        }
1655
1656        m_session->GetPlayer()->learnSpell(spell);
1657    }
1658
1659    SendSysMessage(LANG_COMMAND_LEARN_MANY_SPELLS);
1660
1661    return true;
1662}
1663
1664bool ChatHandler::HandleLearnAllGMCommand(const char* /*args*/)
1665{
1666    static const char *gmSpellList[] =
1667    {
1668        "24347",                                            // Become A Fish, No Breath Bar
1669        "35132",                                            // Visual Boom
1670        "38488",                                            // Attack 4000-8000 AOE
1671        "38795",                                            // Attack 2000 AOE + Slow Down 90%
1672        "15712",                                            // Attack 200
1673        "1852",                                             // GM Spell Silence
1674        "31899",                                            // Kill
1675        "31924",                                            // Kill
1676        "29878",                                            // Kill My Self
1677        "26644",                                            // More Kill
1678
1679        "28550",                                            //Invisible 24
1680        "23452",                                            //Invisible + Target
1681        "0"
1682    };
1683
1684    uint16 gmSpellIter = 0;
1685    while( strcmp(gmSpellList[gmSpellIter], "0") )
1686    {
1687        uint32 spell = atol((char*)gmSpellList[gmSpellIter++]);
1688
1689        SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
1690        if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
1691        {
1692            PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
1693            continue;
1694        }
1695
1696        m_session->GetPlayer()->learnSpell(spell);
1697    }
1698
1699    SendSysMessage(LANG_LEARNING_GM_SKILLS);
1700    return true;
1701}
1702
1703bool ChatHandler::HandleLearnAllMyClassCommand(const char* /*args*/)
1704{
1705    HandleLearnAllMySpellsCommand("");
1706    HandleLearnAllMyTalentsCommand("");
1707    return true;
1708}
1709
1710bool ChatHandler::HandleLearnAllMySpellsCommand(const char* /*args*/)
1711{
1712    ChrClassesEntry const* clsEntry = sChrClassesStore.LookupEntry(m_session->GetPlayer()->getClass());
1713    if(!clsEntry)
1714        return true;
1715    uint32 family = clsEntry->spellfamily;
1716
1717    for (uint32 i = 0; i < sSpellStore.GetNumRows(); i++)
1718    {
1719        SpellEntry const *spellInfo = sSpellStore.LookupEntry(i);
1720        if(!spellInfo)
1721            continue;
1722
1723        // skip wrong class/race skills
1724        if(!m_session->GetPlayer()->IsSpellFitByClassAndRace(spellInfo->Id))
1725            continue;
1726
1727        // skip other spell families
1728        if( spellInfo->SpellFamilyName != family)
1729            continue;
1730
1731        //TODO: skip triggered spells
1732
1733        // skip spells with first rank learned as talent (and all talents then also)
1734        uint32 first_rank = spellmgr.GetFirstSpellInChain(spellInfo->Id);
1735        if(GetTalentSpellCost(first_rank) > 0 )
1736            continue;
1737
1738        // skip broken spells
1739        if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
1740            continue;
1741
1742        m_session->GetPlayer()->learnSpell(i);
1743    }
1744
1745    SendSysMessage(LANG_COMMAND_LEARN_CLASS_SPELLS);
1746    return true;
1747}
1748
1749static void learnAllHighRanks(Player* player, uint32 spellid)
1750{
1751    SpellChainMapNext const& nextMap = spellmgr.GetSpellChainNext();
1752    for(SpellChainMapNext::const_iterator itr = nextMap.lower_bound(spellid); itr != nextMap.upper_bound(spellid); ++itr)
1753    {
1754        player->learnSpell(itr->second);
1755        learnAllHighRanks(player,itr->second);
1756    }
1757}
1758
1759bool ChatHandler::HandleLearnAllMyTalentsCommand(const char* /*args*/)
1760{
1761    Player* player = m_session->GetPlayer();
1762    uint32 classMask = player->getClassMask();
1763
1764    for (uint32 i = 0; i < sTalentStore.GetNumRows(); i++)
1765    {
1766        TalentEntry const *talentInfo = sTalentStore.LookupEntry(i);
1767        if(!talentInfo)
1768            continue;
1769
1770        TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab );
1771        if(!talentTabInfo)
1772            continue;
1773
1774        if( (classMask & talentTabInfo->ClassMask) == 0 )
1775            continue;
1776
1777        // search highest talent rank
1778        uint32 spellid = 0;
1779        int rank = 4;
1780        for(; rank >= 0; --rank)
1781        {
1782            if(talentInfo->RankID[rank]!=0)
1783            {
1784                spellid = talentInfo->RankID[rank];
1785                break;
1786            }
1787        }
1788
1789        if(!spellid)                                        // ??? none spells in talent
1790            continue;
1791
1792        SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid);
1793        if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
1794            continue;
1795
1796        // learn highest rank of talent
1797        player->learnSpell(spellid);
1798
1799        // and learn all non-talent spell ranks (recursive by tree)
1800        learnAllHighRanks(player,spellid);
1801    }
1802
1803    SendSysMessage(LANG_COMMAND_LEARN_CLASS_TALENTS);
1804    return true;
1805}
1806
1807bool ChatHandler::HandleLearnAllLangCommand(const char* /*args*/)
1808{
1809    // skipping UNIVERSAL language (0)
1810    for(int i = 1; i < LANGUAGES_COUNT; ++i)
1811        m_session->GetPlayer()->learnSpell(lang_description[i].spell_id);
1812
1813    SendSysMessage(LANG_COMMAND_LEARN_ALL_LANG);
1814    return true;
1815}
1816
1817bool ChatHandler::HandleLearnAllDefaultCommand(const char* args)
1818{
1819    char* pName = strtok((char*)args, "");
1820    Player *player = NULL;
1821    if (pName)
1822    {
1823        std::string name = pName;
1824
1825        if(!normalizePlayerName(name))
1826        {
1827            SendSysMessage(LANG_PLAYER_NOT_FOUND);
1828            SetSentErrorMessage(true);
1829            return false;
1830        }
1831
1832        player = objmgr.GetPlayer(name.c_str());
1833    }
1834    else
1835        player = getSelectedPlayer();
1836
1837    if(!player)
1838    {
1839        SendSysMessage(LANG_NO_CHAR_SELECTED);
1840        SetSentErrorMessage(true);
1841        return false;
1842    }
1843
1844    player->learnDefaultSpells();
1845    player->learnQuestRewardedSpells();
1846
1847    PSendSysMessage(LANG_COMMAND_LEARN_ALL_DEFAULT_AND_QUEST,player->GetName());
1848    return true;
1849}
1850
1851bool ChatHandler::HandleLearnCommand(const char* args)
1852{
1853    Player* targetPlayer = getSelectedPlayer();
1854
1855    if(!targetPlayer)
1856    {
1857        SendSysMessage(LANG_PLAYER_NOT_FOUND);
1858        SetSentErrorMessage(true);
1859        return false;
1860    }
1861
1862    // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
1863    uint32 spell = extractSpellIdFromLink((char*)args);
1864    if(!spell || !sSpellStore.LookupEntry(spell))
1865        return false;
1866
1867    if (targetPlayer->HasSpell(spell))
1868    {
1869        if(targetPlayer == m_session->GetPlayer())
1870            SendSysMessage(LANG_YOU_KNOWN_SPELL);
1871        else
1872            PSendSysMessage(LANG_TARGET_KNOWN_SPELL,targetPlayer->GetName());
1873        SetSentErrorMessage(true);
1874        return false;
1875    }
1876
1877    SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
1878    if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
1879    {
1880        PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
1881        SetSentErrorMessage(true);
1882        return false;
1883    }
1884
1885    targetPlayer->learnSpell(spell);
1886
1887    return true;
1888}
1889
1890bool ChatHandler::HandleAddItemCommand(const char* args)
1891{
1892    if (!*args)
1893        return false;
1894
1895    uint32 itemId = 0;
1896
1897    if(args[0]=='[')                                        // [name] manual form
1898    {
1899        char* citemName = citemName = strtok((char*)args, "]");
1900
1901        if(citemName && citemName[0])
1902        {
1903            std::string itemName = citemName+1;
1904            WorldDatabase.escape_string(itemName);
1905            QueryResult *result = WorldDatabase.PQuery("SELECT entry FROM item_template WHERE name = '%s'", itemName.c_str());
1906            if (!result)
1907            {
1908                PSendSysMessage(LANG_COMMAND_COULDNOTFIND, citemName+1);
1909                SetSentErrorMessage(true);
1910                return false;
1911            }
1912            itemId = result->Fetch()->GetUInt16();
1913            delete result;
1914        }
1915        else
1916            return false;
1917    }
1918    else                                                    // item_id or [name] Shift-click form |color|Hitem:item_id:0:0:0|h[name]|h|r
1919    {
1920        char* cId = extractKeyFromLink((char*)args,"Hitem");
1921        if(!cId)
1922            return false;
1923        itemId = atol(cId);
1924    }
1925
1926    char* ccount = strtok(NULL, " ");
1927
1928    int32 count = 1;
1929
1930    if (ccount)
1931        count = strtol(ccount, NULL, 10);
1932
1933    if (count == 0)
1934        count = 1;
1935
1936    Player* pl = m_session->GetPlayer();
1937    Player* plTarget = getSelectedPlayer();
1938    if(!plTarget)
1939        plTarget = pl;
1940
1941    sLog.outDetail(GetTrinityString(LANG_ADDITEM), itemId, count);
1942
1943    ItemPrototype const *pProto = objmgr.GetItemPrototype(itemId);
1944    if(!pProto)
1945    {
1946        PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId);
1947        SetSentErrorMessage(true);
1948        return false;
1949    }
1950
1951    //Subtract
1952    if (count < 0)
1953    {
1954        plTarget->DestroyItemCount(itemId, -count, true, false);
1955        PSendSysMessage(LANG_REMOVEITEM, itemId, -count, plTarget->GetName());
1956        return true;
1957    }
1958
1959    //Adding items
1960    uint32 noSpaceForCount = 0;
1961
1962    // check space and find places
1963    ItemPosCountVec dest;
1964    uint8 msg = plTarget->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, itemId, count, &noSpaceForCount );
1965    if( msg != EQUIP_ERR_OK )                               // convert to possible store amount
1966        count -= noSpaceForCount;
1967
1968    if( count == 0 || dest.empty())                         // can't add any
1969    {
1970        PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount );
1971        SetSentErrorMessage(true);
1972        return false;
1973    }
1974
1975    Item* item = plTarget->StoreNewItem( dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId));
1976
1977    // remove binding (let GM give it to another player later)
1978    if(pl==plTarget)
1979        for(ItemPosCountVec::const_iterator itr = dest.begin(); itr != dest.end(); ++itr)
1980            if(Item* item1 = pl->GetItemByPos(itr->pos))
1981                item1->SetBinding( false );
1982
1983    if(count > 0 && item)
1984    {
1985        pl->SendNewItem(item,count,false,true);
1986        if(pl!=plTarget)
1987            plTarget->SendNewItem(item,count,true,false);
1988    }
1989
1990    if(noSpaceForCount > 0)
1991        PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount);
1992
1993    return true;
1994}
1995
1996bool ChatHandler::HandleAddItemSetCommand(const char* args)
1997{
1998    if (!*args)
1999        return false;
2000
2001    char* cId = extractKeyFromLink((char*)args,"Hitemset"); // number or [name] Shift-click form |color|Hitemset:itemset_id|h[name]|h|r
2002    if (!cId)
2003        return false;
2004
2005    uint32 itemsetId = atol(cId);
2006
2007    // prevent generation all items with itemset field value '0'
2008    if (itemsetId == 0)
2009    {
2010        PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND,itemsetId);
2011        SetSentErrorMessage(true);
2012        return false;
2013    }
2014
2015    Player* pl = m_session->GetPlayer();
2016    Player* plTarget = getSelectedPlayer();
2017    if(!plTarget)
2018        plTarget = pl;
2019
2020    sLog.outDetail(GetTrinityString(LANG_ADDITEMSET), itemsetId);
2021
2022    bool found = false;
2023    for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
2024    {
2025        ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype>(id);
2026        if (!pProto)
2027            continue;
2028
2029        if (pProto->ItemSet == itemsetId)
2030        {
2031            found = true;
2032            ItemPosCountVec dest;
2033            uint8 msg = plTarget->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, pProto->ItemId, 1 );
2034            if (msg == EQUIP_ERR_OK)
2035            {
2036                Item* item = plTarget->StoreNewItem( dest, pProto->ItemId, true);
2037
2038                // remove binding (let GM give it to another player later)
2039                if (pl==plTarget)
2040                    item->SetBinding( false );
2041
2042                pl->SendNewItem(item,1,false,true);
2043                if (pl!=plTarget)
2044                    plTarget->SendNewItem(item,1,true,false);
2045            }
2046            else
2047            {
2048                pl->SendEquipError( msg, NULL, NULL );
2049                PSendSysMessage(LANG_ITEM_CANNOT_CREATE, pProto->ItemId, 1);
2050            }
2051        }
2052    }
2053
2054    if (!found)
2055    {
2056        PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND,itemsetId);
2057
2058        SetSentErrorMessage(true);
2059        return false;
2060    }
2061
2062    return true;
2063}
2064
2065bool ChatHandler::HandleListItemCommand(const char* args)
2066{
2067    if(!*args)
2068        return false;
2069
2070    char* cId = extractKeyFromLink((char*)args,"Hitem");
2071    if(!cId)
2072        return false;
2073
2074    uint32 item_id = atol(cId);
2075    if(!item_id)
2076    {
2077        PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
2078        SetSentErrorMessage(true);
2079        return false;
2080    }
2081
2082    ItemPrototype const* itemProto = objmgr.GetItemPrototype(item_id);
2083    if(!itemProto)
2084    {
2085        PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
2086        SetSentErrorMessage(true);
2087        return false;
2088    }
2089
2090    char* c_count = strtok(NULL, " ");
2091    int count = c_count ? atol(c_count) : 10;
2092
2093    if(count < 0)
2094        return false;
2095
2096    QueryResult *result;
2097
2098    // inventory case
2099    uint32 inv_count = 0;
2100    result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM character_inventory WHERE item_template='%u'",item_id);
2101    if(result)
2102    {
2103        inv_count = (*result)[0].GetUInt32();
2104        delete result;
2105    }
2106
2107    result=CharacterDatabase.PQuery(
2108    //          0        1             2             3        4                  5
2109        "SELECT ci.item, cibag.slot AS bag, ci.slot, ci.guid, characters.account,characters.name "
2110        "FROM character_inventory AS ci LEFT JOIN character_inventory AS cibag ON (cibag.item=ci.bag),characters "
2111        "WHERE ci.item_template='%u' AND ci.guid = characters.guid LIMIT %u ",
2112        item_id,uint32(count));
2113
2114    if(result)
2115    {
2116        do
2117        {
2118            Field *fields = result->Fetch();
2119            uint32 item_guid = fields[0].GetUInt32();
2120            uint32 item_bag = fields[1].GetUInt32();
2121            uint32 item_slot = fields[2].GetUInt32();
2122            uint32 owner_guid = fields[3].GetUInt32();
2123            uint32 owner_acc = fields[4].GetUInt32();
2124            std::string owner_name = fields[5].GetCppString();
2125
2126            char const* item_pos = 0;
2127            if(Player::IsEquipmentPos(item_bag,item_slot))
2128                item_pos = "[equipped]";
2129            else if(Player::IsInventoryPos(item_bag,item_slot))
2130                item_pos = "[in inventory]";
2131            else if(Player::IsBankPos(item_bag,item_slot))
2132                item_pos = "[in bank]";
2133            else
2134                item_pos = "";
2135
2136            PSendSysMessage(LANG_ITEMLIST_SLOT,
2137                item_guid,owner_name.c_str(),owner_guid,owner_acc,item_pos);
2138        } while (result->NextRow());
2139
2140        int64 res_count = result->GetRowCount();
2141
2142        delete result;
2143
2144        if(count > res_count)
2145            count-=res_count;
2146        else if(count)
2147            count = 0;
2148    }
2149
2150    // mail case
2151    uint32 mail_count = 0;
2152    result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM mail_items WHERE item_template='%u'", item_id);
2153    if(result)
2154    {
2155        mail_count = (*result)[0].GetUInt32();
2156        delete result;
2157    }
2158
2159    if(count > 0)
2160    {
2161        result=CharacterDatabase.PQuery(
2162        //          0                     1            2              3               4            5               6
2163            "SELECT mail_items.item_guid, mail.sender, mail.receiver, char_s.account, char_s.name, char_r.account, char_r.name "
2164            "FROM mail,mail_items,characters as char_s,characters as char_r "
2165            "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",
2166            item_id,uint32(count));
2167    }
2168    else
2169        result = NULL;
2170
2171    if(result)
2172    {
2173        do
2174        {
2175            Field *fields = result->Fetch();
2176            uint32 item_guid        = fields[0].GetUInt32();
2177            uint32 item_s           = fields[1].GetUInt32();
2178            uint32 item_r           = fields[2].GetUInt32();
2179            uint32 item_s_acc       = fields[3].GetUInt32();
2180            std::string item_s_name = fields[4].GetCppString();
2181            uint32 item_r_acc       = fields[5].GetUInt32();
2182            std::string item_r_name = fields[6].GetCppString();
2183
2184            char const* item_pos = "[in mail]";
2185
2186            PSendSysMessage(LANG_ITEMLIST_MAIL,
2187                item_guid,item_s_name.c_str(),item_s,item_s_acc,item_r_name.c_str(),item_r,item_r_acc,item_pos);
2188        } while (result->NextRow());
2189
2190        int64 res_count = result->GetRowCount();
2191
2192        delete result;
2193
2194        if(count > res_count)
2195            count-=res_count;
2196        else if(count)
2197            count = 0;
2198    }
2199
2200    // auction case
2201    uint32 auc_count = 0;
2202    result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM auctionhouse WHERE item_template='%u'",item_id);
2203    if(result)
2204    {
2205        auc_count = (*result)[0].GetUInt32();
2206        delete result;
2207    }
2208
2209    if(count > 0)
2210    {
2211        result=CharacterDatabase.PQuery(
2212        //           0                      1                       2                   3
2213            "SELECT  auctionhouse.itemguid, auctionhouse.itemowner, characters.account, characters.name "
2214            "FROM auctionhouse,characters WHERE auctionhouse.item_template='%u' AND characters.guid = auctionhouse.itemowner LIMIT %u",
2215            item_id,uint32(count));
2216    }
2217    else
2218        result = NULL;
2219
2220    if(result)
2221    {
2222        do
2223        {
2224            Field *fields = result->Fetch();
2225            uint32 item_guid       = fields[0].GetUInt32();
2226            uint32 owner           = fields[1].GetUInt32();
2227            uint32 owner_acc       = fields[2].GetUInt32();
2228            std::string owner_name = fields[3].GetCppString();
2229
2230            char const* item_pos = "[in auction]";
2231
2232            PSendSysMessage(LANG_ITEMLIST_AUCTION, item_guid, owner_name.c_str(), owner, owner_acc,item_pos);
2233        } while (result->NextRow());
2234
2235        delete result;
2236    }
2237
2238    // guild bank case
2239    uint32 guild_count = 0;
2240    result=CharacterDatabase.PQuery("SELECT COUNT(item_entry) FROM guild_bank_item WHERE item_entry='%u'",item_id);
2241    if(result)
2242    {
2243        guild_count = (*result)[0].GetUInt32();
2244        delete result;
2245    }
2246
2247    result=CharacterDatabase.PQuery(
2248        //      0             1           2
2249        "SELECT gi.item_guid, gi.guildid, guild.name "
2250        "FROM guild_bank_item AS gi, guild WHERE gi.item_entry='%u' AND gi.guildid = guild.guildid LIMIT %u ",
2251        item_id,uint32(count));
2252
2253    if(result)
2254    {
2255        do
2256        {
2257            Field *fields = result->Fetch();
2258            uint32 item_guid = fields[0].GetUInt32();
2259            uint32 guild_guid = fields[1].GetUInt32();
2260            std::string guild_name = fields[2].GetCppString();
2261
2262            char const* item_pos = "[in guild bank]";
2263
2264            PSendSysMessage(LANG_ITEMLIST_GUILD,item_guid,guild_name.c_str(),guild_guid,item_pos);
2265        } while (result->NextRow());
2266
2267        int64 res_count = result->GetRowCount();
2268
2269        delete result;
2270
2271        if(count > res_count)
2272            count-=res_count;
2273        else if(count)
2274            count = 0;
2275    }
2276
2277    if(inv_count+mail_count+auc_count+guild_count == 0)
2278    {
2279        SendSysMessage(LANG_COMMAND_NOITEMFOUND);
2280        SetSentErrorMessage(true);
2281        return false;
2282    }
2283
2284    PSendSysMessage(LANG_COMMAND_LISTITEMMESSAGE,item_id,inv_count+mail_count+auc_count+guild_count,inv_count,mail_count,auc_count,guild_count);
2285
2286    return true;
2287}
2288
2289bool ChatHandler::HandleListObjectCommand(const char* args)
2290{
2291    if(!*args)
2292        return false;
2293
2294    // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r
2295    char* cId = extractKeyFromLink((char*)args,"Hgameobject_entry");
2296    if(!cId)
2297        return false;
2298
2299    uint32 go_id = atol(cId);
2300    if(!go_id)
2301    {
2302        PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id);
2303        SetSentErrorMessage(true);
2304        return false;
2305    }
2306
2307    GameObjectInfo const * gInfo = objmgr.GetGameObjectInfo(go_id);
2308    if(!gInfo)
2309    {
2310        PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id);
2311        SetSentErrorMessage(true);
2312        return false;
2313    }
2314
2315    char* c_count = strtok(NULL, " ");
2316    int count = c_count ? atol(c_count) : 10;
2317
2318    if(count < 0)
2319        return false;
2320
2321    QueryResult *result;
2322
2323    uint32 obj_count = 0;
2324    result=WorldDatabase.PQuery("SELECT COUNT(guid) FROM gameobject WHERE id='%u'",go_id);
2325    if(result)
2326    {
2327        obj_count = (*result)[0].GetUInt32();
2328        delete result;
2329    }
2330
2331    if(m_session)
2332    {
2333        Player* pl = m_session->GetPlayer();
2334        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",
2335            pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),go_id,uint32(count));
2336    }
2337    else
2338        result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map FROM gameobject WHERE id = '%u' LIMIT %u",
2339            go_id,uint32(count));
2340
2341    if (result)
2342    {
2343        do
2344        {
2345            Field *fields = result->Fetch();
2346            uint32 guid = fields[0].GetUInt32();
2347            float x = fields[1].GetFloat();
2348            float y = fields[2].GetFloat();
2349            float z = fields[3].GetFloat();
2350            int mapid = fields[4].GetUInt16();
2351
2352            if (m_session)
2353                PSendSysMessage(LANG_GO_LIST_CHAT, guid, guid, gInfo->name, x, y, z, mapid);
2354            else
2355                PSendSysMessage(LANG_GO_LIST_CONSOLE, guid, gInfo->name, x, y, z, mapid);
2356        } while (result->NextRow());
2357
2358        delete result;
2359    }
2360
2361    PSendSysMessage(LANG_COMMAND_LISTOBJMESSAGE,go_id,obj_count);
2362    return true;
2363}
2364
2365bool ChatHandler::HandleNearObjectCommand(const char* args)
2366{
2367    float distance = (!*args) ? 10 : atol(args);
2368    uint32 count = 0;
2369
2370    Player* pl = m_session->GetPlayer();
2371    QueryResult *result = WorldDatabase.PQuery("SELECT guid, id, position_x, position_y, position_z, map, "
2372        "(POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ "
2373        "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_",
2374        pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),
2375        pl->GetMapId(),pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),distance*distance);
2376
2377    if (result)
2378    {
2379        do
2380        {
2381            Field *fields = result->Fetch();
2382            uint32 guid = fields[0].GetUInt32();
2383            uint32 entry = fields[1].GetUInt32();
2384            float x = fields[2].GetFloat();
2385            float y = fields[3].GetFloat();
2386            float z = fields[4].GetFloat();
2387            int mapid = fields[5].GetUInt16();
2388
2389            GameObjectInfo const * gInfo = objmgr.GetGameObjectInfo(entry);
2390
2391            if(!gInfo)
2392                continue;
2393
2394            PSendSysMessage(LANG_GO_LIST_CHAT, guid, guid, gInfo->name, x, y, z, mapid);
2395
2396            ++count;
2397        } while (result->NextRow());
2398
2399        delete result;
2400    }
2401
2402    PSendSysMessage(LANG_COMMAND_NEAROBJMESSAGE,distance,count);
2403    return true;
2404}
2405
2406bool ChatHandler::HandleObjectStateCommand(const char* args)
2407{
2408    // number or [name] Shift-click form |color|Hgameobject:go_id|h[name]|h|r
2409    char* cId = extractKeyFromLink((char*)args, "Hgameobject");
2410    if(!cId)
2411        return false;
2412
2413    uint32 lowguid = atoi(cId);
2414    if(!lowguid)
2415        return false;
2416
2417    GameObject* gobj = NULL;
2418
2419    if(GameObjectData const* goData = objmgr.GetGOData(lowguid))
2420        gobj = GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid, goData->id);
2421
2422    if(!gobj)
2423    {
2424        PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid);
2425        SetSentErrorMessage(true);
2426        return false;
2427    }
2428
2429    char* cstate = strtok(NULL, " ");
2430    if(!cstate)
2431        return false;
2432
2433    int32 state = atoi(cstate);
2434    if(state < 0)
2435        gobj->SendObjectDeSpawnAnim(gobj->GetGUID());
2436    else
2437        gobj->SetGoState(state);
2438
2439    return true;
2440
2441    return true;
2442}
2443
2444bool ChatHandler::HandleListCreatureCommand(const char* args)
2445{
2446    if(!*args)
2447        return false;
2448
2449    // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
2450    char* cId = extractKeyFromLink((char*)args,"Hcreature_entry");
2451    if(!cId)
2452        return false;
2453
2454    uint32 cr_id = atol(cId);
2455    if(!cr_id)
2456    {
2457        PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id);
2458        SetSentErrorMessage(true);
2459        return false;
2460    }
2461
2462    CreatureInfo const* cInfo = objmgr.GetCreatureTemplate(cr_id);
2463    if(!cInfo)
2464    {
2465        PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id);
2466        SetSentErrorMessage(true);
2467        return false;
2468    }
2469
2470    char* c_count = strtok(NULL, " ");
2471    int count = c_count ? atol(c_count) : 10;
2472
2473    if(count < 0)
2474        return false;
2475
2476    QueryResult *result;
2477
2478    uint32 cr_count = 0;
2479    result=WorldDatabase.PQuery("SELECT COUNT(guid) FROM creature WHERE id='%u'",cr_id);
2480    if(result)
2481    {
2482        cr_count = (*result)[0].GetUInt32();
2483        delete result;
2484    }
2485
2486    if(m_session)
2487    {
2488        Player* pl = m_session->GetPlayer();
2489        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",
2490            pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), cr_id,uint32(count));
2491    }
2492    else
2493        result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map FROM creature WHERE id = '%u' LIMIT %u",
2494            cr_id,uint32(count));
2495
2496    if (result)
2497    {
2498        do
2499        {
2500            Field *fields = result->Fetch();
2501            uint32 guid = fields[0].GetUInt32();
2502            float x = fields[1].GetFloat();
2503            float y = fields[2].GetFloat();
2504            float z = fields[3].GetFloat();
2505            int mapid = fields[4].GetUInt16();
2506
2507            if  (m_session)
2508                PSendSysMessage(LANG_CREATURE_LIST_CHAT, guid, guid, cInfo->Name, x, y, z, mapid);
2509            else
2510                PSendSysMessage(LANG_CREATURE_LIST_CONSOLE, guid, cInfo->Name, x, y, z, mapid);
2511        } while (result->NextRow());
2512
2513        delete result;
2514    }
2515
2516    PSendSysMessage(LANG_COMMAND_LISTCREATUREMESSAGE,cr_id,cr_count);
2517    return true;
2518}
2519
2520bool ChatHandler::HandleLookupItemCommand(const char* args)
2521{
2522    if(!*args)
2523        return false;
2524
2525    std::string namepart = args;
2526    std::wstring wnamepart;
2527
2528    // converting string that we try to find to lower case
2529    if(!Utf8toWStr(namepart,wnamepart))
2530        return false;
2531
2532    wstrToLower(wnamepart);
2533
2534    uint32 counter = 0;
2535
2536    // Search in `item_template`
2537    for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
2538    {
2539        ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype >(id);
2540        if(!pProto)
2541            continue;
2542
2543        int loc_idx = m_session ? m_session->GetSessionDbLocaleIndex() : objmgr.GetDBCLocaleIndex();
2544        if ( loc_idx >= 0 )
2545        {
2546            ItemLocale const *il = objmgr.GetItemLocale(pProto->ItemId);
2547            if (il)
2548            {
2549                if (il->Name.size() > loc_idx && !il->Name[loc_idx].empty())
2550                {
2551                    std::string name = il->Name[loc_idx];
2552
2553                    if (Utf8FitTo(name, wnamepart))
2554                    {
2555                        if (m_session)
2556                            PSendSysMessage(LANG_ITEM_LIST_CHAT, id, id, name.c_str());
2557                        else
2558                            PSendSysMessage(LANG_ITEM_LIST_CONSOLE, id, name.c_str());
2559                        ++counter;
2560                        continue;
2561                    }
2562                }
2563            }
2564        }
2565
2566        std::string name = pProto->Name1;
2567        if(name.empty())
2568            continue;
2569
2570        if (Utf8FitTo(name, wnamepart))
2571        {
2572            if (m_session)
2573                PSendSysMessage(LANG_ITEM_LIST_CHAT, id, id, name.c_str());
2574            else
2575                PSendSysMessage(LANG_ITEM_LIST_CONSOLE, id, name.c_str());
2576            ++counter;
2577        }
2578    }
2579
2580    if (counter==0)
2581        SendSysMessage(LANG_COMMAND_NOITEMFOUND);
2582
2583    return true;
2584}
2585
2586bool ChatHandler::HandleLookupItemSetCommand(const char* args)
2587{
2588    if(!*args)
2589        return false;
2590
2591    std::string namepart = args;
2592    std::wstring wnamepart;
2593
2594    if(!Utf8toWStr(namepart,wnamepart))
2595        return false;
2596
2597    // converting string that we try to find to lower case
2598    wstrToLower( wnamepart );
2599
2600    uint32 counter = 0;                                     // Counter for figure out that we found smth.
2601
2602    // Search in ItemSet.dbc
2603    for (uint32 id = 0; id < sItemSetStore.GetNumRows(); id++)
2604    {
2605        ItemSetEntry const *set = sItemSetStore.LookupEntry(id);
2606        if(set)
2607        {
2608            int loc = m_session ? m_session->GetSessionDbcLocale() : sWorld.GetDefaultDbcLocale();
2609            std::string name = set->name[loc];
2610            if(name.empty())
2611                continue;
2612
2613            if (!Utf8FitTo(name, wnamepart))
2614            {
2615                loc = 0;
2616                for(; loc < MAX_LOCALE; ++loc)
2617                {
2618                    if(m_session && loc==m_session->GetSessionDbcLocale())
2619                        continue;
2620
2621                    name = set->name[loc];
2622                    if(name.empty())
2623                        continue;
2624
2625                    if (Utf8FitTo(name, wnamepart))
2626                        break;
2627                }
2628            }
2629
2630            if(loc < MAX_LOCALE)
2631            {
2632                // send item set in "id - [namedlink locale]" format
2633                if (m_session)
2634                    PSendSysMessage(LANG_ITEMSET_LIST_CHAT,id,id,name.c_str(),localeNames[loc]);
2635                else
2636                    PSendSysMessage(LANG_ITEMSET_LIST_CONSOLE,id,name.c_str(),localeNames[loc]);
2637                ++counter;
2638            }
2639        }
2640    }
2641    if (counter == 0)                                       // if counter == 0 then we found nth
2642        SendSysMessage(LANG_COMMAND_NOITEMSETFOUND);
2643    return true;
2644}
2645
2646bool ChatHandler::HandleLookupSkillCommand(const char* args)
2647{
2648    if(!*args)
2649        return false;
2650
2651    // can be NULL in console call
2652    Player* target = getSelectedPlayer();
2653
2654    std::string namepart = args;
2655    std::wstring wnamepart;
2656
2657    if(!Utf8toWStr(namepart,wnamepart))
2658        return false;
2659
2660    // converting string that we try to find to lower case
2661    wstrToLower( wnamepart );
2662
2663    uint32 counter = 0;                                     // Counter for figure out that we found smth.
2664
2665    // Search in SkillLine.dbc
2666    for (uint32 id = 0; id < sSkillLineStore.GetNumRows(); id++)
2667    {
2668        SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(id);
2669        if(skillInfo)
2670        {
2671            int loc = m_session ? m_session->GetSessionDbcLocale() : sWorld.GetDefaultDbcLocale();
2672            std::string name = skillInfo->name[loc];
2673            if(name.empty())
2674                continue;
2675
2676            if (!Utf8FitTo(name, wnamepart))
2677            {
2678                loc = 0;
2679                for(; loc < MAX_LOCALE; ++loc)
2680                {
2681                    if(m_session && loc==m_session->GetSessionDbcLocale())
2682                        continue;
2683
2684                    name = skillInfo->name[loc];
2685                    if(name.empty())
2686                        continue;
2687
2688                    if (Utf8FitTo(name, wnamepart))
2689                        break;
2690                }
2691            }
2692
2693            if(loc < MAX_LOCALE)
2694            {
2695                char const* knownStr = "";
2696                if(target && target->HasSkill(id))
2697                    knownStr = GetTrinityString(LANG_KNOWN);
2698
2699                // send skill in "id - [namedlink locale]" format
2700                if (m_session)
2701                    PSendSysMessage(LANG_SKILL_LIST_CHAT,id,id,name.c_str(),localeNames[loc],knownStr);
2702                else
2703                    PSendSysMessage(LANG_SKILL_LIST_CONSOLE,id,name.c_str(),localeNames[loc],knownStr);
2704
2705                ++counter;
2706            }
2707        }
2708    }
2709    if (counter == 0)                                       // if counter == 0 then we found nth
2710        SendSysMessage(LANG_COMMAND_NOSKILLFOUND);
2711    return true;
2712}
2713
2714bool ChatHandler::HandleLookupSpellCommand(const char* args)
2715{
2716    if(!*args)
2717        return false;
2718
2719    // can be NULL at console call
2720    Player* target = getSelectedPlayer();
2721
2722    std::string namepart = args;
2723    std::wstring wnamepart;
2724
2725    if(!Utf8toWStr(namepart,wnamepart))
2726        return false;
2727
2728    // converting string that we try to find to lower case
2729    wstrToLower( wnamepart );
2730
2731    uint32 counter = 0;                                     // Counter for figure out that we found smth.
2732
2733    // Search in Spell.dbc
2734    for (uint32 id = 0; id < sSpellStore.GetNumRows(); id++)
2735    {
2736        SpellEntry const *spellInfo = sSpellStore.LookupEntry(id);
2737        if(spellInfo)
2738        {
2739            int loc = m_session ? m_session->GetSessionDbcLocale() : sWorld.GetDefaultDbcLocale();
2740            std::string name = spellInfo->SpellName[loc];
2741            if(name.empty())
2742                continue;
2743
2744            if (!Utf8FitTo(name, wnamepart))
2745            {
2746                loc = 0;
2747                for(; loc < MAX_LOCALE; ++loc)
2748                {
2749                    if(m_session && loc==m_session->GetSessionDbcLocale())
2750                        continue;
2751
2752                    name = spellInfo->SpellName[loc];
2753                    if(name.empty())
2754                        continue;
2755
2756                    if (Utf8FitTo(name, wnamepart))
2757                        break;
2758                }
2759            }
2760
2761            if(loc < MAX_LOCALE)
2762            {
2763                bool known = target && target->HasSpell(id);
2764                bool learn = (spellInfo->Effect[0] == SPELL_EFFECT_LEARN_SPELL);
2765
2766                uint32 talentCost = GetTalentSpellCost(id);
2767
2768                bool talent = (talentCost > 0);
2769                bool passive = IsPassiveSpell(id);
2770                bool active = target && (target->HasAura(id,0) || target->HasAura(id,1) || target->HasAura(id,2));
2771
2772                // unit32 used to prevent interpreting uint8 as char at output
2773                // find rank of learned spell for learning spell, or talent rank
2774                uint32 rank = talentCost ? talentCost : spellmgr.GetSpellRank(learn ? spellInfo->EffectTriggerSpell[0] : id);
2775
2776                // send spell in "id - [name, rank N] [talent] [passive] [learn] [known]" format
2777                std::ostringstream ss;
2778                if (m_session)
2779                    ss << id << " - |cffffffff|Hspell:" << id << "|h[" << name;
2780                else
2781                    ss << id << " - " << name;
2782
2783                // include rank in link name
2784                if(rank)
2785                    ss << GetTrinityString(LANG_SPELL_RANK) << rank;
2786
2787                if (m_session)
2788                    ss << " " << localeNames[loc] << "]|h|r";
2789                else
2790                    ss << " " << localeNames[loc];
2791
2792                if(talent)
2793                    ss << GetTrinityString(LANG_TALENT);
2794                if(passive)
2795                    ss << GetTrinityString(LANG_PASSIVE);
2796                if(learn)
2797                    ss << GetTrinityString(LANG_LEARN);
2798                if(known)
2799                    ss << GetTrinityString(LANG_KNOWN);
2800                if(active)
2801                    ss << GetTrinityString(LANG_ACTIVE);
2802
2803                SendSysMessage(ss.str().c_str());
2804
2805                ++counter;
2806            }
2807        }
2808    }
2809    if (counter == 0)                                       // if counter == 0 then we found nth
2810        SendSysMessage(LANG_COMMAND_NOSPELLFOUND);
2811    return true;
2812}
2813
2814bool ChatHandler::HandleLookupQuestCommand(const char* args)
2815{
2816    if(!*args)
2817        return false;
2818
2819    // can be NULL at console call
2820    Player* target = getSelectedPlayer();
2821
2822    std::string namepart = args;
2823    std::wstring wnamepart;
2824
2825    // converting string that we try to find to lower case
2826    if(!Utf8toWStr(namepart,wnamepart))
2827        return false;
2828
2829    wstrToLower(wnamepart);
2830
2831    uint32 counter = 0 ;
2832
2833    ObjectMgr::QuestMap const& qTemplates = objmgr.GetQuestTemplates();
2834    for (ObjectMgr::QuestMap::const_iterator iter = qTemplates.begin(); iter != qTemplates.end(); ++iter)
2835    {
2836        Quest * qinfo = iter->second;
2837
2838        int loc_idx = m_session ? m_session->GetSessionDbLocaleIndex() : objmgr.GetDBCLocaleIndex();
2839        if ( loc_idx >= 0 )
2840        {
2841            QuestLocale const *il = objmgr.GetQuestLocale(qinfo->GetQuestId());
2842            if (il)
2843            {
2844                if (il->Title.size() > loc_idx && !il->Title[loc_idx].empty())
2845                {
2846                    std::string title = il->Title[loc_idx];
2847
2848                    if (Utf8FitTo(title, wnamepart))
2849                    {
2850                        char const* statusStr = "";
2851
2852                        if(target)
2853                        {
2854                            QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId());
2855
2856                            if(status == QUEST_STATUS_COMPLETE)
2857                            {
2858                                if(target->GetQuestRewardStatus(qinfo->GetQuestId()))
2859                                    statusStr = GetTrinityString(LANG_COMMAND_QUEST_REWARDED);
2860                                else
2861                                    statusStr = GetTrinityString(LANG_COMMAND_QUEST_COMPLETE);
2862                            }
2863                            else if(status == QUEST_STATUS_INCOMPLETE)
2864                                statusStr = GetTrinityString(LANG_COMMAND_QUEST_ACTIVE);
2865                        }
2866
2867                        if (m_session)
2868                            PSendSysMessage(LANG_QUEST_LIST_CHAT,qinfo->GetQuestId(),qinfo->GetQuestId(),title.c_str(),statusStr);
2869                        else
2870                            PSendSysMessage(LANG_QUEST_LIST_CONSOLE,qinfo->GetQuestId(),title.c_str(),statusStr);
2871                        ++counter;
2872                        continue;
2873                    }
2874                }
2875            }
2876        }
2877
2878        std::string title = qinfo->GetTitle();
2879        if(title.empty())
2880            continue;
2881
2882        if (Utf8FitTo(title, wnamepart))
2883        {
2884            char const* statusStr = "";
2885
2886            if(target)
2887            {
2888                QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId());
2889
2890                if(status == QUEST_STATUS_COMPLETE)
2891                {
2892                    if(target->GetQuestRewardStatus(qinfo->GetQuestId()))
2893                        statusStr = GetTrinityString(LANG_COMMAND_QUEST_REWARDED);
2894                    else
2895                        statusStr = GetTrinityString(LANG_COMMAND_QUEST_COMPLETE);
2896                }
2897                else if(status == QUEST_STATUS_INCOMPLETE)
2898                    statusStr = GetTrinityString(LANG_COMMAND_QUEST_ACTIVE);
2899            }
2900
2901            if (m_session)
2902                PSendSysMessage(LANG_QUEST_LIST_CHAT,qinfo->GetQuestId(),qinfo->GetQuestId(),title.c_str(),statusStr);
2903            else
2904                PSendSysMessage(LANG_QUEST_LIST_CONSOLE,qinfo->GetQuestId(),title.c_str(),statusStr);
2905
2906            ++counter;
2907        }
2908    }
2909
2910    if (counter==0)
2911        SendSysMessage(LANG_COMMAND_NOQUESTFOUND);
2912
2913    return true;
2914}
2915
2916bool ChatHandler::HandleLookupCreatureCommand(const char* args)
2917{
2918    if (!*args)
2919        return false;
2920
2921    std::string namepart = args;
2922    std::wstring wnamepart;
2923
2924    // converting string that we try to find to lower case
2925    if (!Utf8toWStr (namepart,wnamepart))
2926        return false;
2927
2928    wstrToLower (wnamepart);
2929
2930    uint32 counter = 0;
2931
2932    for (uint32 id = 0; id< sCreatureStorage.MaxEntry; ++id)
2933    {
2934        CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo> (id);
2935        if(!cInfo)
2936            continue;
2937
2938        int loc_idx = m_session ? m_session->GetSessionDbLocaleIndex() : objmgr.GetDBCLocaleIndex();
2939        if (loc_idx >= 0)
2940        {
2941            CreatureLocale const *cl = objmgr.GetCreatureLocale (id);
2942            if (cl)
2943            {
2944                if (cl->Name.size() > loc_idx && !cl->Name[loc_idx].empty ())
2945                {
2946                    std::string name = cl->Name[loc_idx];
2947
2948                    if (Utf8FitTo (name, wnamepart))
2949                    {
2950                        if (m_session)
2951                            PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CHAT, id, id, name.c_str ());
2952                        else
2953                            PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CONSOLE, id, name.c_str ());
2954                        ++counter;
2955                        continue;
2956                    }
2957                }
2958            }
2959        }
2960
2961        std::string name = cInfo->Name;
2962        if (name.empty ())
2963            continue;
2964
2965        if (Utf8FitTo(name, wnamepart))
2966        {
2967            if (m_session)
2968                PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CHAT, id, id, name.c_str ());
2969            else
2970                PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CONSOLE, id, name.c_str ());
2971            ++counter;
2972        }
2973    }
2974
2975    if (counter==0)
2976        SendSysMessage (LANG_COMMAND_NOCREATUREFOUND);
2977
2978    return true;
2979}
2980
2981bool ChatHandler::HandleLookupObjectCommand(const char* args)
2982{
2983    if(!*args)
2984        return false;
2985
2986    std::string namepart = args;
2987    std::wstring wnamepart;
2988
2989    // converting string that we try to find to lower case
2990    if(!Utf8toWStr(namepart,wnamepart))
2991        return false;
2992
2993    wstrToLower(wnamepart);
2994
2995    uint32 counter = 0;
2996
2997    for (uint32 id = 0; id< sGOStorage.MaxEntry; id++ )
2998    {
2999        GameObjectInfo const* gInfo = sGOStorage.LookupEntry<GameObjectInfo>(id);
3000        if(!gInfo)
3001            continue;
3002
3003        int loc_idx = m_session ? m_session->GetSessionDbLocaleIndex() : objmgr.GetDBCLocaleIndex();
3004        if ( loc_idx >= 0 )
3005        {
3006            GameObjectLocale const *gl = objmgr.GetGameObjectLocale(id);
3007            if (gl)
3008            {
3009                if (gl->Name.size() > loc_idx && !gl->Name[loc_idx].empty())
3010                {
3011                    std::string name = gl->Name[loc_idx];
3012
3013                    if (Utf8FitTo(name, wnamepart))
3014                    {
3015                        if (m_session)
3016                            PSendSysMessage(LANG_GO_ENTRY_LIST_CHAT, id, id, name.c_str());
3017                        else
3018                            PSendSysMessage(LANG_GO_ENTRY_LIST_CONSOLE, id, name.c_str());
3019                        ++counter;
3020                        continue;
3021                    }
3022                }
3023            }
3024        }
3025
3026        std::string name = gInfo->name;
3027        if(name.empty())
3028            continue;
3029
3030        if(Utf8FitTo(name, wnamepart))
3031        {
3032            if (m_session)
3033                PSendSysMessage(LANG_GO_ENTRY_LIST_CHAT, id, id, name.c_str());
3034            else
3035                PSendSysMessage(LANG_GO_ENTRY_LIST_CONSOLE, id, name.c_str());
3036            ++counter;
3037        }
3038    }
3039
3040    if(counter==0)
3041        SendSysMessage(LANG_COMMAND_NOGAMEOBJECTFOUND);
3042
3043    return true;
3044}
3045
3046/** \brief GM command level 3 - Create a guild.
3047 *
3048 * This command allows a GM (level 3) to create a guild.
3049 *
3050 * The "args" parameter contains the name of the guild leader
3051 * and then the name of the guild.
3052 *
3053 */
3054bool ChatHandler::HandleGuildCreateCommand(const char* args)
3055{
3056
3057    if (!*args)
3058        return false;
3059
3060    char *lname = strtok ((char*)args, " ");
3061    char *gname = strtok (NULL, "");
3062
3063    if (!lname)
3064        return false;
3065
3066    if (!gname)
3067    {
3068        SendSysMessage (LANG_INSERT_GUILD_NAME);
3069        SetSentErrorMessage (true);
3070        return false;
3071    }
3072
3073    std::string guildname = gname;
3074
3075    Player* player = ObjectAccessor::Instance ().FindPlayerByName (lname);
3076    if (!player)
3077    {
3078        SendSysMessage (LANG_PLAYER_NOT_FOUND);
3079        SetSentErrorMessage (true);
3080        return false;
3081    }
3082
3083    if (player->GetGuildId())
3084    {
3085        SendSysMessage (LANG_PLAYER_IN_GUILD);
3086        return true;
3087    }
3088
3089    Guild *guild = new Guild;
3090    if (!guild->create (player->GetGUID (),guildname))
3091    {
3092        delete guild;
3093        SendSysMessage (LANG_GUILD_NOT_CREATED);
3094        SetSentErrorMessage (true);
3095        return false;
3096    }
3097
3098    objmgr.AddGuild (guild);
3099    return true;
3100}
3101
3102bool ChatHandler::HandleGuildInviteCommand(const char *args)
3103{
3104    if (!*args)
3105        return false;
3106
3107    char* par1 = strtok ((char*)args, " ");
3108    char* par2 = strtok (NULL, "");
3109    if(!par1 || !par2)
3110        return false;
3111
3112    std::string glName = par2;
3113    Guild* targetGuild = objmgr.GetGuildByName (glName);
3114    if (!targetGuild)
3115        return false;
3116
3117    std::string plName = par1;
3118    if (!normalizePlayerName (plName))
3119    {
3120        SendSysMessage (LANG_PLAYER_NOT_FOUND);
3121        SetSentErrorMessage (true);
3122        return false;
3123    }
3124
3125    uint64 plGuid = 0;
3126    if (Player* targetPlayer = ObjectAccessor::Instance ().FindPlayerByName (plName.c_str ()))
3127        plGuid = targetPlayer->GetGUID ();
3128    else
3129        plGuid = objmgr.GetPlayerGUIDByName (plName.c_str ());
3130
3131    if (!plGuid)
3132        false;
3133
3134    // player's guild membership checked in AddMember before add
3135    if (!targetGuild->AddMember (plGuid,targetGuild->GetLowestRank ()))
3136        return false;
3137
3138    return true;
3139}
3140
3141bool ChatHandler::HandleGuildUninviteCommand(const char *args)
3142{
3143    if (!*args)
3144        return false;
3145
3146    char* par1 = strtok ((char*)args, " ");
3147    if(!par1)
3148        return false;
3149
3150    std::string plName = par1;
3151    if (!normalizePlayerName (plName))
3152    {
3153        SendSysMessage (LANG_PLAYER_NOT_FOUND);
3154        SetSentErrorMessage (true);
3155        return false;
3156    }
3157
3158    uint64 plGuid = 0;
3159    uint32 glId   = 0;
3160    if (Player* targetPlayer = ObjectAccessor::Instance ().FindPlayerByName (plName.c_str ()))
3161    {
3162        plGuid = targetPlayer->GetGUID ();
3163        glId   = targetPlayer->GetGuildId ();
3164    }
3165    else
3166    {
3167        plGuid = objmgr.GetPlayerGUIDByName (plName.c_str ());
3168        glId = Player::GetGuildIdFromDB (plGuid);
3169    }
3170
3171    if (!plGuid || !glId)
3172        return false;
3173
3174    Guild* targetGuild = objmgr.GetGuildById (glId);
3175    if (!targetGuild)
3176        return false;
3177
3178    targetGuild->DelMember (plGuid);
3179
3180    return true;
3181}
3182
3183bool ChatHandler::HandleGuildRankCommand(const char *args)
3184{
3185    if (!*args)
3186        return false;
3187
3188    char* par1 = strtok ((char*)args, " ");
3189    char* par2 = strtok (NULL, " ");
3190    if (!par1 || !par2)
3191        return false;
3192    std::string plName = par1;
3193    if (!normalizePlayerName (plName))
3194    {
3195        SendSysMessage (LANG_PLAYER_NOT_FOUND);
3196        SetSentErrorMessage (true);
3197        return false;
3198    }
3199
3200    uint64 plGuid = 0;
3201    uint32 glId   = 0;
3202    if (Player* targetPlayer = ObjectAccessor::Instance ().FindPlayerByName (plName.c_str ()))
3203    {
3204        plGuid = targetPlayer->GetGUID ();
3205        glId   = targetPlayer->GetGuildId ();
3206    }
3207    else
3208    {
3209        plGuid = objmgr.GetPlayerGUIDByName (plName.c_str ());
3210        glId = Player::GetGuildIdFromDB (plGuid);
3211    }
3212
3213    if (!plGuid || !glId)
3214        return false;
3215
3216    Guild* targetGuild = objmgr.GetGuildById (glId);
3217    if (!targetGuild)
3218        return false;
3219
3220    uint32 newrank = uint32 (atoi (par2));
3221    if (newrank > targetGuild->GetLowestRank ())
3222        return false;
3223
3224    targetGuild->ChangeRank (plGuid,newrank);
3225
3226    return true;
3227}
3228
3229bool ChatHandler::HandleGuildDeleteCommand(const char* args)
3230{
3231    if (!*args)
3232        return false;
3233
3234    char* par1 = strtok ((char*)args, " ");
3235    if (!par1)
3236        return false;
3237
3238    std::string gld = par1;
3239
3240    Guild* targetGuild = objmgr.GetGuildByName (gld);
3241    if (!targetGuild)
3242        return false;
3243
3244    targetGuild->Disband ();
3245
3246    return true;
3247}
3248
3249bool ChatHandler::HandleGetDistanceCommand(const char* /*args*/)
3250{
3251    Unit* pUnit = getSelectedUnit();
3252
3253    if(!pUnit)
3254    {
3255        SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3256        SetSentErrorMessage(true);
3257        return false;
3258    }
3259
3260    PSendSysMessage(LANG_DISTANCE, m_session->GetPlayer()->GetDistance(pUnit),m_session->GetPlayer()->GetDistance2d(pUnit));
3261
3262    return true;
3263}
3264
3265// FIX-ME!!!
3266
3267bool ChatHandler::HandleAddWeaponCommand(const char* /*args*/)
3268{
3269    /*if (!*args)
3270        return false;
3271
3272    uint64 guid = m_session->GetPlayer()->GetSelection();
3273    if (guid == 0)
3274    {
3275        SendSysMessage(LANG_NO_SELECTION);
3276        return true;
3277    }
3278
3279    Creature *pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
3280
3281    if(!pCreature)
3282    {
3283        SendSysMessage(LANG_SELECT_CREATURE);
3284        return true;
3285    }
3286
3287    char* pSlotID = strtok((char*)args, " ");
3288    if (!pSlotID)
3289        return false;
3290
3291    char* pItemID = strtok(NULL, " ");
3292    if (!pItemID)
3293        return false;
3294
3295    uint32 ItemID = atoi(pItemID);
3296    uint32 SlotID = atoi(pSlotID);
3297
3298    ItemPrototype* tmpItem = objmgr.GetItemPrototype(ItemID);
3299
3300    bool added = false;
3301    if(tmpItem)
3302    {
3303        switch(SlotID)
3304        {
3305            case 1:
3306                pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, ItemID);
3307                added = true;
3308                break;
3309            case 2:
3310                pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_01, ItemID);
3311                added = true;
3312                break;
3313            case 3:
3314                pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_02, ItemID);
3315                added = true;
3316                break;
3317            default:
3318                PSendSysMessage(LANG_ITEM_SLOT_NOT_EXIST,SlotID);
3319                added = false;
3320                break;
3321        }
3322        if(added)
3323        {
3324            PSendSysMessage(LANG_ITEM_ADDED_TO_SLOT,ItemID,tmpItem->Name1,SlotID);
3325        }
3326    }
3327    else
3328    {
3329        PSendSysMessage(LANG_ITEM_NOT_FOUND,ItemID);
3330        return true;
3331    }
3332    */
3333    return true;
3334}
3335
3336bool ChatHandler::HandleDieCommand(const char* /*args*/)
3337{
3338    Unit* target = getSelectedUnit();
3339
3340    if(!target || !m_session->GetPlayer()->GetSelection())
3341    {
3342        SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3343        SetSentErrorMessage(true);
3344        return false;
3345    }
3346
3347    if( target->isAlive() )
3348    {
3349        m_session->GetPlayer()->DealDamage(target, target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
3350    }
3351
3352    return true;
3353}
3354
3355bool ChatHandler::HandleDamageCommand(const char * args)
3356{
3357    if (!*args)
3358        return false;
3359
3360    Unit* target = getSelectedUnit();
3361
3362    if(!target || !m_session->GetPlayer()->GetSelection())
3363    {
3364        SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3365        SetSentErrorMessage(true);
3366        return false;
3367    }
3368
3369    if( !target->isAlive() )
3370        return true;
3371
3372    char* damageStr = strtok((char*)args, " ");
3373    if(!damageStr)
3374        return false;
3375
3376    int32 damage = atoi((char*)damageStr);
3377    if(damage <=0)
3378        return true;
3379
3380    char* schoolStr = strtok((char*)NULL, " ");
3381
3382    // flat melee damage without resistence/etc reduction
3383    if(!schoolStr)
3384    {
3385        m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
3386        m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, SPELL_SCHOOL_MASK_NORMAL, damage, 0, 0, VICTIMSTATE_NORMAL, 0);
3387        return true;
3388    }
3389
3390    uint32 school = schoolStr ? atoi((char*)schoolStr) : SPELL_SCHOOL_NORMAL;
3391    if(school >= MAX_SPELL_SCHOOL)
3392        return false;
3393
3394    SpellSchoolMask schoolmask = SpellSchoolMask(1 << school);
3395
3396    if ( schoolmask & SPELL_SCHOOL_MASK_NORMAL )
3397        damage = m_session->GetPlayer()->CalcArmorReducedDamage(target, damage);
3398
3399    char* spellStr = strtok((char*)NULL, " ");
3400
3401    // melee damage by specific school
3402    if(!spellStr)
3403    {
3404        uint32 absorb = 0;
3405        uint32 resist = 0;
3406
3407        m_session->GetPlayer()->CalcAbsorbResist(target,schoolmask, SPELL_DIRECT_DAMAGE, damage, &absorb, &resist);
3408
3409        if (damage <= absorb + resist)
3410            return true;
3411
3412        damage -= absorb + resist;
3413
3414        m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, schoolmask, NULL, false);
3415        m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, schoolmask, damage, absorb, resist, VICTIMSTATE_NORMAL, 0);
3416        return true;
3417    }
3418
3419    // non-melee damage
3420
3421    // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
3422    uint32 spellid = extractSpellIdFromLink((char*)args);
3423    if(!spellid || !sSpellStore.LookupEntry(spellid))
3424        return false;
3425
3426    m_session->GetPlayer()->SpellNonMeleeDamageLog(target, spellid, damage, false);
3427    return true;
3428}
3429
3430bool ChatHandler::HandleModifyArenaCommand(const char * args)
3431{
3432    if (!*args)
3433        return false;
3434
3435    Player *target = getSelectedPlayer();
3436    if(!target)
3437    {
3438        SendSysMessage(LANG_PLAYER_NOT_FOUND);
3439        SetSentErrorMessage(true);
3440        return false;
3441    }
3442
3443    int32 amount = (uint32)atoi(args);
3444
3445    target->ModifyArenaPoints(amount);
3446
3447    PSendSysMessage(LANG_COMMAND_MODIFY_ARENA, target->GetName(), target->GetArenaPoints());
3448
3449    return true;
3450}
3451
3452bool ChatHandler::HandleReviveCommand(const char* args)
3453{
3454    Player* SelectedPlayer = NULL;
3455
3456    if (*args)
3457    {
3458        std::string name = args;
3459        if(!normalizePlayerName(name))
3460        {
3461            SendSysMessage(LANG_PLAYER_NOT_FOUND);
3462            SetSentErrorMessage(true);
3463            return false;
3464        }
3465
3466        SelectedPlayer = objmgr.GetPlayer(name.c_str());
3467    }
3468    else
3469        SelectedPlayer = getSelectedPlayer();
3470
3471    if(!SelectedPlayer)
3472    {
3473        SendSysMessage(LANG_NO_CHAR_SELECTED);
3474        SetSentErrorMessage(true);
3475        return false;
3476    }
3477
3478    SelectedPlayer->ResurrectPlayer(0.5f);
3479    SelectedPlayer->SpawnCorpseBones();
3480    SelectedPlayer->SaveToDB();
3481    return true;
3482}
3483
3484bool ChatHandler::HandleAuraCommand(const char* args)
3485{
3486    char* px = strtok((char*)args, " ");
3487    if (!px)
3488        return false;
3489
3490    Unit *target = getSelectedUnit();
3491    if(!target)
3492    {
3493        SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3494        SetSentErrorMessage(true);
3495        return false;
3496    }
3497
3498    uint32 spellID = (uint32)atoi(px);
3499    SpellEntry const *spellInfo = sSpellStore.LookupEntry( spellID );
3500    if(spellInfo)
3501    {
3502        for(uint32 i = 0;i<3;i++)
3503        {
3504            uint8 eff = spellInfo->Effect[i];
3505            if (eff>=TOTAL_SPELL_EFFECTS)
3506                continue;
3507            if( IsAreaAuraEffect(eff)           ||
3508                eff == SPELL_EFFECT_APPLY_AURA  ||
3509                eff == SPELL_EFFECT_PERSISTENT_AREA_AURA )
3510            {
3511                Aura *Aur = CreateAura(spellInfo, i, NULL, target);
3512                target->AddAura(Aur);
3513            }
3514        }
3515    }
3516
3517    return true;
3518}
3519
3520bool ChatHandler::HandleUnAuraCommand(const char* args)
3521{
3522    char* px = strtok((char*)args, " ");
3523    if (!px)
3524        return false;
3525
3526    Unit *target = getSelectedUnit();
3527    if(!target)
3528    {
3529        SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
3530        SetSentErrorMessage(true);
3531        return false;
3532    }
3533
3534    std::string argstr = args;
3535    if (argstr == "all")
3536    {
3537        target->RemoveAllAuras();
3538        return true;
3539    }
3540
3541    uint32 spellID = (uint32)atoi(px);
3542    target->RemoveAurasDueToSpell(spellID);
3543
3544    return true;
3545}
3546
3547bool ChatHandler::HandleLinkGraveCommand(const char* args)
3548{
3549    if(!*args)
3550        return false;
3551
3552    char* px = strtok((char*)args, " ");
3553    if (!px)
3554        return false;
3555
3556    uint32 g_id = (uint32)atoi(px);
3557
3558    uint32 g_team;
3559
3560    char* px2 = strtok(NULL, " ");
3561
3562    if (!px2)
3563        g_team = 0;
3564    else if (strncmp(px2,"horde",6)==0)
3565        g_team = HORDE;
3566    else if (strncmp(px2,"alliance",9)==0)
3567        g_team = ALLIANCE;
3568    else
3569        return false;
3570
3571    WorldSafeLocsEntry const* graveyard =  sWorldSafeLocsStore.LookupEntry(g_id);
3572
3573    if(!graveyard )
3574    {
3575        PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST, g_id);
3576        SetSentErrorMessage(true);
3577        return false;
3578    }
3579
3580    Player* player = m_session->GetPlayer();
3581
3582    uint32 zoneId = player->GetZoneId();
3583
3584    AreaTableEntry const *areaEntry = GetAreaEntryByAreaID(zoneId);
3585    if(!areaEntry || areaEntry->zone !=0 )
3586    {
3587        PSendSysMessage(LANG_COMMAND_GRAVEYARDWRONGZONE, g_id,zoneId);
3588        SetSentErrorMessage(true);
3589        return false;
3590    }
3591
3592    if(objmgr.AddGraveYardLink(g_id,player->GetZoneId(),g_team))
3593        PSendSysMessage(LANG_COMMAND_GRAVEYARDLINKED, g_id,zoneId);
3594    else
3595        PSendSysMessage(LANG_COMMAND_GRAVEYARDALRLINKED, g_id,zoneId);
3596
3597    return true;
3598}
3599
3600bool ChatHandler::HandleNearGraveCommand(const char* args)
3601{
3602    uint32 g_team;
3603
3604    size_t argslen = strlen(args);
3605
3606    if(!*args)
3607        g_team = 0;
3608    else if (strncmp((char*)args,"horde",argslen)==0)
3609        g_team = HORDE;
3610    else if (strncmp((char*)args,"alliance",argslen)==0)
3611        g_team = ALLIANCE;
3612    else
3613        return false;
3614
3615    Player* player = m_session->GetPlayer();
3616
3617    WorldSafeLocsEntry const* graveyard = objmgr.GetClosestGraveYard(
3618        player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(),player->GetMapId(),g_team);
3619
3620    if(graveyard)
3621    {
3622        uint32 g_id = graveyard->ID;
3623
3624        GraveYardData const* data = objmgr.FindGraveYardData(g_id,player->GetZoneId());
3625        if (!data)
3626        {
3627            PSendSysMessage(LANG_COMMAND_GRAVEYARDERROR,g_id);
3628            SetSentErrorMessage(true);
3629            return false;
3630        }
3631
3632        g_team = data->team;
3633
3634        std::string team_name = GetTrinityString(LANG_COMMAND_GRAVEYARD_NOTEAM);
3635
3636        if(g_team == 0)
3637            team_name = GetTrinityString(LANG_COMMAND_GRAVEYARD_ANY);
3638        else if(g_team == HORDE)
3639            team_name = GetTrinityString(LANG_COMMAND_GRAVEYARD_HORDE);
3640        else if(g_team == ALLIANCE)
3641            team_name = GetTrinityString(LANG_COMMAND_GRAVEYARD_ALLIANCE);
3642
3643        PSendSysMessage(LANG_COMMAND_GRAVEYARDNEAREST, g_id,team_name.c_str(),player->GetZoneId());
3644    }
3645    else
3646    {
3647        std::string team_name;
3648
3649        if(g_team == 0)
3650            team_name = GetTrinityString(LANG_COMMAND_GRAVEYARD_ANY);
3651        else if(g_team == HORDE)
3652            team_name = GetTrinityString(LANG_COMMAND_GRAVEYARD_HORDE);
3653        else if(g_team == ALLIANCE)
3654            team_name = GetTrinityString(LANG_COMMAND_GRAVEYARD_ALLIANCE);
3655
3656        if(g_team == ~uint32(0))
3657            PSendSysMessage(LANG_COMMAND_ZONENOGRAVEYARDS, player->GetZoneId());
3658        else
3659            PSendSysMessage(LANG_COMMAND_ZONENOGRAFACTION, player->GetZoneId(),team_name.c_str());
3660    }
3661
3662    return true;
3663}
3664
3665//play npc emote
3666bool ChatHandler::HandleNpcPlayEmoteCommand(const char* args)
3667{
3668    uint32 emote = atoi((char*)args);
3669
3670    Creature* target = getSelectedCreature();
3671    if(!target)
3672    {
3673        SendSysMessage(LANG_SELECT_CREATURE);
3674        SetSentErrorMessage(true);
3675        return false;
3676    }
3677
3678    target->SetUInt32Value(UNIT_NPC_EMOTESTATE,emote);
3679
3680    return true;
3681}
3682
3683bool ChatHandler::HandleNpcInfoCommand(const char* /*args*/)
3684{
3685    Creature* target = getSelectedCreature();
3686
3687    if(!target)
3688    {
3689        SendSysMessage(LANG_SELECT_CREATURE);
3690        SetSentErrorMessage(true);
3691        return false;
3692    }
3693
3694    uint32 faction = target->getFaction();
3695    uint32 npcflags = target->GetUInt32Value(UNIT_NPC_FLAGS);
3696    uint32 displayid = target->GetDisplayId();
3697    uint32 nativeid = target->GetNativeDisplayId();
3698    uint32 Entry = target->GetEntry();
3699    CreatureInfo const* cInfo = target->GetCreatureInfo();
3700
3701    int32 curRespawnDelay = target->GetRespawnTimeEx()-time(NULL);
3702    if(curRespawnDelay < 0)
3703        curRespawnDelay = 0;
3704    std::string curRespawnDelayStr = secsToTimeString(curRespawnDelay,true);
3705    std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(),true);
3706
3707    PSendSysMessage(LANG_NPCINFO_CHAR,  target->GetDBTableGUIDLow(), faction, npcflags, Entry, displayid, nativeid);
3708    PSendSysMessage(LANG_NPCINFO_LEVEL, target->getLevel());
3709    PSendSysMessage(LANG_NPCINFO_HEALTH,target->GetCreateHealth(), target->GetMaxHealth(), target->GetHealth());
3710    PSendSysMessage(LANG_NPCINFO_FLAGS, target->GetUInt32Value(UNIT_FIELD_FLAGS), target->GetUInt32Value(UNIT_DYNAMIC_FLAGS), target->getFaction());
3711    PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES, defRespawnDelayStr.c_str(),curRespawnDelayStr.c_str());
3712    PSendSysMessage(LANG_NPCINFO_LOOT,  cInfo->lootid,cInfo->pickpocketLootId,cInfo->SkinLootId);
3713    PSendSysMessage(LANG_NPCINFO_DUNGEON_ID, target->GetInstanceId());
3714    PSendSysMessage(LANG_NPCINFO_POSITION,float(target->GetPositionX()), float(target->GetPositionY()), float(target->GetPositionZ()));
3715
3716    if ((npcflags & UNIT_NPC_FLAG_VENDOR) )
3717    {
3718        SendSysMessage(LANG_NPCINFO_VENDOR);
3719    }
3720    if ((npcflags & UNIT_NPC_FLAG_TRAINER) )
3721    {
3722        SendSysMessage(LANG_NPCINFO_TRAINER);
3723    }
3724
3725    return true;
3726}
3727
3728bool ChatHandler::HandleExploreCheatCommand(const char* args)
3729{
3730    if (!*args)
3731        return false;
3732
3733    int flag = atoi((char*)args);
3734
3735    Player *chr = getSelectedPlayer();
3736    if (chr == NULL)
3737    {
3738        SendSysMessage(LANG_NO_CHAR_SELECTED);
3739        SetSentErrorMessage(true);
3740        return false;
3741    }
3742
3743    if (flag != 0)
3744    {
3745        PSendSysMessage(LANG_YOU_SET_EXPLORE_ALL, chr->GetName());
3746        if (needReportToTarget(chr))
3747            ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_ALL,GetName());
3748    }
3749    else
3750    {
3751        PSendSysMessage(LANG_YOU_SET_EXPLORE_NOTHING, chr->GetName());
3752        if (needReportToTarget(chr))
3753            ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_NOTHING,GetName());
3754    }
3755
3756    for (uint8 i=0; i<128; i++)
3757    {
3758        if (flag != 0)
3759        {
3760            m_session->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i,0xFFFFFFFF);
3761        }
3762        else
3763        {
3764            m_session->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i,0);
3765        }
3766    }
3767
3768    return true;
3769}
3770
3771bool ChatHandler::HandleHoverCommand(const char* args)
3772{
3773    char* px = strtok((char*)args, " ");
3774    uint32 flag;
3775    if (!px)
3776        flag = 1;
3777    else
3778        flag = atoi(px);
3779
3780    m_session->GetPlayer()->SetHover(flag);
3781
3782    if (flag)
3783        SendSysMessage(LANG_HOVER_ENABLED);
3784    else
3785        SendSysMessage(LANG_HOVER_DISABLED);
3786
3787    return true;
3788}
3789
3790bool ChatHandler::HandleWaterwalkCommand(const char* args)
3791{
3792    if(!args)
3793        return false;
3794
3795    Player *player = getSelectedPlayer();
3796    if(!player)
3797    {
3798        PSendSysMessage(LANG_NO_CHAR_SELECTED);
3799        SetSentErrorMessage(true);
3800        return false;
3801    }
3802
3803    if (strncmp(args, "on", 3) == 0)
3804        player->SetMovement(MOVE_WATER_WALK);               // ON
3805    else if (strncmp(args, "off", 4) == 0)
3806        player->SetMovement(MOVE_LAND_WALK);                // OFF
3807    else
3808    {
3809        SendSysMessage(LANG_USE_BOL);
3810        return false;
3811    }
3812
3813    PSendSysMessage(LANG_YOU_SET_WATERWALK, args, player->GetName());
3814    if(needReportToTarget(player))
3815        ChatHandler(player).PSendSysMessage(LANG_YOUR_WATERWALK_SET, args, GetName());
3816    return true;
3817
3818}
3819
3820bool ChatHandler::HandleLevelUpCommand(const char* args)
3821{
3822    char* px = strtok((char*)args, " ");
3823    char* py = strtok((char*)NULL, " ");
3824
3825    // command format parsing
3826    char* pname = (char*)NULL;
3827    int addlevel = 1;
3828
3829    if(px && py)                                            // .levelup name level
3830    {
3831        addlevel = atoi(py);
3832        pname = px;
3833    }
3834    else if(px && !py)                                      // .levelup name OR .levelup level
3835    {
3836        if(isalpha(px[0]))                                  // .levelup name
3837            pname = px;
3838        else                                                // .levelup level
3839            addlevel = atoi(px);
3840    }
3841    // else .levelup - nothing do for preparing
3842
3843    // player
3844    Player *chr = NULL;
3845    uint64 chr_guid = 0;
3846
3847    std::string name;
3848
3849    if(pname)                                               // player by name
3850    {
3851        name = pname;
3852        if(!normalizePlayerName(name))
3853        {
3854            SendSysMessage(LANG_PLAYER_NOT_FOUND);
3855            SetSentErrorMessage(true);
3856            return false;
3857        }
3858
3859        chr = objmgr.GetPlayer(name.c_str());
3860        if(!chr)                                            // not in game
3861        {
3862            chr_guid = objmgr.GetPlayerGUIDByName(name);
3863            if (chr_guid == 0)
3864            {
3865                SendSysMessage(LANG_PLAYER_NOT_FOUND);
3866                SetSentErrorMessage(true);
3867                return false;
3868            }
3869        }
3870    }
3871    else                                                    // player by selection
3872    {
3873        chr = getSelectedPlayer();
3874
3875        if (chr == NULL)
3876        {
3877            SendSysMessage(LANG_NO_CHAR_SELECTED);
3878            SetSentErrorMessage(true);
3879            return false;
3880        }
3881
3882        name = chr->GetName();
3883    }
3884
3885    assert(chr || chr_guid);
3886
3887    int32 oldlevel = chr ? chr->getLevel() : Player::GetUInt32ValueFromDB(UNIT_FIELD_LEVEL,chr_guid);
3888    int32 newlevel = oldlevel + addlevel;
3889    if(newlevel < 1)
3890        newlevel = 1;
3891    if(newlevel > 255)                                      // hardcoded maximum level
3892        newlevel = 255;
3893
3894    if(chr)
3895    {
3896        chr->GiveLevel(newlevel);
3897        chr->InitTalentForLevel();
3898        chr->SetUInt32Value(PLAYER_XP,0);
3899
3900        if(oldlevel == newlevel)
3901            ChatHandler(chr).SendSysMessage(LANG_YOURS_LEVEL_PROGRESS_RESET);
3902        else
3903        if(oldlevel < newlevel)
3904            ChatHandler(chr).PSendSysMessage(LANG_YOURS_LEVEL_UP,newlevel-oldlevel);
3905        else
3906        if(oldlevel > newlevel)
3907            ChatHandler(chr).PSendSysMessage(LANG_YOURS_LEVEL_DOWN,newlevel-oldlevel);
3908    }
3909    else
3910    {
3911        // update level and XP at level, all other will be updated at loading
3912        Tokens values;
3913        Player::LoadValuesArrayFromDB(values,chr_guid);
3914        Player::SetUInt32ValueInArray(values,UNIT_FIELD_LEVEL,newlevel);
3915        Player::SetUInt32ValueInArray(values,PLAYER_XP,0);
3916        Player::SaveValuesArrayInDB(values,chr_guid);
3917    }
3918
3919    if(m_session->GetPlayer() != chr)                       // including chr==NULL
3920        PSendSysMessage(LANG_YOU_CHANGE_LVL,name.c_str(),newlevel);
3921    return true;
3922}
3923
3924bool ChatHandler::HandleShowAreaCommand(const char* args)
3925{
3926    if (!*args)
3927        return false;
3928
3929    int area = atoi((char*)args);
3930
3931    Player *chr = getSelectedPlayer();
3932    if (chr == NULL)
3933    {
3934        SendSysMessage(LANG_NO_CHAR_SELECTED);
3935        SetSentErrorMessage(true);
3936        return false;
3937    }
3938
3939    int offset = area / 32;
3940    uint32 val = (uint32)(1 << (area % 32));
3941
3942    if(offset >= 128)
3943    {
3944        SendSysMessage(LANG_BAD_VALUE);
3945        SetSentErrorMessage(true);
3946        return false;
3947    }
3948
3949    uint32 currFields = chr->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset);
3950    chr->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields | val));
3951
3952    SendSysMessage(LANG_EXPLORE_AREA);
3953    return true;
3954}
3955
3956bool ChatHandler::HandleHideAreaCommand(const char* args)
3957{
3958    if (!*args)
3959        return false;
3960
3961    int area = atoi((char*)args);
3962
3963    Player *chr = getSelectedPlayer();
3964    if (chr == NULL)
3965    {
3966        SendSysMessage(LANG_NO_CHAR_SELECTED);
3967        SetSentErrorMessage(true);
3968        return false;
3969    }
3970
3971    int offset = area / 32;
3972    uint32 val = (uint32)(1 << (area % 32));
3973
3974    if(offset >= 128)
3975    {
3976        SendSysMessage(LANG_BAD_VALUE);
3977        SetSentErrorMessage(true);
3978        return false;
3979    }
3980
3981    uint32 currFields = chr->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset);
3982    chr->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields ^ val));
3983
3984    SendSysMessage(LANG_UNEXPLORE_AREA);
3985    return true;
3986}
3987
3988bool ChatHandler::HandleUpdate(const char* args)
3989{
3990    if(!*args)
3991        return false;
3992
3993    uint32 updateIndex;
3994    uint32 value;
3995
3996    char* pUpdateIndex = strtok((char*)args, " ");
3997
3998    Unit* chr = getSelectedUnit();
3999    if (chr == NULL)
4000    {
4001        SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
4002        SetSentErrorMessage(true);
4003        return false;
4004    }
4005
4006    if(!pUpdateIndex)
4007    {
4008        return true;
4009    }
4010    updateIndex = atoi(pUpdateIndex);
4011    //check updateIndex
4012    if(chr->GetTypeId() == TYPEID_PLAYER)
4013    {
4014        if (updateIndex>=PLAYER_END) return true;
4015    }
4016    else
4017    {
4018        if (updateIndex>=UNIT_END) return true;
4019    }
4020
4021    char*  pvalue = strtok(NULL, " ");
4022    if (!pvalue)
4023    {
4024        value=chr->GetUInt32Value(updateIndex);
4025
4026        PSendSysMessage(LANG_UPDATE, chr->GetGUIDLow(),updateIndex,value);
4027        return true;
4028    }
4029
4030    value=atoi(pvalue);
4031
4032    PSendSysMessage(LANG_UPDATE_CHANGE, chr->GetGUIDLow(),updateIndex,value);
4033
4034    chr->SetUInt32Value(updateIndex,value);
4035
4036    return true;
4037}
4038
4039bool ChatHandler::HandleBankCommand(const char* /*args*/)
4040{
4041    m_session->SendShowBank( m_session->GetPlayer()->GetGUID() );
4042
4043    return true;
4044}
4045
4046bool ChatHandler::HandleChangeWeather(const char* args)
4047{
4048    if(!*args)
4049        return false;
4050
4051    //Weather is OFF
4052    if (!sWorld.getConfig(CONFIG_WEATHER))
4053    {
4054        SendSysMessage(LANG_WEATHER_DISABLED);
4055        SetSentErrorMessage(true);
4056        return false;
4057    }
4058
4059    //*Change the weather of a cell
4060    char* px = strtok((char*)args, " ");
4061    char* py = strtok(NULL, " ");
4062
4063    if (!px || !py)
4064        return false;
4065
4066    uint32 type = (uint32)atoi(px);                         //0 to 3, 0: fine, 1: rain, 2: snow, 3: sand
4067    float grade = (float)atof(py);                          //0 to 1, sending -1 is instand good weather
4068
4069    Player *player = m_session->GetPlayer();
4070    uint32 zoneid = player->GetZoneId();
4071
4072    Weather* wth = sWorld.FindWeather(zoneid);
4073
4074    if(!wth)
4075        wth = sWorld.AddWeather(zoneid);
4076    if(!wth)
4077    {
4078        SendSysMessage(LANG_NO_WEATHER);
4079        SetSentErrorMessage(true);
4080        return false;
4081    }
4082
4083    wth->SetWeather(WeatherType(type), grade);
4084
4085    return true;
4086}
4087
4088bool ChatHandler::HandleSetValue(const char* args)
4089{
4090    if(!*args)
4091        return false;
4092
4093    char* px = strtok((char*)args, " ");
4094    char* py = strtok(NULL, " ");
4095    char* pz = strtok(NULL, " ");
4096
4097    if (!px || !py)
4098        return false;
4099
4100    Unit* target = getSelectedUnit();
4101    if(!target)
4102    {
4103        SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
4104        SetSentErrorMessage(true);
4105        return false;
4106    }
4107
4108    uint64 guid = target->GetGUID();
4109
4110    uint32 Opcode = (uint32)atoi(px);
4111    if(Opcode >= target->GetValuesCount())
4112    {
4113        PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, GUID_LOPART(guid), target->GetValuesCount());
4114        return false;
4115    }
4116    uint32 iValue;
4117    float fValue;
4118    bool isint32 = true;
4119    if(pz)
4120        isint32 = (bool)atoi(pz);
4121    if(isint32)
4122    {
4123        iValue = (uint32)atoi(py);
4124        sLog.outDebug(GetTrinityString(LANG_SET_UINT), GUID_LOPART(guid), Opcode, iValue);
4125        target->SetUInt32Value( Opcode , iValue );
4126        PSendSysMessage(LANG_SET_UINT_FIELD, GUID_LOPART(guid), Opcode,iValue);
4127    }
4128    else
4129    {
4130        fValue = (float)atof(py);
4131        sLog.outDebug(GetTrinityString(LANG_SET_FLOAT), GUID_LOPART(guid), Opcode, fValue);
4132        target->SetFloatValue( Opcode , fValue );
4133        PSendSysMessage(LANG_SET_FLOAT_FIELD, GUID_LOPART(guid), Opcode,fValue);
4134    }
4135
4136    return true;
4137}
4138
4139bool ChatHandler::HandleGetValue(const char* args)
4140{
4141    if(!*args)
4142        return false;
4143
4144    char* px = strtok((char*)args, " ");
4145    char* pz = strtok(NULL, " ");
4146
4147    if (!px)
4148        return false;
4149
4150    Unit* target = getSelectedUnit();
4151    if(!target)
4152    {
4153        SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
4154        SetSentErrorMessage(true);
4155        return false;
4156    }
4157
4158    uint64 guid = target->GetGUID();
4159
4160    uint32 Opcode = (uint32)atoi(px);
4161    if(Opcode >= target->GetValuesCount())
4162    {
4163        PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, GUID_LOPART(guid), target->GetValuesCount());
4164        return false;
4165    }
4166    uint32 iValue;
4167    float fValue;
4168    bool isint32 = true;
4169    if(pz)
4170        isint32 = (bool)atoi(pz);
4171
4172    if(isint32)
4173    {
4174        iValue = target->GetUInt32Value( Opcode );
4175        sLog.outDebug(GetTrinityString(LANG_GET_UINT), GUID_LOPART(guid), Opcode, iValue);
4176        PSendSysMessage(LANG_GET_UINT_FIELD, GUID_LOPART(guid), Opcode,    iValue);
4177    }
4178    else
4179    {
4180        fValue = target->GetFloatValue( Opcode );
4181        sLog.outDebug(GetTrinityString(LANG_GET_FLOAT), GUID_LOPART(guid), Opcode, fValue);
4182        PSendSysMessage(LANG_GET_FLOAT_FIELD, GUID_LOPART(guid), Opcode, fValue);
4183    }
4184
4185    return true;
4186}
4187
4188bool ChatHandler::HandleSet32Bit(const char* args)
4189{
4190    if(!*args)
4191        return false;
4192
4193    char* px = strtok((char*)args, " ");
4194    char* py = strtok(NULL, " ");
4195
4196    if (!px || !py)
4197        return false;
4198
4199    uint32 Opcode = (uint32)atoi(px);
4200    uint32 Value = (uint32)atoi(py);
4201    if (Value > 32)                                         //uint32 = 32 bits
4202        return false;
4203
4204    sLog.outDebug(GetTrinityString(LANG_SET_32BIT), Opcode, Value);
4205
4206    m_session->GetPlayer( )->SetUInt32Value( Opcode , 2^Value );
4207
4208    PSendSysMessage(LANG_SET_32BIT_FIELD, Opcode,1);
4209    return true;
4210}
4211
4212bool ChatHandler::HandleMod32Value(const char* args)
4213{
4214    if(!*args)
4215        return false;
4216
4217    char* px = strtok((char*)args, " ");
4218    char* py = strtok(NULL, " ");
4219
4220    if (!px || !py)
4221        return false;
4222
4223    uint32 Opcode = (uint32)atoi(px);
4224    int Value = atoi(py);
4225
4226    if(Opcode >= m_session->GetPlayer()->GetValuesCount())
4227    {
4228        PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, m_session->GetPlayer()->GetGUIDLow(), m_session->GetPlayer( )->GetValuesCount());
4229        return false;
4230    }
4231
4232    sLog.outDebug(GetTrinityString(LANG_CHANGE_32BIT), Opcode, Value);
4233
4234    int CurrentValue = (int)m_session->GetPlayer( )->GetUInt32Value( Opcode );
4235
4236    CurrentValue += Value;
4237    m_session->GetPlayer( )->SetUInt32Value( Opcode , (uint32)CurrentValue );
4238
4239    PSendSysMessage(LANG_CHANGE_32BIT_FIELD, Opcode,CurrentValue);
4240
4241    return true;
4242}
4243
4244bool ChatHandler::HandleAddTeleCommand(const char * args)
4245{
4246    if(!*args)
4247        return false;
4248
4249    Player *player=m_session->GetPlayer();
4250    if (!player)
4251        return false;
4252
4253    std::string name = args;
4254
4255    if(objmgr.GetGameTele(name))
4256    {
4257        SendSysMessage(LANG_COMMAND_TP_ALREADYEXIST);
4258        SetSentErrorMessage(true);
4259        return false;
4260    }
4261
4262    GameTele tele;
4263    tele.position_x  = player->GetPositionX();
4264    tele.position_y  = player->GetPositionY();
4265    tele.position_z  = player->GetPositionZ();
4266    tele.orientation = player->GetOrientation();
4267    tele.mapId       = player->GetMapId();
4268    tele.name        = name;
4269
4270    if(objmgr.AddGameTele(tele))
4271    {
4272        SendSysMessage(LANG_COMMAND_TP_ADDED);
4273    }
4274    else
4275    {
4276        SendSysMessage(LANG_COMMAND_TP_ADDEDERR);
4277        SetSentErrorMessage(true);
4278        return false;
4279    }
4280
4281    return true;
4282}
4283
4284bool ChatHandler::HandleDelTeleCommand(const char * args)
4285{
4286    if(!*args)
4287        return false;
4288
4289    std::string name = args;
4290
4291    if(!objmgr.DeleteGameTele(name))
4292    {
4293        SendSysMessage(LANG_COMMAND_TELE_NOTFOUND);
4294        SetSentErrorMessage(true);
4295        return false;
4296    }
4297
4298    SendSysMessage(LANG_COMMAND_TP_DELETED);
4299    return true;
4300}
4301
4302bool ChatHandler::HandleListAurasCommand (const char * /*args*/)
4303{
4304    Unit *unit = getSelectedUnit();
4305    if(!unit)
4306    {
4307        SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
4308        SetSentErrorMessage(true);
4309        return false;
4310    }
4311
4312    char const* talentStr = GetTrinityString(LANG_TALENT);
4313    char const* passiveStr = GetTrinityString(LANG_PASSIVE);
4314
4315    Unit::AuraMap const& uAuras = unit->GetAuras();
4316    PSendSysMessage(LANG_COMMAND_TARGET_LISTAURAS, uAuras.size());
4317    for (Unit::AuraMap::const_iterator itr = uAuras.begin(); itr != uAuras.end(); ++itr)
4318    {
4319        bool talent = GetTalentSpellCost(itr->second->GetId()) > 0;
4320        PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffIndex(),
4321            itr->second->GetModifier()->m_auraname, itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(),
4322            itr->second->GetSpellProto()->SpellName[m_session->GetSessionDbcLocale()],
4323            (itr->second->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
4324            IS_PLAYER_GUID(itr->second->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(itr->second->GetCasterGUID()));
4325    }
4326    for (int i = 0; i < TOTAL_AURAS; i++)
4327    {
4328        Unit::AuraList const& uAuraList = unit->GetAurasByType(AuraType(i));
4329        if (uAuraList.empty()) continue;
4330        PSendSysMessage(LANG_COMMAND_TARGET_LISTAURATYPE, uAuraList.size(), i);
4331        for (Unit::AuraList::const_iterator itr = uAuraList.begin(); itr != uAuraList.end(); ++itr)
4332        {
4333            bool talent = GetTalentSpellCost((*itr)->GetId()) > 0;
4334            PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(),
4335                (*itr)->GetSpellProto()->SpellName[m_session->GetSessionDbcLocale()],((*itr)->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
4336                IS_PLAYER_GUID((*itr)->GetCasterGUID()) ? "player" : "creature",GUID_LOPART((*itr)->GetCasterGUID()));
4337        }
4338    }
4339    return true;
4340}
4341
4342bool ChatHandler::HandleResetHonorCommand (const char * args)
4343{
4344    char* pName = strtok((char*)args, "");
4345    Player *player = NULL;
4346    if (pName)
4347    {
4348        std::string name = pName;
4349        if(!normalizePlayerName(name))
4350        {
4351            SendSysMessage(LANG_PLAYER_NOT_FOUND);
4352            SetSentErrorMessage(true);
4353            return false;
4354        }
4355
4356        uint64 guid = objmgr.GetPlayerGUIDByName(name.c_str());
4357        player = objmgr.GetPlayer(guid);
4358    }
4359    else
4360        player = getSelectedPlayer();
4361
4362    if(!player)
4363    {
4364        SendSysMessage(LANG_NO_CHAR_SELECTED);
4365        return true;
4366    }
4367
4368    player->SetUInt32Value(PLAYER_FIELD_KILLS, 0);
4369    player->SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORBALE_KILLS, 0);
4370    player->SetUInt32Value(PLAYER_FIELD_HONOR_CURRENCY, 0);
4371    player->SetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, 0);
4372    player->SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, 0);
4373
4374    return true;
4375}
4376
4377static bool HandleResetStatsOrLevelHelper(Player* player)
4378{
4379    PlayerInfo const *info = objmgr.GetPlayerInfo(player->getRace(), player->getClass());
4380    if(!info) return false;
4381
4382    ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(player->getClass());
4383    if(!cEntry)
4384    {
4385        sLog.outError("Class %u not found in DBC (Wrong DBC files?)",player->getClass());
4386        return false;
4387    }
4388
4389    uint8 powertype = cEntry->powerType;
4390
4391    uint32 unitfield;
4392    if(powertype == POWER_RAGE)
4393        unitfield = 0x1100EE00;
4394    else if(powertype == POWER_ENERGY)
4395        unitfield = 0x00000000;
4396    else if(powertype == POWER_MANA)
4397        unitfield = 0x0000EE00;
4398    else
4399    {
4400        sLog.outError("Invalid default powertype %u for player (class %u)",powertype,player->getClass());
4401        return false;
4402    }
4403
4404    // reset m_form if no aura
4405    if(!player->HasAuraType(SPELL_AURA_MOD_SHAPESHIFT))
4406        player->m_form = FORM_NONE;
4407
4408    player->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE );
4409    player->SetFloatValue(UNIT_FIELD_COMBATREACH, 1.5f   );
4410
4411    player->setFactionForRace(player->getRace());
4412
4413    player->SetUInt32Value(UNIT_FIELD_BYTES_0, ( ( player->getRace() ) | ( player->getClass() << 8 ) | ( player->getGender() << 16 ) | ( powertype << 24 ) ) );
4414
4415    // reset only if player not in some form;
4416    if(player->m_form==FORM_NONE)
4417    {
4418        switch(player->getGender())
4419        {
4420            case GENDER_FEMALE:
4421                player->SetDisplayId(info->displayId_f);
4422                player->SetNativeDisplayId(info->displayId_f);
4423                break;
4424            case GENDER_MALE:
4425                player->SetDisplayId(info->displayId_m);
4426                player->SetNativeDisplayId(info->displayId_m);
4427                break;
4428            default:
4429                break;
4430        }
4431    }
4432
4433    // set UNIT_FIELD_BYTES_1 to init state but preserve m_form value
4434    player->SetUInt32Value(UNIT_FIELD_BYTES_1, unitfield);
4435    player->SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_UNK3 | UNIT_BYTE2_FLAG_UNK5 );
4436    player->SetByteValue(UNIT_FIELD_BYTES_2, 3, player->m_form);
4437
4438    player->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
4439
4440    //-1 is default value
4441    player->SetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, uint32(-1));
4442
4443    //player->SetUInt32Value(PLAYER_FIELD_BYTES, 0xEEE00000 );
4444    return true;
4445}
4446
4447bool ChatHandler::HandleResetLevelCommand(const char * args)
4448{
4449    char* pName = strtok((char*)args, "");
4450    Player *player = NULL;
4451    if (pName)
4452    {
4453        std::string name = pName;
4454        if(!normalizePlayerName(name))
4455        {
4456            SendSysMessage(LANG_PLAYER_NOT_FOUND);
4457            SetSentErrorMessage(true);
4458            return false;
4459        }
4460
4461        uint64 guid = objmgr.GetPlayerGUIDByName(name.c_str());
4462        player = objmgr.GetPlayer(guid);
4463    }
4464    else
4465        player = getSelectedPlayer();
4466
4467    if(!player)
4468    {
4469        SendSysMessage(LANG_NO_CHAR_SELECTED);
4470        SetSentErrorMessage(true);
4471        return false;
4472    }
4473
4474    if(!HandleResetStatsOrLevelHelper(player))
4475        return false;
4476
4477    player->SetLevel(1);
4478    player->InitStatsForLevel(true);
4479    player->InitTaxiNodesForLevel();
4480    player->InitTalentForLevel();
4481    player->SetUInt32Value(PLAYER_XP,0);
4482
4483    // reset level to summoned pet
4484    Pet* pet = player->GetPet();
4485    if(pet && pet->getPetType()==SUMMON_PET)
4486        pet->InitStatsForLevel(1);
4487
4488    return true;
4489}
4490
4491bool ChatHandler::HandleResetStatsCommand(const char * args)
4492{
4493    char* pName = strtok((char*)args, "");
4494    Player *player = NULL;
4495    if (pName)
4496    {
4497        std::string name = pName;
4498        if(!normalizePlayerName(name))
4499        {
4500            SendSysMessage(LANG_PLAYER_NOT_FOUND);
4501            SetSentErrorMessage(true);
4502            return false;
4503        }
4504
4505        uint64 guid = objmgr.GetPlayerGUIDByName(name.c_str());
4506        player = objmgr.GetPlayer(guid);
4507    }
4508    else
4509        player = getSelectedPlayer();
4510
4511    if(!player)
4512    {
4513        SendSysMessage(LANG_NO_CHAR_SELECTED);
4514        SetSentErrorMessage(true);
4515        return false;
4516    }
4517
4518    if(!HandleResetStatsOrLevelHelper(player))
4519        return false;
4520
4521    player->InitStatsForLevel(true);
4522    player->InitTaxiNodesForLevel();
4523    player->InitTalentForLevel();
4524
4525    return true;
4526}
4527
4528bool ChatHandler::HandleResetSpellsCommand(const char * args)
4529{
4530    char* pName = strtok((char*)args, "");
4531    Player *player = NULL;
4532    uint64 playerGUID = 0;
4533    if (pName)
4534    {
4535        std::string name = pName;
4536
4537        if(!normalizePlayerName(name))
4538        {
4539            SendSysMessage(LANG_PLAYER_NOT_FOUND);
4540            SetSentErrorMessage(true);
4541            return false;
4542        }
4543
4544        player = objmgr.GetPlayer(name.c_str());
4545        if(!player)
4546            playerGUID = objmgr.GetPlayerGUIDByName(name.c_str());
4547    }
4548    else
4549        player = getSelectedPlayer();
4550
4551    if(!player && !playerGUID)
4552    {
4553        SendSysMessage(LANG_NO_CHAR_SELECTED);
4554        SetSentErrorMessage(true);
4555        return false;
4556    }
4557
4558    if(player)
4559    {
4560        player->resetSpells();
4561
4562        ChatHandler(player).SendSysMessage(LANG_RESET_SPELLS);
4563
4564        if(m_session->GetPlayer()!=player)
4565            PSendSysMessage(LANG_RESET_SPELLS_ONLINE,player->GetName());
4566    }
4567    else
4568    {
4569        CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",uint32(AT_LOGIN_RESET_SPELLS), GUID_LOPART(playerGUID));
4570        PSendSysMessage(LANG_RESET_SPELLS_OFFLINE,pName);
4571    }
4572
4573    return true;
4574}
4575
4576bool ChatHandler::HandleResetTalentsCommand(const char * args)
4577{
4578    char* pName = strtok((char*)args, "");
4579    Player *player = NULL;
4580    uint64 playerGUID = 0;
4581    if (pName)
4582    {
4583        std::string name = pName;
4584        if(!normalizePlayerName(name))
4585        {
4586            SendSysMessage(LANG_PLAYER_NOT_FOUND);
4587            SetSentErrorMessage(true);
4588            return false;
4589        }
4590
4591        player = objmgr.GetPlayer(name.c_str());
4592        if(!player)
4593            playerGUID = objmgr.GetPlayerGUIDByName(name.c_str());
4594    }
4595    else
4596        player = getSelectedPlayer();
4597
4598    if(!player && !playerGUID)
4599    {
4600        SendSysMessage(LANG_NO_CHAR_SELECTED);
4601        SetSentErrorMessage(true);
4602        return false;
4603    }
4604
4605    if(player)
4606    {
4607        player->resetTalents(true);
4608
4609        ChatHandler(player).SendSysMessage(LANG_RESET_TALENTS);
4610
4611        if(m_session->GetPlayer()!=player)
4612            PSendSysMessage(LANG_RESET_TALENTS_ONLINE,player->GetName());
4613    }
4614    else
4615    {
4616        CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",uint32(AT_LOGIN_RESET_TALENTS), GUID_LOPART(playerGUID) );
4617        PSendSysMessage(LANG_RESET_TALENTS_OFFLINE,pName);
4618    }
4619
4620    return true;
4621}
4622
4623bool ChatHandler::HandleResetAllCommand(const char * args)
4624{
4625    if(!*args)
4626        return false;
4627
4628    std::string casename = args;
4629
4630    AtLoginFlags atLogin;
4631
4632    // Command specially created as single command to prevent using short case names
4633    if(casename=="spells")
4634    {
4635        atLogin = AT_LOGIN_RESET_SPELLS;
4636        sWorld.SendWorldText(LANG_RESETALL_SPELLS);
4637    }
4638    else if(casename=="talents")
4639    {
4640        atLogin = AT_LOGIN_RESET_TALENTS;
4641        sWorld.SendWorldText(LANG_RESETALL_TALENTS);
4642    }
4643    else
4644    {
4645        PSendSysMessage(LANG_RESETALL_UNKNOWN_CASE,args);
4646        SetSentErrorMessage(true);
4647        return false;
4648    }
4649
4650    CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u'",atLogin);
4651    HashMapHolder<Player>::MapType const& plist = ObjectAccessor::Instance().GetPlayers();
4652    for(HashMapHolder<Player>::MapType::const_iterator itr = plist.begin(); itr != plist.end(); ++itr)
4653        itr->second->SetAtLoginFlag(atLogin);
4654
4655    return true;
4656}
4657
4658bool ChatHandler::HandleServerShutDownCancelCommand(const char* args)
4659{
4660    sWorld.ShutdownCancel();
4661    return true;
4662}
4663
4664bool ChatHandler::HandleServerShutDownCommand(const char* args)
4665{
4666    if(!*args)
4667        return false;
4668
4669    char* time_str = strtok ((char*) args, " ");
4670    char* exitcode_str = strtok (NULL, "");
4671
4672    int32 time = atoi (time_str);
4673
4674    ///- Prevent interpret wrong arg value as 0 secs shutdown time
4675    if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0)
4676        return false;
4677
4678    if (exitcode_str)
4679    {
4680        int32 exitcode = atoi (exitcode_str);
4681
4682        // Handle atoi() errors
4683        if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4684            return false;
4685
4686        // Exit code should be in range of 0-125, 126-255 is used
4687        // in many shells for their own return codes and code > 255
4688        // is not supported in many others
4689        if (exitcode < 0 || exitcode > 125)
4690            return false;
4691
4692        sWorld.ShutdownServ (time, 0, exitcode);
4693    }
4694    else
4695        sWorld.ShutdownServ(time,0,SHUTDOWN_EXIT_CODE);
4696    return true;
4697}
4698
4699bool ChatHandler::HandleServerRestartCommand(const char* args)
4700{
4701    if(!*args)
4702        return false;
4703
4704    char* time_str = strtok ((char*) args, " ");
4705    char* exitcode_str = strtok (NULL, "");
4706
4707    int32 time = atoi (time_str);
4708
4709    ///- Prevent interpret wrong arg value as 0 secs shutdown time
4710    if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0)
4711        return false;
4712
4713    if (exitcode_str)
4714    {
4715        int32 exitcode = atoi (exitcode_str);
4716
4717        // Handle atoi() errors
4718        if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4719            return false;
4720
4721        // Exit code should be in range of 0-125, 126-255 is used
4722        // in many shells for their own return codes and code > 255
4723        // is not supported in many others
4724        if (exitcode < 0 || exitcode > 125)
4725            return false;
4726
4727        sWorld.ShutdownServ (time, SHUTDOWN_MASK_RESTART, exitcode);
4728    }
4729    else
4730        sWorld.ShutdownServ(time, SHUTDOWN_MASK_RESTART, RESTART_EXIT_CODE);
4731    return true;
4732}
4733
4734bool ChatHandler::HandleServerIdleRestartCommand(const char* args)
4735{
4736    if(!*args)
4737        return false;
4738
4739    char* time_str = strtok ((char*) args, " ");
4740    char* exitcode_str = strtok (NULL, "");
4741
4742    int32 time = atoi (time_str);
4743
4744    ///- Prevent interpret wrong arg value as 0 secs shutdown time
4745    if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0)
4746        return false;
4747
4748    if (exitcode_str)
4749    {
4750        int32 exitcode = atoi (exitcode_str);
4751
4752        // Handle atoi() errors
4753        if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4754            return false;
4755
4756        // Exit code should be in range of 0-125, 126-255 is used
4757        // in many shells for their own return codes and code > 255
4758        // is not supported in many others
4759        if (exitcode < 0 || exitcode > 125)
4760            return false;
4761
4762        sWorld.ShutdownServ (time, SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE, exitcode);
4763    }
4764    else
4765        sWorld.ShutdownServ(time,SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE,RESTART_EXIT_CODE);
4766    return true;
4767}
4768
4769bool ChatHandler::HandleServerIdleShutDownCommand(const char* args)
4770{
4771    if(!*args)
4772        return false;
4773
4774    char* time_str = strtok ((char*) args, " ");
4775    char* exitcode_str = strtok (NULL, "");
4776
4777    int32 time = atoi (time_str);
4778
4779    ///- Prevent interpret wrong arg value as 0 secs shutdown time
4780    if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0)
4781        return false;
4782
4783    if (exitcode_str)
4784    {
4785        int32 exitcode = atoi (exitcode_str);
4786
4787        // Handle atoi() errors
4788        if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
4789            return false;
4790
4791        // Exit code should be in range of 0-125, 126-255 is used
4792        // in many shells for their own return codes and code > 255
4793        // is not supported in many others
4794        if (exitcode < 0 || exitcode > 125)
4795            return false;
4796
4797        sWorld.ShutdownServ (time, SHUTDOWN_MASK_IDLE, exitcode);
4798    }
4799    else
4800        sWorld.ShutdownServ(time,SHUTDOWN_MASK_IDLE,SHUTDOWN_EXIT_CODE);
4801    return true;
4802}
4803
4804bool ChatHandler::HandleAddQuest(const char* args)
4805{
4806    Player* player = getSelectedPlayer();
4807    if(!player)
4808    {
4809        SendSysMessage(LANG_NO_CHAR_SELECTED);
4810        SetSentErrorMessage(true);
4811        return false;
4812    }
4813
4814    // .addquest #entry'
4815    // number or [name] Shift-click form |color|Hquest:quest_id|h[name]|h|r
4816    char* cId = extractKeyFromLink((char*)args,"Hquest");
4817    if(!cId)
4818        return false;
4819
4820    uint32 entry = atol(cId);
4821
4822    Quest const* pQuest = objmgr.GetQuestTemplate(entry);
4823
4824    if(!pQuest)
4825    {
4826        PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND,entry);
4827        SetSentErrorMessage(true);
4828        return false;
4829    }
4830
4831    // check item starting quest (it can work incorrectly if added without item in inventory)
4832    for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
4833    {
4834        ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype>(id);
4835        if (!pProto)
4836            continue;
4837
4838        if (pProto->StartQuest == entry)
4839        {
4840            PSendSysMessage(LANG_COMMAND_QUEST_STARTFROMITEM, entry, pProto->ItemId);
4841            SetSentErrorMessage(true);
4842            return false;
4843        }
4844    }
4845
4846    // ok, normal (creature/GO starting) quest
4847    if( player->CanAddQuest( pQuest, true ) )
4848    {
4849        player->AddQuest( pQuest, NULL );
4850
4851        if ( player->CanCompleteQuest( entry ) )
4852            player->CompleteQuest( entry );
4853    }
4854
4855    return true;
4856}
4857
4858bool ChatHandler::HandleRemoveQuest(const char* args)
4859{
4860    Player* player = getSelectedPlayer();
4861    if(!player)
4862    {
4863        SendSysMessage(LANG_NO_CHAR_SELECTED);
4864        SetSentErrorMessage(true);
4865        return false;
4866    }
4867
4868    // .removequest #entry'
4869    // number or [name] Shift-click form |color|Hquest:quest_id|h[name]|h|r
4870    char* cId = extractKeyFromLink((char*)args,"Hquest");
4871    if(!cId)
4872        return false;
4873
4874    uint32 entry = atol(cId);
4875
4876    Quest const* pQuest = objmgr.GetQuestTemplate(entry);
4877
4878    if(!pQuest)
4879    {
4880        PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry);
4881        SetSentErrorMessage(true);
4882        return false;
4883    }
4884
4885    // remove all quest entries for 'entry' from quest log
4886    for(uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot )
4887    {
4888        uint32 quest = player->GetQuestSlotQuestId(slot);
4889        if(quest==entry)
4890        {
4891            player->SetQuestSlot(slot,0);
4892
4893            // we ignore unequippable quest items in this case, its' still be equipped
4894            player->TakeQuestSourceItem( quest, false );
4895        }
4896    }
4897
4898    // set quest status to not started (will updated in DB at next save)
4899    player->SetQuestStatus( entry, QUEST_STATUS_NONE);
4900
4901    // reset rewarded for restart repeatable quest
4902    player->getQuestStatusMap()[entry].m_rewarded = false;
4903
4904    SendSysMessage(LANG_COMMAND_QUEST_REMOVED);
4905    return true;
4906}
4907
4908bool ChatHandler::HandleCompleteQuest(const char* args)
4909{
4910    Player* player = getSelectedPlayer();
4911    if(!player)
4912    {
4913        SendSysMessage(LANG_NO_CHAR_SELECTED);
4914        SetSentErrorMessage(true);
4915        return false;
4916    }
4917
4918    // .quest complete #entry
4919    // number or [name] Shift-click form |color|Hquest:quest_id|h[name]|h|r
4920    char* cId = extractKeyFromLink((char*)args,"Hquest");
4921    if(!cId)
4922        return false;
4923
4924    uint32 entry = atol(cId);
4925
4926    Quest const* pQuest = objmgr.GetQuestTemplate(entry);
4927
4928    // If player doesn't have the quest
4929    if(!pQuest || player->GetQuestStatus(entry) == QUEST_STATUS_NONE)
4930    {
4931        PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry);
4932        SetSentErrorMessage(true);
4933        return false;
4934    }
4935
4936    // Add quest items for quests that require items
4937    for(uint8 x = 0; x < QUEST_OBJECTIVES_COUNT; ++x)
4938    {
4939        uint32 id = pQuest->ReqItemId[x];
4940        uint32 count = pQuest->ReqItemCount[x];
4941        if(!id || !count)
4942            continue;
4943
4944        uint32 curItemCount = player->GetItemCount(id,true);
4945
4946        ItemPosCountVec dest;
4947        uint8 msg = player->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, id, count-curItemCount );
4948        if( msg == EQUIP_ERR_OK )
4949        {
4950            Item* item = player->StoreNewItem( dest, id, true);
4951            player->SendNewItem(item,count-curItemCount,true,false);
4952        }
4953    }
4954
4955    // All creature/GO slain/casted (not required, but otherwise it will display "Creature slain 0/10")
4956    for(uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; i++)
4957    {
4958        uint32 creature = pQuest->ReqCreatureOrGOId[i];
4959        uint32 creaturecount = pQuest->ReqCreatureOrGOCount[i];
4960
4961        if(uint32 spell_id = pQuest->ReqSpell[i])
4962        {
4963            for(uint16 z = 0; z < creaturecount; ++z)
4964                player->CastedCreatureOrGO(creature,0,spell_id);
4965        }
4966        else if(creature > 0)
4967        {
4968            for(uint16 z = 0; z < creaturecount; ++z)
4969                player->KilledMonster(creature,0);
4970        }
4971        else if(creature < 0)
4972        {
4973            for(uint16 z = 0; z < creaturecount; ++z)
4974                player->CastedCreatureOrGO(creature,0,0);
4975        }
4976    }
4977
4978    // If the quest requires reputation to complete
4979    if(uint32 repFaction = pQuest->GetRepObjectiveFaction())
4980    {
4981        uint32 repValue = pQuest->GetRepObjectiveValue();
4982        uint32 curRep = player->GetReputation(repFaction);
4983        if(curRep < repValue)
4984        {
4985            FactionEntry const *factionEntry = sFactionStore.LookupEntry(repFaction);
4986            player->SetFactionReputation(factionEntry,repValue);
4987        }
4988    }
4989
4990    // If the quest requires money
4991    int32 ReqOrRewMoney = pQuest->GetRewOrReqMoney();
4992    if(ReqOrRewMoney < 0)
4993        player->ModifyMoney(-ReqOrRewMoney);
4994
4995    player->CompleteQuest(entry);
4996    return true;
4997}
4998
4999bool ChatHandler::HandleBanAccountCommand(const char* args)
5000{
5001    return HandleBanHelper(BAN_ACCOUNT,args);
5002}
5003
5004bool ChatHandler::HandleBanCharacterCommand(const char* args)
5005{
5006    return HandleBanHelper(BAN_CHARACTER,args);
5007}
5008
5009bool ChatHandler::HandleBanIPCommand(const char* args)
5010{
5011    return HandleBanHelper(BAN_IP,args);
5012}
5013
5014bool ChatHandler::HandleBanHelper(BanMode mode, const char* args)
5015{
5016    if(!args)
5017        return false;
5018
5019    char* cnameOrIP = strtok ((char*)args, " ");
5020    if (!cnameOrIP)
5021        return false;
5022
5023    std::string nameOrIP = cnameOrIP;
5024
5025    char* duration = strtok (NULL," ");
5026    if(!duration || !atoi(duration))
5027        return false;
5028
5029    char* reason = strtok (NULL,"");
5030    if(!reason)
5031        return false;
5032
5033    switch(mode)
5034    {
5035        case BAN_ACCOUNT:
5036            if(!AccountMgr::normilizeString(nameOrIP))
5037            {
5038                PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,nameOrIP.c_str());
5039                SetSentErrorMessage(true);
5040                return false;
5041            }
5042            break;
5043        case BAN_CHARACTER:
5044            if(!normalizePlayerName(nameOrIP))
5045            {
5046                SendSysMessage(LANG_PLAYER_NOT_FOUND);
5047                SetSentErrorMessage(true);
5048                return false;
5049            }
5050            break;
5051        case BAN_IP:
5052            if(!IsIPAddress(nameOrIP.c_str()))
5053                return false;
5054            break;
5055    }
5056
5057    switch(sWorld.BanAccount(mode, nameOrIP, duration, reason,m_session ? m_session->GetPlayerName() : ""))
5058    {
5059        case BAN_SUCCESS:
5060            if(atoi(duration)>0)
5061                PSendSysMessage(LANG_BAN_YOUBANNED,nameOrIP.c_str(),secsToTimeString(TimeStringToSecs(duration),true).c_str(),reason);
5062            else
5063                PSendSysMessage(LANG_BAN_YOUPERMBANNED,nameOrIP.c_str(),reason);
5064            break;
5065        case BAN_SYNTAX_ERROR:
5066            return false;
5067        case BAN_NOTFOUND:
5068            switch(mode)
5069            {
5070                default:
5071                    PSendSysMessage(LANG_BAN_NOTFOUND,"account",nameOrIP.c_str());
5072                    break;
5073                case BAN_CHARACTER:
5074                    PSendSysMessage(LANG_BAN_NOTFOUND,"character",nameOrIP.c_str());
5075                    break;
5076                case BAN_IP:
5077                    PSendSysMessage(LANG_BAN_NOTFOUND,"ip",nameOrIP.c_str());
5078                    break;
5079            }
5080            SetSentErrorMessage(true);
5081            return false;
5082    }
5083
5084    return true;
5085}
5086
5087bool ChatHandler::HandleUnBanAccountCommand(const char* args)
5088{
5089    return HandleUnBanHelper(BAN_ACCOUNT,args);
5090}
5091
5092bool ChatHandler::HandleUnBanCharacterCommand(const char* args)
5093{
5094    return HandleUnBanHelper(BAN_CHARACTER,args);
5095}
5096
5097bool ChatHandler::HandleUnBanIPCommand(const char* args)
5098{
5099    return HandleUnBanHelper(BAN_IP,args);
5100}
5101
5102bool ChatHandler::HandleUnBanHelper(BanMode mode, const char* args)
5103{
5104    if(!args)
5105        return false;
5106
5107    char* cnameOrIP = strtok ((char*)args, " ");
5108    if(!cnameOrIP)
5109        return false;
5110
5111    std::string nameOrIP = cnameOrIP;
5112
5113    switch(mode)
5114    {
5115        case BAN_ACCOUNT:
5116            if(!AccountMgr::normilizeString(nameOrIP))
5117            {
5118                PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,nameOrIP.c_str());
5119                SetSentErrorMessage(true);
5120                return false;
5121            }
5122            break;
5123        case BAN_CHARACTER:
5124            if(!normalizePlayerName(nameOrIP))
5125            {
5126                SendSysMessage(LANG_PLAYER_NOT_FOUND);
5127                SetSentErrorMessage(true);
5128                return false;
5129            }
5130            break;
5131        case BAN_IP:
5132            if(!IsIPAddress(nameOrIP.c_str()))
5133                return false;
5134            break;
5135    }
5136
5137    if(sWorld.RemoveBanAccount(mode,nameOrIP))
5138        PSendSysMessage(LANG_UNBAN_UNBANNED,nameOrIP.c_str());
5139    else
5140        PSendSysMessage(LANG_UNBAN_ERROR,nameOrIP.c_str());
5141
5142    return true;
5143}
5144
5145bool ChatHandler::HandleBanInfoAccountCommand(const char* args)
5146{
5147    if(!args)
5148        return false;
5149
5150    char* cname = strtok((char*)args, "");
5151    if(!cname)
5152        return false;
5153
5154    std::string account_name = cname;
5155    if(!AccountMgr::normilizeString(account_name))
5156    {
5157        PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5158        SetSentErrorMessage(true);
5159        return false;
5160    }
5161
5162    uint32 accountid = accmgr.GetId(account_name);
5163    if(!accountid)
5164    {
5165        PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5166        return true;
5167    }
5168
5169    return HandleBanInfoHelper(accountid,account_name.c_str());
5170}
5171
5172bool ChatHandler::HandleBanInfoCharacterCommand(const char* args)
5173{
5174    if(!args)
5175        return false;
5176
5177    char* cname = strtok ((char*)args, "");
5178    if(!cname)
5179        return false;
5180
5181    std::string name = cname;
5182    if(!normalizePlayerName(name))
5183    {
5184        SendSysMessage(LANG_PLAYER_NOT_FOUND);
5185        SetSentErrorMessage(true);
5186        return false;
5187    }
5188
5189    uint32 accountid = objmgr.GetPlayerAccountIdByPlayerName(name);
5190    if(!accountid)
5191    {
5192        SendSysMessage(LANG_PLAYER_NOT_FOUND);
5193        SetSentErrorMessage(true);
5194        return false;
5195    }
5196
5197    std::string accountname;
5198    if(!accmgr.GetName(accountid,accountname))
5199    {
5200        PSendSysMessage(LANG_BANINFO_NOCHARACTER);
5201        return true;
5202    }
5203
5204    return HandleBanInfoHelper(accountid,accountname.c_str());
5205}
5206
5207bool ChatHandler::HandleBanInfoHelper(uint32 accountid, char const* accountname)
5208{
5209    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);
5210    if(!result)
5211    {
5212        PSendSysMessage(LANG_BANINFO_NOACCOUNTBAN, accountname);
5213        return true;
5214    }
5215
5216    PSendSysMessage(LANG_BANINFO_BANHISTORY,accountname);
5217    do
5218    {
5219        Field* fields = result->Fetch();
5220
5221        time_t unbandate = time_t(fields[3].GetUInt64());
5222        bool active = false;
5223        if(fields[2].GetBool() && (fields[1].GetUInt64() == (uint64)0 ||unbandate >= time(NULL)) )
5224            active = true;
5225        bool permanent = (fields[1].GetUInt64() == (uint64)0);
5226        std::string bantime = permanent?GetTrinityString(LANG_BANINFO_INFINITE):secsToTimeString(fields[1].GetUInt64(), true);
5227        PSendSysMessage(LANG_BANINFO_HISTORYENTRY,
5228            fields[0].GetString(), bantime.c_str(), active ? GetTrinityString(LANG_BANINFO_YES):GetTrinityString(LANG_BANINFO_NO), fields[4].GetString(), fields[5].GetString());
5229    }while (result->NextRow());
5230
5231    delete result;
5232    return true;
5233}
5234
5235bool ChatHandler::HandleBanInfoIPCommand(const char* args)
5236{
5237    if(!args)
5238        return false;
5239
5240    char* cIP = strtok ((char*)args, "");
5241    if(!cIP)
5242        return false;
5243
5244    if (!IsIPAddress(cIP))
5245        return false;
5246
5247    std::string IP = cIP;
5248
5249    loginDatabase.escape_string(IP);
5250    QueryResult *result = loginDatabase.PQuery("SELECT ip, FROM_UNIXTIME(bandate), FROM_UNIXTIME(unbandate), unbandate-UNIX_TIMESTAMP(), banreason,bannedby,unbandate-bandate FROM ip_banned WHERE ip = '%s'",IP.c_str());
5251    if(!result)
5252    {
5253        PSendSysMessage(LANG_BANINFO_NOIP);
5254        return true;
5255    }
5256
5257    Field *fields = result->Fetch();
5258    bool permanent = !fields[6].GetUInt64();
5259    PSendSysMessage(LANG_BANINFO_IPENTRY,
5260        fields[0].GetString(), fields[1].GetString(), permanent ? GetTrinityString(LANG_BANINFO_NEVER):fields[2].GetString(),
5261        permanent ? GetTrinityString(LANG_BANINFO_INFINITE):secsToTimeString(fields[3].GetUInt64(), true).c_str(), fields[4].GetString(), fields[5].GetString());
5262    delete result;
5263    return true;
5264}
5265
5266bool ChatHandler::HandleBanListCharacterCommand(const char* args)
5267{
5268    loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
5269
5270    char* cFilter = strtok ((char*)args, " ");
5271    if(!cFilter)
5272        return false;
5273
5274    std::string filter = cFilter;
5275    loginDatabase.escape_string(filter);
5276    QueryResult* result = CharacterDatabase.PQuery("SELECT account FROM characters WHERE name "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'"),filter.c_str());
5277    if (!result)
5278    {
5279        PSendSysMessage(LANG_BANLIST_NOCHARACTER);
5280        return true;
5281    }
5282
5283    return HandleBanListHelper(result);
5284}
5285
5286bool ChatHandler::HandleBanListAccountCommand(const char* args)
5287{
5288    loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
5289
5290    char* cFilter = strtok((char*)args, " ");
5291    std::string filter = cFilter ? cFilter : "";
5292    loginDatabase.escape_string(filter);
5293
5294    QueryResult* result;
5295
5296    if(filter.empty())
5297    {
5298        result = loginDatabase.Query("SELECT account.id, username FROM account, account_banned"
5299            " WHERE account.id = account_banned.id AND active = 1 GROUP BY account.id");
5300    }
5301    else
5302    {
5303        result = loginDatabase.PQuery("SELECT account.id, username FROM account, account_banned"
5304            " WHERE account.id = account_banned.id AND active = 1 AND username "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")" GROUP BY account.id",
5305            filter.c_str());
5306    }
5307
5308    if (!result)
5309    {
5310        PSendSysMessage(LANG_BANLIST_NOACCOUNT);
5311        return true;
5312    }
5313
5314    return HandleBanListHelper(result);
5315}
5316
5317bool ChatHandler::HandleBanListHelper(QueryResult* result)
5318{
5319    PSendSysMessage(LANG_BANLIST_MATCHINGACCOUNT);
5320
5321    // Chat short output
5322    if(m_session)
5323    {
5324        do
5325        {
5326            Field* fields = result->Fetch();
5327            uint32 accountid = fields[0].GetUInt32();
5328
5329            QueryResult* banresult = loginDatabase.PQuery("SELECT account.username FROM account,account_banned WHERE account_banned.id='%u' AND account_banned.id=account.id",accountid);
5330            if(banresult)
5331            {
5332                Field* fields2 = banresult->Fetch();
5333                PSendSysMessage("%s",fields2[0].GetString());
5334                delete banresult;
5335            }
5336        } while (result->NextRow());
5337    }
5338    // Console wide output
5339    else
5340    {
5341        SendSysMessage(LANG_BANLIST_ACCOUNTS);
5342        SendSysMessage("===============================================================================");
5343        SendSysMessage(LANG_BANLIST_ACCOUNTS_HEADER);
5344        do
5345        {
5346            SendSysMessage("-------------------------------------------------------------------------------");
5347            Field *fields = result->Fetch();
5348            uint32 account_id = fields[0].GetUInt32 ();
5349
5350            std::string account_name;
5351
5352            // "account" case, name can be get in same query
5353            if(result->GetFieldCount() > 1)
5354                account_name = fields[1].GetCppString();
5355            // "character" case, name need extract from another DB
5356            else
5357                accmgr.GetName (account_id,account_name);
5358
5359            // No SQL injection. id is uint32.
5360            QueryResult *banInfo = loginDatabase.PQuery("SELECT bandate,unbandate,bannedby,banreason FROM account_banned WHERE id = %u ORDER BY unbandate", account_id);
5361            if (banInfo)
5362            {
5363                Field *fields2 = banInfo->Fetch();
5364                do
5365                {
5366                    time_t t_ban = fields2[0].GetUInt64();
5367                    tm* aTm_ban = localtime(&t_ban);
5368
5369                    if (fields2[0].GetUInt64() == fields2[1].GetUInt64())
5370                    {
5371                        PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|   permanent  |%-15.15s|%-15.15s|",
5372                            account_name.c_str(),aTm_ban->tm_year%100, aTm_ban->tm_mon+1, aTm_ban->tm_mday, aTm_ban->tm_hour, aTm_ban->tm_min,
5373                            fields2[2].GetString(),fields2[3].GetString());
5374                    }
5375                    else
5376                    {
5377                        time_t t_unban = fields2[1].GetUInt64();
5378                        tm* aTm_unban = localtime(&t_unban);
5379                        PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|",
5380                            account_name.c_str(),aTm_ban->tm_year%100, aTm_ban->tm_mon+1, aTm_ban->tm_mday, aTm_ban->tm_hour, aTm_ban->tm_min,
5381                            aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min,
5382                            fields2[2].GetString(),fields2[3].GetString());
5383                    }
5384                }while ( banInfo->NextRow() );
5385                delete banInfo;
5386            }
5387        }while( result->NextRow() );
5388        SendSysMessage("===============================================================================");
5389    }
5390
5391    delete result;
5392    return true;
5393}
5394
5395bool ChatHandler::HandleBanListIPCommand(const char* args)
5396{
5397    loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
5398
5399    char* cFilter = strtok((char*)args, " ");
5400    std::string filter = cFilter ? cFilter : "";
5401    loginDatabase.escape_string(filter);
5402
5403    QueryResult* result;
5404
5405    if(filter.empty())
5406    {
5407        result = loginDatabase.Query ("SELECT ip,bandate,unbandate,bannedby,banreason FROM ip_banned"
5408            " WHERE (bandate=unbandate OR unbandate>UNIX_TIMESTAMP())"
5409            " ORDER BY unbandate" );
5410    }
5411    else
5412    {
5413        result = loginDatabase.PQuery( "SELECT ip,bandate,unbandate,bannedby,banreason FROM ip_banned"
5414            " WHERE (bandate=unbandate OR unbandate>UNIX_TIMESTAMP()) AND ip "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")
5415            " ORDER BY unbandate",filter.c_str() );
5416    }
5417
5418    if(!result)
5419    {
5420        PSendSysMessage(LANG_BANLIST_NOIP);
5421        return true;
5422    }
5423
5424    PSendSysMessage(LANG_BANLIST_MATCHINGIP);
5425    // Chat short output
5426    if(m_session)
5427    {
5428        do
5429        {
5430            Field* fields = result->Fetch();
5431            PSendSysMessage("%s",fields[0].GetString());
5432        } while (result->NextRow());
5433    }
5434    // Console wide output
5435    else
5436    {
5437        SendSysMessage(LANG_BANLIST_IPS);
5438        SendSysMessage("===============================================================================");
5439        SendSysMessage(LANG_BANLIST_IPS_HEADER);
5440        do
5441        {
5442            SendSysMessage("-------------------------------------------------------------------------------");
5443            Field *fields = result->Fetch();
5444            time_t t_ban = fields[1].GetUInt64();
5445            tm* aTm_ban = localtime(&t_ban);
5446            if ( fields[1].GetUInt64() == fields[2].GetUInt64() )
5447            {
5448                PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|   permanent  |%-15.15s|%-15.15s|",
5449                    fields[0].GetString(), aTm_ban->tm_year%100, aTm_ban->tm_mon+1, aTm_ban->tm_mday, aTm_ban->tm_hour, aTm_ban->tm_min,
5450                    fields[3].GetString(), fields[4].GetString());
5451            }
5452            else
5453            {
5454                time_t t_unban = fields[2].GetUInt64();
5455                tm* aTm_unban = localtime(&t_unban);
5456                PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|",
5457                    fields[0].GetString(), aTm_ban->tm_year%100, aTm_ban->tm_mon+1, aTm_ban->tm_mday, aTm_ban->tm_hour, aTm_ban->tm_min,
5458                    aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min,
5459                    fields[3].GetString(), fields[4].GetString());
5460            }
5461        }while( result->NextRow() );
5462        SendSysMessage("===============================================================================");
5463    }
5464
5465    delete result;
5466    return true;
5467}
5468
5469bool ChatHandler::HandleRespawnCommand(const char* /*args*/)
5470{
5471    Player* pl = m_session->GetPlayer();
5472
5473    // accept only explicitly selected target (not implicitly self targeting case)
5474    Unit* target = getSelectedUnit();
5475    if(pl->GetSelection() && target)
5476    {
5477        if(target->GetTypeId()!=TYPEID_UNIT)
5478        {
5479            SendSysMessage(LANG_SELECT_CREATURE);
5480            SetSentErrorMessage(true);
5481            return false;
5482        }
5483
5484        if(target->isDead())
5485            ((Creature*)target)->Respawn();
5486        return true;
5487    }
5488
5489    CellPair p(Trinity::ComputeCellPair(pl->GetPositionX(), pl->GetPositionY()));
5490    Cell cell(p);
5491    cell.data.Part.reserved = ALL_DISTRICT;
5492    cell.SetNoCreate();
5493
5494    Trinity::RespawnDo u_do;
5495    Trinity::WorldObjectWorker<Trinity::RespawnDo> worker(u_do);
5496
5497    TypeContainerVisitor<Trinity::WorldObjectWorker<Trinity::RespawnDo>, GridTypeMapContainer > obj_worker(worker);
5498    CellLock<GridReadGuard> cell_lock(cell, p);
5499    cell_lock->Visit(cell_lock, obj_worker, *MapManager::Instance().GetMap(pl->GetMapId(), pl));
5500
5501    return true;
5502}
5503
5504bool ChatHandler::HandleFlyModeCommand(const char* args)
5505{
5506    if(!args)
5507        return false;
5508
5509    Unit *unit = getSelectedUnit();
5510    if (!unit || (unit->GetTypeId() != TYPEID_PLAYER))
5511        unit = m_session->GetPlayer();
5512
5513    WorldPacket data(12);
5514    if (strncmp(args, "on", 3) == 0)
5515        data.SetOpcode(SMSG_MOVE_SET_CAN_FLY);
5516    else if (strncmp(args, "off", 4) == 0)
5517        data.SetOpcode(SMSG_MOVE_UNSET_CAN_FLY);
5518    else
5519    {
5520        SendSysMessage(LANG_USE_BOL);
5521        return false;
5522    }
5523    data.append(unit->GetPackGUID());
5524    data << uint32(0);                                      // unknown
5525    unit->SendMessageToSet(&data, true);
5526    PSendSysMessage(LANG_COMMAND_FLYMODE_STATUS, unit->GetName(), args);
5527    return true;
5528}
5529
5530bool ChatHandler::HandleLoadPDumpCommand(const char *args)
5531{
5532    if(!args)
5533        return false;
5534
5535    char * file = strtok((char*)args, " ");
5536    if(!file)
5537        return false;
5538
5539    char * account = strtok(NULL, " ");
5540    if(!account)
5541        return false;
5542
5543    std::string account_name = account;
5544    if(!AccountMgr::normilizeString(account_name))
5545    {
5546        PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5547        SetSentErrorMessage(true);
5548        return false;
5549    }
5550
5551    uint32 account_id = accmgr.GetId(account_name);
5552    if(!account_id)
5553    {
5554        account_id = atoi(account);                             // use original string
5555        if(!account_id)
5556        {
5557            PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5558            SetSentErrorMessage(true);
5559            return false;
5560        }
5561    }
5562
5563    if(!accmgr.GetName(account_id,account_name))
5564    {
5565        PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
5566        SetSentErrorMessage(true);
5567        return false;
5568    }
5569
5570    char* guid_str = NULL;
5571    char* name_str = strtok(NULL, " ");
5572
5573    std::string name;
5574    if(name_str)
5575    {
5576        name = name_str;
5577        // normalize the name if specified and check if it exists
5578        if(!normalizePlayerName(name))
5579        {
5580            PSendSysMessage(LANG_INVALID_CHARACTER_NAME);
5581            SetSentErrorMessage(true);
5582            return false;
5583        }
5584
5585        if(!ObjectMgr::IsValidName(name,true))
5586        {
5587            PSendSysMessage(LANG_INVALID_CHARACTER_NAME);
5588            SetSentErrorMessage(true);
5589            return false;
5590        }
5591
5592        guid_str = strtok(NULL, " ");
5593    }
5594
5595    uint32 guid = 0;
5596
5597    if(guid_str)
5598    {
5599        guid = atoi(guid_str);
5600        if(!guid)
5601        {
5602            PSendSysMessage(LANG_INVALID_CHARACTER_GUID);
5603            SetSentErrorMessage(true);
5604            return false;
5605        }
5606
5607        if(objmgr.GetPlayerAccountIdByGUID(guid))
5608        {
5609            PSendSysMessage(LANG_CHARACTER_GUID_IN_USE,guid);
5610            SetSentErrorMessage(true);
5611            return false;
5612        }
5613    }
5614
5615    switch(PlayerDumpReader().LoadDump(file, account_id, name, guid))
5616    {
5617        case DUMP_SUCCESS:
5618            PSendSysMessage(LANG_COMMAND_IMPORT_SUCCESS);
5619            break;
5620        case DUMP_FILE_OPEN_ERROR:
5621            PSendSysMessage(LANG_FILE_OPEN_FAIL,file);
5622            SetSentErrorMessage(true);
5623            return false;
5624        case DUMP_FILE_BROKEN:
5625            PSendSysMessage(LANG_DUMP_BROKEN,file);
5626            SetSentErrorMessage(true);
5627            return false;
5628        case DUMP_TOO_MANY_CHARS:
5629            PSendSysMessage(LANG_ACCOUNT_CHARACTER_LIST_FULL,account_name.c_str(),account_id);
5630            SetSentErrorMessage(true);
5631            return false;
5632        default:
5633            PSendSysMessage(LANG_COMMAND_IMPORT_FAILED);
5634            SetSentErrorMessage(true);
5635            return false;
5636    }
5637
5638    return true;
5639}
5640
5641bool ChatHandler::HandleNpcChangeEntryCommand(const char *args)
5642{
5643    if(!args)
5644        return false;
5645
5646    uint32 newEntryNum = atoi(args);
5647    if(!newEntryNum)
5648        return false;
5649
5650    Unit* unit = getSelectedUnit();
5651    if(!unit || unit->GetTypeId() != TYPEID_UNIT)
5652    {
5653        SendSysMessage(LANG_SELECT_CREATURE);
5654        SetSentErrorMessage(true);
5655        return false;
5656    }
5657    Creature* creature = (Creature*)unit;
5658    if(creature->UpdateEntry(newEntryNum))
5659        SendSysMessage(LANG_DONE);
5660    else
5661        SendSysMessage(LANG_ERROR);
5662    return true;
5663}
5664
5665bool ChatHandler::HandleWritePDumpCommand(const char *args)
5666{
5667    if(!args)
5668        return false;
5669
5670    char* file = strtok((char*)args, " ");
5671    char* p2 = strtok(NULL, " ");
5672
5673    if(!file || !p2)
5674        return false;
5675
5676    uint32 guid = objmgr.GetPlayerGUIDByName(p2);
5677    if(!guid)
5678        guid = atoi(p2);
5679
5680    if(!objmgr.GetPlayerAccountIdByGUID(guid))
5681    {
5682        PSendSysMessage(LANG_PLAYER_NOT_FOUND);
5683        SetSentErrorMessage(true);
5684        return false;
5685    }
5686
5687    switch(PlayerDumpWriter().WriteDump(file, guid))
5688    {
5689        case DUMP_SUCCESS:
5690            PSendSysMessage(LANG_COMMAND_EXPORT_SUCCESS);
5691            break;
5692        case DUMP_FILE_OPEN_ERROR:
5693            PSendSysMessage(LANG_FILE_OPEN_FAIL,file);
5694            SetSentErrorMessage(true);
5695            return false;
5696        default:
5697            PSendSysMessage(LANG_COMMAND_EXPORT_FAILED);
5698            SetSentErrorMessage(true);
5699            return false;
5700    }
5701
5702    return true;
5703}
5704
5705bool ChatHandler::HandleMovegensCommand(const char* /*args*/)
5706{
5707    Unit* unit = getSelectedUnit();
5708    if(!unit)
5709    {
5710        SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5711        SetSentErrorMessage(true);
5712        return false;
5713    }
5714
5715    PSendSysMessage(LANG_MOVEGENS_LIST,(unit->GetTypeId()==TYPEID_PLAYER ? "Player" : "Creature" ),unit->GetGUIDLow());
5716
5717    MotionMaster* mm = unit->GetMotionMaster();
5718    for(MotionMaster::const_iterator itr = mm->begin(); itr != mm->end(); ++itr)
5719    {
5720        switch((*itr)->GetMovementGeneratorType())
5721        {
5722            case IDLE_MOTION_TYPE:          SendSysMessage(LANG_MOVEGENS_IDLE);          break;
5723            case RANDOM_MOTION_TYPE:        SendSysMessage(LANG_MOVEGENS_RANDOM);        break;
5724            case WAYPOINT_MOTION_TYPE:      SendSysMessage(LANG_MOVEGENS_WAYPOINT);      break;
5725            case ANIMAL_RANDOM_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_ANIMAL_RANDOM); break;
5726            case CONFUSED_MOTION_TYPE:      SendSysMessage(LANG_MOVEGENS_CONFUSED);      break;
5727            case TARGETED_MOTION_TYPE:
5728            {
5729                if(unit->GetTypeId()==TYPEID_PLAYER)
5730                {
5731                    TargetedMovementGenerator<Player> const* mgen = static_cast<TargetedMovementGenerator<Player> const*>(*itr);
5732                    Unit* target = mgen->GetTarget();
5733                    if(target)
5734                        PSendSysMessage(LANG_MOVEGENS_TARGETED_PLAYER,target->GetName(),target->GetGUIDLow());
5735                    else
5736                        SendSysMessage(LANG_MOVEGENS_TARGETED_NULL);
5737                }
5738                else
5739                {
5740                    TargetedMovementGenerator<Creature> const* mgen = static_cast<TargetedMovementGenerator<Creature> const*>(*itr);
5741                    Unit* target = mgen->GetTarget();
5742                    if(target)
5743                        PSendSysMessage(LANG_MOVEGENS_TARGETED_CREATURE,target->GetName(),target->GetGUIDLow());
5744                    else
5745                        SendSysMessage(LANG_MOVEGENS_TARGETED_NULL);
5746                }
5747                break;
5748            }
5749            case HOME_MOTION_TYPE:
5750                if(unit->GetTypeId()==TYPEID_UNIT)
5751                {
5752                    float x,y,z;
5753                    (*itr)->GetDestination(x,y,z);
5754                    PSendSysMessage(LANG_MOVEGENS_HOME_CREATURE,x,y,z);
5755                }
5756                else
5757                    SendSysMessage(LANG_MOVEGENS_HOME_PLAYER);
5758                break;
5759            case FLIGHT_MOTION_TYPE:   SendSysMessage(LANG_MOVEGENS_FLIGHT);  break;
5760            case POINT_MOTION_TYPE:
5761            {
5762                float x,y,z;
5763                (*itr)->GetDestination(x,y,z);
5764                PSendSysMessage(LANG_MOVEGENS_POINT,x,y,z);
5765                break;
5766            }
5767            case FLEEING_MOTION_TYPE:  SendSysMessage(LANG_MOVEGENS_FEAR);    break;
5768            case DISTRACT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_DISTRACT);  break;
5769            default:
5770                PSendSysMessage(LANG_MOVEGENS_UNKNOWN,(*itr)->GetMovementGeneratorType());
5771                break;
5772        }
5773    }
5774    return true;
5775}
5776
5777bool ChatHandler::HandlePLimitCommand(const char *args)
5778{
5779    if(*args)
5780    {
5781        char* param = strtok((char*)args, " ");
5782        if(!param)
5783            return false;
5784
5785        int l = strlen(param);
5786
5787        if(     strncmp(param,"player",l) == 0 )
5788            sWorld.SetPlayerLimit(-SEC_PLAYER);
5789        else if(strncmp(param,"moderator",l) == 0 )
5790            sWorld.SetPlayerLimit(-SEC_MODERATOR);
5791        else if(strncmp(param,"gamemaster",l) == 0 )
5792            sWorld.SetPlayerLimit(-SEC_GAMEMASTER);
5793        else if(strncmp(param,"administrator",l) == 0 )
5794            sWorld.SetPlayerLimit(-SEC_ADMINISTRATOR);
5795        else if(strncmp(param,"reset",l) == 0 )
5796            sWorld.SetPlayerLimit( sConfig.GetIntDefault("PlayerLimit", DEFAULT_PLAYER_LIMIT) );
5797        else
5798        {
5799            int val = atoi(param);
5800            if(val < -SEC_ADMINISTRATOR) val = -SEC_ADMINISTRATOR;
5801
5802            sWorld.SetPlayerLimit(val);
5803        }
5804
5805        // kick all low security level players
5806        if(sWorld.GetPlayerAmountLimit() > SEC_PLAYER)
5807            sWorld.KickAllLess(sWorld.GetPlayerSecurityLimit());
5808    }
5809
5810    uint32 pLimit = sWorld.GetPlayerAmountLimit();
5811    AccountTypes allowedAccountType = sWorld.GetPlayerSecurityLimit();
5812    char const* secName = "";
5813    switch(allowedAccountType)
5814    {
5815        case SEC_PLAYER:        secName = "Player";        break;
5816        case SEC_MODERATOR:     secName = "Moderator";     break;
5817        case SEC_GAMEMASTER:    secName = "Gamemaster";    break;
5818        case SEC_ADMINISTRATOR: secName = "Administrator"; break;
5819        default:                secName = "<unknown>";     break;
5820    }
5821
5822    PSendSysMessage("Player limits: amount %u, min. security level %s.",pLimit,secName);
5823
5824    return true;
5825}
5826
5827bool ChatHandler::HandleCastCommand(const char* args)
5828{
5829    if(!*args)
5830        return false;
5831
5832    Unit* target = getSelectedUnit();
5833
5834    if(!target)
5835    {
5836        SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5837        SetSentErrorMessage(true);
5838        return false;
5839    }
5840
5841    // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5842    uint32 spell = extractSpellIdFromLink((char*)args);
5843    if(!spell)
5844        return false;
5845
5846    SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
5847    if(!spellInfo)
5848        return false;
5849
5850    if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
5851    {
5852        PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
5853        SetSentErrorMessage(true);
5854        return false;
5855    }
5856
5857    char* trig_str = strtok(NULL, " ");
5858    if(trig_str)
5859    {
5860        int l = strlen(trig_str);
5861        if(strncmp(trig_str,"triggered",l) != 0 )
5862            return false;
5863    }
5864
5865    bool triggered = (trig_str != NULL);
5866
5867    m_session->GetPlayer()->CastSpell(target,spell,triggered);
5868
5869    return true;
5870}
5871
5872bool ChatHandler::HandleCastBackCommand(const char* args)
5873{
5874    Creature* caster = getSelectedCreature();
5875
5876    if(!caster)
5877    {
5878        SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5879        SetSentErrorMessage(true);
5880        return false;
5881    }
5882
5883    // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
5884    // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5885    uint32 spell = extractSpellIdFromLink((char*)args);
5886    if(!spell || !sSpellStore.LookupEntry(spell))
5887        return false;
5888
5889    char* trig_str = strtok(NULL, " ");
5890    if(trig_str)
5891    {
5892        int l = strlen(trig_str);
5893        if(strncmp(trig_str,"triggered",l) != 0 )
5894            return false;
5895    }
5896
5897    bool triggered = (trig_str != NULL);
5898
5899    // update orientation at server
5900    caster->SetOrientation(caster->GetAngle(m_session->GetPlayer()));
5901
5902    // and client
5903    WorldPacket data;
5904    caster->BuildHeartBeatMsg(&data);
5905    caster->SendMessageToSet(&data,true);
5906
5907    caster->CastSpell(m_session->GetPlayer(),spell,triggered);
5908
5909    return true;
5910}
5911
5912bool ChatHandler::HandleCastDistCommand(const char* args)
5913{
5914    if(!*args)
5915        return false;
5916
5917    // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5918    uint32 spell = extractSpellIdFromLink((char*)args);
5919    if(!spell)
5920        return false;
5921
5922    SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
5923    if(!spellInfo)
5924        return false;
5925
5926    if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
5927    {
5928        PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
5929        SetSentErrorMessage(true);
5930        return false;
5931    }
5932
5933    char *distStr = strtok(NULL, " ");
5934
5935    float dist = 0;
5936
5937    if(distStr)
5938        sscanf(distStr, "%f", &dist);
5939
5940    char* trig_str = strtok(NULL, " ");
5941    if(trig_str)
5942    {
5943        int l = strlen(trig_str);
5944        if(strncmp(trig_str,"triggered",l) != 0 )
5945            return false;
5946    }
5947
5948    bool triggered = (trig_str != NULL);
5949
5950    float x,y,z;
5951    m_session->GetPlayer()->GetClosePoint(x,y,z,dist);
5952
5953    m_session->GetPlayer()->CastSpell(x,y,z,spell,triggered);
5954    return true;
5955}
5956
5957bool ChatHandler::HandleCastTargetCommand(const char* args)
5958{
5959    Creature* caster = getSelectedCreature();
5960
5961    if(!caster)
5962    {
5963        SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
5964        SetSentErrorMessage(true);
5965        return false;
5966    }
5967
5968    if(!caster->getVictim())
5969    {
5970        SendSysMessage(LANG_SELECTED_TARGET_NOT_HAVE_VICTIM);
5971        SetSentErrorMessage(true);
5972        return false;
5973    }
5974
5975    // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
5976    uint32 spell = extractSpellIdFromLink((char*)args);
5977    if(!spell || !sSpellStore.LookupEntry(spell))
5978        return false;
5979
5980    char* trig_str = strtok(NULL, " ");
5981    if(trig_str)
5982    {
5983        int l = strlen(trig_str);
5984        if(strncmp(trig_str,"triggered",l) != 0 )
5985            return false;
5986    }
5987
5988    bool triggered = (trig_str != NULL);
5989
5990    // update orientation at server
5991    caster->SetOrientation(caster->GetAngle(m_session->GetPlayer()));
5992
5993    // and client
5994    WorldPacket data;
5995    caster->BuildHeartBeatMsg(&data);
5996    caster->SendMessageToSet(&data,true);
5997
5998    caster->CastSpell(caster->getVictim(),spell,triggered);
5999
6000    return true;
6001}
6002
6003/*
6004ComeToMe command REQUIRED for 3rd party scripting library to have access to PointMovementGenerator
6005Without this function 3rd party scripting library will get linking errors (unresolved external)
6006when attempting to use the PointMovementGenerator
6007*/
6008bool ChatHandler::HandleComeToMeCommand(const char *args)
6009{
6010    Creature* caster = getSelectedCreature();
6011
6012    if(!caster)
6013    {
6014        SendSysMessage(LANG_SELECT_CREATURE);
6015        SetSentErrorMessage(true);
6016        return false;
6017    }
6018
6019    char* newFlagStr = strtok((char*)args, " ");
6020
6021    if(!newFlagStr)
6022        return false;
6023
6024    uint32 newFlags = atoi(newFlagStr);
6025
6026    caster->SetUnitMovementFlags(newFlags);
6027
6028    Player* pl = m_session->GetPlayer();
6029
6030    caster->GetMotionMaster()->MovePoint(0, pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ());
6031    return true;
6032}
6033
6034bool ChatHandler::HandleCastSelfCommand(const char* args)
6035{
6036    if(!*args)
6037        return false;
6038
6039    Unit* target = getSelectedUnit();
6040
6041    if(!target)
6042    {
6043        SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
6044        SetSentErrorMessage(true);
6045        return false;
6046    }
6047
6048    // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
6049    uint32 spell = extractSpellIdFromLink((char*)args);
6050    if(!spell)
6051        return false;
6052
6053    SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
6054    if(!spellInfo)
6055        return false;
6056
6057    if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
6058    {
6059        PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
6060        SetSentErrorMessage(true);
6061        return false;
6062    }
6063
6064    target->CastSpell(target,spell,false);
6065
6066    return true;
6067}
6068
6069std::string GetTimeString(uint32 time)
6070{
6071    uint16 days = time / DAY, hours = (time % DAY) / HOUR, minute = (time % HOUR) / MINUTE;
6072    std::ostringstream ss;
6073    if(days) ss << days << "d ";
6074    if(hours) ss << hours << "h ";
6075    ss << minute << "m";
6076    return ss.str();
6077}
6078
6079bool ChatHandler::HandleInstanceListBindsCommand(const char* /*args*/)
6080{
6081    Player* player = getSelectedPlayer();
6082    if (!player) player = m_session->GetPlayer();
6083    uint32 counter = 0;
6084    for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++)
6085    {
6086        Player::BoundInstancesMap &binds = player->GetBoundInstances(i);
6087        for(Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end(); ++itr)
6088        {
6089            InstanceSave *save = itr->second.save;
6090            std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
6091            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());
6092            counter++;
6093        }
6094    }
6095    PSendSysMessage("player binds: %d", counter);
6096    counter = 0;
6097    Group *group = player->GetGroup();
6098    if(group)
6099    {
6100        for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++)
6101        {
6102            Group::BoundInstancesMap &binds = group->GetBoundInstances(i);
6103            for(Group::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end(); ++itr)
6104            {
6105                InstanceSave *save = itr->second.save;
6106                std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
6107                PSendSysMessage("map: %d inst: %d perm: %s diff: %s canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no",  save->GetDifficulty() == DIFFICULTY_NORMAL ? "normal" : "heroic", save->CanReset() ? "yes" : "no", timeleft.c_str());
6108                counter++;
6109            }
6110        }
6111    }
6112    PSendSysMessage("group binds: %d", counter);
6113
6114    return true;
6115}
6116
6117bool ChatHandler::HandleInstanceUnbindCommand(const char* args)
6118{
6119    if(!*args)
6120        return false;
6121
6122    std::string cmd = args;
6123    if(cmd == "all")
6124    {
6125        Player* player = getSelectedPlayer();
6126        if (!player) player = m_session->GetPlayer();
6127        uint32 counter = 0;
6128        for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++)
6129        {
6130            Player::BoundInstancesMap &binds = player->GetBoundInstances(i);
6131            for(Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end();)
6132            {
6133                if(itr->first != player->GetMapId())
6134                {
6135                    InstanceSave *save = itr->second.save;
6136                    std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
6137                    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());
6138                    player->UnbindInstance(itr, i);
6139                    counter++;
6140                }
6141                else
6142                    ++itr;
6143            }
6144        }
6145        PSendSysMessage("instances unbound: %d", counter);
6146    }
6147    return true;
6148}
6149
6150bool ChatHandler::HandleInstanceStatsCommand(const char* /*args*/)
6151{
6152    PSendSysMessage("instances loaded: %d", MapManager::Instance().GetNumInstances());
6153    PSendSysMessage("players in instances: %d", MapManager::Instance().GetNumPlayersInInstances());
6154    PSendSysMessage("instance saves: %d", sInstanceSaveManager.GetNumInstanceSaves());
6155    PSendSysMessage("players bound: %d", sInstanceSaveManager.GetNumBoundPlayersTotal());
6156    PSendSysMessage("groups bound: %d", sInstanceSaveManager.GetNumBoundGroupsTotal());
6157    return true;
6158}
6159
6160bool ChatHandler::HandleInstanceSaveDataCommand(const char * /*args*/)
6161{
6162    Player* pl = m_session->GetPlayer();
6163
6164    Map* map = pl->GetMap();
6165    if (!map->IsDungeon())
6166    {
6167        PSendSysMessage("Map is not a dungeon.");
6168        SetSentErrorMessage(true);
6169        return false;
6170    }
6171
6172    if (!((InstanceMap*)map)->GetInstanceData())
6173    {
6174        PSendSysMessage("Map has no instance data.");
6175        SetSentErrorMessage(true);
6176        return false;
6177    }
6178
6179    ((InstanceMap*)map)->GetInstanceData()->SaveToDB();
6180    return true;
6181}
6182
6183/// Display the list of GMs
6184bool ChatHandler::HandleGMListFullCommand(const char* /*args*/)
6185{
6186    ///- Get the accounts with GM Level >0
6187    QueryResult *result = loginDatabase.Query( "SELECT username,gmlevel FROM account WHERE gmlevel > 0" );
6188    if(result)
6189    {
6190        SendSysMessage(LANG_GMLIST);
6191        SendSysMessage("========================");
6192        SendSysMessage(LANG_GMLIST_HEADER);
6193        SendSysMessage("========================");
6194
6195        ///- Circle through them. Display username and GM level
6196        do
6197        {
6198            Field *fields = result->Fetch();
6199            PSendSysMessage("|%15s|%6s|", fields[0].GetString(),fields[1].GetString());
6200        }while( result->NextRow() );
6201
6202        PSendSysMessage("========================");
6203        delete result;
6204    }
6205    else
6206        PSendSysMessage(LANG_GMLIST_EMPTY);
6207    return true;
6208}
6209
6210/// Define the 'Message of the day' for the realm
6211bool ChatHandler::HandleServerSetMotdCommand(const char* args)
6212{
6213    sWorld.SetMotd(args);
6214    PSendSysMessage(LANG_MOTD_NEW, args);
6215    return true;
6216}
6217
6218/// Set/Unset the expansion level for an account
6219bool ChatHandler::HandleAccountSetAddonCommand(const char* args)
6220{
6221    ///- Get the command line arguments
6222    char *szAcc = strtok((char*)args," ");
6223    char *szExp = strtok(NULL," ");
6224
6225    if(!szAcc)
6226        return false;
6227
6228    std::string account_name;
6229    uint32 account_id;
6230
6231    if(!szExp)
6232    {
6233        Player* player = getSelectedPlayer();
6234        if(!player)
6235            return false;
6236
6237        account_id = player->GetSession()->GetAccountId();
6238        accmgr.GetName(account_id,account_name);
6239        szExp = szAcc;
6240    }
6241    else
6242    {
6243        ///- Convert Account name to Upper Format
6244        account_name = szAcc;
6245        if(!AccountMgr::normilizeString(account_name))
6246        {
6247            PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
6248            SetSentErrorMessage(true);
6249            return false;
6250        }
6251
6252        account_id = accmgr.GetId(account_name);
6253        if(!account_id)
6254        {
6255            PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
6256            SetSentErrorMessage(true);
6257            return false;
6258        }
6259    }
6260
6261    int lev=atoi(szExp);                                    //get int anyway (0 if error)
6262    if(lev < 0)
6263        return false;
6264
6265    // No SQL injection
6266    loginDatabase.PExecute("UPDATE account SET expansion = '%d' WHERE id = '%u'",lev,account_id);
6267    PSendSysMessage(LANG_ACCOUNT_SETADDON,account_name.c_str(),account_id,lev);
6268    return true;
6269}
6270
6271//Send items by mail
6272bool ChatHandler::HandleSendItemsCommand(const char* args)
6273{
6274    if(!*args)
6275        return false;
6276
6277    // format: name "subject text" "mail text" item1[:count1] item2[:count2] ... item12[:count12]
6278
6279    char* pName = strtok((char*)args, " ");
6280    if(!pName)
6281        return false;
6282
6283    char* tail1 = strtok(NULL, "");
6284    if(!tail1)
6285        return false;
6286
6287    char* msgSubject;
6288    if(*tail1=='"')
6289        msgSubject = strtok(tail1+1, "\"");
6290    else
6291    {
6292        char* space = strtok(tail1, "\"");
6293        if(!space)
6294            return false;
6295        msgSubject = strtok(NULL, "\"");
6296    }
6297
6298    if (!msgSubject)
6299        return false;
6300
6301    char* tail2 = strtok(NULL, "");
6302    if(!tail2)
6303        return false;
6304
6305    char* msgText;
6306    if(*tail2=='"')
6307        msgText = strtok(tail2+1, "\"");
6308    else
6309    {
6310        char* space = strtok(tail2, "\"");
6311        if(!space)
6312            return false;
6313        msgText = strtok(NULL, "\"");
6314    }
6315
6316    if (!msgText)
6317        return false;
6318
6319    // pName, msgSubject, msgText isn't NUL after prev. check
6320    std::string name    = pName;
6321    std::string subject = msgSubject;
6322    std::string text    = msgText;
6323
6324    // extract items
6325    typedef std::pair<uint32,uint32> ItemPair;
6326    typedef std::list< ItemPair > ItemPairs;
6327    ItemPairs items;
6328
6329    // get all tail string
6330    char* tail = strtok(NULL, "");
6331
6332    // get from tail next item str
6333    while(char* itemStr = strtok(tail, " "))
6334    {
6335        // and get new tail
6336        tail = strtok(NULL, "");
6337
6338        // parse item str
6339        char* itemIdStr = strtok(itemStr, ":");
6340        char* itemCountStr = strtok(NULL, " ");
6341
6342        uint32 item_id = atoi(itemIdStr);
6343        if(!item_id)
6344            return false;
6345
6346        ItemPrototype const* item_proto = objmgr.GetItemPrototype(item_id);
6347        if(!item_proto)
6348        {
6349            PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
6350            SetSentErrorMessage(true);
6351            return false;
6352        }
6353
6354        uint32 item_count = itemCountStr ? atoi(itemCountStr) : 1;
6355        if(item_count < 1 || item_proto->MaxCount && item_count > item_proto->MaxCount)
6356        {
6357            PSendSysMessage(LANG_COMMAND_INVALID_ITEM_COUNT, item_count,item_id);
6358            SetSentErrorMessage(true);
6359            return false;
6360        }
6361
6362        while(item_count > item_proto->Stackable)
6363        {
6364            items.push_back(ItemPair(item_id,item_proto->Stackable));
6365            item_count -= item_proto->Stackable;
6366        }
6367
6368        items.push_back(ItemPair(item_id,item_count));
6369
6370        if(items.size() > MAX_MAIL_ITEMS)
6371        {
6372            PSendSysMessage(LANG_COMMAND_MAIL_ITEMS_LIMIT, MAX_MAIL_ITEMS);
6373            SetSentErrorMessage(true);
6374            return false;
6375        }
6376    }
6377
6378    if(!normalizePlayerName(name))
6379    {
6380        SendSysMessage(LANG_PLAYER_NOT_FOUND);
6381        SetSentErrorMessage(true);
6382        return false;
6383    }
6384
6385    uint64 receiver_guid = objmgr.GetPlayerGUIDByName(name);
6386    if(!receiver_guid)
6387    {
6388        SendSysMessage(LANG_PLAYER_NOT_FOUND);
6389        SetSentErrorMessage(true);
6390        return false;
6391    }
6392
6393    // from console show not existed sender
6394    uint32 sender_guidlo = m_session ? m_session->GetPlayer()->GetGUIDLow() : 0;
6395
6396    uint32 messagetype = MAIL_NORMAL;
6397    uint32 stationery = MAIL_STATIONERY_GM;
6398    uint32 itemTextId = !text.empty() ? objmgr.CreateItemText( text ) : 0;
6399
6400    Player *receiver = objmgr.GetPlayer(receiver_guid);
6401
6402    // fill mail
6403    MailItemsInfo mi;                                       // item list preparing
6404
6405    for(ItemPairs::const_iterator itr = items.begin(); itr != items.end(); ++itr)
6406    {
6407        if(Item* item = Item::CreateItem(itr->first,itr->second,m_session ? m_session->GetPlayer() : 0))
6408        {
6409            item->SaveToDB();                               // save for prevent lost at next mail load, if send fail then item will deleted
6410            mi.AddItem(item->GetGUIDLow(), item->GetEntry(), item);
6411        }
6412    }
6413
6414    WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, &mi, 0, 0, MAIL_CHECK_MASK_NONE);
6415
6416    PSendSysMessage(LANG_MAIL_SENT, name.c_str());
6417    return true;
6418}
6419
6420///Send money by mail
6421bool ChatHandler::HandleSendMoneyCommand(const char* args)
6422{
6423    if (!*args)
6424        return false;
6425
6426    /// format: name "subject text" "mail text" money
6427
6428    char* pName = strtok((char*)args, " ");
6429    if (!pName)
6430        return false;
6431
6432    char* tail1 = strtok(NULL, "");
6433    if (!tail1)
6434        return false;
6435
6436    char* msgSubject;
6437    if (*tail1=='"')
6438        msgSubject = strtok(tail1+1, "\"");
6439    else
6440    {
6441        char* space = strtok(tail1, "\"");
6442        if (!space)
6443            return false;
6444        msgSubject = strtok(NULL, "\"");
6445    }
6446
6447    if (!msgSubject)
6448        return false;
6449
6450    char* tail2 = strtok(NULL, "");
6451    if (!tail2)
6452        return false;
6453
6454    char* msgText;
6455    if (*tail2=='"')
6456        msgText = strtok(tail2+1, "\"");
6457    else
6458    {
6459        char* space = strtok(tail2, "\"");
6460        if (!space)
6461            return false;
6462        msgText = strtok(NULL, "\"");
6463    }
6464
6465    if (!msgText)
6466        return false;
6467
6468    char* money_str = strtok(NULL, "");
6469    int32 money = money_str ? atoi(money_str) : 0;
6470    if (money <= 0)
6471        return false;
6472
6473    // pName, msgSubject, msgText isn't NUL after prev. check
6474    std::string name    = pName;
6475    std::string subject = msgSubject;
6476    std::string text    = msgText;
6477
6478    if (!normalizePlayerName(name))
6479    {
6480        SendSysMessage(LANG_PLAYER_NOT_FOUND);
6481        SetSentErrorMessage(true);
6482        return false;
6483    }
6484
6485    uint64 receiver_guid = objmgr.GetPlayerGUIDByName(name);
6486    if (!receiver_guid)
6487    {
6488        SendSysMessage(LANG_PLAYER_NOT_FOUND);
6489        SetSentErrorMessage(true);
6490        return false;
6491    }
6492
6493    uint32 mailId = objmgr.GenerateMailID();
6494
6495    // from console show not existed sender
6496    uint32 sender_guidlo = m_session ? m_session->GetPlayer()->GetGUIDLow() : 0;
6497
6498    uint32 messagetype = MAIL_NORMAL;
6499    uint32 stationery = MAIL_STATIONERY_GM;
6500    uint32 itemTextId = !text.empty() ? objmgr.CreateItemText( text ) : 0;
6501
6502    Player *receiver = objmgr.GetPlayer(receiver_guid);
6503
6504    WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, NULL, money, 0, MAIL_CHECK_MASK_NONE);
6505
6506    PSendSysMessage(LANG_MAIL_SENT, name.c_str());
6507    return true;
6508}
6509
6510/// Send a message to a player in game
6511bool ChatHandler::HandleSendMessageCommand(const char* args)
6512{
6513    ///- Get the command line arguments
6514    char* name_str = strtok((char*)args, " ");
6515    char* msg_str = strtok(NULL, "");
6516
6517    if(!name_str || !msg_str)
6518        return false;
6519
6520    std::string name = name_str;
6521
6522    if(!normalizePlayerName(name))
6523        return false;
6524
6525    ///- Find the player and check that he is not logging out.
6526    Player *rPlayer = objmgr.GetPlayer(name.c_str());
6527    if(!rPlayer)
6528    {
6529        SendSysMessage(LANG_PLAYER_NOT_FOUND);
6530        SetSentErrorMessage(true);
6531        return false;
6532    }
6533
6534    if(rPlayer->GetSession()->isLogingOut())
6535    {
6536        SendSysMessage(LANG_PLAYER_NOT_FOUND);
6537        SetSentErrorMessage(true);
6538        return false;
6539    }
6540
6541    ///- Send the message
6542    //Use SendAreaTriggerMessage for fastest delivery.
6543    rPlayer->GetSession()->SendAreaTriggerMessage("%s", msg_str);
6544    rPlayer->GetSession()->SendAreaTriggerMessage("|cffff0000[Message from administrator]:|r");
6545
6546    //Confirmation message
6547    PSendSysMessage(LANG_SENDMESSAGE,name.c_str(),msg_str);
6548    return true;
6549}
6550
6551bool ChatHandler::HandlePlayAllCommand(const char* args)
6552{
6553    if(!*args)
6554        return false;
6555
6556    uint32 soundId = atoi((char*)args);
6557
6558    if(!sSoundEntriesStore.LookupEntry(soundId))
6559    {
6560        PSendSysMessage(LANG_SOUND_NOT_EXIST, soundId);
6561        SetSentErrorMessage(true);
6562        return false;
6563    }
6564
6565    WorldPacket data(SMSG_PLAY_SOUND, 4);
6566    data << uint32(soundId) << m_session->GetPlayer()->GetGUID();
6567    sWorld.SendGlobalMessage(&data);
6568
6569    PSendSysMessage(LANG_COMMAND_PLAYED_TO_ALL, soundId);
6570    return true;
6571}
6572
6573bool ChatHandler::HandleModifyGenderCommand(const char *args)
6574{
6575    if(!*args)  return false;
6576    Player *player = getSelectedPlayer();
6577
6578    if(!player)
6579    {
6580        PSendSysMessage(LANG_NO_PLAYER);
6581        SetSentErrorMessage(true);
6582        return false;
6583    }
6584
6585    std::string gender = (char*)args;
6586    uint32 displayId = player->GetNativeDisplayId();
6587
6588    if(gender == "male") // MALE
6589    {
6590        if(player->getGender() == GENDER_MALE)
6591        {
6592            PSendSysMessage("%s is already male", player->GetName());
6593            SetSentErrorMessage(true);
6594            return false;
6595        }
6596
6597        // Set gender
6598        player->SetByteValue(UNIT_FIELD_BYTES_0, 2, GENDER_MALE);
6599        // Change display ID
6600        player->SetDisplayId(player->getRace() == RACE_BLOODELF ? displayId+1 : displayId-1);
6601        player->SetNativeDisplayId(player->getRace() == RACE_BLOODELF ? displayId+1 : displayId-1);
6602
6603        ChatHandler(player).PSendSysMessage("Gender changed. You are now a man!");
6604        PSendSysMessage("Gender changed for %s", player->GetName());
6605        return true;
6606    }
6607    else if(gender == "female") // FEMALE
6608    {
6609        if(player->getGender() == GENDER_FEMALE)
6610        {
6611            PSendSysMessage("%s is already female", player->GetName());
6612            SetSentErrorMessage(true);
6613            return false;
6614        }
6615
6616        // Set gender
6617        player->SetByteValue(UNIT_FIELD_BYTES_0, 2, GENDER_FEMALE);
6618        // Change display ID
6619        player->SetDisplayId(player->getRace() == RACE_BLOODELF ? displayId-1 : displayId+1);
6620        player->SetNativeDisplayId(player->getRace() == RACE_BLOODELF ? displayId-1 : displayId+1);
6621
6622        ChatHandler(player).PSendSysMessage("Gender changed. You are now a woman!");
6623        PSendSysMessage("Gender changed for %s", player->GetName());
6624        return true;
6625    }
6626    else
6627    {
6628        PSendSysMessage("You must use male or female as gender.");
6629        SetSentErrorMessage(true);
6630        return false;
6631    }
6632
6633    return true;
6634}
6635
6636bool ChatHandler::HandleFreezeCommand(const char *args)
6637{
6638    std::string name;
6639    Player* player;
6640    char* TargetName = strtok((char*)args, " "); //get entered name
6641    if (!TargetName) //if no name entered use target
6642    {
6643        player = getSelectedPlayer();
6644        if (player) //prevent crash with creature as target
6645        {   
6646            name = player->GetName();
6647            normalizePlayerName(name);
6648        }
6649    }
6650    else // if name entered
6651    {
6652        name = TargetName;
6653        normalizePlayerName(name);
6654        player = objmgr.GetPlayer(name.c_str()); //get player by name
6655    }
6656
6657    if (!player)
6658    {
6659        SendSysMessage(LANG_COMMAND_FREEZE_WRONG);
6660        return true;
6661    }
6662
6663    if (player==m_session->GetPlayer())
6664    {
6665        SendSysMessage(LANG_COMMAND_FREEZE_ERROR);
6666        return true;
6667    }
6668
6669    //effect
6670    if ((player) && (!(player==m_session->GetPlayer())))
6671    {
6672        PSendSysMessage(LANG_COMMAND_FREEZE,name.c_str());
6673
6674        //stop combat + make player unattackable + duel stop + stop some spells
6675        player->setFaction(35);
6676        player->CombatStop();
6677        if(player->IsNonMeleeSpellCasted(true))
6678            player->InterruptNonMeleeSpells(true);
6679        player->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
6680        player->SetUInt32Value(PLAYER_DUEL_TEAM, 1);
6681
6682        //if player class = hunter || warlock remove pet if alive
6683        if((player->getClass() == CLASS_HUNTER) || (player->getClass() == CLASS_WARLOCK))
6684        {
6685            if(Pet* pet = player->GetPet())
6686            {
6687                pet->SavePetToDB(PET_SAVE_AS_CURRENT);
6688                // not let dismiss dead pet
6689                if(pet && pet->isAlive())
6690                    player->RemovePet(pet,PET_SAVE_NOT_IN_SLOT);
6691            }
6692        }
6693
6694        //stop movement and disable spells
6695        uint32 spellID = 9454;
6696        //m_session->GetPlayer()->CastSpell(player,spellID,false);
6697        SpellEntry const *spellInfo = sSpellStore.LookupEntry( spellID );
6698        if(spellInfo) //TODO: Change the duration of the aura to -1 instead of 5000000
6699        {
6700            for(uint32 i = 0;i<3;i++)
6701            {
6702                uint8 eff = spellInfo->Effect[i];
6703                if (eff>=TOTAL_SPELL_EFFECTS)
6704                    continue;
6705                if( eff == SPELL_EFFECT_APPLY_AREA_AURA_PARTY || eff == SPELL_EFFECT_APPLY_AURA ||
6706                    eff == SPELL_EFFECT_PERSISTENT_AREA_AURA || eff == SPELL_EFFECT_APPLY_AREA_AURA_FRIEND || 
6707                    eff == SPELL_EFFECT_APPLY_AREA_AURA_ENEMY)
6708                {
6709                    Aura *Aur = CreateAura(spellInfo, i, NULL, player);
6710                    player->AddAura(Aur);
6711                }
6712            }
6713        }
6714
6715        //save player
6716        player->SaveToDB();
6717    }
6718    return true;
6719}
6720
6721bool ChatHandler::HandleUnFreezeCommand(const char *args)
6722{
6723    std::string name;
6724    Player* player;
6725    char* TargetName = strtok((char*)args, " "); //get entered name
6726    if (!TargetName) //if no name entered use target
6727    {
6728        player = getSelectedPlayer();
6729        if (player) //prevent crash with creature as target
6730        {   
6731            name = player->GetName();
6732        }
6733    }
6734
6735    else // if name entered
6736    {
6737        name = TargetName;
6738        normalizePlayerName(name);
6739        player = objmgr.GetPlayer(name.c_str()); //get player by name
6740    }
6741
6742    //effect
6743    if (player)
6744    {
6745        PSendSysMessage(LANG_COMMAND_UNFREEZE,name.c_str());
6746
6747        //Reset player faction + allow combat + allow duels
6748        player->setFactionForRace(player->getRace());
6749        player->RemoveFlag (UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
6750
6751        //allow movement and spells
6752        uint32 spellID = 9454;
6753        player->RemoveAurasDueToSpell(spellID);
6754
6755        //save player
6756        player->SaveToDB();
6757    }
6758
6759    if (!player)
6760    {
6761        if (TargetName)
6762        {       
6763            //check for offline players
6764            QueryResult *result = CharacterDatabase.PQuery("SELECT characters.guid FROM `characters` WHERE characters.name = '%s'",name.c_str());
6765            if(!result)
6766            {
6767                SendSysMessage(LANG_COMMAND_FREEZE_WRONG);
6768                return true;
6769            }
6770            //if player found: delete his freeze aura
6771            Field *fields=result->Fetch();
6772            uint64 pguid = fields[0].GetUInt64();
6773            delete result;
6774            CharacterDatabase.PQuery("DELETE FROM `character_aura` WHERE character_aura.spell = 9454 AND character_aura.guid = '%u'",pguid);
6775            PSendSysMessage(LANG_COMMAND_UNFREEZE,name.c_str());
6776            return true;
6777        }
6778        else
6779        {
6780            SendSysMessage(LANG_COMMAND_FREEZE_WRONG);
6781            return true;
6782        }
6783    }
6784
6785    return true;
6786}
6787
6788bool ChatHandler::HandleListFreezeCommand(const char* args)
6789{
6790    //Get names from DB
6791    QueryResult *result = CharacterDatabase.PQuery("SELECT characters.name FROM `characters` LEFT JOIN `character_aura` ON (characters.guid = character_aura.guid) WHERE character_aura.spell = 9454");
6792    if(!result)
6793    {
6794        SendSysMessage(LANG_COMMAND_NO_FROZEN_PLAYERS);
6795        return true;
6796    }
6797    //Header of the names
6798    PSendSysMessage(LANG_COMMAND_LIST_FREEZE);
6799
6800    //Output of the results
6801    do
6802    {
6803        Field *fields = result->Fetch();
6804        std::string fplayers = fields[0].GetCppString();
6805        PSendSysMessage(LANG_COMMAND_FROZEN_PLAYERS,fplayers.c_str());
6806    } while (result->NextRow());
6807
6808    delete result;
6809    return true;
6810}
6811
6812bool ChatHandler::HandleFlushArenaPointsCommand(const char * /*args*/)
6813{
6814    sBattleGroundMgr.DistributeArenaPoints();
6815    return true;
6816}
6817
6818bool ChatHandler::HandleGroupLeaderCommand(const char* args)
6819{
6820    Player* plr  = NULL;
6821    Group* group = NULL;
6822    uint64 guid  = 0;
6823    char* cname  = strtok((char*)args, " ");
6824
6825    if(GetPlayerGroupAndGUIDByName(cname, plr, group, guid))
6826        if(group && group->GetLeaderGUID() != guid)
6827            group->ChangeLeader(guid);
6828
6829    return true;
6830}
6831
6832bool ChatHandler::HandleGroupDisbandCommand(const char* args)
6833{
6834    Player* plr  = NULL;
6835    Group* group = NULL;
6836    uint64 guid  = 0;
6837    char* cname  = strtok((char*)args, " ");
6838
6839    if(GetPlayerGroupAndGUIDByName(cname, plr, group, guid))
6840        if(group)
6841            group->Disband();
6842
6843    return true;
6844}
6845
6846bool ChatHandler::HandleGroupRemoveCommand(const char* args)
6847{
6848    Player* plr  = NULL;
6849    Group* group = NULL;
6850    uint64 guid  = 0;
6851    char* cname  = strtok((char*)args, " ");
6852
6853    if(GetPlayerGroupAndGUIDByName(cname, plr, group, guid, true))
6854        if(group)
6855            group->RemoveMember(guid, 0);
6856
6857    return true;
6858}
6859
6860bool ChatHandler::HandlePossessCommand(const char* args)
6861{
6862    Unit* pUnit = getSelectedUnit();
6863    if(!pUnit)
6864        return false;
6865
6866    // Don't allow unlimited possession of players
6867    if (pUnit->GetTypeId() == TYPEID_PLAYER)
6868        return false;
6869
6870    m_session->GetPlayer()->Possess(pUnit);
6871
6872    return true;
6873}
6874
6875bool ChatHandler::HandleUnPossessCommand(const char* args)
6876{
6877    // Use this command to also unpossess ourselves
6878    if (m_session->GetPlayer()->isPossessed())
6879        m_session->GetPlayer()->UnpossessSelf(false);
6880    else
6881        m_session->GetPlayer()->RemovePossess(false);
6882
6883    return true;
6884}
6885
6886bool ChatHandler::HandleBindSightCommand(const char* args)
6887{
6888    Unit* pUnit = getSelectedUnit();
6889    if (!pUnit)
6890        return false;
6891       
6892    if (m_session->GetPlayer()->isPossessing())
6893        return false;
6894
6895    pUnit->AddPlayerToVision(m_session->GetPlayer());
6896
6897    return true;
6898}
6899
6900bool ChatHandler::HandleUnbindSightCommand(const char* args)
6901{
6902    if (m_session->GetPlayer()->isPossessing())
6903        return false;
6904       
6905    m_session->GetPlayer()->RemoveFarsightTarget();
6906    return true;
6907}
Note: See TracBrowser for help on using the browser.