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

Revision 42, 150.5 kB (checked in by yumileroy, 17 years ago)

[svn] * Send ShutdownMsg? to console using outstring_log.
* Prevent Client Crashes when MOVEMENTFLAG_ONTRANSPORT and MOVEMENTFLAG_SPLINE2 is set on creatures.
* Implement four new SEC_ADMINISTRATOR commands:

  • Group (.group [leader]/[disband]/[remove]) commands.
  • GameObject? State (.gobject state <guid> <state>) command.

Original author: Seline
Date: 2008-10-12 18:26:26-05:00

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