root/trunk/src/game/Level2.cpp @ 100

Revision 79, 118.6 kB (checked in by yumileroy, 17 years ago)

[svn] * Minor code fixes
* Move account related functions from ObjectMgr? to AccountMgr? and drop duplicate functions - source mangos
* recognize the dummy spells 38637, 38638 and 38639 as negative - source mangos
* added new command ".reload all_locales". Now all locales_* tables can be reloaded - source mangos

Original author: KingPin?
Date: 2008-10-20 12:59:45-05:00

Line 
1/*
2 * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
3 *
4 * Thanks to the original authors: MaNGOS <http://www.mangosproject.org/>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include "Common.h"
22#include "Database/DatabaseEnv.h"
23#include "WorldPacket.h"
24#include "WorldSession.h"
25#include "World.h"
26#include "ObjectMgr.h"
27#include "Player.h"
28#include "Item.h"
29#include "GameObject.h"
30#include "Opcodes.h"
31#include "Chat.h"
32#include "ObjectAccessor.h"
33#include "MapManager.h"
34#include "Language.h"
35#include "World.h"
36#include "GameEvent.h"
37#include "SpellMgr.h"
38#include "AccountMgr.h"
39#include "WaypointManager.h"
40#include "Util.h"
41#include <cctype>
42#include <iostream>
43#include <fstream>
44#include <map>
45
46static uint32 ReputationRankStrIndex[MAX_REPUTATION_RANK] =
47{
48    LANG_REP_HATED,    LANG_REP_HOSTILE, LANG_REP_UNFRIENDLY, LANG_REP_NEUTRAL,
49    LANG_REP_FRIENDLY, LANG_REP_HONORED, LANG_REP_REVERED,    LANG_REP_EXALTED
50};
51
52//mute player for some times
53bool ChatHandler::HandleMuteCommand(const char* args)
54{
55    if (!*args)
56        return false;
57
58    char *charname = strtok((char*)args, " ");
59    if (!charname)
60        return false;
61
62    std::string cname = charname;
63
64    char *timetonotspeak = strtok(NULL, " ");
65    if(!timetonotspeak)
66        return false;
67
68    uint32 notspeaktime = (uint32) atoi(timetonotspeak);
69
70    if(!normalizePlayerName(cname))
71    {
72        SendSysMessage(LANG_PLAYER_NOT_FOUND);
73        SetSentErrorMessage(true);
74        return false;
75    }
76
77    uint64 guid = objmgr.GetPlayerGUIDByName(cname.c_str());
78    if(!guid)
79    {
80        SendSysMessage(LANG_PLAYER_NOT_FOUND);
81        SetSentErrorMessage(true);
82        return false;
83    }
84
85    Player *chr = objmgr.GetPlayer(guid);
86
87    // check security
88    uint32 account_id = 0;
89    uint32 security = 0;
90
91    if (chr)
92    {
93        account_id = chr->GetSession()->GetAccountId();
94        security = chr->GetSession()->GetSecurity();
95    }
96    else
97    {
98        account_id = objmgr.GetPlayerAccountIdByGUID(guid);
99        security = accmgr.GetSecurity(account_id);
100    }
101
102    if(security >= m_session->GetSecurity())
103    {
104        SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
105        SetSentErrorMessage(true);
106        return false;
107    }
108
109    time_t mutetime = time(NULL) + notspeaktime*60;
110
111    if (chr)
112        chr->GetSession()->m_muteTime = mutetime;
113
114    loginDatabase.PExecute("UPDATE account SET mutetime = " I64FMTD " WHERE id = '%u'",uint64(mutetime), account_id );
115
116    if(chr)
117        ChatHandler(chr).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notspeaktime);
118
119    PSendSysMessage(LANG_YOU_DISABLE_CHAT, cname.c_str(), notspeaktime);
120
121    return true;
122}
123
124//unmute player
125bool ChatHandler::HandleUnmuteCommand(const char* args)
126{
127    if (!*args)
128        return false;
129
130    char *charname = strtok((char*)args, " ");
131    if (!charname)
132        return false;
133
134    std::string cname = charname;
135
136    if(!normalizePlayerName(cname))
137    {
138        SendSysMessage(LANG_PLAYER_NOT_FOUND);
139        SetSentErrorMessage(true);
140        return false;
141    }
142
143    uint64 guid = objmgr.GetPlayerGUIDByName(cname.c_str());
144    if(!guid)
145    {
146        SendSysMessage(LANG_PLAYER_NOT_FOUND);
147        SetSentErrorMessage(true);
148        return false;
149    }
150
151    Player *chr = objmgr.GetPlayer(guid);
152
153    // check security
154    uint32 account_id = 0;
155    uint32 security = 0;
156
157    if (chr)
158    {
159        account_id = chr->GetSession()->GetAccountId();
160        security = chr->GetSession()->GetSecurity();
161    }
162    else
163    {
164        account_id = objmgr.GetPlayerAccountIdByGUID(guid);
165        security = accmgr.GetSecurity(account_id);
166    }
167
168    if(security >= m_session->GetSecurity())
169    {
170        SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
171        SetSentErrorMessage(true);
172        return false;
173    }
174
175    if (chr)
176    {
177        if(chr->CanSpeak())
178        {
179            SendSysMessage(LANG_CHAT_ALREADY_ENABLED);
180            SetSentErrorMessage(true);
181            return false;
182        }
183
184        chr->GetSession()->m_muteTime = 0;
185    }
186
187    loginDatabase.PExecute("UPDATE account SET mutetime = '0' WHERE id = '%u'", account_id );
188
189    if(chr)
190        ChatHandler(chr).PSendSysMessage(LANG_YOUR_CHAT_ENABLED);
191
192    PSendSysMessage(LANG_YOU_ENABLE_CHAT, cname.c_str());
193    return true;
194}
195
196bool ChatHandler::HandleTargetObjectCommand(const char* args)
197{
198    Player* pl = m_session->GetPlayer();
199    QueryResult *result;
200    GameEvent::ActiveEvents const& activeEventsList = gameeventmgr.GetActiveEventList();
201    if(*args)
202    {
203        int32 id = atoi((char*)args);
204        if(id)
205            result = WorldDatabase.PQuery("SELECT guid, id, position_x, position_y, position_z, orientation, map, (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ FROM gameobject WHERE map = '%i' AND id = '%u' ORDER BY order_ ASC LIMIT 1",
206                pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), pl->GetMapId(),id);
207        else
208        {
209            std::string name = args;
210            WorldDatabase.escape_string(name);
211            result = WorldDatabase.PQuery(
212                "SELECT guid, id, position_x, position_y, position_z, orientation, map, (POW(position_x - %f, 2) + POW(position_y - %f, 2) + POW(position_z - %f, 2)) AS order_ "
213                "FROM gameobject,gameobject_template WHERE gameobject_template.entry = gameobject.id AND map = %i AND name "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")" ORDER BY order_ ASC LIMIT 1",
214                pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), pl->GetMapId(),name.c_str());
215        }
216    }
217    else
218    {
219        std::ostringstream eventFilter;
220        eventFilter << " AND (event IS NULL ";
221        bool initString = true;
222
223        for (GameEvent::ActiveEvents::const_iterator itr = activeEventsList.begin(); itr != activeEventsList.end(); ++itr)
224        {
225            if (initString)
226            {
227                eventFilter  <<  "OR event IN (" <<*itr;
228                initString =false;
229            }
230            else
231                eventFilter << "," << *itr;
232        }
233
234        if (!initString)
235            eventFilter << "))";
236        else
237            eventFilter << ")";
238
239        result = WorldDatabase.PQuery("SELECT gameobject.guid, id, position_x, position_y, position_z, orientation, map, "
240            "(POW(position_x - %f, 2) + POW(position_y - %f, 2) + POW(position_z - %f, 2)) AS order_ FROM gameobject "
241            "LEFT OUTER JOIN game_event_gameobject on gameobject.guid=game_event_gameobject.guid WHERE map = '%i' %s ORDER BY order_ ASC LIMIT 1",
242            m_session->GetPlayer()->GetPositionX(), m_session->GetPlayer()->GetPositionY(), m_session->GetPlayer()->GetPositionZ(), m_session->GetPlayer()->GetMapId(),eventFilter.str().c_str());
243    }
244
245    if (!result)
246    {
247        SendSysMessage(LANG_COMMAND_TARGETOBJNOTFOUND);
248        return true;
249    }
250
251    Field *fields = result->Fetch();
252    uint32 lowguid = fields[0].GetUInt32();
253    uint32 id = fields[1].GetUInt32();
254    float x = fields[2].GetFloat();
255    float y = fields[3].GetFloat();
256    float z = fields[4].GetFloat();
257    float o = fields[5].GetFloat();
258    int mapid = fields[6].GetUInt16();
259    delete result;
260
261    GameObjectInfo const* goI = objmgr.GetGameObjectInfo(id);
262
263    if (!goI)
264    {
265        PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST,id);
266        return false;
267    }
268
269    GameObject* target = ObjectAccessor::GetGameObject(*m_session->GetPlayer(),MAKE_NEW_GUID(lowguid,id,HIGHGUID_GAMEOBJECT));
270
271    PSendSysMessage(LANG_GAMEOBJECT_DETAIL, lowguid, goI->name, lowguid, id, x, y, z, mapid, o);
272
273    if(target)
274    {
275        int32 curRespawnDelay = target->GetRespawnTimeEx()-time(NULL);
276        if(curRespawnDelay < 0)
277            curRespawnDelay = 0;
278
279        std::string curRespawnDelayStr = secsToTimeString(curRespawnDelay,true);
280        std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(),true);
281
282        PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES, defRespawnDelayStr.c_str(),curRespawnDelayStr.c_str());
283    }
284    return true;
285}
286
287//teleport to gameobject
288bool ChatHandler::HandleGoObjectCommand(const char* args)
289{
290    if(!*args)
291        return false;
292
293    Player* _player = m_session->GetPlayer();
294
295    // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
296    char* cId = extractKeyFromLink((char*)args,"Hgameobject");
297    if(!cId)
298        return false;
299
300    int32 guid = atoi(cId);
301    if(!guid)
302        return false;
303
304    float x, y, z, ort;
305    int mapid;
306
307    // by DB guid
308    if (GameObjectData const* go_data = objmgr.GetGOData(guid))
309    {
310        x = go_data->posX;
311        y = go_data->posY;
312        z = go_data->posZ;
313        ort = go_data->orientation;
314        mapid = go_data->mapid;
315    }
316    else
317    {
318        SendSysMessage(LANG_COMMAND_GOOBJNOTFOUND);
319        SetSentErrorMessage(true);
320        return false;
321    }
322
323    if(!MapManager::IsValidMapCoord(mapid,x,y,z,ort))
324    {
325        PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid);
326        SetSentErrorMessage(true);
327        return false;
328    }
329
330    // stop flight if need
331    if(_player->isInFlight())
332    {
333        _player->GetMotionMaster()->MovementExpired();
334        _player->m_taxi.ClearTaxiDestinations();
335    }
336    // save only in non-flight case
337    else
338        _player->SaveRecallPosition();
339
340    _player->TeleportTo(mapid, x, y, z, ort);
341    return true;
342}
343
344bool ChatHandler::HandleGoTriggerCommand(const char* args)
345{
346    Player* _player = m_session->GetPlayer();
347
348    if (!*args)
349        return false;
350
351    char *atId = strtok((char*)args, " ");
352    if (!atId)
353        return false;
354
355    int32 i_atId = atoi(atId);
356
357    if(!i_atId)
358        return false;
359
360    AreaTriggerEntry const* at = sAreaTriggerStore.LookupEntry(i_atId);
361    if (!at)
362    {
363        PSendSysMessage(LANG_COMMAND_GOAREATRNOTFOUND,i_atId);
364        SetSentErrorMessage(true);
365        return false;
366    }
367
368    if(!MapManager::IsValidMapCoord(at->mapid,at->x,at->y,at->z))
369    {
370        PSendSysMessage(LANG_INVALID_TARGET_COORD,at->x,at->y,at->mapid);
371        SetSentErrorMessage(true);
372        return false;
373    }
374
375    // stop flight if need
376    if(_player->isInFlight())
377    {
378        _player->GetMotionMaster()->MovementExpired();
379        _player->m_taxi.ClearTaxiDestinations();
380    }
381    // save only in non-flight case
382    else
383        _player->SaveRecallPosition();
384
385    _player->TeleportTo(at->mapid, at->x, at->y, at->z, _player->GetOrientation());
386    return true;
387}
388
389bool ChatHandler::HandleGoGraveyardCommand(const char* args)
390{
391    Player* _player = m_session->GetPlayer();
392
393    if (!*args)
394        return false;
395
396    char *gyId = strtok((char*)args, " ");
397    if (!gyId)
398        return false;
399
400    int32 i_gyId = atoi(gyId);
401
402    if(!i_gyId)
403        return false;
404
405    WorldSafeLocsEntry const* gy = sWorldSafeLocsStore.LookupEntry(i_gyId);
406    if (!gy)
407    {
408        PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST,i_gyId);
409        SetSentErrorMessage(true);
410        return false;
411    }
412
413    if(!MapManager::IsValidMapCoord(gy->map_id,gy->x,gy->y,gy->z))
414    {
415        PSendSysMessage(LANG_INVALID_TARGET_COORD,gy->x,gy->y,gy->map_id);
416        SetSentErrorMessage(true);
417        return false;
418    }
419
420    // stop flight if need
421    if(_player->isInFlight())
422    {
423        _player->GetMotionMaster()->MovementExpired();
424        _player->m_taxi.ClearTaxiDestinations();
425    }
426    // save only in non-flight case
427    else
428        _player->SaveRecallPosition();
429
430    _player->TeleportTo(gy->map_id, gy->x, gy->y, gy->z, _player->GetOrientation());
431    return true;
432}
433
434/** \brief Teleport the GM to the specified creature
435 *
436 * .gocreature <GUID>      --> TP using creature.guid
437 * .gocreature azuregos    --> TP player to the mob with this name
438 *                             Warning: If there is more than one mob with this name
439 *                                      you will be teleported to the first one that is found.
440 * .gocreature id 6109     --> TP player to the mob, that has this creature_template.entry
441 *                             Warning: If there is more than one mob with this "id"
442 *                                      you will be teleported to the first one that is found.
443 */
444//teleport to creature
445bool ChatHandler::HandleGoCreatureCommand(const char* args)
446{
447    if(!*args)
448        return false;
449    Player* _player = m_session->GetPlayer();
450
451    // "id" or number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
452    char* pParam1 = extractKeyFromLink((char*)args,"Hcreature");
453    if (!pParam1)
454        return false;
455
456    std::ostringstream whereClause;
457
458    // User wants to teleport to the NPC's template entry
459    if( strcmp(pParam1, "id") == 0 )
460    {
461        //sLog.outError("DEBUG: ID found");
462
463        // Get the "creature_template.entry"
464        // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
465        char* tail = strtok(NULL,"");
466        if(!tail)
467            return false;
468        char* cId = extractKeyFromLink(tail,"Hcreature_entry");
469        if(!cId)
470            return false;
471
472        int32 tEntry = atoi(cId);
473        //sLog.outError("DEBUG: ID value: %d", tEntry);
474        if(!tEntry)
475            return false;
476
477        whereClause << "WHERE id = '" << tEntry << "'";
478    }
479    else
480    {
481        //sLog.outError("DEBUG: ID *not found*");
482
483        int32 guid = atoi(pParam1);
484
485        // Number is invalid - maybe the user specified the mob's name
486        if(!guid)
487        {
488            std::string name = pParam1;
489            WorldDatabase.escape_string(name);
490            whereClause << ", creature_template WHERE creature.id = creature_template.entry AND creature_template.name "_LIKE_" '" << name << "'";
491        }
492        else
493        {
494            whereClause <<  "WHERE guid = '" << guid << "'";
495        }
496    }
497    //sLog.outError("DEBUG: %s", whereClause.c_str());
498
499    QueryResult *result = WorldDatabase.PQuery("SELECT position_x,position_y,position_z,orientation,map FROM creature %s", whereClause.str().c_str() );
500    if (!result)
501    {
502        SendSysMessage(LANG_COMMAND_GOCREATNOTFOUND);
503        SetSentErrorMessage(true);
504        return false;
505    }
506    if( result->GetRowCount() > 1 )
507    {
508        SendSysMessage(LANG_COMMAND_GOCREATMULTIPLE);
509    }
510
511    Field *fields = result->Fetch();
512    float x = fields[0].GetFloat();
513    float y = fields[1].GetFloat();
514    float z = fields[2].GetFloat();
515    float ort = fields[3].GetFloat();
516    int mapid = fields[4].GetUInt16();
517
518    delete result;
519
520    if(!MapManager::IsValidMapCoord(mapid,x,y,z,ort))
521    {
522        PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid);
523        SetSentErrorMessage(true);
524        return false;
525    }
526
527    // stop flight if need
528    if(_player->isInFlight())
529    {
530        _player->GetMotionMaster()->MovementExpired();
531        _player->m_taxi.ClearTaxiDestinations();
532    }
533    // save only in non-flight case
534    else
535        _player->SaveRecallPosition();
536
537    _player->TeleportTo(mapid, x, y, z, ort);
538    return true;
539}
540
541bool ChatHandler::HandleGUIDCommand(const char* /*args*/)
542{
543    uint64 guid = m_session->GetPlayer()->GetSelection();
544
545    if (guid == 0)
546    {
547        SendSysMessage(LANG_NO_SELECTION);
548        SetSentErrorMessage(true);
549        return false;
550    }
551
552    PSendSysMessage(LANG_OBJECT_GUID, GUID_LOPART(guid), GUID_HIPART(guid));
553    return true;
554}
555
556bool ChatHandler::HandleLookupFactionCommand(const char* args)
557{
558    if(!*args)
559        return false;
560
561    Player *target = getSelectedPlayer();
562    if (!target)
563    {
564        SendSysMessage(LANG_NO_CHAR_SELECTED);
565        SetSentErrorMessage(true);
566        return false;
567    }
568
569    std::string namepart = args;
570    std::wstring wnamepart;
571
572    if(!Utf8toWStr(namepart,wnamepart))
573        return false;
574
575    // converting string that we try to find to lower case
576    wstrToLower( wnamepart );
577
578    uint32 counter = 0;                                     // Counter for figure out that we found smth.
579
580    for (uint32 id = 0; id < sFactionStore.GetNumRows(); id++)
581        //for(FactionStateList::const_iterator itr = target->m_factions.begin(); itr != target->m_factions.end(); ++itr)
582    {
583        FactionEntry const *factionEntry = sFactionStore.LookupEntry(id);
584        //FactionEntry const *factionEntry = sFactionStore.LookupEntry(itr->second.ID);
585        if (factionEntry)
586        {
587            FactionStateList::const_iterator repItr = target->m_factions.find(factionEntry->reputationListID);
588
589            int loc = m_session->GetSessionDbcLocale();
590            std::string name = factionEntry->name[loc];
591            if(name.empty())
592                continue;
593
594            if (!Utf8FitTo(name, wnamepart))
595            {
596                loc = 0;
597                for(; loc < MAX_LOCALE; ++loc)
598                {
599                    if(loc==m_session->GetSessionDbcLocale())
600                        continue;
601
602                    name = factionEntry->name[loc];
603                    if(name.empty())
604                        continue;
605
606                    if (Utf8FitTo(name, wnamepart))
607                        break;
608                }
609            }
610
611            if(loc < MAX_LOCALE)
612            {
613                // send faction in "id - [faction] rank reputation [visible] [at war] [own team] [unknown] [invisible] [inactive]" format
614                // or              "id - [faction] [no reputation]" format
615                std::ostringstream ss;
616                ss << id << " - |cffffffff|Hfaction:" << id << "|h[" << name << " " << localeNames[loc] << "]|h|r";
617
618                if (repItr != target->m_factions.end())
619                {
620                    ReputationRank rank = target->GetReputationRank(factionEntry);
621                    std::string rankName = GetTrinityString(ReputationRankStrIndex[rank]);
622
623                    ss << " " << rankName << "|h|r (" << target->GetReputation(factionEntry) << ")";
624
625                    if(repItr->second.Flags & FACTION_FLAG_VISIBLE)
626                        ss << GetTrinityString(LANG_FACTION_VISIBLE);
627                    if(repItr->second.Flags & FACTION_FLAG_AT_WAR)
628                        ss << GetTrinityString(LANG_FACTION_ATWAR);
629                    if(repItr->second.Flags & FACTION_FLAG_PEACE_FORCED)
630                        ss << GetTrinityString(LANG_FACTION_PEACE_FORCED);
631                    if(repItr->second.Flags & FACTION_FLAG_HIDDEN)
632                        ss << GetTrinityString(LANG_FACTION_HIDDEN);
633                    if(repItr->second.Flags & FACTION_FLAG_INVISIBLE_FORCED)
634                        ss << GetTrinityString(LANG_FACTION_INVISIBLE_FORCED);
635                    if(repItr->second.Flags & FACTION_FLAG_INACTIVE)
636                        ss << GetTrinityString(LANG_FACTION_INACTIVE);
637                }
638                else
639                    ss << GetTrinityString(LANG_FACTION_NOREPUTATION);
640
641                SendSysMessage(ss.str().c_str());
642                counter++;
643            }
644        }
645    }
646
647    if (counter == 0)                                       // if counter == 0 then we found nth
648        SendSysMessage(LANG_COMMAND_FACTION_NOTFOUND);
649    return true;
650}
651
652bool ChatHandler::HandleModifyRepCommand(const char * args)
653{
654    if (!*args) return false;
655
656    Player* target = NULL;
657    target = getSelectedPlayer();
658
659    if(!target)
660    {
661        SendSysMessage(LANG_PLAYER_NOT_FOUND);
662        SetSentErrorMessage(true);
663        return false;
664    }
665
666    char* factionTxt = extractKeyFromLink((char*)args,"Hfaction");
667    if(!factionTxt)
668        return false;
669
670    uint32 factionId = atoi(factionTxt);
671
672    int32 amount = 0;
673    char *rankTxt = strtok(NULL, " ");
674    if (!factionTxt || !rankTxt)
675        return false;
676
677    amount = atoi(rankTxt);
678    if ((amount == 0) && (rankTxt[0] != '-') && !isdigit(rankTxt[0]))
679    {
680        std::string rankStr = rankTxt;
681        std::wstring wrankStr;
682        if(!Utf8toWStr(rankStr,wrankStr))
683            return false;
684        wstrToLower( wrankStr );
685
686        int r = 0;
687        amount = -42000;
688        for (; r < MAX_REPUTATION_RANK; ++r)
689        {
690            std::string rank = GetTrinityString(ReputationRankStrIndex[r]);
691            if(rank.empty())
692                continue;
693
694            std::wstring wrank;
695            if(!Utf8toWStr(rank,wrank))
696                continue;
697
698            wstrToLower(wrank);
699
700            if(wrank.substr(0,wrankStr.size())==wrankStr)
701            {
702                char *deltaTxt = strtok(NULL, " ");
703                if (deltaTxt)
704                {
705                    int32 delta = atoi(deltaTxt);
706                    if ((delta < 0) || (delta > Player::ReputationRank_Length[r] -1))
707                    {
708                        PSendSysMessage(LANG_COMMAND_FACTION_DELTA, (Player::ReputationRank_Length[r]-1));
709                        SetSentErrorMessage(true);
710                        return false;
711                    }
712                    amount += delta;
713                }
714                break;
715            }
716            amount += Player::ReputationRank_Length[r];
717        }
718        if (r >= MAX_REPUTATION_RANK)
719        {
720            PSendSysMessage(LANG_COMMAND_FACTION_INVPARAM, rankTxt);
721            SetSentErrorMessage(true);
722            return false;
723        }
724    }
725
726    FactionEntry const *factionEntry = sFactionStore.LookupEntry(factionId);
727
728    if (!factionEntry)
729    {
730        PSendSysMessage(LANG_COMMAND_FACTION_UNKNOWN, factionId);
731        SetSentErrorMessage(true);
732        return false;
733    }
734
735    if (factionEntry->reputationListID < 0)
736    {
737        PSendSysMessage(LANG_COMMAND_FACTION_NOREP_ERROR, factionEntry->name[m_session->GetSessionDbcLocale()], factionId);
738        SetSentErrorMessage(true);
739        return false;
740    }
741
742    target->SetFactionReputation(factionEntry,amount);
743    PSendSysMessage(LANG_COMMAND_MODIFY_REP, factionEntry->name[m_session->GetSessionDbcLocale()], factionId, target->GetName(), target->GetReputation(factionId));
744    return true;
745}
746
747bool ChatHandler::HandleNameCommand(const char* args)
748{
749    /* Temp. disabled
750        if(!*args)
751            return false;
752
753        if(strlen((char*)args)>75)
754        {
755            PSendSysMessage(LANG_TOO_LONG_NAME, strlen((char*)args)-75);
756            return true;
757        }
758
759        for (uint8 i = 0; i < strlen(args); i++)
760        {
761            if(!isalpha(args[i]) && args[i]!=' ')
762            {
763                SendSysMessage(LANG_CHARS_ONLY);
764                return false;
765            }
766        }
767
768        uint64 guid;
769        guid = m_session->GetPlayer()->GetSelection();
770        if (guid == 0)
771        {
772            SendSysMessage(LANG_NO_SELECTION);
773            return true;
774        }
775
776        Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
777
778        if(!pCreature)
779        {
780            SendSysMessage(LANG_SELECT_CREATURE);
781            return true;
782        }
783
784        pCreature->SetName(args);
785        uint32 idname = objmgr.AddCreatureTemplate(pCreature->GetName());
786        pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname);
787
788        pCreature->SaveToDB();
789    */
790
791    return true;
792}
793
794bool ChatHandler::HandleSubNameCommand(const char* /*args*/)
795{
796    /* Temp. disabled
797
798    if(!*args)
799        args = "";
800
801    if(strlen((char*)args)>75)
802    {
803
804        PSendSysMessage(LANG_TOO_LONG_SUBNAME, strlen((char*)args)-75);
805        return true;
806    }
807
808    for (uint8 i = 0; i < strlen(args); i++)
809    {
810        if(!isalpha(args[i]) && args[i]!=' ')
811        {
812            SendSysMessage(LANG_CHARS_ONLY);
813            return false;
814        }
815    }
816    uint64 guid;
817    guid = m_session->GetPlayer()->GetSelection();
818    if (guid == 0)
819    {
820        SendSysMessage(LANG_NO_SELECTION);
821        return true;
822    }
823
824    Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
825
826    if(!pCreature)
827    {
828        SendSysMessage(LANG_SELECT_CREATURE);
829        return true;
830    }
831
832    uint32 idname = objmgr.AddCreatureSubName(pCreature->GetName(),args,pCreature->GetUInt32Value(UNIT_FIELD_DISPLAYID));
833    pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname);
834
835    pCreature->SaveToDB();
836    */
837    return true;
838}
839
840//move item to other slot
841bool ChatHandler::HandleItemMoveCommand(const char* args)
842{
843    if(!*args)
844        return false;
845    uint8 srcslot, dstslot;
846
847    char* pParam1 = strtok((char*)args, " ");
848    if (!pParam1)
849        return false;
850
851    char* pParam2 = strtok(NULL, " ");
852    if (!pParam2)
853        return false;
854
855    srcslot = (uint8)atoi(pParam1);
856    dstslot = (uint8)atoi(pParam2);
857
858    uint16 src = ((INVENTORY_SLOT_BAG_0 << 8) | srcslot);
859    uint16 dst = ((INVENTORY_SLOT_BAG_0 << 8) | dstslot);
860
861    if(srcslot==dstslot)
862        return true;
863
864    m_session->GetPlayer()->SwapItem( src, dst );
865
866    return true;
867}
868
869//add spawn of creature
870bool ChatHandler::HandleAddSpwCommand(const char* args)
871{
872    if(!*args)
873        return false;
874    char* charID = strtok((char*)args, " ");
875    if (!charID)
876        return false;
877
878    char* team = strtok(NULL, " ");
879    int32 teamval = 0;
880    if (team) { teamval = atoi(team); }
881    if (teamval < 0) { teamval = 0; }
882
883    uint32 id  = atoi(charID);
884
885    Player *chr = m_session->GetPlayer();
886    float x = chr->GetPositionX();
887    float y = chr->GetPositionY();
888    float z = chr->GetPositionZ();
889    float o = chr->GetOrientation();
890    Map *map = chr->GetMap();
891
892    Creature* pCreature = new Creature;
893    if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, id, (uint32)teamval))
894    {
895        delete pCreature;
896        return false;
897    }
898
899    pCreature->Relocate(x,y,z,o);
900
901    if(!pCreature->IsPositionValid())
902    {
903        sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY());
904        delete pCreature;
905        return false;
906    }
907
908    pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
909
910    uint32 db_guid = pCreature->GetDBTableGUIDLow();
911
912    // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
913    pCreature->LoadFromDB(db_guid, map);
914
915    map->Add(pCreature);
916    objmgr.AddCreatureToGrid(db_guid, objmgr.GetCreatureData(db_guid));
917    return true;
918}
919
920bool ChatHandler::HandleDelCreatureCommand(const char* args)
921{
922    Creature* unit = NULL;
923
924    if(*args)
925    {
926        // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r
927        char* cId = extractKeyFromLink((char*)args,"Hcreature");
928        if(!cId)
929            return false;
930
931        uint32 lowguid = atoi(cId);
932        if(!lowguid)
933            return false;
934
935        if (CreatureData const* cr_data = objmgr.GetCreatureData(lowguid))
936            unit = ObjectAccessor::GetCreature(*m_session->GetPlayer(), MAKE_NEW_GUID(lowguid, cr_data->id, HIGHGUID_UNIT));
937    }
938    else
939        unit = getSelectedCreature();
940
941    if(!unit || unit->isPet() || unit->isTotem())
942    {
943        SendSysMessage(LANG_SELECT_CREATURE);
944        SetSentErrorMessage(true);
945        return false;
946    }
947
948    // Delete the creature
949    unit->CombatStop();
950    unit->DeleteFromDB();
951    unit->CleanupsBeforeDelete();
952    unit->AddObjectToRemoveList();
953
954    SendSysMessage(LANG_COMMAND_DELCREATMESSAGE);
955
956    return true;
957}
958
959//delete object by selection or guid
960bool ChatHandler::HandleDelObjectCommand(const char* args)
961{
962    // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
963    char* cId = extractKeyFromLink((char*)args,"Hgameobject");
964    if(!cId)
965        return false;
966
967    uint32 lowguid = atoi(cId);
968    if(!lowguid)
969        return false;
970
971    GameObject* obj = NULL;
972
973    // by DB guid
974    if (GameObjectData const* go_data = objmgr.GetGOData(lowguid))
975        obj = GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid,go_data->id);
976
977    if(!obj)
978    {
979        PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid);
980        SetSentErrorMessage(true);
981        return false;
982    }
983
984    uint64 owner_guid = obj->GetOwnerGUID();
985    if(owner_guid)
986    {
987        Unit* owner = ObjectAccessor::GetUnit(*m_session->GetPlayer(),owner_guid);
988        if(!owner && !IS_PLAYER_GUID(owner_guid))
989        {
990            PSendSysMessage(LANG_COMMAND_DELOBJREFERCREATURE, GUID_LOPART(owner_guid), obj->GetGUIDLow());
991            SetSentErrorMessage(true);
992            return false;
993        }
994
995        owner->RemoveGameObject(obj,false);
996    }
997
998    obj->SetRespawnTime(0);                                 // not save respawn time
999    obj->Delete();
1000    obj->DeleteFromDB();
1001
1002    PSendSysMessage(LANG_COMMAND_DELOBJMESSAGE, obj->GetGUIDLow());
1003
1004    return true;
1005}
1006
1007//turn selected object
1008bool ChatHandler::HandleTurnObjectCommand(const char* args)
1009{
1010    // number or [name] Shift-click form |color|Hgameobject:go_id|h[name]|h|r
1011    char* cId = extractKeyFromLink((char*)args,"Hgameobject");
1012    if(!cId)
1013        return false;
1014
1015    uint32 lowguid = atoi(cId);
1016    if(!lowguid)
1017        return false;
1018
1019    GameObject* obj = NULL;
1020
1021    // by DB guid
1022    if (GameObjectData const* go_data = objmgr.GetGOData(lowguid))
1023        obj = GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid,go_data->id);
1024
1025    if(!obj)
1026    {
1027        PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid);
1028        SetSentErrorMessage(true);
1029        return false;
1030    }
1031
1032    char* po = strtok(NULL, " ");
1033    float o;
1034
1035    if (po)
1036    {
1037        o = (float)atof(po);
1038    }
1039    else
1040    {
1041        Player *chr = m_session->GetPlayer();
1042        o = chr->GetOrientation();
1043    }
1044
1045    float rot2 = sin(o/2);
1046    float rot3 = cos(o/2);
1047
1048    Map* map = MapManager::Instance().GetMap(obj->GetMapId(),obj);
1049    map->Remove(obj,false);
1050
1051    obj->Relocate(obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), o);
1052
1053    obj->SetFloatValue(GAMEOBJECT_FACING, o);
1054    obj->SetFloatValue(GAMEOBJECT_ROTATION+2, rot2);
1055    obj->SetFloatValue(GAMEOBJECT_ROTATION+3, rot3);
1056
1057    map->Add(obj);
1058
1059    obj->SaveToDB();
1060    obj->Refresh();
1061
1062    PSendSysMessage(LANG_COMMAND_TURNOBJMESSAGE, obj->GetGUIDLow(), o);
1063
1064    return true;
1065}
1066
1067//move selected creature
1068bool ChatHandler::HandleMoveCreatureCommand(const char* args)
1069{
1070    uint32 lowguid = 0;
1071
1072    Creature* pCreature = getSelectedCreature();
1073
1074    if(!pCreature)
1075    {
1076        // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r
1077        char* cId = extractKeyFromLink((char*)args,"Hcreature");
1078        if(!cId)
1079            return false;
1080
1081        uint32 lowguid = atoi(cId);
1082
1083        /* FIXME: impossibel without entry
1084        if(lowguid)
1085            pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
1086        */
1087
1088        // Attempting creature load from DB data
1089        if(!pCreature)
1090        {
1091            CreatureData const* data = objmgr.GetCreatureData(lowguid);
1092            if(!data)
1093            {
1094                PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid);
1095                SetSentErrorMessage(true);
1096                return false;
1097            }
1098
1099            uint32 map_id = data->mapid;
1100
1101            if(m_session->GetPlayer()->GetMapId()!=map_id)
1102            {
1103                PSendSysMessage(LANG_COMMAND_CREATUREATSAMEMAP, lowguid);
1104                SetSentErrorMessage(true);
1105                return false;
1106            }
1107        }
1108        else
1109        {
1110            lowguid = pCreature->GetDBTableGUIDLow();
1111        }
1112    }
1113    else
1114    {
1115        lowguid = pCreature->GetDBTableGUIDLow();
1116    }
1117
1118    float x = m_session->GetPlayer()->GetPositionX();
1119    float y = m_session->GetPlayer()->GetPositionY();
1120    float z = m_session->GetPlayer()->GetPositionZ();
1121    float o = m_session->GetPlayer()->GetOrientation();
1122
1123    if (pCreature)
1124    {
1125        if(CreatureData const* data = objmgr.GetCreatureData(pCreature->GetDBTableGUIDLow()))
1126        {
1127            const_cast<CreatureData*>(data)->posX = x;
1128            const_cast<CreatureData*>(data)->posY = y;
1129            const_cast<CreatureData*>(data)->posZ = z;
1130            const_cast<CreatureData*>(data)->orientation = o;
1131        }
1132        MapManager::Instance().GetMap(pCreature->GetMapId(),pCreature)->CreatureRelocation(pCreature,x, y, z,o);
1133        pCreature->GetMotionMaster()->Initialize();
1134        if(pCreature->isAlive())                            // dead creature will reset movement generator at respawn
1135        {
1136            pCreature->setDeathState(JUST_DIED);
1137            pCreature->Respawn();
1138        }
1139    }
1140
1141    WorldDatabase.PExecuteLog("UPDATE creature SET position_x = '%f', position_y = '%f', position_z = '%f', orientation = '%f' WHERE guid = '%u'", x, y, z, o, lowguid);
1142    PSendSysMessage(LANG_COMMAND_CREATUREMOVED);
1143    return true;
1144}
1145
1146//move selected object
1147bool ChatHandler::HandleMoveObjectCommand(const char* args)
1148{
1149    // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
1150    char* cId = extractKeyFromLink((char*)args,"Hgameobject");
1151    if(!cId)
1152        return false;
1153
1154    uint32 lowguid = atoi(cId);
1155    if(!lowguid)
1156        return false;
1157
1158    GameObject* obj = NULL;
1159
1160    // by DB guid
1161    if (GameObjectData const* go_data = objmgr.GetGOData(lowguid))
1162        obj = GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid,go_data->id);
1163
1164    if(!obj)
1165    {
1166        PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid);
1167        SetSentErrorMessage(true);
1168        return false;
1169    }
1170
1171    char* px = strtok(NULL, " ");
1172    char* py = strtok(NULL, " ");
1173    char* pz = strtok(NULL, " ");
1174
1175    if (!px)
1176    {
1177        Player *chr = m_session->GetPlayer();
1178
1179        Map* map = MapManager::Instance().GetMap(obj->GetMapId(),obj);
1180        map->Remove(obj,false);
1181
1182        obj->Relocate(chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), obj->GetOrientation());
1183        obj->SetFloatValue(GAMEOBJECT_POS_X, chr->GetPositionX());
1184        obj->SetFloatValue(GAMEOBJECT_POS_Y, chr->GetPositionY());
1185        obj->SetFloatValue(GAMEOBJECT_POS_Z, chr->GetPositionZ());
1186
1187        map->Add(obj);
1188    }
1189    else
1190    {
1191        if(!py || !pz)
1192            return false;
1193
1194        float x = (float)atof(px);
1195        float y = (float)atof(py);
1196        float z = (float)atof(pz);
1197
1198        if(!MapManager::IsValidMapCoord(obj->GetMapId(),x,y,z))
1199        {
1200            PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,obj->GetMapId());
1201            SetSentErrorMessage(true);
1202            return false;
1203        }
1204
1205        Map* map = MapManager::Instance().GetMap(obj->GetMapId(),obj);
1206        map->Remove(obj,false);
1207
1208        obj->Relocate(x, y, z, obj->GetOrientation());
1209        obj->SetFloatValue(GAMEOBJECT_POS_X, x);
1210        obj->SetFloatValue(GAMEOBJECT_POS_Y, y);
1211        obj->SetFloatValue(GAMEOBJECT_POS_Z, z);
1212
1213        map->Add(obj);
1214    }
1215
1216    obj->SaveToDB();
1217    obj->Refresh();
1218
1219    PSendSysMessage(LANG_COMMAND_MOVEOBJMESSAGE, obj->GetGUIDLow());
1220
1221    return true;
1222}
1223
1224//demorph player or unit
1225bool ChatHandler::HandleDeMorphCommand(const char* /*args*/)
1226{
1227    Unit *target = getSelectedUnit();
1228    if(!target)
1229        target = m_session->GetPlayer();
1230
1231    target->DeMorph();
1232
1233    return true;
1234}
1235
1236//add item in vendorlist
1237bool ChatHandler::HandleAddVendorItemCommand(const char* args)
1238{
1239    if (!*args)
1240        return false;
1241
1242    char* pitem  = extractKeyFromLink((char*)args,"Hitem");
1243    if (!pitem)
1244    {
1245        SendSysMessage(LANG_COMMAND_NEEDITEMSEND);
1246        SetSentErrorMessage(true);
1247        return false;
1248    }
1249
1250    uint32 itemId = atol(pitem);
1251
1252    char* fmaxcount = strtok(NULL, " ");                    //add maxcount, default: 0
1253    uint32 maxcount = 0;
1254    if (fmaxcount)
1255        maxcount = atol(fmaxcount);
1256
1257    char* fincrtime = strtok(NULL, " ");                    //add incrtime, default: 0
1258    uint32 incrtime = 0;
1259    if (fincrtime)
1260        incrtime = atol(fincrtime);
1261
1262    char* fextendedcost = strtok(NULL, " ");                //add ExtendedCost, default: 0
1263    uint32 extendedcost = fextendedcost ? atol(fextendedcost) : 0;
1264
1265    Creature* vendor = getSelectedCreature();
1266
1267    uint32 vendor_entry = vendor ? vendor->GetEntry() : 0;
1268
1269    if(!objmgr.IsVendorItemValid(vendor_entry,itemId,maxcount,incrtime,extendedcost,m_session->GetPlayer()))
1270    {
1271        SetSentErrorMessage(true);
1272        return false;
1273    }
1274
1275    objmgr.AddVendorItem(vendor_entry,itemId,maxcount,incrtime,extendedcost);
1276
1277    ItemPrototype const* pProto = objmgr.GetItemPrototype(itemId);
1278
1279    PSendSysMessage(LANG_ITEM_ADDED_TO_LIST,itemId,pProto->Name1,maxcount,incrtime,extendedcost);
1280    return true;
1281}
1282
1283//del item from vendor list
1284bool ChatHandler::HandleDelVendorItemCommand(const char* args)
1285{
1286    if (!*args)
1287        return false;
1288
1289    Creature* vendor = getSelectedCreature();
1290    if (!vendor || !vendor->isVendor())
1291    {
1292        SendSysMessage(LANG_COMMAND_VENDORSELECTION);
1293        SetSentErrorMessage(true);
1294        return false;
1295    }
1296
1297    char* pitem  = extractKeyFromLink((char*)args,"Hitem");
1298    if (!pitem)
1299    {
1300        SendSysMessage(LANG_COMMAND_NEEDITEMSEND);
1301        SetSentErrorMessage(true);
1302        return false;
1303    }
1304    uint32 itemId = atol(pitem);
1305
1306
1307    if(!objmgr.RemoveVendorItem(vendor->GetEntry(),itemId))
1308    {
1309        PSendSysMessage(LANG_ITEM_NOT_IN_LIST,itemId);
1310        SetSentErrorMessage(true);
1311        return false;
1312    }
1313
1314    ItemPrototype const* pProto = objmgr.GetItemPrototype(itemId);
1315
1316    PSendSysMessage(LANG_ITEM_DELETED_FROM_LIST,itemId,pProto->Name1);
1317    return true;
1318}
1319
1320//add move for creature
1321bool ChatHandler::HandleAddMoveCommand(const char* args)
1322{
1323    if(!*args)
1324        return false;
1325
1326    char* guid_str = strtok((char*)args, " ");
1327    char* wait_str = strtok((char*)NULL, " ");
1328
1329    uint32 lowguid = atoi((char*)guid_str);
1330
1331    Creature* pCreature = NULL;
1332
1333    /* FIXME: impossible without entry
1334    if(lowguid)
1335        pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
1336    */
1337
1338    // attempt check creature existence by DB data
1339    if(!pCreature)
1340    {
1341        CreatureData const* data = objmgr.GetCreatureData(lowguid);
1342        if(!data)
1343        {
1344            PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid);
1345            SetSentErrorMessage(true);
1346            return false;
1347        }
1348    }
1349    else
1350    {
1351        // obtain real GUID for DB operations
1352        lowguid = pCreature->GetDBTableGUIDLow();
1353    }
1354
1355    int wait = wait_str ? atoi(wait_str) : 0;
1356
1357    if(wait < 0)
1358        wait = 0;
1359
1360    Player* player = m_session->GetPlayer();
1361
1362    WaypointMgr.AddLastNode(lowguid, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation(), wait, 0);
1363
1364    // update movement type
1365    WorldDatabase.PExecuteLog("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE,lowguid);
1366    if(pCreature)
1367    {
1368        pCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
1369        pCreature->GetMotionMaster()->Initialize();
1370        if(pCreature->isAlive())                            // dead creature will reset movement generator at respawn
1371        {
1372            pCreature->setDeathState(JUST_DIED);
1373            pCreature->Respawn();
1374        }
1375        pCreature->SaveToDB();
1376    }
1377
1378    SendSysMessage(LANG_WAYPOINT_ADDED);
1379
1380    return true;
1381}
1382
1383/**
1384 * Set the movement type for an NPC.<br/>
1385 * <br/>
1386 * Valid movement types are:
1387 * <ul>
1388 * <li> stay - NPC wont move </li>
1389 * <li> random - NPC will move randomly according to the spawndist </li>
1390 * <li> way - NPC will move with given waypoints set </li>
1391 * </ul>
1392 * additional parameter: NODEL - so no waypoints are deleted, if you
1393 *                       change the movement type
1394 */
1395bool ChatHandler::HandleSetMoveTypeCommand(const char* args)
1396{
1397    if(!*args)
1398        return false;
1399
1400    // 3 arguments:
1401    // GUID (optional - you can also select the creature)
1402    // stay|random|way (determines the kind of movement)
1403    // NODEL (optional - tells the system NOT to delete any waypoints)
1404    //        this is very handy if you want to do waypoints, that are
1405    //        later switched on/off according to special events (like escort
1406    //        quests, etc)
1407    char* guid_str = strtok((char*)args, " ");
1408    char* type_str = strtok((char*)NULL, " ");
1409    char* dontdel_str = strtok((char*)NULL, " ");
1410
1411    bool doNotDelete = false;
1412
1413    if(!guid_str)
1414        return false;
1415
1416    uint32 lowguid = 0;
1417    Creature* pCreature = NULL;
1418
1419    if( dontdel_str )
1420    {
1421        //sLog.outError("DEBUG: All 3 params are set");
1422
1423        // All 3 params are set
1424        // GUID
1425        // type
1426        // doNotDEL
1427        if( stricmp( dontdel_str, "NODEL" ) == 0 )
1428        {
1429            //sLog.outError("DEBUG: doNotDelete = true;");
1430            doNotDelete = true;
1431        }
1432    }
1433    else
1434    {
1435        // Only 2 params - but maybe NODEL is set
1436        if( type_str )
1437        {
1438            sLog.outError("DEBUG: Only 2 params ");
1439            if( stricmp( type_str, "NODEL" ) == 0 )
1440            {
1441                //sLog.outError("DEBUG: type_str, NODEL ");
1442                doNotDelete = true;
1443                type_str = NULL;
1444            }
1445        }
1446    }
1447
1448    if(!type_str)                                           // case .setmovetype $move_type (with selected creature)
1449    {
1450        type_str = guid_str;
1451        pCreature = getSelectedCreature();
1452        if(!pCreature || pCreature->isPet())
1453            return false;
1454        lowguid = pCreature->GetDBTableGUIDLow();
1455    }
1456    else                                                    // case .setmovetype #creature_guid $move_type (with selected creature)
1457    {
1458        lowguid = atoi((char*)guid_str);
1459
1460        /* impossible without entry
1461        if(lowguid)
1462            pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
1463        */
1464
1465        // attempt check creature existence by DB data
1466        if(!pCreature)
1467        {
1468            CreatureData const* data = objmgr.GetCreatureData(lowguid);
1469            if(!data)
1470            {
1471                PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid);
1472                SetSentErrorMessage(true);
1473                return false;
1474            }
1475        }
1476        else
1477        {
1478            lowguid = pCreature->GetDBTableGUIDLow();
1479        }
1480    }
1481
1482    // now lowguid is low guid really existed creature
1483    // and pCreature point (maybe) to this creature or NULL
1484
1485    MovementGeneratorType move_type;
1486
1487    std::string type = type_str;
1488
1489    if(type == "stay")
1490        move_type = IDLE_MOTION_TYPE;
1491    else if(type == "random")
1492        move_type = RANDOM_MOTION_TYPE;
1493    else if(type == "way")
1494        move_type = WAYPOINT_MOTION_TYPE;
1495    else
1496        return false;
1497
1498    // update movement type
1499    if(doNotDelete == false)
1500        WaypointMgr.DeletePath(lowguid);
1501
1502    if(pCreature)
1503    {
1504        pCreature->SetDefaultMovementType(move_type);
1505        pCreature->GetMotionMaster()->Initialize();
1506        if(pCreature->isAlive())                            // dead creature will reset movement generator at respawn
1507        {
1508            pCreature->setDeathState(JUST_DIED);
1509            pCreature->Respawn();
1510        }
1511        pCreature->SaveToDB();
1512    }
1513    if( doNotDelete == false )
1514    {
1515        PSendSysMessage(LANG_MOVE_TYPE_SET,type_str);
1516    }
1517    else
1518    {
1519        PSendSysMessage(LANG_MOVE_TYPE_SET_NODEL,type_str);
1520    }
1521
1522    return true;
1523}                                                           // HandleSetMoveTypeCommand
1524
1525//change level of creature or pet
1526bool ChatHandler::HandleChangeLevelCommand(const char* args)
1527{
1528    if (!*args)
1529        return false;
1530
1531    uint8 lvl = (uint8) atoi((char*)args);
1532    if ( lvl < 1 || lvl > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL) + 3)
1533    {
1534        SendSysMessage(LANG_BAD_VALUE);
1535        SetSentErrorMessage(true);
1536        return false;
1537    }
1538
1539    Creature* pCreature = getSelectedCreature();
1540    if(!pCreature)
1541    {
1542        SendSysMessage(LANG_SELECT_CREATURE);
1543        SetSentErrorMessage(true);
1544        return false;
1545    }
1546
1547    if(pCreature->isPet())
1548    {
1549        ((Pet*)pCreature)->GivePetLevel(lvl);
1550    }
1551    else
1552    {
1553        pCreature->SetMaxHealth( 100 + 30*lvl);
1554        pCreature->SetHealth( 100 + 30*lvl);
1555        pCreature->SetLevel( lvl);
1556        pCreature->SaveToDB();
1557    }
1558
1559    return true;
1560}
1561
1562//set npcflag of creature
1563bool ChatHandler::HandleNPCFlagCommand(const char* args)
1564{
1565    if (!*args)
1566        return false;
1567
1568    uint32 npcFlags = (uint32) atoi((char*)args);
1569
1570    Creature* pCreature = getSelectedCreature();
1571
1572    if(!pCreature)
1573    {
1574        SendSysMessage(LANG_SELECT_CREATURE);
1575        SetSentErrorMessage(true);
1576        return false;
1577    }
1578
1579    pCreature->SetUInt32Value(UNIT_NPC_FLAGS, npcFlags);
1580
1581    WorldDatabase.PExecuteLog("UPDATE creature_template SET npcflag = '%u' WHERE entry = '%u'", npcFlags, pCreature->GetEntry());
1582
1583    SendSysMessage(LANG_VALUE_SAVED_REJOIN);
1584
1585    return true;
1586}
1587
1588//set model of creature
1589bool ChatHandler::HandleSetModelCommand(const char* args)
1590{
1591    if (!*args)
1592        return false;
1593
1594    uint32 displayId = (uint32) atoi((char*)args);
1595
1596    Creature *pCreature = getSelectedCreature();
1597
1598    if(!pCreature || pCreature->isPet())
1599    {
1600        SendSysMessage(LANG_SELECT_CREATURE);
1601        SetSentErrorMessage(true);
1602        return false;
1603    }
1604
1605    pCreature->SetDisplayId(displayId);
1606    pCreature->SetNativeDisplayId(displayId);
1607
1608    pCreature->SaveToDB();
1609
1610    return true;
1611}
1612
1613//morph creature or player
1614bool ChatHandler::HandleMorphCommand(const char* args)
1615{
1616    if (!*args)
1617        return false;
1618
1619    uint16 display_id = (uint16)atoi((char*)args);
1620
1621    Unit *target = getSelectedUnit();
1622    if(!target)
1623        target = m_session->GetPlayer();
1624
1625    target->SetDisplayId(display_id);
1626
1627    return true;
1628}
1629
1630//set faction of creature  or go
1631bool ChatHandler::HandleFactionIdCommand(const char* args)
1632{
1633    if (!*args)
1634        return false;
1635
1636    uint32 factionId = (uint32) atoi((char*)args);
1637
1638    if (!sFactionTemplateStore.LookupEntry(factionId))
1639    {
1640        PSendSysMessage(LANG_WRONG_FACTION, factionId);
1641        SetSentErrorMessage(true);
1642        return false;
1643    }
1644
1645    Creature* pCreature = getSelectedCreature();
1646
1647    if(!pCreature)
1648    {
1649        SendSysMessage(LANG_SELECT_CREATURE);
1650        SetSentErrorMessage(true);
1651        return false;
1652    }
1653
1654    pCreature->setFaction(factionId);
1655
1656    // faction is set in creature_template - not inside creature
1657
1658    // update in memory
1659    if(CreatureInfo const *cinfo = pCreature->GetCreatureInfo())
1660    {
1661        const_cast<CreatureInfo*>(cinfo)->faction_A = factionId;
1662        const_cast<CreatureInfo*>(cinfo)->faction_H = factionId;
1663    }
1664
1665    // and DB
1666    WorldDatabase.PExecuteLog("UPDATE creature_template SET faction_A = '%u', faction_H = '%u' WHERE entry = '%u'", factionId, factionId, pCreature->GetEntry());
1667
1668    return true;
1669}
1670
1671//kick player
1672bool ChatHandler::HandleKickPlayerCommand(const char *args)
1673{
1674    char* kickName = strtok((char*)args, " ");
1675    if (!kickName)
1676    {
1677        Player* player = getSelectedPlayer();
1678
1679        if(!player)
1680        {
1681            SendSysMessage(LANG_NO_CHAR_SELECTED);
1682            SetSentErrorMessage(true);
1683            return false;
1684        }
1685
1686        if(player==m_session->GetPlayer())
1687        {
1688            SendSysMessage(LANG_COMMAND_KICKSELF);
1689            SetSentErrorMessage(true);
1690            return false;
1691        }
1692
1693        player->GetSession()->KickPlayer();
1694    }
1695    else
1696    {
1697        std::string name = kickName;
1698        if(!normalizePlayerName(name))
1699        {
1700            SendSysMessage(LANG_PLAYER_NOT_FOUND);
1701            SetSentErrorMessage(true);
1702            return false;
1703        }
1704
1705        if(name==m_session->GetPlayer()->GetName())
1706        {
1707            SendSysMessage(LANG_COMMAND_KICKSELF);
1708            SetSentErrorMessage(true);
1709            return false;
1710        }
1711
1712        if(sWorld.KickPlayer(name))
1713        {
1714            PSendSysMessage(LANG_COMMAND_KICKMESSAGE,name.c_str());
1715        }
1716        else
1717            PSendSysMessage(LANG_COMMAND_KICKNOTFOUNDPLAYER,name.c_str());
1718    }
1719
1720    return true;
1721}
1722
1723//show info of player
1724bool ChatHandler::HandlePInfoCommand(const char* args)
1725{
1726    Player* target = NULL;
1727    uint64 targetGUID = 0;
1728
1729    char* px = strtok((char*)args, " ");
1730    char* py = NULL;
1731
1732    std::string name;
1733
1734    if (px)
1735    {
1736        name = px;
1737
1738        if(name.empty())
1739            return false;
1740
1741        if(!normalizePlayerName(name))
1742        {
1743            SendSysMessage(LANG_PLAYER_NOT_FOUND);
1744            SetSentErrorMessage(true);
1745            return false;
1746        }
1747
1748        target = objmgr.GetPlayer(name.c_str());
1749        if (target)
1750            py = strtok(NULL, " ");
1751        else
1752        {
1753            targetGUID = objmgr.GetPlayerGUIDByName(name);
1754            if(targetGUID)
1755                py = strtok(NULL, " ");
1756            else
1757                py = px;
1758        }
1759    }
1760
1761    if(!target && !targetGUID)
1762    {
1763        target = getSelectedPlayer();
1764    }
1765
1766    if(!target && !targetGUID)
1767    {
1768        SendSysMessage(LANG_PLAYER_NOT_FOUND);
1769        SetSentErrorMessage(true);
1770        return false;
1771    }
1772
1773    uint32 accId = 0;
1774    uint32 money = 0;
1775    uint32 total_player_time = 0;
1776    uint32 level = 0;
1777    uint32 latency = 0;
1778
1779    // get additional information from Player object
1780    if(target)
1781    {
1782        targetGUID = target->GetGUID();
1783        name = target->GetName();                           // re-read for case getSelectedPlayer() target
1784        accId = target->GetSession()->GetAccountId();
1785        money = target->GetMoney();
1786        total_player_time = target->GetTotalPlayedTime();
1787        level = target->getLevel();
1788        latency = target->GetSession()->GetLatency();
1789    }
1790    // get additional information from DB
1791    else
1792    {
1793        accId = objmgr.GetPlayerAccountIdByGUID(targetGUID);
1794        Player plr(m_session);                              // use current session for temporary load
1795        plr.MinimalLoadFromDB(NULL, targetGUID);
1796        money = plr.GetMoney();
1797        total_player_time = plr.GetTotalPlayedTime();
1798        level = plr.getLevel();
1799    }
1800
1801    std::string username = GetTrinityString(LANG_ERROR);
1802    std::string last_ip = GetTrinityString(LANG_ERROR);
1803    uint32 security = 0;
1804    std::string last_login = GetTrinityString(LANG_ERROR);
1805
1806    QueryResult* result = loginDatabase.PQuery("SELECT username,gmlevel,last_ip,last_login FROM account WHERE id = '%u'",accId);
1807    if(result)
1808    {
1809        Field* fields = result->Fetch();
1810        username = fields[0].GetCppString();
1811        security = fields[1].GetUInt32();
1812        if(m_session->GetSecurity() >= security)
1813        {
1814            last_ip = fields[2].GetCppString();
1815            last_login = fields[3].GetCppString();
1816        }
1817        else
1818        {
1819            last_ip = "-";
1820            last_login = "-";
1821        }
1822
1823        delete result;
1824    }
1825
1826    PSendSysMessage(LANG_PINFO_ACCOUNT, (target?"":GetTrinityString(LANG_OFFLINE)), name.c_str(), GUID_LOPART(targetGUID), username.c_str(), accId, security, last_ip.c_str(), last_login.c_str(), latency);
1827
1828    std::string timeStr = secsToTimeString(total_player_time,true,true);
1829    uint32 gold = money /GOLD;
1830    uint32 silv = (money % GOLD) / SILVER;
1831    uint32 copp = (money % GOLD) % SILVER;
1832    PSendSysMessage(LANG_PINFO_LEVEL,  timeStr.c_str(), level, gold,silv,copp );
1833
1834    if ( py && strncmp(py, "rep", 3) == 0 )
1835    {
1836        if(!target)
1837        {
1838            // rep option not implemented for offline case
1839            SendSysMessage(LANG_PINFO_NO_REP);
1840            SetSentErrorMessage(true);
1841            return false;
1842        }
1843
1844        char* FactionName;
1845        for(FactionStateList::const_iterator itr = target->m_factions.begin(); itr != target->m_factions.end(); ++itr)
1846        {
1847            FactionEntry const *factionEntry = sFactionStore.LookupEntry(itr->second.ID);
1848            if (factionEntry)
1849                FactionName = factionEntry->name[m_session->GetSessionDbcLocale()];
1850            else
1851                FactionName = "#Not found#";
1852            ReputationRank rank = target->GetReputationRank(factionEntry);
1853            std::string rankName = GetTrinityString(ReputationRankStrIndex[rank]);
1854            std::ostringstream ss;
1855            ss << itr->second.ID << ": |cffffffff|Hfaction:" << itr->second.ID << "|h[" << FactionName << "]|h|r " << rankName << "|h|r (" << target->GetReputation(factionEntry) << ")";
1856
1857            if(itr->second.Flags & FACTION_FLAG_VISIBLE)
1858                ss << GetTrinityString(LANG_FACTION_VISIBLE);
1859            if(itr->second.Flags & FACTION_FLAG_AT_WAR)
1860                ss << GetTrinityString(LANG_FACTION_ATWAR);
1861            if(itr->second.Flags & FACTION_FLAG_PEACE_FORCED)
1862                ss << GetTrinityString(LANG_FACTION_PEACE_FORCED);
1863            if(itr->second.Flags & FACTION_FLAG_HIDDEN)
1864                ss << GetTrinityString(LANG_FACTION_HIDDEN);
1865            if(itr->second.Flags & FACTION_FLAG_INVISIBLE_FORCED)
1866                ss << GetTrinityString(LANG_FACTION_INVISIBLE_FORCED);
1867            if(itr->second.Flags & FACTION_FLAG_INACTIVE)
1868                ss << GetTrinityString(LANG_FACTION_INACTIVE);
1869
1870            SendSysMessage(ss.str().c_str());
1871        }
1872    }
1873    return true;
1874}
1875
1876//show tickets
1877void ChatHandler::ShowTicket(uint64 guid, char const* text, char const* time)
1878{
1879    std::string name;
1880    if(!objmgr.GetPlayerNameByGUID(guid,name))
1881        name = GetTrinityString(LANG_UNKNOWN);
1882
1883    PSendSysMessage(LANG_COMMAND_TICKETVIEW, name.c_str(),time,text);
1884}
1885
1886//ticket commands
1887bool ChatHandler::HandleTicketCommand(const char* args)
1888{
1889    char* px = strtok((char*)args, " ");
1890
1891    // ticket<end>
1892    if (!px)
1893    {
1894        size_t count;
1895        QueryResult *result = CharacterDatabase.Query("SELECT COUNT(ticket_id) FROM character_ticket");
1896        if(result)
1897        {
1898            count = (*result)[0].GetUInt32();
1899            delete result;
1900        }
1901        else
1902            count = 0;
1903
1904        PSendSysMessage(LANG_COMMAND_TICKETCOUNT, count, m_session->GetPlayer()->isAcceptTickets() ?  GetTrinityString(LANG_ON) : GetTrinityString(LANG_OFF));
1905        return true;
1906    }
1907
1908    // ticket on
1909    if(strncmp(px,"on",3) == 0)
1910    {
1911        m_session->GetPlayer()->SetAcceptTicket(true);
1912        SendSysMessage(LANG_COMMAND_TICKETON);
1913        return true;
1914    }
1915
1916    // ticket off
1917    if(strncmp(px,"off",4) == 0)
1918    {
1919        m_session->GetPlayer()->SetAcceptTicket(false);
1920        SendSysMessage(LANG_COMMAND_TICKETOFF);
1921        return true;
1922    }
1923
1924    // ticket #num
1925    int num = atoi(px);
1926    if(num > 0)
1927    {
1928        QueryResult *result = CharacterDatabase.PQuery("SELECT guid,ticket_text,ticket_lastchange FROM character_ticket ORDER BY ticket_id ASC LIMIT %d,1",num-1);
1929
1930        if(!result)
1931        {
1932            PSendSysMessage(LANG_COMMAND_TICKENOTEXIST, num);
1933            delete result;
1934            SetSentErrorMessage(true);
1935            return false;
1936        }
1937
1938        Field* fields = result->Fetch();
1939
1940        uint64 guid = fields[0].GetUInt64();
1941        char const* text = fields[1].GetString();
1942        char const* time = fields[2].GetString();
1943
1944        ShowTicket(guid,text,time);
1945        delete result;
1946        return true;
1947    }
1948
1949    std::string name = px;
1950
1951    if(!normalizePlayerName(name))
1952    {
1953        SendSysMessage(LANG_PLAYER_NOT_FOUND);
1954        SetSentErrorMessage(true);
1955        return false;
1956    }
1957
1958    uint64 guid = objmgr.GetPlayerGUIDByName(name);
1959
1960    if(!guid)
1961        return false;
1962
1963    // ticket $char_name
1964    QueryResult *result = CharacterDatabase.PQuery("SELECT ticket_text,ticket_lastchange FROM character_ticket WHERE guid = '%u' ORDER BY ticket_id ASC",GUID_LOPART(guid));
1965
1966    if(!result)
1967        return false;
1968
1969    Field* fields = result->Fetch();
1970
1971    char const* text = fields[0].GetString();
1972    char const* time = fields[1].GetString();
1973
1974    ShowTicket(guid,text,time);
1975    delete result;
1976
1977    return true;
1978}
1979
1980uint32 ChatHandler::GetTicketIDByNum(uint32 num)
1981{
1982    QueryResult *result = CharacterDatabase.Query("SELECT ticket_id FROM character_ticket");
1983
1984    if(!result || num > result->GetRowCount())
1985    {
1986        PSendSysMessage(LANG_COMMAND_TICKENOTEXIST, num);
1987        delete result;
1988        return 0;
1989    }
1990
1991    for(uint32 i = 1; i < num; ++i)
1992        result->NextRow();
1993
1994    Field* fields = result->Fetch();
1995
1996    uint32 id = fields[0].GetUInt32();
1997    delete result;
1998    return id;
1999}
2000
2001//dell all tickets
2002bool ChatHandler::HandleDelTicketCommand(const char *args)
2003{
2004    char* px = strtok((char*)args, " ");
2005    if (!px)
2006        return false;
2007
2008    // delticket all
2009    if(strncmp(px,"all",4) == 0)
2010    {
2011        QueryResult *result = CharacterDatabase.Query("SELECT guid FROM character_ticket");
2012
2013        if(!result)
2014            return true;
2015
2016        // notify players about ticket deleting
2017        do
2018        {
2019            Field* fields = result->Fetch();
2020
2021            uint64 guid = fields[0].GetUInt64();
2022
2023            if(Player* sender = objmgr.GetPlayer(guid))
2024                sender->GetSession()->SendGMTicketGetTicket(0x0A,0);
2025
2026        }while(result->NextRow());
2027
2028        delete result;
2029
2030        CharacterDatabase.PExecute("DELETE FROM character_ticket");
2031        SendSysMessage(LANG_COMMAND_ALLTICKETDELETED);
2032        return true;
2033    }
2034
2035    int num = (uint32)atoi(px);
2036
2037    // delticket #num
2038    if(num > 0)
2039    {
2040        QueryResult *result = CharacterDatabase.PQuery("SELECT ticket_id,guid FROM character_ticket LIMIT %i",num);
2041
2042        if(!result || uint64(num) > result->GetRowCount())
2043        {
2044            PSendSysMessage(LANG_COMMAND_TICKENOTEXIST, num);
2045            delete result;
2046            SetSentErrorMessage(true);
2047            return false;
2048        }
2049
2050        for(int i = 1; i < num; ++i)
2051            result->NextRow();
2052
2053        Field* fields = result->Fetch();
2054
2055        uint32 id   = fields[0].GetUInt32();
2056        uint64 guid = fields[1].GetUInt64();
2057        delete result;
2058
2059        CharacterDatabase.PExecute("DELETE FROM character_ticket WHERE ticket_id = '%u'", id);
2060
2061        // notify players about ticket deleting
2062        if(Player* sender = objmgr.GetPlayer(guid))
2063        {
2064            sender->GetSession()->SendGMTicketGetTicket(0x0A,0);
2065            PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL,sender->GetName());
2066        }
2067        else
2068            SendSysMessage(LANG_COMMAND_TICKETDEL);
2069
2070        return true;
2071    }
2072
2073    std::string name = px;
2074
2075    if(!normalizePlayerName(name))
2076    {
2077        SendSysMessage(LANG_PLAYER_NOT_FOUND);
2078        SetSentErrorMessage(true);
2079        return false;
2080    }
2081
2082    uint64 guid = objmgr.GetPlayerGUIDByName(name);
2083
2084    if(!guid)
2085        return false;
2086
2087    // delticket $char_name
2088    CharacterDatabase.PExecute("DELETE FROM character_ticket WHERE guid = '%u'",GUID_LOPART(guid));
2089
2090    // notify players about ticket deleting
2091    if(Player* sender = objmgr.GetPlayer(guid))
2092        sender->GetSession()->SendGMTicketGetTicket(0x0A,0);
2093
2094    PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL,px);
2095    return true;
2096}
2097
2098//set spawn dist of creature
2099bool ChatHandler::HandleSpawnDistCommand(const char* args)
2100{
2101    if(!*args)
2102        return false;
2103
2104    float option = atof((char*)args);
2105    if (option < 0.0f)
2106    {
2107        SendSysMessage(LANG_BAD_VALUE);
2108        return false;
2109    }
2110
2111    MovementGeneratorType mtype = IDLE_MOTION_TYPE;
2112    if (option >0.0f)
2113        mtype = RANDOM_MOTION_TYPE;
2114
2115    Creature *pCreature = getSelectedCreature();
2116    uint32 u_guidlow = 0;
2117
2118    if (pCreature)
2119        u_guidlow = pCreature->GetDBTableGUIDLow();
2120    else
2121        return false;
2122
2123    pCreature->SetRespawnRadius((float)option);
2124    pCreature->SetDefaultMovementType(mtype);
2125    pCreature->GetMotionMaster()->Initialize();
2126    if(pCreature->isAlive())                                // dead creature will reset movement generator at respawn
2127    {
2128        pCreature->setDeathState(JUST_DIED);
2129        pCreature->Respawn();
2130    }
2131
2132    WorldDatabase.PExecuteLog("UPDATE creature SET spawndist=%f, MovementType=%i WHERE guid=%u",option,mtype,u_guidlow);
2133    PSendSysMessage(LANG_COMMAND_SPAWNDIST,option);
2134    return true;
2135}
2136
2137bool ChatHandler::HandleSpawnTimeCommand(const char* args)
2138{
2139    if(!*args)
2140        return false;
2141
2142    char* stime = strtok((char*)args, " ");
2143
2144    if (!stime)
2145        return false;
2146
2147    int i_stime = atoi((char*)stime);
2148
2149    if (i_stime < 0)
2150    {
2151        SendSysMessage(LANG_BAD_VALUE);
2152        SetSentErrorMessage(true);
2153        return false;
2154    }
2155
2156    Creature *pCreature = getSelectedCreature();
2157    uint32 u_guidlow = 0;
2158
2159    if (pCreature)
2160        u_guidlow = pCreature->GetDBTableGUIDLow();
2161    else
2162        return false;
2163
2164    WorldDatabase.PExecuteLog("UPDATE creature SET spawntimesecs=%i WHERE guid=%u",i_stime,u_guidlow);
2165    pCreature->SetRespawnDelay((uint32)i_stime);
2166    PSendSysMessage(LANG_COMMAND_SPAWNTIME,i_stime);
2167
2168    return true;
2169}
2170
2171/**
2172 * Add a waypoint to a creature.
2173 *
2174 * The user can either select an npc or provide its GUID.
2175 *
2176 * The user can even select a visual waypoint - then the new waypoint
2177 * is placed *after* the selected one - this makes insertion of new
2178 * waypoints possible.
2179 *
2180 * eg:
2181 * .wp add 12345
2182 * -> adds a waypoint to the npc with the GUID 12345
2183 *
2184 * .wp add
2185 * -> adds a waypoint to the currently selected creature
2186 *
2187 *
2188 * @param args if the user did not provide a GUID, it is NULL
2189 *
2190 * @return true - command did succeed, false - something went wrong
2191 */
2192bool ChatHandler::HandleWpAddCommand(const char* args)
2193{
2194    sLog.outDebug("DEBUG: HandleWpAddCommand");
2195
2196    // optional
2197    char* guid_str = NULL;
2198
2199    if(*args)
2200    {
2201        guid_str = strtok((char*)args, " ");
2202    }
2203
2204    uint32 lowguid = 0;
2205    uint32 point = 0;
2206    Creature* target = getSelectedCreature();
2207    // Did player provide a GUID?
2208    if (!guid_str)
2209    {
2210        sLog.outDebug("DEBUG: HandleWpAddCommand - No GUID provided");
2211
2212        // No GUID provided
2213        // -> Player must have selected a creature
2214
2215        if(!target || target->isPet())
2216        {
2217            SendSysMessage(LANG_SELECT_CREATURE);
2218            SetSentErrorMessage(true);
2219            return false;
2220        }
2221        if (target->GetEntry() == VISUAL_WAYPOINT )
2222        {
2223            sLog.outDebug("DEBUG: HandleWpAddCommand - target->GetEntry() == VISUAL_WAYPOINT (1) ");
2224
2225            QueryResult *result =
2226                WorldDatabase.PQuery( "SELECT id, point FROM creature_movement WHERE wpguid = %u",
2227                target->GetGUIDLow() );
2228            if(!result)
2229            {
2230                PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, target->GetGUIDLow());
2231                // User selected a visual spawnpoint -> get the NPC
2232                // Select NPC GUID
2233                // Since we compare float values, we have to deal with
2234                // some difficulties.
2235                // Here we search for all waypoints that only differ in one from 1 thousand
2236                // (0.001) - There is no other way to compare C++ floats with mySQL floats
2237                // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
2238                const char* maxDIFF = "0.01";
2239                result = WorldDatabase.PQuery( "SELECT id, point FROM creature_movement WHERE (abs(position_x - %f) <= %s ) and (abs(position_y - %f) <= %s ) and (abs(position_z - %f) <= %s )",
2240                    target->GetPositionX(), maxDIFF, target->GetPositionY(), maxDIFF, target->GetPositionZ(), maxDIFF);
2241                if(!result)
2242                {
2243                    PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, target->GetGUIDLow());
2244                    SetSentErrorMessage(true);
2245                    return false;
2246                }
2247            }
2248            do
2249            {
2250                Field *fields = result->Fetch();
2251                lowguid = fields[0].GetUInt32();
2252                point   = fields[1].GetUInt32();
2253            }while( result->NextRow() );
2254            delete result;
2255
2256            CreatureData const* data = objmgr.GetCreatureData(lowguid);
2257            if(!data)
2258            {
2259                PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2260                SetSentErrorMessage(true);
2261                return false;
2262            }
2263
2264            target = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(lowguid,data->id,HIGHGUID_UNIT));
2265            if(!target)
2266            {
2267                PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, lowguid);
2268                SetSentErrorMessage(true);
2269                return false;
2270            }
2271        }
2272        else
2273        {
2274            lowguid = target->GetDBTableGUIDLow();
2275        }
2276    }
2277    else
2278    {
2279        sLog.outDebug("DEBUG: HandleWpAddCommand - GUID provided");
2280
2281        // GUID provided
2282        // Warn if player also selected a creature
2283        // -> Creature selection is ignored <-
2284        if(target)
2285        {
2286            SendSysMessage(LANG_WAYPOINT_CREATSELECTED);
2287        }
2288        lowguid = atoi((char*)guid_str);
2289
2290        CreatureData const* data = objmgr.GetCreatureData(lowguid);
2291        if(!data)
2292        {
2293            PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2294            SetSentErrorMessage(true);
2295            return false;
2296        }
2297
2298        target = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(lowguid,data->id,HIGHGUID_UNIT));
2299        if(!target || target->isPet())
2300        {
2301            PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2302            SetSentErrorMessage(true);
2303            return false;
2304        }
2305    }
2306    // lowguid -> GUID of the NPC
2307    // point   -> number of the waypoint (if not 0)
2308    sLog.outDebug("DEBUG: HandleWpAddCommand - danach");
2309
2310    sLog.outDebug("DEBUG: HandleWpAddCommand - point == 0");
2311
2312    Player* player = m_session->GetPlayer();
2313    WaypointMgr.AddLastNode(lowguid, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation(), 0, 0);
2314
2315    // update movement type
2316    if(target)
2317    {
2318        target->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
2319        target->GetMotionMaster()->Initialize();
2320        if(target->isAlive())                               // dead creature will reset movement generator at respawn
2321        {
2322            target->setDeathState(JUST_DIED);
2323            target->Respawn();
2324        }
2325        target->SaveToDB();
2326    }
2327    else
2328        WorldDatabase.PExecuteLog("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE,lowguid);
2329
2330    PSendSysMessage(LANG_WAYPOINT_ADDED, point, lowguid);
2331
2332    return true;
2333}                                                           // HandleWpAddCommand
2334
2335/**
2336 * .wp modify emote | spell | text | del | move | add
2337 *
2338 * add -> add a WP after the selected visual waypoint
2339 *        User must select a visual waypoint and then issue ".wp modify add"
2340 *
2341 * emote <emoteID>
2342 *   User has selected a visual waypoint before.
2343 *   <emoteID> is added to this waypoint. Everytime the
2344 *   NPC comes to this waypoint, the emote is called.
2345 *
2346 * emote <GUID> <WPNUM> <emoteID>
2347 *   User has not selected visual waypoint before.
2348 *   For the waypoint <WPNUM> for the NPC with <GUID>
2349 *   an emote <emoteID> is added.
2350 *   Everytime the NPC comes to this waypoint, the emote is called.
2351 *
2352 *
2353 * info <GUID> <WPNUM> -> User did not select a visual waypoint and
2354 */
2355bool ChatHandler::HandleWpModifyCommand(const char* args)
2356{
2357    sLog.outDebug("DEBUG: HandleWpModifyCommand");
2358
2359    if(!*args)
2360        return false;
2361
2362    // first arg: add del text emote spell waittime move
2363    char* show_str = strtok((char*)args, " ");
2364    if (!show_str)
2365    {
2366        return false;
2367    }
2368
2369    std::string show = show_str;
2370    // Check
2371    // Remember: "show" must also be the name of a column!
2372    if( (show != "emote") && (show != "spell") && (show != "text1") && (show != "text2")
2373        && (show != "text3") && (show != "text4") && (show != "text5")
2374        && (show != "waittime") && (show != "del") && (show != "move") && (show != "add")
2375        && (show != "model1") && (show != "model2") && (show != "orientation"))
2376    {
2377        return false;
2378    }
2379
2380    // Next arg is: <GUID> <WPNUM> <ARGUMENT>
2381
2382    // Did user provide a GUID
2383    // or did the user select a creature?
2384    // -> variable lowguid is filled with the GUID of the NPC
2385    uint32 lowguid = 0;
2386    uint32 point = 0;
2387    uint32 wpGuid = 0;
2388    Creature* target = getSelectedCreature();
2389
2390    if(target)
2391    {
2392        sLog.outDebug("DEBUG: HandleWpModifyCommand - User did select an NPC");
2393
2394        // Did the user select a visual spawnpoint?
2395        if (target->GetEntry() != VISUAL_WAYPOINT )
2396        {
2397            PSendSysMessage(LANG_WAYPOINT_VP_SELECT);
2398            SetSentErrorMessage(true);
2399            return false;
2400        }
2401
2402        wpGuid = target->GetGUIDLow();
2403
2404        // The visual waypoint
2405        QueryResult *result =
2406            WorldDatabase.PQuery( "SELECT id, point FROM creature_movement WHERE wpguid = %u LIMIT 1",
2407            target->GetGUIDLow() );
2408        if(!result)
2409        {
2410            PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, wpGuid);
2411            SetSentErrorMessage(true);
2412            return false;
2413        }
2414        sLog.outDebug("DEBUG: HandleWpModifyCommand - After getting wpGuid");
2415
2416        Field *fields = result->Fetch();
2417        lowguid = fields[0].GetUInt32();
2418        point   = fields[1].GetUInt32();
2419
2420        // Cleanup memory
2421        sLog.outDebug("DEBUG: HandleWpModifyCommand - Cleanup memory");
2422        delete result;
2423    }
2424    else
2425    {
2426        // User did provide <GUID> <WPNUM>
2427
2428        char* guid_str = strtok((char*)NULL, " ");
2429        if( !guid_str )
2430        {
2431            SendSysMessage(LANG_WAYPOINT_NOGUID);
2432            return false;
2433        }
2434        lowguid = atoi((char*)guid_str);
2435
2436        CreatureData const* data = objmgr.GetCreatureData(lowguid);
2437        if(!data)
2438        {
2439            PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2440            SetSentErrorMessage(true);
2441            return false;
2442        }
2443
2444        PSendSysMessage("DEBUG: GUID provided: %d", lowguid);
2445
2446        char* point_str = strtok((char*)NULL, " ");
2447        if( !point_str )
2448        {
2449            SendSysMessage(LANG_WAYPOINT_NOWAYPOINTGIVEN);
2450            return false;
2451        }
2452        point    = atoi((char*)point_str);
2453
2454        PSendSysMessage("DEBUG: wpNumber provided: %d", point);
2455
2456        // Now we need the GUID of the visual waypoint
2457        // -> "del", "move", "add" command
2458
2459        QueryResult *result = WorldDatabase.PQuery( "SELECT wpguid FROM creature_movement WHERE id = '%u' AND point = '%u' LIMIT 1", lowguid, point);
2460        if (!result)
2461        {
2462            PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, lowguid, point);
2463            SetSentErrorMessage(true);
2464            return false;
2465        }
2466
2467        Field *fields = result->Fetch();
2468        wpGuid  = fields[0].GetUInt32();
2469
2470        // Free memory
2471        delete result;
2472    }
2473
2474    char* arg_str = NULL;
2475    // Check for argument
2476    if( (show.find("text") == std::string::npos ) && (show != "del") && (show != "move") && (show != "add"))
2477    {
2478        // Text is enclosed in "<>", all other arguments not
2479        if( show.find("text") != std::string::npos )
2480            arg_str = strtok((char*)NULL, "<>");
2481        else
2482            arg_str = strtok((char*)NULL, " ");
2483
2484        if( !arg_str)
2485        {
2486            PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ, show_str);
2487            return false;
2488        }
2489    }
2490
2491    sLog.outDebug("DEBUG: HandleWpModifyCommand - Parameters parsed - now execute the command");
2492
2493    // wpGuid  -> GUID of the waypoint creature
2494    // lowguid -> GUID of the NPC
2495    // point   -> waypoint number
2496
2497    // Special functions:
2498    // add - move - del -> no args commands
2499    // Add a waypoint after the selected visual
2500    if(show == "add" && target)
2501    {
2502        PSendSysMessage("DEBUG: wp modify add, GUID: %u", lowguid);
2503
2504        // Get the creature for which we read the waypoint
2505        CreatureData const* data = objmgr.GetCreatureData(lowguid);
2506        if(!data)
2507        {
2508            PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2509            SetSentErrorMessage(true);
2510            return false;
2511        }
2512
2513        Creature* npcCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), MAKE_NEW_GUID(lowguid, data->id, HIGHGUID_UNIT));
2514
2515        if( !npcCreature )
2516        {
2517            PSendSysMessage(LANG_WAYPOINT_NPCNOTFOUND);
2518            SetSentErrorMessage(true);
2519            return false;
2520        }
2521
2522        sLog.outDebug("DEBUG: HandleWpModifyCommand - add -- npcCreature");
2523
2524        // What to do:
2525        // Add the visual spawnpoint (DB only)
2526        // Adjust the waypoints
2527        // Respawn the owner of the waypoints
2528        sLog.outDebug("DEBUG: HandleWpModifyCommand - add");
2529
2530        Player* chr = m_session->GetPlayer();
2531        Map *map = chr->GetMap();
2532
2533        if(npcCreature)
2534        {
2535            npcCreature->GetMotionMaster()->Initialize();
2536            if(npcCreature->isAlive())                      // dead creature will reset movement generator at respawn
2537            {
2538                npcCreature->setDeathState(JUST_DIED);
2539                npcCreature->Respawn();
2540            }
2541        }
2542
2543        // create the waypoint creature
2544        wpGuid = 0;
2545        Creature* wpCreature = new Creature;
2546        if (!wpCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map,VISUAL_WAYPOINT,0))
2547        {
2548            PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT);
2549            delete wpCreature;
2550        }
2551        else
2552        {
2553            wpCreature->Relocate(chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation());
2554
2555            if(!wpCreature->IsPositionValid())
2556            {
2557                sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",wpCreature->GetGUIDLow(),wpCreature->GetEntry(),wpCreature->GetPositionX(),wpCreature->GetPositionY());
2558                delete wpCreature;
2559            }
2560            else
2561            {
2562                wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
2563                // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
2564                wpCreature->LoadFromDB(wpCreature->GetDBTableGUIDLow(), map);
2565                map->Add(wpCreature);
2566                wpGuid = wpCreature->GetGUIDLow();
2567            }
2568        }
2569
2570        WaypointMgr.AddAfterNode(lowguid, point, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), 0, 0, wpGuid);
2571
2572        if(!wpGuid)
2573            return false;
2574
2575        PSendSysMessage(LANG_WAYPOINT_ADDED_NO, point+1);
2576        return true;
2577    }                                                       // add
2578
2579    if(show == "del" && target)
2580    {
2581        PSendSysMessage("DEBUG: wp modify del, GUID: %u", lowguid);
2582
2583        // Get the creature for which we read the waypoint
2584        CreatureData const* data = objmgr.GetCreatureData(lowguid);
2585        if(!data)
2586        {
2587            PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2588            SetSentErrorMessage(true);
2589            return false;
2590        }
2591
2592        Creature* npcCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), MAKE_NEW_GUID(lowguid, data->id, HIGHGUID_UNIT));
2593
2594        // wpCreature
2595        Creature* wpCreature = NULL;
2596        if( wpGuid != 0 )
2597        {
2598            wpCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT));
2599            wpCreature->DeleteFromDB();
2600            wpCreature->CleanupsBeforeDelete();
2601            wpCreature->AddObjectToRemoveList();
2602        }
2603
2604        // What to do:
2605        // Remove the visual spawnpoint
2606        // Adjust the waypoints
2607        // Respawn the owner of the waypoints
2608
2609        WaypointMgr.DeleteNode(lowguid, point);
2610
2611        if(npcCreature)
2612        {
2613            // Any waypoints left?
2614            QueryResult *result2 = WorldDatabase.PQuery( "SELECT point FROM creature_movement WHERE id = '%u'",lowguid);
2615            if(!result2)
2616            {
2617                npcCreature->SetDefaultMovementType(RANDOM_MOTION_TYPE);
2618            }
2619            else
2620            {
2621                npcCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
2622                delete result2;
2623            }
2624            npcCreature->GetMotionMaster()->Initialize();
2625            if(npcCreature->isAlive())                      // dead creature will reset movement generator at respawn
2626            {
2627                npcCreature->setDeathState(JUST_DIED);
2628                npcCreature->Respawn();
2629            }
2630            npcCreature->SaveToDB();
2631        }
2632
2633        PSendSysMessage(LANG_WAYPOINT_REMOVED);
2634        return true;
2635    }                                                       // del
2636
2637    if(show == "move" && target)
2638    {
2639        PSendSysMessage("DEBUG: wp move, GUID: %u", lowguid);
2640
2641        Player *chr = m_session->GetPlayer();
2642        Map *map = chr->GetMap();
2643        {
2644            // Get the creature for which we read the waypoint
2645            CreatureData const* data = objmgr.GetCreatureData(lowguid);
2646            if(!data)
2647            {
2648                PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2649                SetSentErrorMessage(true);
2650                return false;
2651            }
2652
2653            Creature* npcCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), MAKE_NEW_GUID(lowguid, data->id, HIGHGUID_UNIT));
2654
2655            // wpCreature
2656            Creature* wpCreature = NULL;
2657            // What to do:
2658            // Move the visual spawnpoint
2659            // Respawn the owner of the waypoints
2660            if( wpGuid != 0 )
2661            {
2662                wpCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT));
2663                wpCreature->DeleteFromDB();
2664                wpCreature->CleanupsBeforeDelete();
2665                wpCreature->AddObjectToRemoveList();
2666                // re-create
2667                Creature* wpCreature2 = new Creature;
2668                if (!wpCreature2->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, VISUAL_WAYPOINT, 0))
2669                {
2670                    PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT);
2671                    delete wpCreature2;
2672                    return false;
2673                }
2674
2675                wpCreature2->Relocate(chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation());
2676
2677                if(!wpCreature2->IsPositionValid())
2678                {
2679                    sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",wpCreature2->GetGUIDLow(),wpCreature2->GetEntry(),wpCreature2->GetPositionX(),wpCreature2->GetPositionY());
2680                    delete wpCreature2;
2681                    return false;
2682                }
2683
2684                wpCreature2->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
2685                // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
2686                wpCreature2->LoadFromDB(wpCreature2->GetDBTableGUIDLow(), map);
2687                map->Add(wpCreature2);
2688                //MapManager::Instance().GetMap(npcCreature->GetMapId())->Add(wpCreature2);
2689            }
2690
2691            WaypointMgr.SetNodePosition(lowguid, point, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ());
2692
2693            if(npcCreature)
2694            {
2695                npcCreature->GetMotionMaster()->Initialize();
2696                if(npcCreature->isAlive())                  // dead creature will reset movement generator at respawn
2697                {
2698                    npcCreature->setDeathState(JUST_DIED);
2699                    npcCreature->Respawn();
2700                }
2701            }
2702            PSendSysMessage(LANG_WAYPOINT_CHANGED);
2703        }
2704        return true;
2705    }                                                       // move
2706
2707    // Create creature - npc that has the waypoint
2708    CreatureData const* data = objmgr.GetCreatureData(lowguid);
2709    if(!data)
2710    {
2711        PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2712        SetSentErrorMessage(true);
2713        return false;
2714    }
2715
2716    WaypointMgr.SetNodeText(lowguid, point, show_str, arg_str);
2717
2718    Creature* npcCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), MAKE_NEW_GUID(lowguid, data->id, HIGHGUID_UNIT));
2719    if(npcCreature)
2720    {
2721        npcCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
2722        npcCreature->GetMotionMaster()->Initialize();
2723        if(npcCreature->isAlive())                          // dead creature will reset movement generator at respawn
2724        {
2725            npcCreature->setDeathState(JUST_DIED);
2726            npcCreature->Respawn();
2727        }
2728    }
2729    PSendSysMessage(LANG_WAYPOINT_CHANGED_NO, show_str);
2730
2731    return true;
2732}
2733
2734/**
2735 * .wp show info | on | off
2736 *
2737 * info -> User has selected a visual waypoint before
2738 *
2739 * info <GUID> <WPNUM> -> User did not select a visual waypoint and
2740 *                        provided the GUID of the NPC and the number of
2741 *                        the waypoint.
2742 *
2743 * on -> User has selected an NPC; all visual waypoints for this
2744 *       NPC are added to the world
2745 *
2746 * on <GUID> -> User did not select an NPC - instead the GUID of the
2747 *              NPC is provided. All visual waypoints for this NPC
2748 *              are added from the world.
2749 *
2750 * off -> User has selected an NPC; all visual waypoints for this
2751 *        NPC are removed from the world.
2752 *
2753 * on <GUID> -> User did not select an NPC - instead the GUID of the
2754 *              NPC is provided. All visual waypoints for this NPC
2755 *              are removed from the world.
2756 *
2757 *
2758 */
2759bool ChatHandler::HandleWpShowCommand(const char* args)
2760{
2761    sLog.outDebug("DEBUG: HandleWpShowCommand");
2762
2763    if(!*args)
2764        return false;
2765
2766    // first arg: on, off, first, last
2767    char* show_str = strtok((char*)args, " ");
2768    if (!show_str)
2769    {
2770        return false;
2771    }
2772    // second arg: GUID (optional, if a creature is selected)
2773    char* guid_str = strtok((char*)NULL, " ");
2774    sLog.outDebug("DEBUG: HandleWpShowCommand: show_str: %s guid_str: %s", show_str, guid_str);
2775    //if (!guid_str) {
2776    //    return false;
2777    //}
2778
2779    // Did user provide a GUID
2780    // or did the user select a creature?
2781    // -> variable lowguid is filled with the GUID
2782    Creature* target = getSelectedCreature();
2783    // Did player provide a GUID?
2784    if (!guid_str)
2785    {
2786        sLog.outDebug("DEBUG: HandleWpShowCommand: !guid_str");
2787        // No GUID provided
2788        // -> Player must have selected a creature
2789
2790        if(!target)
2791        {
2792            SendSysMessage(LANG_SELECT_CREATURE);
2793            SetSentErrorMessage(true);
2794            return false;
2795        }
2796    }
2797    else
2798    {
2799        sLog.outDebug("DEBUG: HandleWpShowCommand: GUID provided");
2800        // GUID provided
2801        // Warn if player also selected a creature
2802        // -> Creature selection is ignored <-
2803        if(target)
2804        {
2805            SendSysMessage(LANG_WAYPOINT_CREATSELECTED);
2806        }
2807
2808        uint32 lowguid = atoi((char*)guid_str);
2809
2810        CreatureData const* data = objmgr.GetCreatureData(lowguid);
2811        if(!data)
2812        {
2813            PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2814            SetSentErrorMessage(true);
2815            return false;
2816        }
2817
2818        target = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(lowguid,data->id,HIGHGUID_UNIT));
2819
2820        if(!target)
2821        {
2822            PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2823            SetSentErrorMessage(true);
2824            return false;
2825        }
2826    }
2827
2828    uint32 lowguid = target->GetDBTableGUIDLow();
2829
2830    std::string show = show_str;
2831    uint32 Maxpoint;
2832
2833    sLog.outDebug("DEBUG: HandleWpShowCommand: lowguid: %u", lowguid);
2834
2835    sLog.outDebug("DEBUG: HandleWpShowCommand: Habe creature: %ld", target );
2836
2837    sLog.outDebug("DEBUG: HandleWpShowCommand: wpshow - show: %s", show_str);
2838    //PSendSysMessage("wpshow - show: %s", show);
2839
2840    // Show info for the selected waypoint
2841    if(show == "info")
2842    {
2843        PSendSysMessage("DEBUG: wp info, GUID: %u", lowguid);
2844
2845        // Check if the user did specify a visual waypoint
2846        if( target->GetEntry() != VISUAL_WAYPOINT )
2847        {
2848            PSendSysMessage(LANG_WAYPOINT_VP_SELECT);
2849            SetSentErrorMessage(true);
2850            return false;
2851        }
2852
2853        //PSendSysMessage("wp on, GUID: %u", lowguid);
2854
2855        //pCreature->GetPositionX();
2856
2857        QueryResult *result =
2858            WorldDatabase.PQuery( "SELECT id, point, waittime, emote, spell, text1, text2, text3, text4, text5, model1, model2 FROM creature_movement WHERE wpguid = %u",
2859            target->GetGUID() );
2860        if(!result)
2861        {
2862            // Since we compare float values, we have to deal with
2863            // some difficulties.
2864            // Here we search for all waypoints that only differ in one from 1 thousand
2865            // (0.001) - There is no other way to compare C++ floats with mySQL floats
2866            // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
2867            const char* maxDIFF = "0.01";
2868            PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, target->GetGUID());
2869
2870            result = WorldDatabase.PQuery( "SELECT id, point, waittime, emote, spell, text1, text2, text3, text4, text5, model1, model2 FROM creature_movement WHERE (abs(position_x - %f) <= %s ) and (abs(position_y - %f) <= %s ) and (abs(position_z - %f) <= %s )",
2871                target->GetPositionX(), maxDIFF, target->GetPositionY(), maxDIFF, target->GetPositionZ(), maxDIFF);
2872            if(!result)
2873            {
2874                PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, lowguid);
2875                SetSentErrorMessage(true);
2876                return false;
2877            }
2878        }
2879        do
2880        {
2881            Field *fields = result->Fetch();
2882            uint32 creGUID          = fields[0].GetUInt32();
2883            uint32 point            = fields[1].GetUInt32();
2884            int waittime            = fields[2].GetUInt32();
2885            uint32 emote            = fields[3].GetUInt32();
2886            uint32 spell            = fields[4].GetUInt32();
2887            const char * text1      = fields[5].GetString();
2888            const char * text2      = fields[6].GetString();
2889            const char * text3      = fields[7].GetString();
2890            const char * text4      = fields[8].GetString();
2891            const char * text5      = fields[9].GetString();
2892            uint32 model1           = fields[10].GetUInt32();
2893            uint32 model2           = fields[11].GetUInt32();
2894
2895            // Get the creature for which we read the waypoint
2896            Creature* wpCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(creGUID,VISUAL_WAYPOINT,HIGHGUID_UNIT));
2897
2898            PSendSysMessage(LANG_WAYPOINT_INFO_TITLE, point, (wpCreature ? wpCreature->GetName() : "<not found>"), creGUID);
2899            PSendSysMessage(LANG_WAYPOINT_INFO_WAITTIME, waittime);
2900            PSendSysMessage(LANG_WAYPOINT_INFO_MODEL, 1, model1);
2901            PSendSysMessage(LANG_WAYPOINT_INFO_MODEL, 2, model2);
2902            PSendSysMessage(LANG_WAYPOINT_INFO_EMOTE, emote);
2903            PSendSysMessage(LANG_WAYPOINT_INFO_SPELL, spell);
2904            PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 1, text1);
2905            PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 2, text2);
2906            PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 3, text3);
2907            PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 4, text4);
2908            PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 5, text5);
2909
2910        }while( result->NextRow() );
2911        // Cleanup memory
2912        delete result;
2913        return true;
2914    }
2915
2916    if(show == "on")
2917    {
2918        PSendSysMessage("DEBUG: wp on, GUID: %u", lowguid);
2919
2920        QueryResult *result = WorldDatabase.PQuery( "SELECT point, position_x,position_y,position_z FROM creature_movement WHERE id = '%u'",lowguid);
2921        if(!result)
2922        {
2923            PSendSysMessage(LANG_WAYPOINT_NOTFOUND, lowguid);
2924            SetSentErrorMessage(true);
2925            return false;
2926        }
2927        // Delete all visuals for this NPC
2928        QueryResult *result2 = WorldDatabase.PQuery( "SELECT wpguid FROM creature_movement WHERE id = '%u' and wpguid <> 0", lowguid);
2929        if(result2)
2930        {
2931            bool hasError = false;
2932            do
2933            {
2934                Field *fields = result2->Fetch();
2935                uint32 wpguid = fields[0].GetUInt32();
2936                Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(wpguid,VISUAL_WAYPOINT,HIGHGUID_UNIT));
2937
2938                if(!pCreature)
2939                {
2940                    PSendSysMessage(LANG_WAYPOINT_NOTREMOVED, wpguid);
2941                    hasError = true;
2942                    WorldDatabase.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", wpguid);
2943                }
2944                else
2945                {
2946                    pCreature->DeleteFromDB();
2947                    pCreature->CleanupsBeforeDelete();
2948                    pCreature->AddObjectToRemoveList();
2949                }
2950
2951            }while( result2->NextRow() );
2952            delete result2;
2953            if( hasError )
2954            {
2955                PSendSysMessage(LANG_WAYPOINT_TOOFAR1);
2956                PSendSysMessage(LANG_WAYPOINT_TOOFAR2);
2957                PSendSysMessage(LANG_WAYPOINT_TOOFAR3);
2958            }
2959        }
2960
2961        do
2962        {
2963            Field *fields = result->Fetch();
2964            uint32 point    = fields[0].GetUInt32();
2965            float x         = fields[1].GetFloat();
2966            float y         = fields[2].GetFloat();
2967            float z         = fields[3].GetFloat();
2968
2969            uint32 id = VISUAL_WAYPOINT;
2970
2971            Player *chr = m_session->GetPlayer();
2972            Map *map = chr->GetMap();
2973            float o = chr->GetOrientation();
2974
2975            Creature* wpCreature = new Creature;
2976            if (!wpCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, id, 0))
2977            {
2978                PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);
2979                delete wpCreature;
2980                delete result;
2981                return false;
2982            }
2983
2984            wpCreature->Relocate(x, y, z, o);
2985
2986            if(!wpCreature->IsPositionValid())
2987            {
2988                sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",wpCreature->GetGUIDLow(),wpCreature->GetEntry(),wpCreature->GetPositionX(),wpCreature->GetPositionY());
2989                delete wpCreature;
2990                delete result;
2991                return false;
2992            }
2993
2994            wpCreature->SetVisibility(VISIBILITY_OFF);
2995            sLog.outDebug("DEBUG: UPDATE creature_movement SET wpguid = '%u");
2996            // set "wpguid" column to the visual waypoint
2997            WorldDatabase.PExecuteLog("UPDATE creature_movement SET wpguid = '%u' WHERE id = '%u' and point = '%u'", wpCreature->GetGUIDLow(), lowguid, point);
2998
2999            wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
3000            // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
3001            wpCreature->LoadFromDB(wpCreature->GetDBTableGUIDLow(),map);
3002            map->Add(wpCreature);
3003            //MapManager::Instance().GetMap(wpCreature->GetMapId())->Add(wpCreature);
3004        }while( result->NextRow() );
3005
3006        // Cleanup memory
3007        delete result;
3008        return true;
3009    }
3010
3011    if(show == "first")
3012    {
3013        PSendSysMessage("DEBUG: wp first, GUID: %u", lowguid);
3014
3015        QueryResult *result = WorldDatabase.PQuery( "SELECT position_x,position_y,position_z FROM creature_movement WHERE point='1' AND id = '%u'",lowguid);
3016        if(!result)
3017        {
3018            PSendSysMessage(LANG_WAYPOINT_NOTFOUND, lowguid);
3019            SetSentErrorMessage(true);
3020            return false;
3021        }
3022
3023        Field *fields = result->Fetch();
3024        float x         = fields[0].GetFloat();
3025        float y         = fields[1].GetFloat();
3026        float z         = fields[2].GetFloat();
3027        uint32 id = VISUAL_WAYPOINT;
3028
3029        Player *chr = m_session->GetPlayer();
3030        float o = chr->GetOrientation();
3031        Map *map = chr->GetMap();
3032
3033        Creature* pCreature = new Creature;
3034        if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT),map, id, 0))
3035        {
3036            PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);
3037            delete pCreature;
3038            delete result;
3039            return false;
3040        }
3041
3042        pCreature->Relocate(x, y, z, o);
3043
3044        if(!pCreature->IsPositionValid())
3045        {
3046            sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY());
3047            delete pCreature;
3048            delete result;
3049            return false;
3050        }
3051
3052        pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
3053        pCreature->LoadFromDB(pCreature->GetDBTableGUIDLow(), map);
3054        map->Add(pCreature);
3055        //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "First Waypoint");
3056
3057        // Cleanup memory
3058        delete result;
3059        return true;
3060    }
3061
3062    if(show == "last")
3063    {
3064        PSendSysMessage("DEBUG: wp last, GUID: %u", lowguid);
3065
3066        QueryResult *result = WorldDatabase.PQuery( "SELECT MAX(point) FROM creature_movement WHERE id = '%u'",lowguid);
3067        if( result )
3068        {
3069            Maxpoint = (*result)[0].GetUInt32();
3070
3071            delete result;
3072        }
3073        else
3074            Maxpoint = 0;
3075
3076        result = WorldDatabase.PQuery( "SELECT position_x,position_y,position_z FROM creature_movement WHERE point ='%u' AND id = '%u'",Maxpoint, lowguid);
3077        if(!result)
3078        {
3079            PSendSysMessage(LANG_WAYPOINT_NOTFOUNDLAST, lowguid);
3080            SetSentErrorMessage(true);
3081            return false;
3082        }
3083        Field *fields = result->Fetch();
3084        float x         = fields[0].GetFloat();
3085        float y         = fields[1].GetFloat();
3086        float z         = fields[2].GetFloat();
3087        uint32 id = VISUAL_WAYPOINT;
3088
3089        Player *chr = m_session->GetPlayer();
3090        float o = chr->GetOrientation();
3091        Map *map = chr->GetMap();
3092
3093        Creature* pCreature = new Creature;
3094        if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, id, 0))
3095        {
3096            PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id);
3097            delete pCreature;
3098            delete result;
3099            return false;
3100        }
3101
3102        pCreature->Relocate(x, y, z, o);
3103
3104        if(!pCreature->IsPositionValid())
3105        {
3106            sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY());
3107            delete pCreature;
3108            delete result;
3109            return false;
3110        }
3111
3112        pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
3113        pCreature->LoadFromDB(pCreature->GetDBTableGUIDLow(), map);
3114        map->Add(pCreature);
3115        //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "Last Waypoint");
3116        // Cleanup memory
3117        delete result;
3118        return true;
3119    }
3120
3121    if(show == "off")
3122    {
3123        QueryResult *result = WorldDatabase.PQuery("SELECT guid FROM creature WHERE id = '%d'", VISUAL_WAYPOINT);
3124        if(!result)
3125        {
3126            SendSysMessage(LANG_WAYPOINT_VP_NOTFOUND);
3127            SetSentErrorMessage(true);
3128            return false;
3129        }
3130        bool hasError = false;
3131        do
3132        {
3133            Field *fields = result->Fetch();
3134            uint32 guid = fields[0].GetUInt32();
3135            Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(guid,VISUAL_WAYPOINT,HIGHGUID_UNIT));
3136
3137            //Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
3138
3139            if(!pCreature)
3140            {
3141                PSendSysMessage(LANG_WAYPOINT_NOTREMOVED, guid);
3142                hasError = true;
3143                WorldDatabase.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", guid);
3144            }
3145            else
3146            {
3147                pCreature->DeleteFromDB();
3148                pCreature->CleanupsBeforeDelete();
3149                pCreature->AddObjectToRemoveList();
3150            }
3151        }while(result->NextRow());
3152        // set "wpguid" column to "empty" - no visual waypoint spawned
3153        WorldDatabase.PExecuteLog("UPDATE creature_movement SET wpguid = '0'");
3154
3155        if( hasError )
3156        {
3157            PSendSysMessage(LANG_WAYPOINT_TOOFAR1);
3158            PSendSysMessage(LANG_WAYPOINT_TOOFAR2);
3159            PSendSysMessage(LANG_WAYPOINT_TOOFAR3);
3160        }
3161
3162        SendSysMessage(LANG_WAYPOINT_VP_ALLREMOVED);
3163        // Cleanup memory
3164        delete result;
3165
3166        return true;
3167    }
3168
3169    PSendSysMessage("DEBUG: wpshow - no valid command found");
3170
3171    return true;
3172}                                                           // HandleWpShowCommand
3173
3174bool ChatHandler::HandleWpExportCommand(const char *args)
3175{
3176    if(!*args)
3177        return false;
3178
3179    // Next arg is: <GUID> <ARGUMENT>
3180
3181    // Did user provide a GUID
3182    // or did the user select a creature?
3183    // -> variable lowguid is filled with the GUID of the NPC
3184    uint32 lowguid = 0;
3185    Creature* target = getSelectedCreature();
3186    char* arg_str = NULL;
3187    if (target)
3188    {
3189        if (target->GetEntry() != VISUAL_WAYPOINT)
3190            lowguid = target->GetGUIDLow();
3191        else
3192        {
3193            QueryResult *result = WorldDatabase.PQuery( "SELECT id FROM creature_movement WHERE wpguid = %u LIMIT 1", target->GetGUIDLow() );
3194            if (!result)
3195            {
3196                PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, target->GetGUIDLow());
3197                return true;
3198            }
3199            Field *fields = result->Fetch();
3200            lowguid = fields[0].GetUInt32();;
3201            delete result;
3202        }
3203
3204        arg_str = strtok((char*)args, " ");
3205    }
3206    else
3207    {
3208        // user provided <GUID>
3209        char* guid_str = strtok((char*)args, " ");
3210        if( !guid_str )
3211        {
3212            SendSysMessage(LANG_WAYPOINT_NOGUID);
3213            return false;
3214        }
3215        lowguid = atoi((char*)guid_str);
3216
3217        arg_str = strtok((char*)NULL, " ");
3218    }
3219
3220    if( !arg_str)
3221    {
3222        PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ, "export");
3223        return false;
3224    }
3225
3226    PSendSysMessage("DEBUG: wp export, GUID: %u", lowguid);
3227
3228    QueryResult *result = WorldDatabase.PQuery(
3229    //          0      1           2           3           4            5       6       7         8      9      10     11     12     13     14     15
3230        "SELECT point, position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, text1, text2, text3, text4, text5, id FROM creature_movement WHERE id = '%u' ORDER BY point", lowguid );
3231
3232    if (!result)
3233    {
3234        PSendSysMessage(LANG_WAYPOINT_NOTHINGTOEXPORT);
3235        SetSentErrorMessage(true);
3236        return false;
3237    }
3238
3239    std::ofstream outfile;
3240    outfile.open (arg_str);
3241
3242    do
3243    {
3244        Field *fields = result->Fetch();
3245
3246        outfile << "INSERT INTO creature_movement ";
3247        outfile << "( id, point, position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, text1, text2, text3, text4, text5 ) VALUES ";
3248
3249        outfile << "( ";
3250        outfile << fields[15].GetUInt32();                  // id
3251        outfile << ", ";
3252        outfile << fields[0].GetUInt32();                   // point
3253        outfile << ", ";
3254        outfile << fields[1].GetFloat();                    // position_x
3255        outfile << ", ";
3256        outfile << fields[2].GetFloat();                    // position_y
3257        outfile << ", ";
3258        outfile << fields[3].GetUInt32();                   // position_z
3259        outfile << ", ";
3260        outfile << fields[4].GetUInt32();                   // orientation
3261        outfile << ", ";
3262        outfile << fields[5].GetUInt32();                   // model1
3263        outfile << ", ";
3264        outfile << fields[6].GetUInt32();                   // model2
3265        outfile << ", ";
3266        outfile << fields[7].GetUInt16();                   // waittime
3267        outfile << ", ";
3268        outfile << fields[8].GetUInt32();                   // emote
3269        outfile << ", ";
3270        outfile << fields[9].GetUInt32();                   // spell
3271        outfile << ", ";
3272        const char *tmpChar = fields[10].GetString();
3273        if( !tmpChar )
3274        {
3275            outfile << "NULL";                              // text1
3276        }
3277        else
3278        {
3279            outfile << "'";
3280            outfile << tmpChar;                             // text1
3281            outfile << "'";
3282        }
3283        outfile << ", ";
3284        tmpChar = fields[11].GetString();
3285        if( !tmpChar )
3286        {
3287            outfile << "NULL";                              // text2
3288        }
3289        else
3290        {
3291            outfile << "'";
3292            outfile << tmpChar;                             // text2
3293            outfile << "'";
3294        }
3295        outfile << ", ";
3296        tmpChar = fields[12].GetString();
3297        if( !tmpChar )
3298        {
3299            outfile << "NULL";                              // text3
3300        }
3301        else
3302        {
3303            outfile << "'";
3304            outfile << tmpChar;                             // text3
3305            outfile << "'";
3306        }
3307        outfile << ", ";
3308        tmpChar = fields[13].GetString();
3309        if( !tmpChar )
3310        {
3311            outfile << "NULL";                              // text4
3312        }
3313        else
3314        {
3315            outfile << "'";
3316            outfile << tmpChar;                             // text4
3317            outfile << "'";
3318        }
3319        outfile << ", ";
3320        tmpChar = fields[14].GetString();
3321        if( !tmpChar )
3322        {
3323            outfile << "NULL";                              // text5
3324        }
3325        else
3326        {
3327            outfile << "'";
3328            outfile << tmpChar;                             // text5
3329            outfile << "'";
3330        }
3331        outfile << ");\n ";
3332
3333    } while( result->NextRow() );
3334    delete result;
3335
3336    PSendSysMessage(LANG_WAYPOINT_EXPORTED);
3337    outfile.close();
3338
3339    return true;
3340}
3341
3342bool ChatHandler::HandleWpImportCommand(const char *args)
3343{
3344    if(!*args)
3345        return false;
3346
3347    char* arg_str = strtok((char*)args, " ");
3348    if (!arg_str)
3349        return false;
3350
3351    std::string line;
3352    std::ifstream infile (arg_str);
3353    if (infile.is_open())
3354    {
3355        while (! infile.eof() )
3356        {
3357            getline (infile,line);
3358            //cout << line << endl;
3359            QueryResult *result = WorldDatabase.PQuery(line.c_str());
3360            delete result;
3361        }
3362        infile.close();
3363    }
3364    PSendSysMessage(LANG_WAYPOINT_IMPORTED);
3365
3366    return true;
3367}
3368
3369//rename characters
3370bool ChatHandler::HandleRenameCommand(const char* args)
3371{
3372    Player* target = NULL;
3373    uint64 targetGUID = 0;
3374    std::string oldname;
3375
3376    char* px = strtok((char*)args, " ");
3377
3378    if(px)
3379    {
3380        oldname = px;
3381
3382        if(!normalizePlayerName(oldname))
3383        {
3384            SendSysMessage(LANG_PLAYER_NOT_FOUND);
3385            SetSentErrorMessage(true);
3386            return false;
3387        }
3388
3389        target = objmgr.GetPlayer(oldname.c_str());
3390
3391        if (!target)
3392            targetGUID = objmgr.GetPlayerGUIDByName(oldname);
3393    }
3394
3395    if(!target && !targetGUID)
3396    {
3397        target = getSelectedPlayer();
3398    }
3399
3400    if(!target && !targetGUID)
3401    {
3402        SendSysMessage(LANG_PLAYER_NOT_FOUND);
3403        SetSentErrorMessage(true);
3404        return false;
3405    }
3406
3407    if(target)
3408    {
3409        PSendSysMessage(LANG_RENAME_PLAYER, target->GetName());
3410        target->SetAtLoginFlag(AT_LOGIN_RENAME);
3411        CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", target->GetGUIDLow());
3412    }
3413    else
3414    {
3415        PSendSysMessage(LANG_RENAME_PLAYER_GUID, oldname.c_str(), GUID_LOPART(targetGUID));
3416        CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", GUID_LOPART(targetGUID));
3417    }
3418
3419    return true;
3420}
3421
3422//spawn go
3423bool ChatHandler::HandleGameObjectCommand(const char* args)
3424{
3425    if (!*args)
3426        return false;
3427
3428    char* pParam1 = strtok((char*)args, " ");
3429    if (!pParam1)
3430        return false;
3431
3432    uint32 id = atoi((char*)pParam1);
3433    if(!id)
3434        return false;
3435
3436    char* spawntimeSecs = strtok(NULL, " ");
3437
3438    const GameObjectInfo *goI = objmgr.GetGameObjectInfo(id);
3439
3440    if (!goI)
3441    {
3442        PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST,id);
3443        SetSentErrorMessage(true);
3444        return false;
3445    }
3446
3447    Player *chr = m_session->GetPlayer();
3448    float x = float(chr->GetPositionX());
3449    float y = float(chr->GetPositionY());
3450    float z = float(chr->GetPositionZ());
3451    float o = float(chr->GetOrientation());
3452    Map *map = chr->GetMap();
3453
3454    float rot2 = sin(o/2);
3455    float rot3 = cos(o/2);
3456
3457    GameObject* pGameObj = new GameObject;
3458    uint32 db_lowGUID = objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT);
3459
3460    if(!pGameObj->Create(db_lowGUID, goI->id, map, x, y, z, o, 0, 0, rot2, rot3, 0, 1))
3461    {
3462        delete pGameObj;
3463        return false;
3464    }
3465
3466    if( spawntimeSecs )
3467    {
3468        uint32 value = atoi((char*)spawntimeSecs);
3469        pGameObj->SetRespawnTime(value);
3470        //sLog.outDebug("*** spawntimeSecs: %d", value);
3471    }
3472
3473    // fill the gameobject data and save to the db
3474    pGameObj->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
3475
3476    // this will generate a new guid if the object is in an instance
3477    if(!pGameObj->LoadFromDB(db_lowGUID, map))
3478    {
3479        delete pGameObj;
3480        return false;
3481    }
3482
3483    sLog.outDebug(GetTrinityString(LANG_GAMEOBJECT_CURRENT), goI->name, db_lowGUID, x, y, z, o);
3484
3485    map->Add(pGameObj);
3486
3487    // TODO: is it really necessary to add both the real and DB table guid here ?
3488    objmgr.AddGameobjectToGrid(db_lowGUID, objmgr.GetGOData(db_lowGUID));
3489
3490    PSendSysMessage(LANG_GAMEOBJECT_ADD,id,goI->name,db_lowGUID,x,y,z);
3491    return true;
3492}
3493
3494//show animation
3495bool ChatHandler::HandleAnimCommand(const char* args)
3496{
3497    if (!*args)
3498        return false;
3499
3500    uint32 anim_id = atoi((char*)args);
3501    m_session->GetPlayer()->HandleEmoteCommand(anim_id);
3502    return true;
3503}
3504
3505//change standstate
3506bool ChatHandler::HandleStandStateCommand(const char* args)
3507{
3508    if (!*args)
3509        return false;
3510
3511    uint32 anim_id = atoi((char*)args);
3512    m_session->GetPlayer( )->SetUInt32Value( UNIT_NPC_EMOTESTATE , anim_id );
3513
3514    return true;
3515}
3516
3517bool ChatHandler::HandleAddHonorCommand(const char* args)
3518{
3519    if (!*args)
3520        return false;
3521
3522    Player *target = getSelectedPlayer();
3523    if(!target)
3524    {
3525        SendSysMessage(LANG_PLAYER_NOT_FOUND);
3526        SetSentErrorMessage(true);
3527        return false;
3528    }
3529
3530    uint32 amount = (uint32)atoi(args);
3531    target->RewardHonor(NULL, 1, amount);
3532    return true;
3533}
3534
3535bool ChatHandler::HandleHonorAddKillCommand(const char* /*args*/)
3536{
3537    Unit *target = getSelectedUnit();
3538    if(!target)
3539    {
3540        SendSysMessage(LANG_PLAYER_NOT_FOUND);
3541        SetSentErrorMessage(true);
3542        return false;
3543    }
3544
3545    m_session->GetPlayer()->RewardHonor(target, 1);
3546    return true;
3547}
3548
3549bool ChatHandler::HandleUpdateHonorFieldsCommand(const char* /*args*/)
3550{
3551    Player *target = getSelectedPlayer();
3552    if(!target)
3553    {
3554        SendSysMessage(LANG_PLAYER_NOT_FOUND);
3555        SetSentErrorMessage(true);
3556        return false;
3557    }
3558
3559    target->UpdateHonorFields();
3560    return true;
3561}
3562
3563bool ChatHandler::HandleLookupEventCommand(const char* args)
3564{
3565    if(!*args)
3566        return false;
3567
3568    std::string namepart = args;
3569    std::wstring wnamepart;
3570
3571    // converting string that we try to find to lower case
3572    if(!Utf8toWStr(namepart,wnamepart))
3573        return false;
3574
3575    wstrToLower(wnamepart);
3576
3577    uint32 counter = 0;
3578
3579    GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap();
3580    GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
3581
3582    for(uint32 id = 0; id < events.size(); ++id )
3583    {
3584        GameEventData const& eventData = events[id];
3585
3586        std::string descr = eventData.description;
3587        if(descr.empty())
3588            continue;
3589
3590        if (Utf8FitTo(descr, wnamepart))
3591        {
3592            char const* active = activeEvents.find(id) != activeEvents.end() ? GetTrinityString(LANG_ACTIVE) : "";
3593            PSendSysMessage(LANG_EVENT_ENTRY_LIST,id,id,descr.c_str(),active );
3594            ++counter;
3595        }
3596    }
3597
3598    if (counter==0)
3599        SendSysMessage(LANG_NOEVENTFOUND);
3600
3601    return true;
3602}
3603
3604bool ChatHandler::HandleEventActiveListCommand(const char* args)
3605{
3606    uint32 counter = 0;
3607
3608    GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap();
3609    GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
3610
3611    char const* active = GetTrinityString(LANG_ACTIVE);
3612
3613    for(GameEvent::ActiveEvents::const_iterator itr = activeEvents.begin(); itr != activeEvents.end(); ++itr )
3614    {
3615        uint32 event_id = *itr;
3616        GameEventData const& eventData = events[event_id];
3617
3618        PSendSysMessage(LANG_EVENT_ENTRY_LIST,event_id,event_id,eventData.description.c_str(),active );
3619        ++counter;
3620    }
3621
3622    if (counter==0)
3623        SendSysMessage(LANG_NOEVENTFOUND);
3624
3625    return true;
3626}
3627
3628bool ChatHandler::HandleEventInfoCommand(const char* args)
3629{
3630    if(!*args)
3631        return false;
3632
3633    // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
3634    char* cId = extractKeyFromLink((char*)args,"Hgameevent");
3635    if(!cId)
3636        return false;
3637
3638    uint32 event_id = atoi(cId);
3639
3640    GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap();
3641
3642    if(event_id >=events.size())
3643    {
3644        SendSysMessage(LANG_EVENT_NOT_EXIST);
3645        SetSentErrorMessage(true);
3646        return false;
3647    }
3648
3649    GameEventData const& eventData = events[event_id];
3650    if(!eventData.isValid())
3651    {
3652        SendSysMessage(LANG_EVENT_NOT_EXIST);
3653        SetSentErrorMessage(true);
3654        return false;
3655    }
3656
3657    GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
3658    bool active = activeEvents.find(event_id) != activeEvents.end();
3659    char const* activeStr = active ? GetTrinityString(LANG_ACTIVE) : "";
3660
3661    std::string startTimeStr = TimeToTimestampStr(eventData.start);
3662    std::string endTimeStr = TimeToTimestampStr(eventData.end);
3663
3664    uint32 delay = gameeventmgr.NextCheck(event_id);
3665    time_t nextTime = time(NULL)+delay;
3666    std::string nextStr = nextTime >= eventData.start && nextTime < eventData.end ? TimeToTimestampStr(time(NULL)+delay) : "-";
3667
3668    std::string occurenceStr = secsToTimeString(eventData.occurence * MINUTE);
3669    std::string lengthStr = secsToTimeString(eventData.length * MINUTE);
3670
3671    PSendSysMessage(LANG_EVENT_INFO,event_id,eventData.description.c_str(),activeStr,
3672        startTimeStr.c_str(),endTimeStr.c_str(),occurenceStr.c_str(),lengthStr.c_str(),
3673        nextStr.c_str());
3674    return true;
3675}
3676
3677bool ChatHandler::HandleEventStartCommand(const char* args)
3678{
3679    if(!*args)
3680        return false;
3681
3682    // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
3683    char* cId = extractKeyFromLink((char*)args,"Hgameevent");
3684    if(!cId)
3685        return false;
3686
3687    int32 event_id = atoi(cId);
3688
3689    GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap();
3690
3691    if(event_id < 1 || event_id >=events.size())
3692    {
3693        SendSysMessage(LANG_EVENT_NOT_EXIST);
3694        SetSentErrorMessage(true);
3695        return false;
3696    }
3697
3698    GameEventData const& eventData = events[event_id];
3699    if(!eventData.isValid())
3700    {
3701        SendSysMessage(LANG_EVENT_NOT_EXIST);
3702        SetSentErrorMessage(true);
3703        return false;
3704    }
3705
3706    GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
3707    if(activeEvents.find(event_id) != activeEvents.end())
3708    {
3709        PSendSysMessage(LANG_EVENT_ALREADY_ACTIVE,event_id);
3710        SetSentErrorMessage(true);
3711        return false;
3712    }
3713
3714    gameeventmgr.StartEvent(event_id,true);
3715    return true;
3716}
3717
3718bool ChatHandler::HandleEventStopCommand(const char* args)
3719{
3720    if(!*args)
3721        return false;
3722
3723    // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
3724    char* cId = extractKeyFromLink((char*)args,"Hgameevent");
3725    if(!cId)
3726        return false;
3727
3728    int32 event_id = atoi(cId);
3729
3730    GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap();
3731
3732    if(event_id < 1 || event_id >=events.size())
3733    {
3734        SendSysMessage(LANG_EVENT_NOT_EXIST);
3735        SetSentErrorMessage(true);
3736        return false;
3737    }
3738
3739    GameEventData const& eventData = events[event_id];
3740    if(!eventData.isValid())
3741    {
3742        SendSysMessage(LANG_EVENT_NOT_EXIST);
3743        SetSentErrorMessage(true);
3744        return false;
3745    }
3746
3747    GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
3748
3749    if(activeEvents.find(event_id) == activeEvents.end())
3750    {
3751        PSendSysMessage(LANG_EVENT_NOT_ACTIVE,event_id);
3752        SetSentErrorMessage(true);
3753        return false;
3754    }
3755
3756    gameeventmgr.StopEvent(event_id,true);
3757    return true;
3758}
3759
3760bool ChatHandler::HandleCombatStopCommand(const char* args)
3761{
3762    Player *player;
3763
3764    if(*args)
3765    {
3766        std::string playername = args;
3767
3768        if(!normalizePlayerName(playername))
3769        {
3770            SendSysMessage(LANG_PLAYER_NOT_FOUND);
3771            SetSentErrorMessage(true);
3772            return false;
3773        }
3774
3775        player = objmgr.GetPlayer(playername.c_str());
3776
3777        if(!player)
3778        {
3779            SendSysMessage(LANG_PLAYER_NOT_FOUND);
3780            SetSentErrorMessage(true);
3781            return false;
3782        }
3783    }
3784    else
3785    {
3786        player = getSelectedPlayer();
3787
3788        if (!player)
3789            player = m_session->GetPlayer();
3790    }
3791
3792    player->CombatStop();
3793    player->getHostilRefManager().deleteReferences();
3794    return true;
3795}
3796
3797bool ChatHandler::HandleLearnAllCraftsCommand(const char* /*args*/)
3798{
3799    uint32 classmask = m_session->GetPlayer()->getClassMask();
3800
3801    for (uint32 i = 0; i < sSkillLineStore.GetNumRows(); ++i)
3802    {
3803        SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(i);
3804        if( !skillInfo )
3805            continue;
3806
3807        if( skillInfo->categoryId == SKILL_CATEGORY_PROFESSION || skillInfo->categoryId == SKILL_CATEGORY_SECONDARY )
3808        {
3809            for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j)
3810            {
3811                SkillLineAbilityEntry const *skillLine = sSkillLineAbilityStore.LookupEntry(j);
3812                if( !skillLine )
3813                    continue;
3814
3815                // skip racial skills
3816                if( skillLine->racemask != 0 )
3817                    continue;
3818
3819                // skip wrong class skills
3820                if( skillLine->classmask && (skillLine->classmask & classmask) == 0)
3821                    continue;
3822
3823                if( skillLine->skillId != i || skillLine->forward_spellid )
3824                    continue;
3825
3826                SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId);
3827                if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
3828                    continue;
3829
3830                m_session->GetPlayer()->learnSpell(skillLine->spellId);
3831            }
3832        }
3833    }
3834
3835    SendSysMessage(LANG_COMMAND_LEARN_ALL_CRAFT);
3836    return true;
3837}
3838
3839bool ChatHandler::HandleLearnAllRecipesCommand(const char* args)
3840{
3841    //  Learns all recipes of specified profession and sets skill to max
3842    //  Example: .learn all_recipes enchanting
3843
3844    Player* target = getSelectedPlayer();
3845    if( !target )
3846    {
3847        SendSysMessage(LANG_PLAYER_NOT_FOUND);
3848        return false;
3849    }
3850
3851    if(!*args)
3852        return false;
3853
3854    std::wstring wnamepart;
3855
3856    if(!Utf8toWStr(args,wnamepart))
3857        return false;
3858
3859    uint32 counter = 0;                                     // Counter for figure out that we found smth.
3860
3861    // converting string that we try to find to lower case
3862    wstrToLower( wnamepart );
3863
3864    uint32 classmask = m_session->GetPlayer()->getClassMask();
3865
3866    for (uint32 i = 0; i < sSkillLineStore.GetNumRows(); ++i)
3867    {
3868        SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(i);
3869        if( !skillInfo )
3870            continue;
3871
3872        if( skillInfo->categoryId != SKILL_CATEGORY_PROFESSION &&
3873            skillInfo->categoryId != SKILL_CATEGORY_SECONDARY )
3874            continue;
3875
3876        int loc = m_session->GetSessionDbcLocale();
3877        std::string name = skillInfo->name[loc];
3878
3879        if(Utf8FitTo(name, wnamepart))
3880        {
3881            for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j)
3882            {
3883                SkillLineAbilityEntry const *skillLine = sSkillLineAbilityStore.LookupEntry(j);
3884                if( !skillLine )
3885                    continue;
3886
3887                if( skillLine->skillId != i || skillLine->forward_spellid )
3888                    continue;
3889
3890                // skip racial skills
3891                if( skillLine->racemask != 0 )
3892                    continue;
3893
3894                // skip wrong class skills
3895                if( skillLine->classmask && (skillLine->classmask & classmask) == 0)
3896                    continue;
3897
3898                SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId);
3899                if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
3900                    continue;
3901
3902                if( !target->HasSpell(spellInfo->Id) )
3903                    m_session->GetPlayer()->learnSpell(skillLine->spellId);
3904            }
3905
3906            uint16 maxLevel = target->GetPureMaxSkillValue(skillInfo->id);
3907            target->SetSkill(skillInfo->id, maxLevel, maxLevel);
3908            PSendSysMessage(LANG_COMMAND_LEARN_ALL_RECIPES, name.c_str());
3909            return true;
3910        }
3911    }
3912
3913    return false;
3914}
3915
3916bool ChatHandler::HandleLookupPlayerIpCommand(const char* args)
3917{
3918 
3919    if(!*args)
3920        return false;
3921
3922    std::string ip = strtok((char*)args, " ");
3923    char* limit_str = strtok(NULL, " ");
3924    int32 limit = limit_str ? atoi(limit_str) : -1;
3925
3926    loginDatabase.escape_string(ip);
3927
3928    QueryResult* result = loginDatabase.PQuery("SELECT id,username FROM account WHERE last_ip = '%s'", ip.c_str());
3929
3930    return LookupPlayerSearchCommand(result,limit);
3931}
3932
3933bool ChatHandler::HandleLookupPlayerAccountCommand(const char* args)
3934{
3935    if(!*args)
3936        return false;
3937
3938    std::string account = strtok((char*)args, " ");
3939    char* limit_str = strtok(NULL, " ");
3940    int32 limit = limit_str ? atoi(limit_str) : -1;
3941
3942    if(!AccountMgr::normilizeString(account))
3943        return false;
3944
3945    loginDatabase.escape_string(account);
3946
3947    QueryResult* result = loginDatabase.PQuery("SELECT id,username FROM account WHERE username = '%s'", account.c_str());
3948
3949    return LookupPlayerSearchCommand(result,limit);
3950}
3951
3952bool ChatHandler::HandleLookupPlayerEmailCommand(const char* args)
3953{
3954 
3955    if(!*args)
3956        return false;
3957
3958    std::string email = strtok((char*)args, " ");
3959    char* limit_str = strtok(NULL, " ");
3960    int32 limit = limit_str ? atoi(limit_str) : -1;
3961
3962    loginDatabase.escape_string(email);
3963
3964    QueryResult* result = loginDatabase.PQuery("SELECT id,username FROM account WHERE email = '%s'", email.c_str());
3965
3966    return LookupPlayerSearchCommand(result,limit);
3967}
3968
3969bool ChatHandler::LookupPlayerSearchCommand(QueryResult* result, int32 limit)
3970{
3971    if(!result)
3972    {
3973        PSendSysMessage(LANG_NO_PLAYERS_FOUND);
3974        SetSentErrorMessage(true);
3975        return false;
3976    }
3977
3978    int i =0;
3979    do
3980    {
3981        Field* fields = result->Fetch();
3982        uint32 acc_id = fields[0].GetUInt32();
3983        std::string acc_name = fields[1].GetCppString();
3984       
3985        QueryResult* chars = CharacterDatabase.PQuery("SELECT guid,name FROM characters WHERE account = '%u'", acc_id);
3986        if(chars)
3987        {
3988            PSendSysMessage(LANG_LOOKUP_PLAYER_ACCOUNT,acc_name.c_str(),acc_id);
3989
3990            uint64 guid = 0;
3991            std::string name;
3992
3993            do
3994            {
3995                Field* charfields = chars->Fetch();
3996                guid = charfields[0].GetUInt64();
3997                name = charfields[1].GetCppString();
3998
3999                PSendSysMessage(LANG_LOOKUP_PLAYER_CHARACTER,name.c_str(),guid);
4000                ++i;
4001
4002            } while( chars->NextRow() && ( limit == -1 || i < limit ) );
4003
4004            delete chars;
4005        }
4006    } while(result->NextRow());
4007
4008    delete result;
4009
4010    return true;
4011}
Note: See TracBrowser for help on using the browser.