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

Revision 40, 148.6 kB (checked in by yumileroy, 17 years ago)

[svn] * Changed: .respawn now respawns only single creature if selected. <3 Seline.
* Added: .nameannounce command. Includes name of announcer.

Original author: XTZGZoReX
Date: 2008-10-12 14:43:55-05:00

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