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

Revision 6, 153.6 kB (checked in by yumileroy, 17 years ago)

[svn] * Added ACE for Linux and Windows (Thanks Derex for Linux part and partial Windows part)
* Updated to 6721 and 676
* Fixed TrinityScript? logo
* Version updated to 0.2.6721.676

Original author: Neo2003
Date: 2008-10-04 06:17:19-05:00

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