aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Chat
diff options
context:
space:
mode:
authorRat <none@none>2010-06-05 23:40:08 +0200
committerRat <none@none>2010-06-05 23:40:08 +0200
commit75b80d9f5b02a643c983b2fb1ededed79fd5d133 (patch)
treeebd1c2cc12a2715909dd04c1ed147a260c6ceb14 /src/server/game/Chat
parent6a9357b13d7ea6bd7d77dbfc6587af9028caa401 (diff)
rearranged core files
--HG-- branch : trunk
Diffstat (limited to 'src/server/game/Chat')
-rw-r--r--src/server/game/Chat/Channel.cpp1102
-rw-r--r--src/server/game/Chat/Channel.h292
-rw-r--r--src/server/game/Chat/ChannelHandler.cpp323
-rw-r--r--src/server/game/Chat/ChannelMgr.cpp110
-rw-r--r--src/server/game/Chat/ChannelMgr.h57
-rw-r--r--src/server/game/Chat/Chat.cpp2458
-rw-r--r--src/server/game/Chat/Chat.h654
-rw-r--r--src/server/game/Chat/ChatHandler.cpp756
-rw-r--r--src/server/game/Chat/Debugcmds.cpp1127
-rw-r--r--src/server/game/Chat/Level0.cpp295
-rw-r--r--src/server/game/Chat/Level1.cpp2960
-rw-r--r--src/server/game/Chat/Level2.cpp4526
-rw-r--r--src/server/game/Chat/Level3.cpp7743
13 files changed, 22403 insertions, 0 deletions
diff --git a/src/server/game/Chat/Channel.cpp b/src/server/game/Chat/Channel.cpp
new file mode 100644
index 00000000000..0047892972b
--- /dev/null
+++ b/src/server/game/Chat/Channel.cpp
@@ -0,0 +1,1102 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "Channel.h"
+#include "Chat.h"
+#include "ObjectMgr.h"
+#include "SocialMgr.h"
+#include "World.h"
+
+Channel::Channel(const std::string& name, uint32 channel_id, uint32 Team)
+ : m_name(name), m_announce(true), m_moderate(false), m_channelId(channel_id), m_ownerGUID(0), m_password(""), m_flags(0), m_Team(Team)
+{
+ // set special flags if built-in channel
+ ChatChannelsEntry const* ch = GetChannelEntryFor(channel_id);
+ if (ch) // it's built-in channel
+ {
+ channel_id = ch->ChannelID; // built-in channel
+ m_announce = false; // no join/leave announces
+
+ m_flags |= CHANNEL_FLAG_GENERAL; // for all built-in channels
+
+ if (ch->flags & CHANNEL_DBC_FLAG_TRADE) // for trade channel
+ m_flags |= CHANNEL_FLAG_TRADE;
+
+ if (ch->flags & CHANNEL_DBC_FLAG_CITY_ONLY2) // for city only channels
+ m_flags |= CHANNEL_FLAG_CITY;
+
+ if (ch->flags & CHANNEL_DBC_FLAG_LFG) // for LFG channel
+ m_flags |= CHANNEL_FLAG_LFG;
+ else // for all other channels
+ m_flags |= CHANNEL_FLAG_NOT_LFG;
+ m_IsSaved = false;
+ }
+ else // it's custom channel
+ {
+ m_flags |= CHANNEL_FLAG_CUSTOM;
+ //load not built in channel if saved
+ std::string _name(name);
+ CharacterDatabase.escape_string(_name);
+ QueryResult_AutoPtr result = CharacterDatabase.PQuery("SELECT m_announce, m_moderate, m_public, m_password, BannedList FROM channels WHERE m_name = '%s' AND m_team = '%u'", _name.c_str(), m_Team);
+ if (result)//load
+ {
+ Field *fields = result->Fetch();
+ m_announce = fields[0].GetBool();
+ m_moderate = fields[1].GetBool();
+ m_public = fields[2].GetBool();
+ m_password = fields[3].GetString();
+ const char* db_BannedList = fields[4].GetString();
+
+ m_IsSaved = true;
+
+ if (db_BannedList)
+ {
+ Tokens tokens = StrSplit(db_BannedList, " ");
+ Tokens::iterator iter;
+ for (iter = tokens.begin(); iter != tokens.end(); ++iter)
+ {
+ uint64 banned_guid = atol((*iter).c_str());
+ if (banned_guid)
+ {
+ sLog.outDebug("Channel(%s) loaded banned guid: %u",name.c_str(), banned_guid);
+ banned.insert(banned_guid);
+ }
+ }
+ }
+ }
+ else // save
+ {
+ // _name is already escaped at this point.
+ if (CharacterDatabase.PExecute("INSERT INTO channels (m_name, m_team, m_announce, m_moderate, m_public, m_password) "
+ "VALUES ('%s', '%u', '1', '0', '1', '')", _name.c_str(), m_Team))
+ {
+ sLog.outDebug("New Channel(%s) saved", name.c_str());
+ m_IsSaved = true;
+ }
+ }
+ }
+}
+
+bool Channel::_UpdateStringInDB(const std::string& colName, const std::string& colValue) const
+{
+ // Prevent SQL-injection
+ std::string _name(m_name);
+ std::string _colValue(colValue);
+ CharacterDatabase.escape_string(_colValue);
+ CharacterDatabase.escape_string(_name);
+ return CharacterDatabase.PExecute("UPDATE channels SET %s = '%s' WHERE m_name = '%s' AND m_team = '%u'",
+ colName.c_str(), _colValue.c_str(), _name.c_str(), m_Team);
+}
+
+bool Channel::_UpdateIntInDB(const std::string& colName, int colValue) const
+{
+ // Prevent SQL-injection
+ std::string _name(m_name);
+ CharacterDatabase.escape_string(_name);
+ return CharacterDatabase.PExecute("UPDATE channels SET %s = '%u' WHERE m_name = '%s' AND m_team = '%u'",
+ colName.c_str(), colValue, _name.c_str(), m_Team);
+}
+
+void Channel::_UpdateBanListInDB() const
+{
+ // save banlist
+ if (m_IsSaved)
+ {
+ std::ostringstream banlist;
+ BannedList::const_iterator iter;
+ for (iter = banned.begin(); iter != banned.end(); ++iter)
+ banlist << (*iter) << " ";
+ std::string banListStr = banlist.str();
+ if (_UpdateStringInDB("BannedList", banListStr))
+ sLog.outDebug("Channel(%s) BannedList saved", m_name.c_str());
+ }
+}
+
+void Channel::Join(uint64 p, const char *pass)
+{
+ WorldPacket data;
+ if (IsOn(p))
+ {
+ if (!IsConstant()) // non send error message for built-in channels
+ {
+ MakePlayerAlreadyMember(&data, p);
+ SendToOne(&data, p);
+ }
+ return;
+ }
+
+ if (IsBanned(p))
+ {
+ MakeBanned(&data);
+ SendToOne(&data, p);
+ return;
+ }
+
+ if (m_password.length() > 0 && strcmp(pass, m_password.c_str()))
+ {
+ MakeWrongPassword(&data);
+ SendToOne(&data, p);
+ return;
+ }
+
+ Player *plr = objmgr.GetPlayer(p);
+
+ if (plr)
+ {
+ if (HasFlag(CHANNEL_FLAG_LFG) &&
+ sWorld.getConfig(CONFIG_RESTRICTED_LFG_CHANNEL) && plr->GetSession()->GetSecurity() == SEC_PLAYER && plr->GetGroup())
+ {
+ MakeNotInLfg(&data);
+ SendToOne(&data, p);
+ return;
+ }
+
+ if (plr->GetGuildId() && (GetFlags() == 0x38))
+ return;
+
+ plr->JoinedChannel(this);
+ }
+
+ if (m_announce && (!plr || plr->GetSession()->GetSecurity() < SEC_GAMEMASTER || !sWorld.getConfig(CONFIG_SILENTLY_GM_JOIN_TO_CHANNEL)))
+ {
+ MakeJoined(&data, p);
+ SendToAll(&data);
+ }
+
+ data.clear();
+
+ PlayerInfo pinfo;
+ pinfo.player = p;
+ pinfo.flags = MEMBER_FLAG_NONE;
+ players[p] = pinfo;
+
+ MakeYouJoined(&data);
+ SendToOne(&data, p);
+
+ JoinNotify(p);
+
+ // if no owner first logged will become
+ if (!IsConstant() && !m_ownerGUID)
+ {
+ SetOwner(p, (players.size() > 1 ? true : false));
+ players[p].SetModerator(true);
+ }
+ /*
+ else if (!IsConstant() && m_ownerGUID && plr && m_ownerGUID == plr->GetGUID()))
+ {
+ SetOwner(p, (players.size() > 1 ? true : false));
+ players[p].SetModerator(true);
+ }*/
+}
+
+void Channel::Leave(uint64 p, bool send)
+{
+ if (!IsOn(p))
+ {
+ if (send)
+ {
+ WorldPacket data;
+ MakeNotMember(&data);
+ SendToOne(&data, p);
+ }
+ }
+ else
+ {
+ Player *plr = objmgr.GetPlayer(p);
+
+ if (send)
+ {
+ WorldPacket data;
+ MakeYouLeft(&data);
+ SendToOne(&data, p);
+ if (plr)
+ plr->LeftChannel(this);
+ data.clear();
+ }
+
+ bool changeowner = players[p].IsOwner();
+
+ players.erase(p);
+ if (m_announce && (!plr || plr->GetSession()->GetSecurity() < SEC_GAMEMASTER || !sWorld.getConfig(CONFIG_SILENTLY_GM_JOIN_TO_CHANNEL)))
+ {
+ WorldPacket data;
+ MakeLeft(&data, p);
+ SendToAll(&data);
+ }
+
+ LeaveNotify(p);
+
+ if (changeowner)
+ {
+ uint64 newowner = !players.empty() ? players.begin()->second.player : 0;
+ players[newowner].SetModerator(true);
+ SetOwner(newowner);
+ }
+ }
+}
+
+void Channel::KickOrBan(uint64 good, const char *badname, bool ban)
+{
+ AccountTypes sec = SEC_PLAYER;
+ Player *gplr = objmgr.GetPlayer(good);
+ if (gplr)
+ sec = gplr->GetSession()->GetSecurity();
+
+ if (!IsOn(good))
+ {
+ WorldPacket data;
+ MakeNotMember(&data);
+ SendToOne(&data, good);
+ }
+ else if (!players[good].IsModerator() && sec < SEC_GAMEMASTER)
+ {
+ WorldPacket data;
+ MakeNotModerator(&data);
+ SendToOne(&data, good);
+ }
+ else
+ {
+ Player *bad = objmgr.GetPlayer(badname);
+ if (bad == NULL || !IsOn(bad->GetGUID()))
+ {
+ WorldPacket data;
+ MakePlayerNotFound(&data, badname);
+ SendToOne(&data, good);
+ }
+ else if (sec < SEC_GAMEMASTER && bad->GetGUID() == m_ownerGUID && good != m_ownerGUID)
+ {
+ WorldPacket data;
+ MakeNotOwner(&data);
+ SendToOne(&data, good);
+ }
+ else
+ {
+ bool changeowner = (m_ownerGUID == bad->GetGUID());
+
+ WorldPacket data;
+
+ if (ban && !IsBanned(bad->GetGUID()))
+ {
+ banned.insert(bad->GetGUID());
+ MakePlayerBanned(&data, bad->GetGUID(), good);
+ _UpdateBanListInDB();
+
+ }
+ else
+ MakePlayerKicked(&data, bad->GetGUID(), good);
+
+ SendToAll(&data);
+ players.erase(bad->GetGUID());
+ bad->LeftChannel(this);
+
+ if (changeowner)
+ {
+ uint64 newowner = !players.empty() ? good : false;
+ players[newowner].SetModerator(true);
+ SetOwner(newowner);
+ }
+ }
+ }
+}
+
+void Channel::UnBan(uint64 good, const char *badname)
+{
+ uint32 sec = 0;
+ Player *gplr = objmgr.GetPlayer(good);
+ if (gplr)
+ sec = gplr->GetSession()->GetSecurity();
+
+ if (!IsOn(good))
+ {
+ WorldPacket data;
+ MakeNotMember(&data);
+ SendToOne(&data, good);
+ }
+ else if (!players[good].IsModerator() && sec < SEC_GAMEMASTER)
+ {
+ WorldPacket data;
+ MakeNotModerator(&data);
+ SendToOne(&data, good);
+ }
+ else
+ {
+ Player *bad = objmgr.GetPlayer(badname);
+ if (bad == NULL || !IsBanned(bad->GetGUID()))
+ {
+ WorldPacket data;
+ MakePlayerNotFound(&data, badname);
+ SendToOne(&data, good);
+ }
+ else
+ {
+ banned.erase(bad->GetGUID());
+
+ WorldPacket data;
+ MakePlayerUnbanned(&data, bad->GetGUID(), good);
+ SendToAll(&data);
+ //save banlist
+ _UpdateBanListInDB();
+ }
+ }
+}
+
+void Channel::Password(uint64 p, const char *pass)
+{
+ std::string plName;
+ uint32 sec = 0;
+ Player *plr = objmgr.GetPlayer(p);
+ if (plr)
+ sec = plr->GetSession()->GetSecurity();
+
+ ChatHandler chat(plr);
+
+ if (!m_public && sec <= SEC_MODERATOR)
+ {
+ chat.PSendSysMessage(LANG_CHANNEL_NOT_PUBLIC);
+ return;
+ }
+
+ if (!IsOn(p))
+ {
+ WorldPacket data;
+ MakeNotMember(&data);
+ SendToOne(&data, p);
+ }
+ else if (!players[p].IsModerator() && sec < SEC_GAMEMASTER)
+ {
+ WorldPacket data;
+ MakeNotModerator(&data);
+ SendToOne(&data, p);
+ }
+ else
+ {
+ m_password = pass;
+
+ WorldPacket data;
+ MakePasswordChanged(&data, p);
+ SendToAll(&data);
+ if (m_IsSaved && _UpdateStringInDB("m_password", m_password))
+ sLog.outDebug("Channel(%s) password saved", m_name.c_str());
+ }
+}
+
+void Channel::SetMode(uint64 p, const char *p2n, bool mod, bool set)
+{
+ Player *plr = objmgr.GetPlayer(p);
+ if (!plr)
+ return;
+
+ uint32 sec = plr->GetSession()->GetSecurity();
+
+ if (!IsOn(p))
+ {
+ WorldPacket data;
+ MakeNotMember(&data);
+ SendToOne(&data, p);
+ }
+ else if (!players[p].IsModerator() && sec < SEC_GAMEMASTER)
+ {
+ WorldPacket data;
+ MakeNotModerator(&data);
+ SendToOne(&data, p);
+ }
+ else
+ {
+ Player *newp = objmgr.GetPlayer(p2n);
+ if (!newp)
+ {
+ WorldPacket data;
+ MakePlayerNotFound(&data, p2n);
+ SendToOne(&data, p);
+ return;
+ }
+
+ if (p == m_ownerGUID && newp->GetGUID() == m_ownerGUID && mod)
+ return;
+
+ if (!IsOn(newp->GetGUID()))
+ {
+ WorldPacket data;
+ MakePlayerNotFound(&data, p2n);
+ SendToOne(&data, p);
+ return;
+ }
+
+ // allow make moderator from another team only if both is GMs
+ // at this moment this only way to show channel post for GM from another team
+ if ((plr->GetSession()->GetSecurity() < SEC_GAMEMASTER || newp->GetSession()->GetSecurity() < SEC_GAMEMASTER) &&
+ plr->GetTeam() != newp->GetTeam() && !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL))
+ {
+ WorldPacket data;
+ MakePlayerNotFound(&data, p2n);
+ SendToOne(&data, p);
+ return;
+ }
+
+ if (m_ownerGUID == newp->GetGUID() && m_ownerGUID != p)
+ {
+ WorldPacket data;
+ MakeNotOwner(&data);
+ SendToOne(&data, p);
+ return;
+ }
+
+ if (mod)
+ SetModerator(newp->GetGUID(), set);
+ else
+ SetMute(newp->GetGUID(), set);
+ }
+}
+
+void Channel::SetOwner(uint64 p, const char *newname)
+{
+ Player *plr = objmgr.GetPlayer(p);
+ if (!plr)
+ return;
+
+ uint32 sec = plr->GetSession()->GetSecurity();
+
+ if (!IsOn(p))
+ {
+ WorldPacket data;
+ MakeNotMember(&data);
+ SendToOne(&data, p);
+ return;
+ }
+
+ if (sec < SEC_GAMEMASTER && p != m_ownerGUID)
+ {
+ WorldPacket data;
+ MakeNotOwner(&data);
+ SendToOne(&data, p);
+ return;
+ }
+
+ Player *newp = objmgr.GetPlayer(newname);
+ if (newp == NULL || !IsOn(newp->GetGUID()))
+ {
+ WorldPacket data;
+ MakePlayerNotFound(&data, newname);
+ SendToOne(&data, p);
+ return;
+ }
+
+ if (newp->GetTeam() != plr->GetTeam() && !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL))
+ {
+ WorldPacket data;
+ MakePlayerNotFound(&data, newname);
+ SendToOne(&data, p);
+ return;
+ }
+
+ players[newp->GetGUID()].SetModerator(true);
+ SetOwner(newp->GetGUID());
+}
+
+void Channel::SendWhoOwner(uint64 p)
+{
+ if (!IsOn(p))
+ {
+ WorldPacket data;
+ MakeNotMember(&data);
+ SendToOne(&data, p);
+ }
+ else
+ {
+ WorldPacket data;
+ MakeChannelOwner(&data);
+ SendToOne(&data, p);
+ }
+}
+
+void Channel::List(Player* player)
+{
+ uint64 p = player->GetGUID();
+
+ if (!IsOn(p))
+ {
+ WorldPacket data;
+ MakeNotMember(&data);
+ SendToOne(&data, p);
+ }
+ else
+ {
+ WorldPacket data(SMSG_CHANNEL_LIST, 1+(GetName().size()+1)+1+4+players.size()*(8+1));
+ data << uint8(1); // channel type?
+ data << GetName(); // channel name
+ data << uint8(GetFlags()); // channel flags?
+
+ size_t pos = data.wpos();
+ data << uint32(0); // size of list, placeholder
+
+ uint32 gmLevelInWhoList = sWorld.getConfig(CONFIG_GM_LEVEL_IN_WHO_LIST);
+
+ uint32 count = 0;
+ for (PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
+ {
+ Player *plr = objmgr.GetPlayer(i->first);
+
+ // PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters
+ // MODERATOR, GAME MASTER, ADMINISTRATOR can see all
+ if (plr && (player->GetSession()->GetSecurity() > SEC_PLAYER || plr->GetSession()->GetSecurity() <= gmLevelInWhoList) &&
+ plr->IsVisibleGloballyFor(player))
+ {
+ data << uint64(i->first);
+ data << uint8(i->second.flags); // flags seems to be changed...
+ ++count;
+ }
+ }
+
+ data.put<uint32>(pos,count);
+
+ SendToOne(&data, p);
+ }
+}
+
+void Channel::Announce(uint64 p)
+{
+ uint32 sec = 0;
+ Player *plr = objmgr.GetPlayer(p);
+ if (plr)
+ sec = plr->GetSession()->GetSecurity();
+
+ if (!IsOn(p))
+ {
+ WorldPacket data;
+ MakeNotMember(&data);
+ SendToOne(&data, p);
+ }
+ else if (!players[p].IsModerator() && sec < SEC_GAMEMASTER)
+ {
+ WorldPacket data;
+ MakeNotModerator(&data);
+ SendToOne(&data, p);
+ }
+ else
+ {
+ m_announce = !m_announce;
+
+ WorldPacket data;
+ if (m_announce)
+ MakeAnnouncementsOn(&data, p);
+ else
+ MakeAnnouncementsOff(&data, p);
+ SendToAll(&data);
+ if (m_IsSaved && _UpdateIntInDB("m_announce", m_announce ? 1 : 0))
+ sLog.outDebug("Channel(%s) announce saved", m_name.c_str());
+
+ }
+}
+
+void Channel::Moderate(uint64 p)
+{
+ uint32 sec = 0;
+ Player *plr = objmgr.GetPlayer(p);
+ if (plr)
+ sec = plr->GetSession()->GetSecurity();
+
+ if (!IsOn(p))
+ {
+ WorldPacket data;
+ MakeNotMember(&data);
+ SendToOne(&data, p);
+ }
+ else if (!players[p].IsModerator() && sec < SEC_GAMEMASTER)
+ {
+ WorldPacket data;
+ MakeNotModerator(&data);
+ SendToOne(&data, p);
+ }
+ else
+ {
+ m_moderate = !m_moderate;
+
+ WorldPacket data;
+ if (m_moderate)
+ MakeModerationOn(&data, p);
+ else
+ MakeModerationOff(&data, p);
+ SendToAll(&data);
+ if (m_IsSaved && _UpdateIntInDB("m_announce", m_announce ? 1 : 0))
+ sLog.outDebug("Channel(%s) announce saved", m_name.c_str());
+ }
+}
+
+void Channel::Say(uint64 p, const char *what, uint32 lang)
+{
+ if (!what)
+ return;
+ if (sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL))
+ lang = LANG_UNIVERSAL;
+
+ uint32 sec = 0;
+ Player *plr = objmgr.GetPlayer(p);
+ if (plr)
+ sec = plr->GetSession()->GetSecurity();
+
+ if (!IsOn(p))
+ {
+ WorldPacket data;
+ MakeNotMember(&data);
+ SendToOne(&data, p);
+ }
+ else if (players[p].IsMuted())
+ {
+ WorldPacket data;
+ MakeMuted(&data);
+ SendToOne(&data, p);
+ }
+ else if (m_moderate && !players[p].IsModerator() && sec < SEC_GAMEMASTER)
+ {
+ WorldPacket data;
+ MakeNotModerator(&data);
+ SendToOne(&data, p);
+ }
+ else
+ {
+ uint32 messageLength = strlen(what) + 1;
+
+ WorldPacket data(SMSG_MESSAGECHAT, 1+4+8+4+m_name.size()+1+8+4+messageLength+1);
+ data << (uint8)CHAT_MSG_CHANNEL;
+ data << (uint32)lang;
+ data << p; // 2.1.0
+ data << uint32(0); // 2.1.0
+ data << m_name;
+ data << p;
+ data << messageLength;
+ data << what;
+ data << uint8(plr ? plr->chatTag() : 0);
+
+ SendToAll(&data, !players[p].IsModerator() ? p : false);
+ }
+}
+
+void Channel::Invite(uint64 p, const char *newname)
+{
+ if (!IsOn(p))
+ {
+ WorldPacket data;
+ MakeNotMember(&data);
+ SendToOne(&data, p);
+ return;
+ }
+
+ Player *newp = objmgr.GetPlayer(newname);
+ if (!newp)
+ {
+ WorldPacket data;
+ MakePlayerNotFound(&data, newname);
+ SendToOne(&data, p);
+ return;
+ }
+
+ Player *plr = objmgr.GetPlayer(p);
+ if (!plr)
+ return;
+
+ if (newp->GetTeam() != plr->GetTeam() && !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL))
+ {
+ WorldPacket data;
+ MakeInviteWrongFaction(&data);
+ SendToOne(&data, p);
+ return;
+ }
+
+ if (IsOn(newp->GetGUID()))
+ {
+ WorldPacket data;
+ MakePlayerAlreadyMember(&data, newp->GetGUID());
+ SendToOne(&data, p);
+ return;
+ }
+
+ WorldPacket data;
+ if (!newp->GetSocial()->HasIgnore(GUID_LOPART(p)))
+ {
+ MakeInvite(&data, p);
+ SendToOne(&data, newp->GetGUID());
+ data.clear();
+ }
+ MakePlayerInvited(&data, newp->GetName());
+ SendToOne(&data, p);
+}
+
+void Channel::SetOwner(uint64 guid, bool exclaim)
+{
+ if (m_ownerGUID)
+ {
+ // [] will re-add player after it possible removed
+ PlayerList::iterator p_itr = players.find(m_ownerGUID);
+ if (p_itr != players.end())
+ p_itr->second.SetOwner(false);
+ }
+
+ m_ownerGUID = guid;
+ if (m_ownerGUID)
+ {
+ uint8 oldFlag = GetPlayerFlags(m_ownerGUID);
+ players[m_ownerGUID].SetModerator(true);
+ players[m_ownerGUID].SetOwner(true);
+
+ WorldPacket data;
+ MakeModeChange(&data, m_ownerGUID, oldFlag);
+ SendToAll(&data);
+
+ if (exclaim)
+ {
+ MakeOwnerChanged(&data, m_ownerGUID);
+ SendToAll(&data);
+ }
+ if (m_IsSaved && _UpdateIntInDB("m_moderate", m_moderate ? 1 : 0))
+ sLog.outDebug("Channel(%s) moderate saved", m_name.c_str());
+
+ }
+}
+
+void Channel::SendToAll(WorldPacket *data, uint64 p)
+{
+ for (PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
+ {
+ Player *plr = objmgr.GetPlayer(i->first);
+ if (plr)
+ {
+ if (!p || !plr->GetSocial()->HasIgnore(GUID_LOPART(p)))
+ plr->GetSession()->SendPacket(data);
+ }
+ }
+}
+
+void Channel::SendToAllButOne(WorldPacket *data, uint64 who)
+{
+ for (PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
+ {
+ if (i->first != who)
+ {
+ Player *plr = objmgr.GetPlayer(i->first);
+ if (plr)
+ plr->GetSession()->SendPacket(data);
+ }
+ }
+}
+
+void Channel::SendToOne(WorldPacket *data, uint64 who)
+{
+ Player *plr = objmgr.GetPlayer(who);
+ if (plr)
+ plr->GetSession()->SendPacket(data);
+}
+
+void Channel::Voice(uint64 /*guid1*/, uint64 /*guid2*/)
+{
+
+}
+
+void Channel::DeVoice(uint64 /*guid1*/, uint64 /*guid2*/)
+{
+
+}
+
+// done
+void Channel::MakeNotifyPacket(WorldPacket *data, uint8 notify_type)
+{
+ data->Initialize(SMSG_CHANNEL_NOTIFY, 1+m_name.size()+1);
+ *data << uint8(notify_type);
+ *data << m_name;
+}
+
+// done 0x00
+void Channel::MakeJoined(WorldPacket *data, uint64 guid)
+{
+ MakeNotifyPacket(data, CHAT_JOINED_NOTICE);
+ *data << uint64(guid);
+}
+
+// done 0x01
+void Channel::MakeLeft(WorldPacket *data, uint64 guid)
+{
+ MakeNotifyPacket(data, CHAT_LEFT_NOTICE);
+ *data << uint64(guid);
+}
+
+// done 0x02
+void Channel::MakeYouJoined(WorldPacket *data)
+{
+ MakeNotifyPacket(data, CHAT_YOU_JOINED_NOTICE);
+ *data << uint8(GetFlags());
+ *data << uint32(GetChannelId());
+ *data << uint32(0);
+}
+
+// done 0x03
+void Channel::MakeYouLeft(WorldPacket *data)
+{
+ MakeNotifyPacket(data, CHAT_YOU_LEFT_NOTICE);
+ *data << uint32(GetChannelId());
+ *data << uint8(0); // can be 0x00 and 0x01
+}
+
+// done 0x04
+void Channel::MakeWrongPassword(WorldPacket *data)
+{
+ MakeNotifyPacket(data, CHAT_WRONG_PASSWORD_NOTICE);
+}
+
+// done 0x05
+void Channel::MakeNotMember(WorldPacket *data)
+{
+ MakeNotifyPacket(data, CHAT_NOT_MEMBER_NOTICE);
+}
+
+// done 0x06
+void Channel::MakeNotModerator(WorldPacket *data)
+{
+ MakeNotifyPacket(data, CHAT_NOT_MODERATOR_NOTICE);
+}
+
+// done 0x07
+void Channel::MakePasswordChanged(WorldPacket *data, uint64 guid)
+{
+ MakeNotifyPacket(data, CHAT_PASSWORD_CHANGED_NOTICE);
+ *data << uint64(guid);
+}
+
+// done 0x08
+void Channel::MakeOwnerChanged(WorldPacket *data, uint64 guid)
+{
+ MakeNotifyPacket(data, CHAT_OWNER_CHANGED_NOTICE);
+ *data << uint64(guid);
+}
+
+// done 0x09
+void Channel::MakePlayerNotFound(WorldPacket *data, const std::string& name)
+{
+ MakeNotifyPacket(data, CHAT_PLAYER_NOT_FOUND_NOTICE);
+ *data << name;
+}
+
+// done 0x0A
+void Channel::MakeNotOwner(WorldPacket *data)
+{
+ MakeNotifyPacket(data, CHAT_NOT_OWNER_NOTICE);
+}
+
+// done 0x0B
+void Channel::MakeChannelOwner(WorldPacket *data)
+{
+ std::string name = "";
+
+ if (!objmgr.GetPlayerNameByGUID(m_ownerGUID, name) || name.empty())
+ name = "PLAYER_NOT_FOUND";
+
+ MakeNotifyPacket(data, CHAT_CHANNEL_OWNER_NOTICE);
+ *data << ((IsConstant() || !m_ownerGUID) ? "Nobody" : name);
+}
+
+// done 0x0C
+void Channel::MakeModeChange(WorldPacket *data, uint64 guid, uint8 oldflags)
+{
+ MakeNotifyPacket(data, CHAT_MODE_CHANGE_NOTICE);
+ *data << uint64(guid);
+ *data << uint8(oldflags);
+ *data << uint8(GetPlayerFlags(guid));
+}
+
+// done 0x0D
+void Channel::MakeAnnouncementsOn(WorldPacket *data, uint64 guid)
+{
+ MakeNotifyPacket(data, CHAT_ANNOUNCEMENTS_ON_NOTICE);
+ *data << uint64(guid);
+}
+
+// done 0x0E
+void Channel::MakeAnnouncementsOff(WorldPacket *data, uint64 guid)
+{
+ MakeNotifyPacket(data, CHAT_ANNOUNCEMENTS_OFF_NOTICE);
+ *data << uint64(guid);
+}
+
+// done 0x0F
+void Channel::MakeModerationOn(WorldPacket *data, uint64 guid)
+{
+ MakeNotifyPacket(data, CHAT_MODERATION_ON_NOTICE);
+ *data << uint64(guid);
+}
+
+// done 0x10
+void Channel::MakeModerationOff(WorldPacket *data, uint64 guid)
+{
+ MakeNotifyPacket(data, CHAT_MODERATION_OFF_NOTICE);
+ *data << uint64(guid);
+}
+
+// done 0x11
+void Channel::MakeMuted(WorldPacket *data)
+{
+ MakeNotifyPacket(data, CHAT_MUTED_NOTICE);
+}
+
+// done 0x12
+void Channel::MakePlayerKicked(WorldPacket *data, uint64 bad, uint64 good)
+{
+ MakeNotifyPacket(data, CHAT_PLAYER_KICKED_NOTICE);
+ *data << uint64(bad);
+ *data << uint64(good);
+}
+
+// done 0x13
+void Channel::MakeBanned(WorldPacket *data)
+{
+ MakeNotifyPacket(data, CHAT_BANNED_NOTICE);
+}
+
+// done 0x14
+void Channel::MakePlayerBanned(WorldPacket *data, uint64 bad, uint64 good)
+{
+ MakeNotifyPacket(data, CHAT_PLAYER_BANNED_NOTICE);
+ *data << uint64(bad);
+ *data << uint64(good);
+}
+
+// done 0x15
+void Channel::MakePlayerUnbanned(WorldPacket *data, uint64 bad, uint64 good)
+{
+ MakeNotifyPacket(data, CHAT_PLAYER_UNBANNED_NOTICE);
+ *data << uint64(bad);
+ *data << uint64(good);
+}
+
+// done 0x16
+void Channel::MakePlayerNotBanned(WorldPacket *data, uint64 guid)
+{
+ MakeNotifyPacket(data, CHAT_PLAYER_NOT_BANNED_NOTICE);
+ *data << uint64(guid);
+}
+
+// done 0x17
+void Channel::MakePlayerAlreadyMember(WorldPacket *data, uint64 guid)
+{
+ MakeNotifyPacket(data, CHAT_PLAYER_ALREADY_MEMBER_NOTICE);
+ *data << uint64(guid);
+}
+
+// done 0x18
+void Channel::MakeInvite(WorldPacket *data, uint64 guid)
+{
+ MakeNotifyPacket(data, CHAT_INVITE_NOTICE);
+ *data << uint64(guid);
+}
+
+// done 0x19
+void Channel::MakeInviteWrongFaction(WorldPacket *data)
+{
+ MakeNotifyPacket(data, CHAT_INVITE_WRONG_FACTION_NOTICE);
+}
+
+// done 0x1A
+void Channel::MakeWrongFaction(WorldPacket *data)
+{
+ MakeNotifyPacket(data, CHAT_WRONG_FACTION_NOTICE);
+}
+
+// done 0x1B
+void Channel::MakeInvalidName(WorldPacket *data)
+{
+ MakeNotifyPacket(data, CHAT_INVALID_NAME_NOTICE);
+}
+
+// done 0x1C
+void Channel::MakeNotModerated(WorldPacket *data)
+{
+ MakeNotifyPacket(data, CHAT_NOT_MODERATED_NOTICE);
+}
+
+// done 0x1D
+void Channel::MakePlayerInvited(WorldPacket *data, const std::string& name)
+{
+ MakeNotifyPacket(data, CHAT_PLAYER_INVITED_NOTICE);
+ *data << name;
+}
+
+// done 0x1E
+void Channel::MakePlayerInviteBanned(WorldPacket *data, uint64 guid)
+{
+ MakeNotifyPacket(data, CHAT_PLAYER_INVITE_BANNED_NOTICE);
+ *data << uint64(guid);
+}
+
+// done 0x1F
+void Channel::MakeThrottled(WorldPacket *data)
+{
+ MakeNotifyPacket(data, CHAT_THROTTLED_NOTICE);
+}
+
+// done 0x20
+void Channel::MakeNotInArea(WorldPacket *data)
+{
+ MakeNotifyPacket(data, CHAT_NOT_IN_AREA_NOTICE);
+}
+
+// done 0x21
+void Channel::MakeNotInLfg(WorldPacket *data)
+{
+ MakeNotifyPacket(data, CHAT_NOT_IN_LFG_NOTICE);
+}
+
+// done 0x22
+void Channel::MakeVoiceOn(WorldPacket *data, uint64 guid)
+{
+ MakeNotifyPacket(data, CHAT_VOICE_ON_NOTICE);
+ *data << uint64(guid);
+}
+
+// done 0x23
+void Channel::MakeVoiceOff(WorldPacket *data, uint64 guid)
+{
+ MakeNotifyPacket(data, CHAT_VOICE_OFF_NOTICE);
+ *data << uint64(guid);
+}
+
+void Channel::JoinNotify(uint64 guid)
+{
+ WorldPacket data;
+
+ if (IsConstant())
+ data.Initialize(SMSG_USERLIST_ADD, 8+1+1+4+GetName().size()+1);
+ else
+ data.Initialize(SMSG_USERLIST_UPDATE, 8+1+1+4+GetName().size()+1);
+
+ data << uint64(guid);
+ data << uint8(GetPlayerFlags(guid));
+ data << uint8(GetFlags());
+ data << uint32(GetNumPlayers());
+ data << GetName();
+ SendToAll(&data);
+}
+
+void Channel::LeaveNotify(uint64 guid)
+{
+ WorldPacket data(SMSG_USERLIST_REMOVE, 8+1+4+GetName().size()+1);
+ data << uint64(guid);
+ data << uint8(GetFlags());
+ data << uint32(GetNumPlayers());
+ data << GetName();
+ SendToAll(&data);
+}
+
diff --git a/src/server/game/Chat/Channel.h b/src/server/game/Chat/Channel.h
new file mode 100644
index 00000000000..d0b5923e30e
--- /dev/null
+++ b/src/server/game/Chat/Channel.h
@@ -0,0 +1,292 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _CHANNEL_H
+#define _CHANNEL_H
+
+#include <list>
+#include <map>
+#include <string>
+
+#include "Common.h"
+
+#include "Opcodes.h"
+#include "Player.h"
+#include "WorldPacket.h"
+
+enum ChatNotify
+{
+ CHAT_JOINED_NOTICE = 0x00, //+ "%s joined channel.";
+ CHAT_LEFT_NOTICE = 0x01, //+ "%s left channel.";
+ //CHAT_SUSPENDED_NOTICE = 0x01, // "%s left channel.";
+ CHAT_YOU_JOINED_NOTICE = 0x02, //+ "Joined Channel: [%s]"; -- You joined
+ //CHAT_YOU_CHANGED_NOTICE = 0x02, // "Changed Channel: [%s]";
+ CHAT_YOU_LEFT_NOTICE = 0x03, //+ "Left Channel: [%s]"; -- You left
+ CHAT_WRONG_PASSWORD_NOTICE = 0x04, //+ "Wrong password for %s.";
+ CHAT_NOT_MEMBER_NOTICE = 0x05, //+ "Not on channel %s.";
+ CHAT_NOT_MODERATOR_NOTICE = 0x06, //+ "Not a moderator of %s.";
+ CHAT_PASSWORD_CHANGED_NOTICE = 0x07, //+ "[%s] Password changed by %s.";
+ CHAT_OWNER_CHANGED_NOTICE = 0x08, //+ "[%s] Owner changed to %s.";
+ CHAT_PLAYER_NOT_FOUND_NOTICE = 0x09, //+ "[%s] Player %s was not found.";
+ CHAT_NOT_OWNER_NOTICE = 0x0A, //+ "[%s] You are not the channel owner.";
+ CHAT_CHANNEL_OWNER_NOTICE = 0x0B, //+ "[%s] Channel owner is %s.";
+ CHAT_MODE_CHANGE_NOTICE = 0x0C, //?
+ CHAT_ANNOUNCEMENTS_ON_NOTICE = 0x0D, //+ "[%s] Channel announcements enabled by %s.";
+ CHAT_ANNOUNCEMENTS_OFF_NOTICE = 0x0E, //+ "[%s] Channel announcements disabled by %s.";
+ CHAT_MODERATION_ON_NOTICE = 0x0F, //+ "[%s] Channel moderation enabled by %s.";
+ CHAT_MODERATION_OFF_NOTICE = 0x10, //+ "[%s] Channel moderation disabled by %s.";
+ CHAT_MUTED_NOTICE = 0x11, //+ "[%s] You do not have permission to speak.";
+ CHAT_PLAYER_KICKED_NOTICE = 0x12, //? "[%s] Player %s kicked by %s.";
+ CHAT_BANNED_NOTICE = 0x13, //+ "[%s] You are banned from that channel.";
+ CHAT_PLAYER_BANNED_NOTICE = 0x14, //? "[%s] Player %s banned by %s.";
+ CHAT_PLAYER_UNBANNED_NOTICE = 0x15, //? "[%s] Player %s unbanned by %s.";
+ CHAT_PLAYER_NOT_BANNED_NOTICE = 0x16, //+ "[%s] Player %s is not banned.";
+ CHAT_PLAYER_ALREADY_MEMBER_NOTICE = 0x17, //+ "[%s] Player %s is already on the channel.";
+ CHAT_INVITE_NOTICE = 0x18, //+ "%2$s has invited you to join the channel '%1$s'.";
+ CHAT_INVITE_WRONG_FACTION_NOTICE = 0x19, //+ "Target is in the wrong alliance for %s.";
+ CHAT_WRONG_FACTION_NOTICE = 0x1A, //+ "Wrong alliance for %s.";
+ CHAT_INVALID_NAME_NOTICE = 0x1B, //+ "Invalid channel name";
+ CHAT_NOT_MODERATED_NOTICE = 0x1C, //+ "%s is not moderated";
+ CHAT_PLAYER_INVITED_NOTICE = 0x1D, //+ "[%s] You invited %s to join the channel";
+ CHAT_PLAYER_INVITE_BANNED_NOTICE = 0x1E, //+ "[%s] %s has been banned.";
+ CHAT_THROTTLED_NOTICE = 0x1F, //+ "[%s] The number of messages that can be sent to this channel is limited, please wait to send another message.";
+ CHAT_NOT_IN_AREA_NOTICE = 0x20, //+ "[%s] You are not in the correct area for this channel."; -- The user is trying to send a chat to a zone specific channel, and they're not physically in that zone.
+ CHAT_NOT_IN_LFG_NOTICE = 0x21, //+ "[%s] You must be queued in looking for group before joining this channel."; -- The user must be in the looking for group system to join LFG chat channels.
+ CHAT_VOICE_ON_NOTICE = 0x22, //+ "[%s] Channel voice enabled by %s.";
+ CHAT_VOICE_OFF_NOTICE = 0x23, //+ "[%s] Channel voice disabled by %s.";
+};
+
+enum ChannelFlags
+{
+ CHANNEL_FLAG_NONE = 0x00,
+ CHANNEL_FLAG_CUSTOM = 0x01,
+ // 0x02
+ CHANNEL_FLAG_TRADE = 0x04,
+ CHANNEL_FLAG_NOT_LFG = 0x08,
+ CHANNEL_FLAG_GENERAL = 0x10,
+ CHANNEL_FLAG_CITY = 0x20,
+ CHANNEL_FLAG_LFG = 0x40,
+ CHANNEL_FLAG_VOICE = 0x80
+ // General 0x18 = 0x10 | 0x08
+ // Trade 0x3C = 0x20 | 0x10 | 0x08 | 0x04
+ // LocalDefence 0x18 = 0x10 | 0x08
+ // GuildRecruitment 0x38 = 0x20 | 0x10 | 0x08
+ // LookingForGroup 0x50 = 0x40 | 0x10
+};
+
+enum ChannelDBCFlags
+{
+ CHANNEL_DBC_FLAG_NONE = 0x00000,
+ CHANNEL_DBC_FLAG_INITIAL = 0x00001, // General, Trade, LocalDefense, LFG
+ CHANNEL_DBC_FLAG_ZONE_DEP = 0x00002, // General, Trade, LocalDefense, GuildRecruitment
+ CHANNEL_DBC_FLAG_GLOBAL = 0x00004, // WorldDefense
+ CHANNEL_DBC_FLAG_TRADE = 0x00008, // Trade
+ CHANNEL_DBC_FLAG_CITY_ONLY = 0x00010, // Trade, GuildRecruitment
+ CHANNEL_DBC_FLAG_CITY_ONLY2 = 0x00020, // Trade, GuildRecruitment
+ CHANNEL_DBC_FLAG_DEFENSE = 0x10000, // LocalDefense, WorldDefense
+ CHANNEL_DBC_FLAG_GUILD_REQ = 0x20000, // GuildRecruitment
+ CHANNEL_DBC_FLAG_LFG = 0x40000 // LookingForGroup
+};
+
+enum ChannelMemberFlags
+{
+ MEMBER_FLAG_NONE = 0x00,
+ MEMBER_FLAG_OWNER = 0x01,
+ MEMBER_FLAG_MODERATOR = 0x02,
+ MEMBER_FLAG_VOICED = 0x04,
+ MEMBER_FLAG_MUTED = 0x08,
+ MEMBER_FLAG_CUSTOM = 0x10,
+ MEMBER_FLAG_MIC_MUTED = 0x20,
+ // 0x40
+ // 0x80
+};
+
+class Channel
+{
+ struct PlayerInfo
+ {
+ uint64 player;
+ uint8 flags;
+
+ bool HasFlag(uint8 flag) { return flags & flag; }
+ void SetFlag(uint8 flag) { if (!HasFlag(flag)) flags |= flag; }
+ bool IsOwner() { return flags & MEMBER_FLAG_OWNER; }
+ void SetOwner(bool state)
+ {
+ if (state) flags |= MEMBER_FLAG_OWNER;
+ else flags &= ~MEMBER_FLAG_OWNER;
+ }
+ bool IsModerator() { return flags & MEMBER_FLAG_MODERATOR; }
+ void SetModerator(bool state)
+ {
+ if (state) flags |= MEMBER_FLAG_MODERATOR;
+ else flags &= ~MEMBER_FLAG_MODERATOR;
+ }
+ bool IsMuted() { return flags & MEMBER_FLAG_MUTED; }
+ void SetMuted(bool state)
+ {
+ if (state) flags |= MEMBER_FLAG_MUTED;
+ else flags &= ~MEMBER_FLAG_MUTED;
+ }
+ };
+
+ typedef std::map<uint64, PlayerInfo> PlayerList;
+ PlayerList players;
+ typedef std::set<uint64> BannedList;
+ BannedList banned;
+ bool m_announce;
+ bool m_moderate;
+ bool m_public;
+ std::string m_name;
+ std::string m_password;
+ uint8 m_flags;
+ uint32 m_channelId;
+ uint64 m_ownerGUID;
+ bool m_IsSaved;
+
+ private:
+ // initial packet data (notify type and channel name)
+ void MakeNotifyPacket(WorldPacket *data, uint8 notify_type);
+ // type specific packet data
+ void MakeJoined(WorldPacket *data, uint64 guid); //+ 0x00
+ void MakeLeft(WorldPacket *data, uint64 guid); //+ 0x01
+ void MakeYouJoined(WorldPacket *data); //+ 0x02
+ void MakeYouLeft(WorldPacket *data); //+ 0x03
+ void MakeWrongPassword(WorldPacket *data); //? 0x04
+ void MakeNotMember(WorldPacket *data); //? 0x05
+ void MakeNotModerator(WorldPacket *data); //? 0x06
+ void MakePasswordChanged(WorldPacket *data, uint64 guid); //+ 0x07
+ void MakeOwnerChanged(WorldPacket *data, uint64 guid); //? 0x08
+ void MakePlayerNotFound(WorldPacket *data, const std::string& name); //+ 0x09
+ void MakeNotOwner(WorldPacket *data); //? 0x0A
+ void MakeChannelOwner(WorldPacket *data); //? 0x0B
+ void MakeModeChange(WorldPacket *data, uint64 guid, uint8 oldflags); //+ 0x0C
+ void MakeAnnouncementsOn(WorldPacket *data, uint64 guid); //+ 0x0D
+ void MakeAnnouncementsOff(WorldPacket *data, uint64 guid); //+ 0x0E
+ void MakeModerationOn(WorldPacket *data, uint64 guid); //+ 0x0F
+ void MakeModerationOff(WorldPacket *data, uint64 guid); //+ 0x10
+ void MakeMuted(WorldPacket *data); //? 0x11
+ void MakePlayerKicked(WorldPacket *data, uint64 bad, uint64 good); //? 0x12
+ void MakeBanned(WorldPacket *data); //? 0x13
+ void MakePlayerBanned(WorldPacket *data, uint64 bad, uint64 good); //? 0x14
+ void MakePlayerUnbanned(WorldPacket *data, uint64 bad, uint64 good); //? 0x15
+ void MakePlayerNotBanned(WorldPacket *data, uint64 guid); //? 0x16
+ void MakePlayerAlreadyMember(WorldPacket *data, uint64 guid); //+ 0x17
+ void MakeInvite(WorldPacket *data, uint64 guid); //? 0x18
+ void MakeInviteWrongFaction(WorldPacket *data); //? 0x19
+ void MakeWrongFaction(WorldPacket *data); //? 0x1A
+ void MakeInvalidName(WorldPacket *data); //? 0x1B
+ void MakeNotModerated(WorldPacket *data); //? 0x1C
+ void MakePlayerInvited(WorldPacket *data, const std::string& name); //+ 0x1D
+ void MakePlayerInviteBanned(WorldPacket *data, uint64 guid); //? 0x1E
+ void MakeThrottled(WorldPacket *data); //? 0x1F
+ void MakeNotInArea(WorldPacket *data); //? 0x20
+ void MakeNotInLfg(WorldPacket *data); //? 0x21
+ void MakeVoiceOn(WorldPacket *data, uint64 guid); //+ 0x22
+ void MakeVoiceOff(WorldPacket *data, uint64 guid); //+ 0x23
+
+ void SendToAll(WorldPacket *data, uint64 p = 0);
+ void SendToAllButOne(WorldPacket *data, uint64 who);
+ void SendToOne(WorldPacket *data, uint64 who);
+
+ bool IsOn(uint64 who) const { return players.find(who) != players.end(); }
+ bool IsBanned(uint64 guid) const { return banned.find(guid) != banned.end(); }
+
+ bool _UpdateStringInDB(const std::string& colName, const std::string& colValue) const;
+ bool _UpdateIntInDB(const std::string& colName, int colValue) const;
+ void _UpdateBanListInDB() const;
+
+ uint8 GetPlayerFlags(uint64 p) const
+ {
+ PlayerList::const_iterator p_itr = players.find(p);
+ if (p_itr == players.end())
+ return 0;
+
+ return p_itr->second.flags;
+ }
+
+ void SetModerator(uint64 p, bool set)
+ {
+ if (players[p].IsModerator() != set)
+ {
+ uint8 oldFlag = GetPlayerFlags(p);
+ players[p].SetModerator(set);
+
+ WorldPacket data;
+ MakeModeChange(&data, p, oldFlag);
+ SendToAll(&data);
+ }
+ }
+
+ void SetMute(uint64 p, bool set)
+ {
+ if (players[p].IsMuted() != set)
+ {
+ uint8 oldFlag = GetPlayerFlags(p);
+ players[p].SetMuted(set);
+
+ WorldPacket data;
+ MakeModeChange(&data, p, oldFlag);
+ SendToAll(&data);
+ }
+ }
+
+ public:
+ uint32 m_Team;
+ Channel(const std::string& name, uint32 channel_id, uint32 Team = 0);
+ std::string GetName() const { return m_name; }
+ uint32 GetChannelId() const { return m_channelId; }
+ bool IsConstant() const { return m_channelId != 0; }
+ bool IsAnnounce() const { return m_announce; }
+ bool IsLFG() const { return GetFlags() & CHANNEL_FLAG_LFG; }
+ std::string GetPassword() const { return m_password; }
+ void SetPassword(const std::string& npassword) { m_password = npassword; }
+ void SetAnnounce(bool nannounce) { m_announce = nannounce; }
+ uint32 GetNumPlayers() const { return players.size(); }
+ uint8 GetFlags() const { return m_flags; }
+ bool HasFlag(uint8 flag) { return m_flags & flag; }
+
+ void Join(uint64 p, const char *pass);
+ void Leave(uint64 p, bool send = true);
+ void KickOrBan(uint64 good, const char *badname, bool ban);
+ void Kick(uint64 good, const char *badname) { KickOrBan(good, badname, false); }
+ void Ban(uint64 good, const char *badname) { KickOrBan(good, badname, true); }
+ void UnBan(uint64 good, const char *badname);
+ void Password(uint64 p, const char *pass);
+ void SetMode(uint64 p, const char *p2n, bool mod, bool set);
+ void SetOwner(uint64 p, bool exclaim = true);
+ void SetOwner(uint64 p, const char *newname);
+ void SendWhoOwner(uint64 p);
+ void SetModerator(uint64 p, const char *newname) { SetMode(p, newname, true, true); }
+ void UnsetModerator(uint64 p, const char *newname) { SetMode(p, newname, true, false); }
+ void SetMute(uint64 p, const char *newname) { SetMode(p, newname, false, true); }
+ void UnsetMute(uint64 p, const char *newname) { SetMode(p, newname, false, false); }
+ void List(Player* p);
+ void Announce(uint64 p);
+ void Moderate(uint64 p);
+ void Say(uint64 p, const char *what, uint32 lang);
+ void Invite(uint64 p, const char *newp);
+ void Voice(uint64 guid1, uint64 guid2);
+ void DeVoice(uint64 guid1, uint64 guid2);
+ void JoinNotify(uint64 guid); // invisible notify
+ void LeaveNotify(uint64 guid); // invisible notify
+};
+#endif
+
diff --git a/src/server/game/Chat/ChannelHandler.cpp b/src/server/game/Chat/ChannelHandler.cpp
new file mode 100644
index 00000000000..0f615579cb6
--- /dev/null
+++ b/src/server/game/Chat/ChannelHandler.cpp
@@ -0,0 +1,323 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "Policies/SingletonImp.h"
+
+#include "ObjectMgr.h" // for normalizePlayerName
+#include "ChannelMgr.h"
+
+void WorldSession::HandleJoinChannel(WorldPacket& recvPacket)
+{
+ sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
+
+ uint32 channel_id;
+ uint8 unknown1, unknown2;
+ std::string channelname, pass;
+
+ recvPacket >> channel_id >> unknown1 >> unknown2;
+ recvPacket >> channelname;
+
+ if (channelname.empty())
+ return;
+
+ recvPacket >> pass;
+ if (ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
+ {
+ cMgr->team = _player->GetTeam();
+ if (Channel *chn = cMgr->GetJoinChannel(channelname, channel_id))
+ chn->Join(_player->GetGUID(), pass.c_str());
+ }
+}
+
+void WorldSession::HandleLeaveChannel(WorldPacket& recvPacket)
+{
+ sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
+ //recvPacket.hexlike();
+
+ uint32 unk;
+ std::string channelname;
+ recvPacket >> unk; // channel id?
+ recvPacket >> channelname;
+
+ if (channelname.empty())
+ return;
+
+ if (ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
+ {
+ if (Channel *chn = cMgr->GetChannel(channelname, _player))
+ chn->Leave(_player->GetGUID(), true);
+ cMgr->LeftChannel(channelname);
+ }
+}
+
+void WorldSession::HandleChannelList(WorldPacket& recvPacket)
+{
+ sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
+ //recvPacket.hexlike();
+ std::string channelname;
+ recvPacket >> channelname;
+
+ if (ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
+ if (Channel *chn = cMgr->GetChannel(channelname, _player))
+ chn->List(_player);
+}
+
+void WorldSession::HandleChannelPassword(WorldPacket& recvPacket)
+{
+ sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
+ //recvPacket.hexlike();
+ std::string channelname, pass;
+ recvPacket >> channelname;
+
+ recvPacket >> pass;
+
+ if (ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
+ if (Channel *chn = cMgr->GetChannel(channelname, _player))
+ chn->Password(_player->GetGUID(), pass.c_str());
+}
+
+void WorldSession::HandleChannelSetOwner(WorldPacket& recvPacket)
+{
+ sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
+ //recvPacket.hexlike();
+ std::string channelname, newp;
+ recvPacket >> channelname;
+
+ recvPacket >> newp;
+
+ if (!normalizePlayerName(newp))
+ return;
+
+ if (ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
+ if (Channel *chn = cMgr->GetChannel(channelname, _player))
+ chn->SetOwner(_player->GetGUID(), newp.c_str());
+}
+
+void WorldSession::HandleChannelOwner(WorldPacket& recvPacket)
+{
+ sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
+ //recvPacket.hexlike();
+ std::string channelname;
+ recvPacket >> channelname;
+ if (ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
+ if (Channel *chn = cMgr->GetChannel(channelname, _player))
+ chn->SendWhoOwner(_player->GetGUID());
+}
+
+void WorldSession::HandleChannelModerator(WorldPacket& recvPacket)
+{
+ sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
+ //recvPacket.hexlike();
+ std::string channelname, otp;
+ recvPacket >> channelname;
+
+ recvPacket >> otp;
+
+ if (!normalizePlayerName(otp))
+ return;
+
+ if (ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
+ if (Channel *chn = cMgr->GetChannel(channelname, _player))
+ chn->SetModerator(_player->GetGUID(), otp.c_str());
+}
+
+void WorldSession::HandleChannelUnmoderator(WorldPacket& recvPacket)
+{
+ sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
+ //recvPacket.hexlike();
+ std::string channelname, otp;
+ recvPacket >> channelname;
+
+ recvPacket >> otp;
+
+ if (!normalizePlayerName(otp))
+ return;
+
+ if (ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
+ if (Channel *chn = cMgr->GetChannel(channelname, _player))
+ chn->UnsetModerator(_player->GetGUID(), otp.c_str());
+}
+
+void WorldSession::HandleChannelMute(WorldPacket& recvPacket)
+{
+ sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
+ //recvPacket.hexlike();
+ std::string channelname, otp;
+ recvPacket >> channelname;
+
+ recvPacket >> otp;
+
+ if (!normalizePlayerName(otp))
+ return;
+
+ if (ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
+ if (Channel *chn = cMgr->GetChannel(channelname, _player))
+ chn->SetMute(_player->GetGUID(), otp.c_str());
+}
+
+void WorldSession::HandleChannelUnmute(WorldPacket& recvPacket)
+{
+ sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
+ //recvPacket.hexlike();
+
+ std::string channelname, otp;
+ recvPacket >> channelname;
+
+ recvPacket >> otp;
+
+ if (!normalizePlayerName(otp))
+ return;
+
+ if (ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
+ if (Channel *chn = cMgr->GetChannel(channelname, _player))
+ chn->UnsetMute(_player->GetGUID(), otp.c_str());
+}
+
+void WorldSession::HandleChannelInvite(WorldPacket& recvPacket)
+{
+ sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
+ //recvPacket.hexlike();
+ std::string channelname, otp;
+ recvPacket >> channelname;
+
+ recvPacket >> otp;
+
+ if (!normalizePlayerName(otp))
+ return;
+
+ if (ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
+ if (Channel *chn = cMgr->GetChannel(channelname, _player))
+ chn->Invite(_player->GetGUID(), otp.c_str());
+}
+
+void WorldSession::HandleChannelKick(WorldPacket& recvPacket)
+{
+ sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
+ //recvPacket.hexlike();
+ std::string channelname, otp;
+ recvPacket >> channelname;
+
+ recvPacket >> otp;
+ if (!normalizePlayerName(otp))
+ return;
+
+ if (ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
+ if (Channel *chn = cMgr->GetChannel(channelname, _player))
+ chn->Kick(_player->GetGUID(), otp.c_str());
+}
+
+void WorldSession::HandleChannelBan(WorldPacket& recvPacket)
+{
+ sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
+ //recvPacket.hexlike();
+ std::string channelname, otp;
+ recvPacket >> channelname;
+
+ recvPacket >> otp;
+
+ if (!normalizePlayerName(otp))
+ return;
+
+ if (ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
+ if (Channel *chn = cMgr->GetChannel(channelname, _player))
+ chn->Ban(_player->GetGUID(), otp.c_str());
+}
+
+void WorldSession::HandleChannelUnban(WorldPacket& recvPacket)
+{
+ sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
+ //recvPacket.hexlike();
+
+ std::string channelname, otp;
+ recvPacket >> channelname;
+
+ recvPacket >> otp;
+
+ if (!normalizePlayerName(otp))
+ return;
+
+ if (ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
+ if (Channel *chn = cMgr->GetChannel(channelname, _player))
+ chn->UnBan(_player->GetGUID(), otp.c_str());
+}
+
+void WorldSession::HandleChannelAnnouncements(WorldPacket& recvPacket)
+{
+ sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
+ //recvPacket.hexlike();
+ std::string channelname;
+ recvPacket >> channelname;
+ if (ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
+ if (Channel *chn = cMgr->GetChannel(channelname, _player))
+ chn->Announce(_player->GetGUID());
+}
+
+void WorldSession::HandleChannelModerate(WorldPacket& recvPacket)
+{
+ sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
+ //recvPacket.hexlike();
+ std::string channelname;
+ recvPacket >> channelname;
+ if (ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
+ if (Channel *chn = cMgr->GetChannel(channelname, _player))
+ chn->Moderate(_player->GetGUID());
+}
+
+void WorldSession::HandleChannelDisplayListQuery(WorldPacket &recvPacket)
+{
+ sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
+ //recvPacket.hexlike();
+ std::string channelname;
+ recvPacket >> channelname;
+ if (ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
+ if (Channel *chn = cMgr->GetChannel(channelname, _player))
+ chn->List(_player);
+}
+
+void WorldSession::HandleGetChannelMemberCount(WorldPacket &recvPacket)
+{
+ sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
+ //recvPacket.hexlike();
+ std::string channelname;
+ recvPacket >> channelname;
+ if (ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
+ {
+ if (Channel *chn = cMgr->GetChannel(channelname, _player))
+ {
+ WorldPacket data(SMSG_CHANNEL_MEMBER_COUNT, chn->GetName().size()+1+1+4);
+ data << chn->GetName();
+ data << uint8(chn->GetFlags());
+ data << uint32(chn->GetNumPlayers());
+ SendPacket(&data);
+ }
+ }
+}
+
+void WorldSession::HandleSetChannelWatch(WorldPacket &recvPacket)
+{
+ sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
+ //recvPacket.hexlike();
+ std::string channelname;
+ recvPacket >> channelname;
+ /*if (ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
+ if (Channel *chn = cMgr->GetChannel(channelname, _player))
+ chn->JoinNotify(_player->GetGUID());*/
+}
+
diff --git a/src/server/game/Chat/ChannelMgr.cpp b/src/server/game/Chat/ChannelMgr.cpp
new file mode 100644
index 00000000000..f31d3ffde50
--- /dev/null
+++ b/src/server/game/Chat/ChannelMgr.cpp
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ChannelMgr.h"
+#include "Policies/SingletonImp.h"
+#include "World.h"
+
+INSTANTIATE_SINGLETON_1(AllianceChannelMgr);
+INSTANTIATE_SINGLETON_1(HordeChannelMgr);
+
+ChannelMgr* channelMgr(uint32 team)
+{
+ if (sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL))
+ return &Trinity::Singleton<AllianceChannelMgr>::Instance(); // cross-faction
+
+ if (team == ALLIANCE)
+ return &Trinity::Singleton<AllianceChannelMgr>::Instance();
+ if (team == HORDE)
+ return &Trinity::Singleton<HordeChannelMgr>::Instance();
+
+ return NULL;
+}
+
+ChannelMgr::~ChannelMgr()
+{
+ for (ChannelMap::iterator itr = channels.begin(); itr != channels.end(); ++itr)
+ delete itr->second;
+
+ channels.clear();
+}
+
+Channel *ChannelMgr::GetJoinChannel(std::string name, uint32 channel_id)
+{
+ std::wstring wname;
+ Utf8toWStr(name,wname);
+ wstrToLower(wname);
+
+ if (channels.find(wname) == channels.end())
+ {
+ Channel *nchan = new Channel(name,channel_id, team);
+ channels[wname] = nchan;
+ return nchan;
+ }
+
+ return channels[wname];
+}
+
+Channel *ChannelMgr::GetChannel(std::string name, Player *p, bool pkt)
+{
+ std::wstring wname;
+ Utf8toWStr(name,wname);
+ wstrToLower(wname);
+
+ ChannelMap::const_iterator i = channels.find(wname);
+
+ if (i == channels.end())
+ {
+ if (pkt)
+ {
+ WorldPacket data;
+ MakeNotOnPacket(&data,name);
+ p->GetSession()->SendPacket(&data);
+ }
+
+ return NULL;
+ }
+ else
+ return i->second;
+}
+
+void ChannelMgr::LeftChannel(std::string name)
+{
+ std::wstring wname;
+ Utf8toWStr(name,wname);
+ wstrToLower(wname);
+
+ ChannelMap::const_iterator i = channels.find(wname);
+
+ if (i == channels.end())
+ return;
+
+ Channel* channel = i->second;
+
+ if (channel->GetNumPlayers() == 0 && !channel->IsConstant())
+ {
+ channels.erase(wname);
+ delete channel;
+ }
+}
+
+void ChannelMgr::MakeNotOnPacket(WorldPacket *data, std::string name)
+{
+ data->Initialize(SMSG_CHANNEL_NOTIFY, (1+10)); // we guess size
+ (*data) << (uint8)0x05 << name;
+}
diff --git a/src/server/game/Chat/ChannelMgr.h b/src/server/game/Chat/ChannelMgr.h
new file mode 100644
index 00000000000..6f3b7c415ae
--- /dev/null
+++ b/src/server/game/Chat/ChannelMgr.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __TRINITY_CHANNELMGR_H
+#define __TRINITY_CHANNELMGR_H
+
+#include "Common.h"
+#include "Channel.h"
+#include "Policies/Singleton.h"
+
+#include <map>
+#include <string>
+
+#include "Policies/Singleton.h"
+
+#include "Channel.h"
+#include "World.h"
+
+class ChannelMgr
+{
+ public:
+ uint32 team;
+ typedef std::map<std::wstring,Channel*> ChannelMap;
+ ChannelMgr() {team = 0;}
+ ~ChannelMgr();
+
+ Channel *GetJoinChannel(std::string name, uint32 channel_id);
+ Channel *GetChannel(std::string name, Player *p, bool pkt = true);
+ void LeftChannel(std::string name);
+ private:
+ ChannelMap channels;
+ void MakeNotOnPacket(WorldPacket *data, std::string name);
+};
+
+class AllianceChannelMgr : public ChannelMgr {};
+class HordeChannelMgr : public ChannelMgr {};
+
+ChannelMgr* channelMgr(uint32 team);
+
+#endif
+
diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp
new file mode 100644
index 00000000000..6e1adffa625
--- /dev/null
+++ b/src/server/game/Chat/Chat.cpp
@@ -0,0 +1,2458 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "Common.h"
+#include "ObjectMgr.h"
+#include "World.h"
+#include "WorldPacket.h"
+#include "WorldSession.h"
+#include "Database/DatabaseEnv.h"
+
+#include "AccountMgr.h"
+#include "CellImpl.h"
+#include "Chat.h"
+#include "GridNotifiersImpl.h"
+#include "Language.h"
+#include "Log.h"
+#include "Opcodes.h"
+#include "Player.h"
+#include "UpdateMask.h"
+#include "SpellMgr.h"
+
+// Supported shift-links (client generated and server side)
+// |color|Hachievement:achievement_id:player_guid:0:0:0:0:0:0:0:0|h[name]|h|r
+// - client, item icon shift click, not used in server currently
+// |color|Harea:area_id|h[name]|h|r
+// |color|Hcreature:creature_guid|h[name]|h|r
+// |color|Hcreature_entry:creature_id|h[name]|h|r
+// |color|Henchant:recipe_spell_id|h[prof_name: recipe_name]|h|r - client, at shift click in recipes list dialog
+// |color|Hgameevent:id|h[name]|h|r
+// |color|Hgameobject:go_guid|h[name]|h|r
+// |color|Hgameobject_entry:go_id|h[name]|h|r
+// |color|Hglyph:glyph_slot_id:glyph_prop_id|h[%s]|h|r - client, at shift click in glyphs dialog, GlyphSlot.dbc, GlyphProperties.dbc
+// |color|Hitem:item_id:perm_ench_id:gem1:gem2:gem3:0:0:0:0:reporter_level|h[name]|h|r
+// - client, item icon shift click
+// |color|Hitemset:itemset_id|h[name]|h|r
+// |color|Hplayer:name|h[name]|h|r - client, in some messages, at click copy only name instead link
+// |color|Hquest:quest_id:quest_level|h[name]|h|r - client, quest list name shift-click
+// |color|Hskill:skill_id|h[name]|h|r
+// |color|Hspell:spell_id|h[name]|h|r - client, spellbook spell icon shift-click
+// |color|Htalent:talent_id,rank|h[name]|h|r - client, talent icon shift-click
+// |color|Htaxinode:id|h[name]|h|r
+// |color|Htele:id|h[name]|h|r
+// |color|Htitle:id|h[name]|h|r
+// |color|Htrade:spell_id,cur_value,max_value,unk3int,unk3str|h[name]|h|r - client, spellbook profession icon shift-click
+
+bool ChatHandler::load_command_table = true;
+
+ChatCommand * ChatHandler::getCommandTable()
+{
+ static ChatCommand accountSetCommandTable[] =
+ {
+ { "addon", SEC_ADMINISTRATOR, true, &ChatHandler::HandleAccountSetAddonCommand, "", NULL },
+ { "gmlevel", SEC_CONSOLE, true, &ChatHandler::HandleAccountSetGmLevelCommand, "", NULL },
+ { "password", SEC_CONSOLE, true, &ChatHandler::HandleAccountSetPasswordCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand accountCommandTable[] =
+ {
+ { "addon", SEC_MODERATOR, false, &ChatHandler::HandleAccountAddonCommand, "", NULL },
+ { "create", SEC_CONSOLE, true, &ChatHandler::HandleAccountCreateCommand, "", NULL },
+ { "delete", SEC_CONSOLE, true, &ChatHandler::HandleAccountDeleteCommand, "", NULL },
+ { "onlinelist", SEC_CONSOLE, true, &ChatHandler::HandleAccountOnlineListCommand, "", NULL },
+ { "lock", SEC_PLAYER, false, &ChatHandler::HandleAccountLockCommand, "", NULL },
+ { "set", SEC_ADMINISTRATOR, true, NULL, "", accountSetCommandTable },
+ { "password", SEC_PLAYER, false, &ChatHandler::HandleAccountPasswordCommand, "", NULL },
+ { "", SEC_PLAYER, false, &ChatHandler::HandleAccountCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand banCommandTable[] =
+ {
+ { "account", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanAccountCommand, "", NULL },
+ { "character", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanCharacterCommand, "", NULL },
+ { "ip", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanIPCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand baninfoCommandTable[] =
+ {
+ { "account", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanInfoAccountCommand, "", NULL },
+ { "character", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanInfoCharacterCommand, "", NULL },
+ { "ip", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanInfoIPCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand banlistCommandTable[] =
+ {
+ { "account", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanListAccountCommand, "", NULL },
+ { "character", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanListCharacterCommand, "", NULL },
+ { "ip", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanListIPCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand castCommandTable[] =
+ {
+ { "back", SEC_ADMINISTRATOR, false, &ChatHandler::HandleCastBackCommand, "", NULL },
+ { "dist", SEC_ADMINISTRATOR, false, &ChatHandler::HandleCastDistCommand, "", NULL },
+ { "self", SEC_ADMINISTRATOR, false, &ChatHandler::HandleCastSelfCommand, "", NULL },
+ { "target", SEC_ADMINISTRATOR, false, &ChatHandler::HandleCastTargetCommand, "", NULL },
+ { "", SEC_ADMINISTRATOR, false, &ChatHandler::HandleCastCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand characterCommandTable[] =
+ {
+ { "customize", SEC_GAMEMASTER, true, &ChatHandler::HandleCharacterCustomizeCommand, "", NULL },
+ { "delete", SEC_CONSOLE, true, &ChatHandler::HandleCharacterDeleteCommand, "", NULL },
+ { "level", SEC_ADMINISTRATOR, true, &ChatHandler::HandleCharacterLevelCommand, "", NULL },
+ { "rename", SEC_GAMEMASTER, true, &ChatHandler::HandleCharacterRenameCommand, "", NULL },
+ { "reputation", SEC_GAMEMASTER, true, &ChatHandler::HandleCharacterReputationCommand, "", NULL },
+ { "titles", SEC_GAMEMASTER, true, &ChatHandler::HandleCharacterTitlesCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand channelSetCommandTable[] =
+ {
+ { "public", SEC_ADMINISTRATOR, true, &ChatHandler::HandleChannelSetPublic, "", NULL },
+ };
+
+ static ChatCommand channelCommandTable[] =
+ {
+ { "set", SEC_ADMINISTRATOR, true, NULL, "", channelSetCommandTable },
+ };
+
+ static ChatCommand debugPlayCommandTable[] =
+ {
+ { "cinematic", SEC_MODERATOR, false, &ChatHandler::HandleDebugPlayCinematicCommand, "", NULL },
+ { "movie", SEC_MODERATOR, false, &ChatHandler::HandleDebugPlayMovieCommand, "", NULL },
+ { "sound", SEC_MODERATOR, false, &ChatHandler::HandleDebugPlaySoundCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand debugSendCommandTable[] =
+ {
+ { "buyerror", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSendBuyErrorCommand, "", NULL },
+ { "channelnotify", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSendChannelNotifyCommand, "", NULL },
+ { "chatmmessage", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSendChatMsgCommand, "", NULL },
+ { "equiperror", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSendEquipErrorCommand, "", NULL },
+ { "largepacket", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSendLargePacketCommand, "", NULL },
+ { "opcode", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSendOpcodeCommand, "", NULL },
+ { "poi", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSendPoiCommand, "", NULL },
+ { "qpartymsg", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSendQuestPartyMsgCommand, "", NULL },
+ { "qinvalidmsg", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSendQuestInvalidMsgCommand, "", NULL },
+ { "sellerror", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSendSellErrorCommand, "", NULL },
+ { "setphaseshift", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSendSetPhaseShiftCommand, "", NULL },
+ { "spellfail", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSendSpellFailCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand debugCommandTable[] =
+ {
+ { "setbit", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSet32Bit, "", NULL },
+ { "threat", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugThreatList, "", NULL },
+ { "hostil", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugHostileRefList, "", NULL },
+ { "anim", SEC_GAMEMASTER, false, &ChatHandler::HandleDebugAnimCommand, "", NULL },
+ { "arena", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugArenaCommand, "", NULL },
+ { "bg", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugBattlegroundCommand, "", NULL },
+ { "getitemstate", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugGetItemStateCommand, "", NULL },
+ { "lootrecipient", SEC_GAMEMASTER, false, &ChatHandler::HandleDebugGetLootRecipientCommand, "", NULL },
+ { "getvalue", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugGetValueCommand, "", NULL },
+ { "getitemvalue", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugGetItemValueCommand, "", NULL },
+ { "Mod32Value", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugMod32ValueCommand, "", NULL },
+ { "play", SEC_MODERATOR, false, NULL, "", debugPlayCommandTable },
+ { "send", SEC_ADMINISTRATOR, false, NULL, "", debugSendCommandTable },
+ { "setaurastate", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSetAuraStateCommand, "", NULL },
+ { "setitemvalue", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSetItemValueCommand, "", NULL },
+ { "setvalue", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSetValueCommand, "", NULL },
+ { "spawnvehicle", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSpawnVehicle, "", NULL },
+ { "setvid", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSetVehicleId, "", NULL },
+ { "entervehicle", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugEnterVehicle, "", NULL },
+ { "uws", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugUpdateWorldStateCommand, "", NULL },
+ { "update", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugUpdateCommand, "", NULL },
+ { "itemexpire", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugItemExpireCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand eventCommandTable[] =
+ {
+ { "activelist", SEC_GAMEMASTER, true, &ChatHandler::HandleEventActiveListCommand, "", NULL },
+ { "start", SEC_GAMEMASTER, true, &ChatHandler::HandleEventStartCommand, "", NULL },
+ { "stop", SEC_GAMEMASTER, true, &ChatHandler::HandleEventStopCommand, "", NULL },
+ { "", SEC_GAMEMASTER, true, &ChatHandler::HandleEventInfoCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand gmCommandTable[] =
+ {
+ { "chat", SEC_MODERATOR, false, &ChatHandler::HandleGMChatCommand, "", NULL },
+ { "fly", SEC_ADMINISTRATOR, false, &ChatHandler::HandleGMFlyCommand, "", NULL },
+ { "ingame", SEC_PLAYER, true, &ChatHandler::HandleGMListIngameCommand, "", NULL },
+ { "list", SEC_ADMINISTRATOR, true, &ChatHandler::HandleGMListFullCommand, "", NULL },
+ { "visible", SEC_MODERATOR, false, &ChatHandler::HandleGMVisibleCommand, "", NULL },
+ { "", SEC_MODERATOR, false, &ChatHandler::HandleGMCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand goCommandTable[] =
+ {
+ { "creature", SEC_MODERATOR, false, &ChatHandler::HandleGoCreatureCommand, "", NULL },
+ { "graveyard", SEC_MODERATOR, false, &ChatHandler::HandleGoGraveyardCommand, "", NULL },
+ { "grid", SEC_MODERATOR, false, &ChatHandler::HandleGoGridCommand, "", NULL },
+ { "object", SEC_MODERATOR, false, &ChatHandler::HandleGoObjectCommand, "", NULL },
+ { "taxinode", SEC_MODERATOR, false, &ChatHandler::HandleGoTaxinodeCommand, "", NULL },
+ { "trigger", SEC_MODERATOR, false, &ChatHandler::HandleGoTriggerCommand, "", NULL },
+ { "zonexy", SEC_MODERATOR, false, &ChatHandler::HandleGoZoneXYCommand, "", NULL },
+ { "xy", SEC_MODERATOR, false, &ChatHandler::HandleGoXYCommand, "", NULL },
+ { "xyz", SEC_MODERATOR, false, &ChatHandler::HandleGoXYZCommand, "", NULL },
+ { "ticket", SEC_MODERATOR, false, &ChatHandler::HandleGoTicketCommand, "", NULL },
+ { "", SEC_MODERATOR, false, &ChatHandler::HandleGoXYZCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand gobjectCommandTable[] =
+ {
+ { "activate", SEC_GAMEMASTER, false, &ChatHandler::HandleActivateObjectCommand, "", NULL },
+ { "add", SEC_GAMEMASTER, false, &ChatHandler::HandleGameObjectAddCommand, "", NULL },
+ { "delete", SEC_GAMEMASTER, false, &ChatHandler::HandleGameObjectDeleteCommand, "", NULL },
+ { "info", SEC_GAMEMASTER, false, &ChatHandler::HandleGOInfoCommand, "", NULL },
+ { "move", SEC_GAMEMASTER, false, &ChatHandler::HandleGameObjectMoveCommand, "", NULL },
+ { "near", SEC_GAMEMASTER, false, &ChatHandler::HandleGameObjectNearCommand, "", NULL },
+ { "state", SEC_GAMEMASTER, false, &ChatHandler::HandleGameObjectStateCommand, "", NULL },
+ { "setphase", SEC_GAMEMASTER, false, &ChatHandler::HandleGameObjectPhaseCommand, "", NULL },
+ { "target", SEC_GAMEMASTER, false, &ChatHandler::HandleGameObjectTargetCommand, "", NULL },
+ { "tempadd", SEC_GAMEMASTER, false, &ChatHandler::HandleTempGameObjectCommand, "", NULL },
+ { "turn", SEC_GAMEMASTER, false, &ChatHandler::HandleGameObjectTurnCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand groupCommandTable[] =
+ {
+ { "leader", SEC_ADMINISTRATOR, false, &ChatHandler::HandleGroupLeaderCommand, "", NULL },
+ { "disband", SEC_ADMINISTRATOR, false, &ChatHandler::HandleGroupDisbandCommand, "", NULL },
+ { "remove", SEC_ADMINISTRATOR, false, &ChatHandler::HandleGroupRemoveCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand guildCommandTable[] =
+ {
+ { "create", SEC_GAMEMASTER, true, &ChatHandler::HandleGuildCreateCommand, "", NULL },
+ { "delete", SEC_GAMEMASTER, true, &ChatHandler::HandleGuildDeleteCommand, "", NULL },
+ { "invite", SEC_GAMEMASTER, true, &ChatHandler::HandleGuildInviteCommand, "", NULL },
+ { "uninvite", SEC_GAMEMASTER, true, &ChatHandler::HandleGuildUninviteCommand, "", NULL },
+ { "rank", SEC_GAMEMASTER, true, &ChatHandler::HandleGuildRankCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand honorCommandTable[] =
+ {
+ { "add", SEC_GAMEMASTER, false, &ChatHandler::HandleHonorAddCommand, "", NULL },
+ { "addkill", SEC_GAMEMASTER, false, &ChatHandler::HandleHonorAddKillCommand, "", NULL },
+ { "update", SEC_GAMEMASTER, false, &ChatHandler::HandleHonorUpdateCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand instanceCommandTable[] =
+ {
+ { "listbinds", SEC_ADMINISTRATOR, false, &ChatHandler::HandleInstanceListBindsCommand, "", NULL },
+ { "unbind", SEC_ADMINISTRATOR, false, &ChatHandler::HandleInstanceUnbindCommand, "", NULL },
+ { "stats", SEC_ADMINISTRATOR, true, &ChatHandler::HandleInstanceStatsCommand, "", NULL },
+ { "savedata", SEC_ADMINISTRATOR, false, &ChatHandler::HandleInstanceSaveDataCommand, "", NULL },
+ { "open", SEC_ADMINISTRATOR, true, &ChatHandler::HandleInstanceOpenCommand, "", NULL },
+ { "close", SEC_ADMINISTRATOR, true, &ChatHandler::HandleInstanceCloseCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand learnCommandTable[] =
+ {
+ { "all", SEC_ADMINISTRATOR, false, &ChatHandler::HandleLearnAllCommand, "", NULL },
+ { "all_gm", SEC_GAMEMASTER, false, &ChatHandler::HandleLearnAllGMCommand, "", NULL },
+ { "all_crafts", SEC_GAMEMASTER, false, &ChatHandler::HandleLearnAllCraftsCommand, "", NULL },
+ { "all_default", SEC_MODERATOR, false, &ChatHandler::HandleLearnAllDefaultCommand, "", NULL },
+ { "all_lang", SEC_MODERATOR, false, &ChatHandler::HandleLearnAllLangCommand, "", NULL },
+ { "all_myclass", SEC_ADMINISTRATOR, false, &ChatHandler::HandleLearnAllMyClassCommand, "", NULL },
+ { "all_mypettalents",SEC_ADMINISTRATOR, false, &ChatHandler::HandleLearnAllMyPetTalentsCommand,"", NULL },
+ { "all_myspells", SEC_ADMINISTRATOR, false, &ChatHandler::HandleLearnAllMySpellsCommand, "", NULL },
+ { "all_mytalents", SEC_ADMINISTRATOR, false, &ChatHandler::HandleLearnAllMyTalentsCommand, "", NULL },
+ { "all_recipes", SEC_GAMEMASTER, false, &ChatHandler::HandleLearnAllRecipesCommand, "", NULL },
+ { "", SEC_ADMINISTRATOR, false, &ChatHandler::HandleLearnCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand listCommandTable[] =
+ {
+ { "creature", SEC_ADMINISTRATOR, true, &ChatHandler::HandleListCreatureCommand, "", NULL },
+ { "item", SEC_ADMINISTRATOR, true, &ChatHandler::HandleListItemCommand, "", NULL },
+ { "object", SEC_ADMINISTRATOR, true, &ChatHandler::HandleListObjectCommand, "", NULL },
+ { "auras", SEC_ADMINISTRATOR, false, &ChatHandler::HandleListAurasCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand lookupPlayerCommandTable[] =
+ {
+ { "ip", SEC_GAMEMASTER, true, &ChatHandler::HandleLookupPlayerIpCommand, "", NULL },
+ { "account", SEC_GAMEMASTER, true, &ChatHandler::HandleLookupPlayerAccountCommand, "", NULL },
+ { "email", SEC_GAMEMASTER, true, &ChatHandler::HandleLookupPlayerEmailCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand lookupCommandTable[] =
+ {
+ { "area", SEC_MODERATOR, true, &ChatHandler::HandleLookupAreaCommand, "", NULL },
+ { "creature", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLookupCreatureCommand, "", NULL },
+ { "event", SEC_GAMEMASTER, true, &ChatHandler::HandleLookupEventCommand, "", NULL },
+ { "faction", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLookupFactionCommand, "", NULL },
+ { "item", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLookupItemCommand, "", NULL },
+ { "itemset", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLookupItemSetCommand, "", NULL },
+ { "object", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLookupObjectCommand, "", NULL },
+ { "quest", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLookupQuestCommand, "", NULL },
+ { "player", SEC_GAMEMASTER, true, NULL, "", lookupPlayerCommandTable },
+ { "skill", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLookupSkillCommand, "", NULL },
+ { "spell", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLookupSpellCommand, "", NULL },
+ { "taxinode", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLookupTaxiNodeCommand, "", NULL },
+ { "tele", SEC_MODERATOR, true, &ChatHandler::HandleLookupTeleCommand, "", NULL },
+ { "title", SEC_GAMEMASTER, true, &ChatHandler::HandleLookupTitleCommand, "", NULL },
+ { "map", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLookupMapCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand modifyCommandTable[] =
+ {
+ { "hp", SEC_MODERATOR, false, &ChatHandler::HandleModifyHPCommand, "", NULL },
+ { "mana", SEC_MODERATOR, false, &ChatHandler::HandleModifyManaCommand, "", NULL },
+ { "rage", SEC_MODERATOR, false, &ChatHandler::HandleModifyRageCommand, "", NULL },
+ { "runicpower", SEC_MODERATOR, false, &ChatHandler::HandleModifyRunicPowerCommand, "", NULL },
+ { "energy", SEC_MODERATOR, false, &ChatHandler::HandleModifyEnergyCommand, "", NULL },
+ { "money", SEC_MODERATOR, false, &ChatHandler::HandleModifyMoneyCommand, "", NULL },
+ { "speed", SEC_MODERATOR, false, &ChatHandler::HandleModifySpeedCommand, "", NULL },
+ { "swim", SEC_MODERATOR, false, &ChatHandler::HandleModifySwimCommand, "", NULL },
+ { "scale", SEC_MODERATOR, false, &ChatHandler::HandleModifyScaleCommand, "", NULL },
+ { "bit", SEC_MODERATOR, false, &ChatHandler::HandleModifyBitCommand, "", NULL },
+ { "bwalk", SEC_MODERATOR, false, &ChatHandler::HandleModifyBWalkCommand, "", NULL },
+ { "fly", SEC_MODERATOR, false, &ChatHandler::HandleModifyFlyCommand, "", NULL },
+ { "aspeed", SEC_MODERATOR, false, &ChatHandler::HandleModifyASpeedCommand, "", NULL },
+ { "faction", SEC_MODERATOR, false, &ChatHandler::HandleModifyFactionCommand, "", NULL },
+ { "spell", SEC_MODERATOR, false, &ChatHandler::HandleModifySpellCommand, "", NULL },
+ { "tp", SEC_MODERATOR, false, &ChatHandler::HandleModifyTalentCommand, "", NULL },
+ { "mount", SEC_MODERATOR, false, &ChatHandler::HandleModifyMountCommand, "", NULL },
+ { "honor", SEC_MODERATOR, false, &ChatHandler::HandleModifyHonorCommand, "", NULL },
+ { "rep", SEC_GAMEMASTER, false, &ChatHandler::HandleModifyRepCommand, "", NULL },
+ { "arena", SEC_MODERATOR, false, &ChatHandler::HandleModifyArenaCommand, "", NULL },
+ { "drunk", SEC_MODERATOR, false, &ChatHandler::HandleModifyDrunkCommand, "", NULL },
+ { "standstate", SEC_GAMEMASTER, false, &ChatHandler::HandleModifyStandStateCommand, "", NULL },
+ { "morph", SEC_GAMEMASTER, false, &ChatHandler::HandleModifyMorphCommand, "", NULL },
+ { "phase", SEC_ADMINISTRATOR, false, &ChatHandler::HandleModifyPhaseCommand, "", NULL },
+ { "gender", SEC_GAMEMASTER, false, &ChatHandler::HandleModifyGenderCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand npcCommandTable[] =
+ {
+ { "add", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcAddCommand, "", NULL },
+ { "additem", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcAddVendorItemCommand, "", NULL },
+ { "addmove", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcAddMoveCommand, "", NULL },
+ { "allowmove", SEC_ADMINISTRATOR, false, &ChatHandler::HandleNpcAllowMovementCommand, "", NULL },
+ { "changeentry", SEC_ADMINISTRATOR, false, &ChatHandler::HandleNpcChangeEntryCommand, "", NULL },
+ { "changelevel", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcChangeLevelCommand, "", NULL },
+ { "delete", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcDeleteCommand, "", NULL },
+ { "delitem", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcDelVendorItemCommand, "", NULL },
+ { "factionid", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcFactionIdCommand, "", NULL },
+ { "flag", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcFlagCommand, "", NULL },
+ { "follow", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcFollowCommand, "", NULL },
+ { "info", SEC_ADMINISTRATOR, false, &ChatHandler::HandleNpcInfoCommand, "", NULL },
+ { "move", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcMoveCommand, "", NULL },
+ { "playemote", SEC_ADMINISTRATOR, false, &ChatHandler::HandleNpcPlayEmoteCommand, "", NULL },
+ { "setmodel", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcSetModelCommand, "", NULL },
+ { "setmovetype", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcSetMoveTypeCommand, "", NULL },
+ { "setphase", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcSetPhaseCommand, "", NULL },
+ { "spawndist", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcSpawnDistCommand, "", NULL },
+ { "spawntime", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcSpawnTimeCommand, "", NULL },
+ { "say", SEC_MODERATOR, false, &ChatHandler::HandleNpcSayCommand, "", NULL },
+ { "textemote", SEC_MODERATOR, false, &ChatHandler::HandleNpcTextEmoteCommand, "", NULL },
+ { "unfollow", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcUnFollowCommand, "", NULL },
+ { "whisper", SEC_MODERATOR, false, &ChatHandler::HandleNpcWhisperCommand, "", NULL },
+ { "yell", SEC_MODERATOR, false, &ChatHandler::HandleNpcYellCommand, "", NULL },
+ { "tempadd", SEC_GAMEMASTER, false, &ChatHandler::HandleTempAddSpwCommand, "", NULL },
+ { "tame", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcTameCommand, "", NULL },
+ { "setdeathstate", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcSetDeathStateCommand, "", NULL },
+ { "addformation", SEC_MODERATOR, false, &ChatHandler::HandleNpcAddFormationCommand, "", NULL },
+ { "setlink", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcSetLinkCommand, "", NULL },
+
+ //{ TODO: fix or remove this commands
+ { "addweapon", SEC_ADMINISTRATOR, false, &ChatHandler::HandleNpcAddWeaponCommand, "", NULL },
+ { "name", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcNameCommand, "", NULL },
+ { "subname", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcSubNameCommand, "", NULL },
+ //}
+
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand petCommandTable[] =
+ {
+ { "create", SEC_GAMEMASTER, false, &ChatHandler::HandleCreatePetCommand, "", NULL },
+ { "learn", SEC_GAMEMASTER, false, &ChatHandler::HandlePetLearnCommand, "", NULL },
+ { "unlearn", SEC_GAMEMASTER, false, &ChatHandler::HandlePetUnlearnCommand, "", NULL },
+ { "tp", SEC_GAMEMASTER, false, &ChatHandler::HandlePetTpCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand pdumpCommandTable[] =
+ {
+ { "load", SEC_ADMINISTRATOR, true, &ChatHandler::HandlePDumpLoadCommand, "", NULL },
+ { "write", SEC_ADMINISTRATOR, true, &ChatHandler::HandlePDumpWriteCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand questCommandTable[] =
+ {
+ { "add", SEC_ADMINISTRATOR, false, &ChatHandler::HandleQuestAdd, "", NULL },
+ { "complete", SEC_ADMINISTRATOR, false, &ChatHandler::HandleQuestComplete, "", NULL },
+ { "remove", SEC_ADMINISTRATOR, false, &ChatHandler::HandleQuestRemove, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand reloadCommandTable[] =
+ {
+ { "all", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllCommand, "", NULL },
+ { "all_achievement",SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllAchievementCommand,"", NULL },
+ { "all_area", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllAreaCommand, "", NULL },
+ { "all_eventai", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllEventAICommand, "", NULL },
+ { "all_item", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllItemCommand, "", NULL },
+ { "all_locales", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllLocalesCommand, "", NULL },
+ { "all_loot", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllLootCommand, "", NULL },
+ { "all_npc", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllNpcCommand, "", NULL },
+ { "all_quest", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllQuestCommand, "", NULL },
+ { "all_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllScriptsCommand, "", NULL },
+ { "all_spell", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllSpellCommand, "", NULL },
+
+ { "config", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadConfigCommand, "", NULL },
+
+ { "access_requirement", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAccessRequirementCommand, "", NULL },
+ { "achievement_criteria_data", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAchievementCriteriaDataCommand, "", NULL },
+ { "achievement_reward", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAchievementRewardCommand, "", NULL },
+ { "areatrigger_involvedrelation",SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadQuestAreaTriggersCommand, "", NULL },
+ { "areatrigger_tavern", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAreaTriggerTavernCommand, "", NULL },
+ { "areatrigger_teleport", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAreaTriggerTeleportCommand, "", NULL },
+ { "autobroadcast", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAutobroadcastCommand, "", NULL },
+ { "command", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadCommandCommand, "", NULL },
+ { "conditions", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadConditions, "", NULL },
+ { "creature_ai_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadEventAIScriptsCommand, "", NULL },
+ { "creature_ai_summons", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadEventAISummonsCommand, "", NULL },
+ { "creature_ai_texts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadEventAITextsCommand, "", NULL },
+ { "creature_involvedrelation", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadCreatureQuestInvRelationsCommand,"",NULL },
+ { "creature_linked_respawn", SEC_GAMEMASTER, true, &ChatHandler::HandleReloadCreatureLinkedRespawnCommand, "", NULL },
+ { "creature_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesCreatureCommand, "", NULL },
+ { "creature_questrelation", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadCreatureQuestRelationsCommand, "", NULL },
+ { "creature_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadCreatureTemplateCommand, "", NULL },
+ //{ "db_script_string", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadDbScriptStringCommand, "", NULL },
+ { "disenchant_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesDisenchantCommand, "", NULL },
+ { "event_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadEventScriptsCommand, "", NULL },
+ { "fishing_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesFishingCommand, "", NULL },
+ { "game_graveyard_zone", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadGameGraveyardZoneCommand, "", NULL },
+ { "game_tele", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadGameTeleCommand, "", NULL },
+ { "gameobject_involvedrelation", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadGOQuestInvRelationsCommand, "", NULL },
+ { "gameobject_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesGameobjectCommand, "", NULL },
+ { "gameobject_questrelation", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadGOQuestRelationsCommand, "", NULL },
+ { "gameobject_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadGameObjectScriptsCommand, "", NULL },
+ { "gossip_menu", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadGossipMenuCommand, "", NULL },
+ { "gossip_menu_option", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadGossipMenuOptionCommand, "", NULL },
+ { "item_enchantment_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadItemEnchantementsCommand, "", NULL },
+ { "item_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesItemCommand, "", NULL },
+ { "locales_achievement_reward", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesAchievementRewardCommand,"", NULL },
+ { "locales_creature", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesCreatureCommand, "", NULL },
+ { "locales_gameobject", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesGameobjectCommand, "", NULL },
+ { "locales_item", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesItemCommand, "", NULL },
+ { "locales_npc_text", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesNpcTextCommand, "", NULL },
+ { "locales_page_text", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesPageTextCommand, "", NULL },
+ { "locales_points_of_interest", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesPointsOfInterestCommand, "", NULL },
+ { "locales_quest", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesQuestCommand, "", NULL },
+// { "auctions", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAuctionsCommand, "", NULL },
+ { "mail_level_reward", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadMailLevelRewardCommand, "", NULL },
+ { "mail_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesMailCommand, "", NULL },
+ { "milling_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesMillingCommand, "", NULL },
+ { "npc_gossip", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcGossipCommand, "", NULL },
+ { "npc_spellclick_spells", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellClickSpellsCommand, "",NULL},
+ { "npc_trainer", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcTrainerCommand, "", NULL },
+ { "npc_vendor", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcVendorCommand, "", NULL },
+ { "page_text", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadPageTextsCommand, "", NULL },
+ { "pickpocketing_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesPickpocketingCommand,"",NULL},
+ { "points_of_interest", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadPointsOfInterestCommand, "",NULL},
+ { "prospecting_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesProspectingCommand,"", NULL },
+ { "quest_end_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadQuestEndScriptsCommand, "", NULL },
+ { "quest_start_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadQuestStartScriptsCommand, "", NULL },
+ { "quest_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadQuestTemplateCommand, "", NULL },
+ { "reference_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesReferenceCommand, "", NULL },
+ { "reserved_name", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadReservedNameCommand, "", NULL },
+ { "skill_discovery_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSkillDiscoveryTemplateCommand, "", NULL },
+ { "skill_extra_item_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSkillExtraItemTemplateCommand, "", NULL },
+ { "skill_fishing_base_level", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSkillFishingBaseLevelCommand, "", NULL },
+ { "skinning_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesSkinningCommand, "", NULL },
+ { "spell_required", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellRequiredCommand, "", NULL },
+ { "spell_area", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellAreaCommand, "", NULL },
+ { "spell_bonus_data", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellBonusesCommand, "", NULL },
+ { "spell_group", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellGroupsCommand, "", NULL },
+ { "spell_learn_spell", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellLearnSpellCommand, "", NULL },
+ { "spell_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesSpellCommand, "", NULL },
+ { "spell_linked_spell", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellLinkedSpellCommand, "", NULL },
+ { "spell_pet_auras", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellPetAurasCommand, "", NULL },
+ { "spell_proc_event", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellProcEventCommand, "", NULL },
+ { "spell_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellScriptsCommand, "", NULL },
+ { "spell_target_position", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellTargetPositionCommand, "", NULL },
+ { "spell_threats", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellThreatsCommand, "", NULL },
+ { "spell_disabled", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellDisabledCommand, "", NULL },
+ { "spell_group_stack_rules", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellGroupStackRulesCommand, "", NULL },
+ { "trinity_string", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadTrinityStringCommand, "", NULL },
+ { "auctions", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAuctionsCommand, "", NULL },
+ { "waypoint_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadWpScriptsCommand, "", NULL },
+ { "gm_tickets", SEC_ADMINISTRATOR, true, &ChatHandler::HandleGMTicketReloadCommand, "", NULL },
+
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand resetCommandTable[] =
+ {
+ { "achievements", SEC_ADMINISTRATOR, true, &ChatHandler::HandleResetAchievementsCommand, "", NULL },
+ { "honor", SEC_ADMINISTRATOR, true, &ChatHandler::HandleResetHonorCommand, "", NULL },
+ { "level", SEC_ADMINISTRATOR, true, &ChatHandler::HandleResetLevelCommand, "", NULL },
+ { "spells", SEC_ADMINISTRATOR, true, &ChatHandler::HandleResetSpellsCommand, "", NULL },
+ { "stats", SEC_ADMINISTRATOR, true, &ChatHandler::HandleResetStatsCommand, "", NULL },
+ { "talents", SEC_ADMINISTRATOR, true, &ChatHandler::HandleResetTalentsCommand, "", NULL },
+ { "all", SEC_ADMINISTRATOR, true, &ChatHandler::HandleResetAllCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand sendCommandTable[] =
+ {
+ { "items", SEC_ADMINISTRATOR, true, &ChatHandler::HandleSendItemsCommand, "", NULL },
+ { "mail", SEC_MODERATOR, true, &ChatHandler::HandleSendMailCommand, "", NULL },
+ { "message", SEC_ADMINISTRATOR, true, &ChatHandler::HandleSendMessageCommand, "", NULL },
+ { "money", SEC_ADMINISTRATOR, true, &ChatHandler::HandleSendMoneyCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand serverIdleRestartCommandTable[] =
+ {
+ { "cancel", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerShutDownCancelCommand,"", NULL },
+ { "" , SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerIdleRestartCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand serverIdleShutdownCommandTable[] =
+ {
+ { "cancel", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerShutDownCancelCommand,"", NULL },
+ { "" , SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerIdleShutDownCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand serverRestartCommandTable[] =
+ {
+ { "cancel", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerShutDownCancelCommand,"", NULL },
+ { "" , SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerRestartCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand serverShutdownCommandTable[] =
+ {
+ { "cancel", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerShutDownCancelCommand,"", NULL },
+ { "" , SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerShutDownCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand serverSetCommandTable[] =
+ {
+ { "difftime", SEC_CONSOLE, true, &ChatHandler::HandleServerSetDiffTimeCommand, "", NULL },
+ { "loglevel", SEC_CONSOLE, true, &ChatHandler::HandleServerSetLogLevelCommand, "", NULL },
+ { "logfilelevel", SEC_CONSOLE, true, &ChatHandler::HandleServerSetLogFileLevelCommand, "", NULL },
+ { "motd", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerSetMotdCommand, "", NULL },
+ { "closed", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerSetClosedCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand serverCommandTable[] =
+ {
+ { "corpses", SEC_GAMEMASTER, true, &ChatHandler::HandleServerCorpsesCommand, "", NULL },
+ { "exit", SEC_CONSOLE, true, &ChatHandler::HandleServerExitCommand, "", NULL },
+ { "idlerestart", SEC_ADMINISTRATOR, true, NULL, "", serverIdleRestartCommandTable },
+ { "idleshutdown", SEC_ADMINISTRATOR, true, NULL, "", serverShutdownCommandTable },
+ { "info", SEC_PLAYER, true, &ChatHandler::HandleServerInfoCommand, "", NULL },
+ { "motd", SEC_PLAYER, true, &ChatHandler::HandleServerMotdCommand, "", NULL },
+ { "plimit", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerPLimitCommand, "", NULL },
+ { "restart", SEC_ADMINISTRATOR, true, NULL, "", serverRestartCommandTable },
+ { "shutdown", SEC_ADMINISTRATOR, true, NULL, "", serverShutdownCommandTable },
+ { "set", SEC_ADMINISTRATOR, true, NULL, "", serverSetCommandTable },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand teleCommandTable[] =
+ {
+ { "add", SEC_ADMINISTRATOR, false, &ChatHandler::HandleTeleAddCommand, "", NULL },
+ { "del", SEC_ADMINISTRATOR, true, &ChatHandler::HandleTeleDelCommand, "", NULL },
+ { "name", SEC_MODERATOR, true, &ChatHandler::HandleTeleNameCommand, "", NULL },
+ { "group", SEC_MODERATOR, false, &ChatHandler::HandleTeleGroupCommand, "", NULL },
+ { "", SEC_MODERATOR, false, &ChatHandler::HandleTeleCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand titlesCommandTable[] =
+ {
+ { "add", SEC_GAMEMASTER, false, &ChatHandler::HandleTitlesAddCommand, "", NULL },
+ { "current", SEC_GAMEMASTER, false, &ChatHandler::HandleTitlesCurrentCommand, "", NULL },
+ { "remove", SEC_GAMEMASTER, false, &ChatHandler::HandleTitlesRemoveCommand, "", NULL },
+ { "setmask", SEC_GAMEMASTER, false, &ChatHandler::HandleTitlesSetMaskCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand unbanCommandTable[] =
+ {
+ { "account", SEC_ADMINISTRATOR, true, &ChatHandler::HandleUnBanAccountCommand, "", NULL },
+ { "character", SEC_ADMINISTRATOR, true, &ChatHandler::HandleUnBanCharacterCommand, "", NULL },
+ { "ip", SEC_ADMINISTRATOR, true, &ChatHandler::HandleUnBanIPCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand wpCommandTable[] =
+ {
+ { "show", SEC_GAMEMASTER, false, &ChatHandler::HandleWpShowCommand, "", NULL },
+ { "addwp", SEC_GAMEMASTER, false, &ChatHandler::HandleWpAddCommand, "", NULL },
+ { "load", SEC_GAMEMASTER, false, &ChatHandler::HandleWpLoadPathCommand, "", NULL },
+ { "modify", SEC_GAMEMASTER, false, &ChatHandler::HandleWpModifyCommand, "", NULL },
+ { "event", SEC_GAMEMASTER, false, &ChatHandler::HandleWpEventCommand, "", NULL },
+ { "unload", SEC_GAMEMASTER, false, &ChatHandler::HandleWpUnLoadPathCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand ticketCommandTable[] =
+ {
+ { "list", SEC_MODERATOR, false, &ChatHandler::HandleGMTicketListCommand, "", NULL },
+ { "onlinelist", SEC_MODERATOR, false, &ChatHandler::HandleGMTicketListOnlineCommand, "", NULL },
+ { "viewname", SEC_MODERATOR, false, &ChatHandler::HandleGMTicketGetByNameCommand, "", NULL },
+ { "viewid", SEC_MODERATOR, false, &ChatHandler::HandleGMTicketGetByIdCommand, "", NULL },
+ { "close", SEC_MODERATOR, false, &ChatHandler::HandleGMTicketCloseByIdCommand, "", NULL },
+ { "closedlist", SEC_MODERATOR, false, &ChatHandler::HandleGMTicketListClosedCommand, "", NULL },
+ { "delete", SEC_ADMINISTRATOR, false, &ChatHandler::HandleGMTicketDeleteByIdCommand, "", NULL },
+ { "assign", SEC_MODERATOR, false, &ChatHandler::HandleGMTicketAssignToCommand, "", NULL },
+ { "unassign", SEC_MODERATOR, false, &ChatHandler::HandleGMTicketUnAssignCommand, "", NULL },
+ { "comment", SEC_MODERATOR, false, &ChatHandler::HandleGMTicketCommentCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand commandTable[] =
+ {
+ { "account", SEC_PLAYER, true, NULL, "", accountCommandTable },
+ { "gm", SEC_MODERATOR, true, NULL, "", gmCommandTable },
+ { "npc", SEC_MODERATOR, false, NULL, "", npcCommandTable },
+ { "go", SEC_MODERATOR, false, NULL, "", goCommandTable },
+ { "learn", SEC_MODERATOR, false, NULL, "", learnCommandTable },
+ { "modify", SEC_MODERATOR, false, NULL, "", modifyCommandTable },
+ { "debug", SEC_MODERATOR, true, NULL, "", debugCommandTable },
+ { "tele", SEC_MODERATOR, true, NULL, "", teleCommandTable },
+ { "character", SEC_GAMEMASTER, false, NULL, "", characterCommandTable},
+ { "event", SEC_GAMEMASTER, false, NULL, "", eventCommandTable },
+ { "gobject", SEC_GAMEMASTER, false, NULL, "", gobjectCommandTable },
+ { "honor", SEC_GAMEMASTER, false, NULL, "", honorCommandTable },
+ { "wp", SEC_GAMEMASTER, false, NULL, "", wpCommandTable },
+ { "titles", SEC_GAMEMASTER, false, NULL, "", titlesCommandTable },
+ { "quest", SEC_ADMINISTRATOR, false, NULL, "", questCommandTable },
+ { "reload", SEC_ADMINISTRATOR, true, NULL, "", reloadCommandTable },
+ { "list", SEC_ADMINISTRATOR, true, NULL, "", listCommandTable },
+ { "lookup", SEC_ADMINISTRATOR, true, NULL, "", lookupCommandTable },
+ { "pdump", SEC_ADMINISTRATOR, true, NULL, "", pdumpCommandTable },
+ { "guild", SEC_ADMINISTRATOR, true, NULL, "", guildCommandTable },
+ { "cast", SEC_ADMINISTRATOR, false, NULL, "", castCommandTable },
+ { "reset", SEC_ADMINISTRATOR, true, NULL, "", resetCommandTable },
+ { "instance", SEC_ADMINISTRATOR, true, NULL, "", instanceCommandTable },
+ { "server", SEC_ADMINISTRATOR, true, NULL, "", serverCommandTable },
+
+ { "channel", SEC_ADMINISTRATOR, true, NULL, "", channelCommandTable },
+
+ { "pet", SEC_GAMEMASTER, false, NULL, "", petCommandTable },
+ { "loadpath", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadAllPaths, "", NULL },
+ { "ahbotoptions", SEC_GAMEMASTER, true, &ChatHandler::HandleAHBotOptionsCommand, "", NULL },
+ { "ticket", SEC_MODERATOR, false, NULL, "", ticketCommandTable },
+
+ { "aura", SEC_ADMINISTRATOR, false, &ChatHandler::HandleAuraCommand, "", NULL },
+ { "unaura", SEC_ADMINISTRATOR, false, &ChatHandler::HandleUnAuraCommand, "", NULL },
+ { "nameannounce", SEC_MODERATOR, false, &ChatHandler::HandleNameAnnounceCommand, "", NULL },
+ { "gmnameannounce", SEC_MODERATOR, false, &ChatHandler::HandleGMNameAnnounceCommand, "", NULL },
+ { "announce", SEC_MODERATOR, true, &ChatHandler::HandleAnnounceCommand, "", NULL },
+ { "gmannounce", SEC_MODERATOR, true, &ChatHandler::HandleGMAnnounceCommand, "", NULL },
+ { "notify", SEC_MODERATOR, true, &ChatHandler::HandleNotifyCommand, "", NULL },
+ { "gmnotify", SEC_MODERATOR, true, &ChatHandler::HandleGMNotifyCommand, "", NULL },
+ { "goname", SEC_MODERATOR, false, &ChatHandler::HandleGonameCommand, "", NULL },
+ { "namego", SEC_MODERATOR, false, &ChatHandler::HandleNamegoCommand, "", NULL },
+ { "groupgo", SEC_MODERATOR, false, &ChatHandler::HandleGroupgoCommand, "", NULL },
+ { "commands", SEC_PLAYER, true, &ChatHandler::HandleCommandsCommand, "", NULL },
+ { "demorph", SEC_GAMEMASTER, false, &ChatHandler::HandleDeMorphCommand, "", NULL },
+ { "die", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDieCommand, "", NULL },
+ { "revive", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReviveCommand, "", NULL },
+ { "dismount", SEC_PLAYER, false, &ChatHandler::HandleDismountCommand, "", NULL },
+ { "gps", SEC_MODERATOR, false, &ChatHandler::HandleGPSCommand, "", NULL },
+ { "guid", SEC_GAMEMASTER, false, &ChatHandler::HandleGUIDCommand, "", NULL },
+ { "help", SEC_PLAYER, true, &ChatHandler::HandleHelpCommand, "", NULL },
+ { "itemmove", SEC_GAMEMASTER, false, &ChatHandler::HandleItemMoveCommand, "", NULL },
+ { "cooldown", SEC_ADMINISTRATOR, false, &ChatHandler::HandleCooldownCommand, "", NULL },
+ { "unlearn", SEC_ADMINISTRATOR, false, &ChatHandler::HandleUnLearnCommand, "", NULL },
+ { "distance", SEC_ADMINISTRATOR, false, &ChatHandler::HandleGetDistanceCommand, "", NULL },
+ { "recall", SEC_MODERATOR, false, &ChatHandler::HandleRecallCommand, "", NULL },
+ { "save", SEC_PLAYER, false, &ChatHandler::HandleSaveCommand, "", NULL },
+ { "saveall", SEC_MODERATOR, true, &ChatHandler::HandleSaveAllCommand, "", NULL },
+ { "kick", SEC_GAMEMASTER, true, &ChatHandler::HandleKickPlayerCommand, "", NULL },
+ { "ban", SEC_ADMINISTRATOR, true, NULL, "", banCommandTable },
+ { "unban", SEC_ADMINISTRATOR, true, NULL, "", unbanCommandTable },
+ { "baninfo", SEC_ADMINISTRATOR, false, NULL, "", baninfoCommandTable },
+ { "banlist", SEC_ADMINISTRATOR, true, NULL, "", banlistCommandTable },
+ { "start", SEC_PLAYER, false, &ChatHandler::HandleStartCommand, "", NULL },
+ { "taxicheat", SEC_MODERATOR, false, &ChatHandler::HandleTaxiCheatCommand, "", NULL },
+ { "linkgrave", SEC_ADMINISTRATOR, false, &ChatHandler::HandleLinkGraveCommand, "", NULL },
+ { "neargrave", SEC_ADMINISTRATOR, false, &ChatHandler::HandleNearGraveCommand, "", NULL },
+ { "explorecheat", SEC_ADMINISTRATOR, false, &ChatHandler::HandleExploreCheatCommand, "", NULL },
+ { "hover", SEC_ADMINISTRATOR, false, &ChatHandler::HandleHoverCommand, "", NULL },
+ { "levelup", SEC_ADMINISTRATOR, false, &ChatHandler::HandleLevelUpCommand, "", NULL },
+ { "showarea", SEC_ADMINISTRATOR, false, &ChatHandler::HandleShowAreaCommand, "", NULL },
+ { "hidearea", SEC_ADMINISTRATOR, false, &ChatHandler::HandleHideAreaCommand, "", NULL },
+ { "additem", SEC_ADMINISTRATOR, false, &ChatHandler::HandleAddItemCommand, "", NULL },
+ { "additemset", SEC_ADMINISTRATOR, false, &ChatHandler::HandleAddItemSetCommand, "", NULL },
+ { "bank", SEC_ADMINISTRATOR, false, &ChatHandler::HandleBankCommand, "", NULL },
+ { "wchange", SEC_ADMINISTRATOR, false, &ChatHandler::HandleChangeWeather, "", NULL },
+ { "maxskill", SEC_ADMINISTRATOR, false, &ChatHandler::HandleMaxSkillCommand, "", NULL },
+ { "setskill", SEC_ADMINISTRATOR, false, &ChatHandler::HandleSetSkillCommand, "", NULL },
+ { "whispers", SEC_MODERATOR, false, &ChatHandler::HandleWhispersCommand, "", NULL },
+ { "pinfo", SEC_GAMEMASTER, true, &ChatHandler::HandlePInfoCommand, "", NULL },
+ { "respawn", SEC_ADMINISTRATOR, false, &ChatHandler::HandleRespawnCommand, "", NULL },
+ { "send", SEC_MODERATOR, true, NULL, "", sendCommandTable },
+ { "mute", SEC_MODERATOR, true, &ChatHandler::HandleMuteCommand, "", NULL },
+ { "unmute", SEC_MODERATOR, true, &ChatHandler::HandleUnmuteCommand, "", NULL },
+ { "movegens", SEC_ADMINISTRATOR, false, &ChatHandler::HandleMovegensCommand, "", NULL },
+ { "cometome", SEC_ADMINISTRATOR, false, &ChatHandler::HandleComeToMeCommand, "", NULL },
+ { "damage", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDamageCommand, "", NULL },
+ { "combatstop", SEC_GAMEMASTER, false, &ChatHandler::HandleCombatStopCommand, "", NULL },
+ { "flusharenapoints",SEC_ADMINISTRATOR, false, &ChatHandler::HandleFlushArenaPointsCommand, "", NULL },
+ { "repairitems", SEC_GAMEMASTER, true, &ChatHandler::HandleRepairitemsCommand, "", NULL },
+ { "waterwalk", SEC_GAMEMASTER, false, &ChatHandler::HandleWaterwalkCommand, "", NULL },
+
+ { "freeze", SEC_MODERATOR, false, &ChatHandler::HandleFreezeCommand, "", NULL },
+ { "unfreeze", SEC_MODERATOR, false, &ChatHandler::HandleUnFreezeCommand, "", NULL },
+ { "listfreeze", SEC_MODERATOR, false, &ChatHandler::HandleListFreezeCommand, "", NULL },
+
+ { "possess", SEC_ADMINISTRATOR, false, &ChatHandler::HandlePossessCommand, "", NULL },
+ { "unpossess", SEC_ADMINISTRATOR, false, &ChatHandler::HandleUnPossessCommand, "", NULL },
+ { "bindsight", SEC_ADMINISTRATOR, false, &ChatHandler::HandleBindSightCommand, "", NULL },
+ { "unbindsight", SEC_ADMINISTRATOR, false, &ChatHandler::HandleUnbindSightCommand, "", NULL },
+ { "playall", SEC_GAMEMASTER, false, &ChatHandler::HandlePlayAllCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ if (load_command_table)
+ {
+ load_command_table = false;
+
+ QueryResult_AutoPtr result = WorldDatabase.Query("SELECT name,security,help FROM command");
+ if (result)
+ {
+ do
+ {
+ Field *fields = result->Fetch();
+ std::string name = fields[0].GetCppString();
+
+ SetDataForCommandInTable(commandTable, name.c_str(), fields[1].GetUInt16(), fields[2].GetCppString(), name);
+
+ } while (result->NextRow());
+ }
+ }
+
+ return commandTable;
+}
+
+const char *ChatHandler::GetTrinityString(int32 entry) const
+{
+ return m_session->GetTrinityString(entry);
+}
+
+bool ChatHandler::isAvailable(ChatCommand const& cmd) const
+{
+ // check security level only for simple command (without child commands)
+ return m_session->GetSecurity() >= cmd.SecurityLevel;
+}
+
+bool ChatHandler::HasLowerSecurity(Player* target, uint64 guid, bool strong)
+{
+ WorldSession* target_session = NULL;
+ uint32 target_account = 0;
+
+ if (target)
+ target_session = target->GetSession();
+ else if (guid)
+ target_account = objmgr.GetPlayerAccountIdByGUID(guid);
+
+ if (!target_session && !target_account)
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return true;
+ }
+
+ return HasLowerSecurityAccount(target_session,target_account,strong);
+}
+
+bool ChatHandler::HasLowerSecurityAccount(WorldSession* target, uint32 target_account, bool strong)
+{
+ uint32 target_sec;
+
+ // allow everything from console and RA console
+ if (!m_session)
+ return false;
+
+ // ignore only for non-players for non strong checks (when allow apply command at least to same sec level)
+ if (m_session->GetSecurity() > SEC_PLAYER && !strong && !sWorld.getConfig(CONFIG_GM_LOWER_SECURITY))
+ return false;
+
+ if (target)
+ target_sec = target->GetSecurity();
+ else if (target_account)
+ target_sec = accmgr.GetSecurity(target_account);
+ else
+ return true; // caller must report error for (target == NULL && target_account == 0)
+
+ if (m_session->GetSecurity() < target_sec || (strong && m_session->GetSecurity() <= target_sec))
+ {
+ SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
+ SetSentErrorMessage(true);
+ return true;
+ }
+
+ return false;
+}
+
+bool ChatHandler::hasStringAbbr(const char* name, const char* part)
+{
+ // non "" command
+ if (*name)
+ {
+ // "" part from non-"" command
+ if (!*part)
+ return false;
+
+ for (;;)
+ {
+ if (!*part)
+ return true;
+ else if (!*name)
+ return false;
+ else if (tolower(*name) != tolower(*part))
+ return false;
+ ++name; ++part;
+ }
+ }
+ // allow with any for ""
+
+ return true;
+}
+
+void ChatHandler::SendSysMessage(const char *str)
+{
+ WorldPacket data;
+
+ // need copy to prevent corruption by strtok call in LineFromMessage original string
+ char* buf = strdup(str);
+ char* pos = buf;
+
+ while (char* line = LineFromMessage(pos))
+ {
+ FillSystemMessageData(&data, line);
+ m_session->SendPacket(&data);
+ }
+
+ free(buf);
+}
+
+void ChatHandler::SendGlobalSysMessage(const char *str)
+{
+ // Chat output
+ WorldPacket data;
+
+ // need copy to prevent corruption by strtok call in LineFromMessage original string
+ char* buf = strdup(str);
+ char* pos = buf;
+
+ while (char* line = LineFromMessage(pos))
+ {
+ FillSystemMessageData(&data, line);
+ sWorld.SendGlobalMessage(&data);
+ }
+
+ free(buf);
+}
+
+void ChatHandler::SendGlobalGMSysMessage(const char *str)
+{
+ // Chat output
+ WorldPacket data;
+
+ // need copy to prevent corruption by strtok call in LineFromMessage original string
+ char* buf = strdup(str);
+ char* pos = buf;
+
+ while (char* line = LineFromMessage(pos))
+ {
+ FillSystemMessageData(&data, line);
+ sWorld.SendGlobalGMMessage(&data);
+ }
+ free(buf);
+}
+
+void ChatHandler::SendSysMessage(int32 entry)
+{
+ SendSysMessage(GetTrinityString(entry));
+}
+
+void ChatHandler::PSendSysMessage(int32 entry, ...)
+{
+ const char *format = GetTrinityString(entry);
+ va_list ap;
+ char str [2048];
+ va_start(ap, entry);
+ vsnprintf(str,2048,format, ap);
+ va_end(ap);
+ SendSysMessage(str);
+}
+
+void ChatHandler::PSendSysMessage(const char *format, ...)
+{
+ va_list ap;
+ char str [2048];
+ va_start(ap, format);
+ vsnprintf(str,2048,format, ap);
+ va_end(ap);
+ SendSysMessage(str);
+}
+
+bool ChatHandler::ExecuteCommandInTable(ChatCommand *table, const char* text, const std::string& fullcmd)
+{
+ char const* oldtext = text;
+ std::string cmd = "";
+
+ while (*text != ' ' && *text != '\0')
+ {
+ cmd += *text;
+ ++text;
+ }
+
+ while (*text == ' ') ++text;
+
+ for (uint32 i = 0; table[i].Name != NULL; ++i)
+ {
+ if (!hasStringAbbr(table[i].Name, cmd.c_str()))
+ continue;
+
+ // select subcommand from child commands list
+ if (table[i].ChildCommands != NULL)
+ {
+ if (!ExecuteCommandInTable(table[i].ChildCommands, text, fullcmd))
+ {
+ if (text && text[0] != '\0')
+ SendSysMessage(LANG_NO_SUBCMD);
+ else
+ SendSysMessage(LANG_CMD_SYNTAX);
+
+ ShowHelpForCommand(table[i].ChildCommands,text);
+ }
+
+ return true;
+ }
+
+ // must be available and have handler
+ if (!table[i].Handler || !isAvailable(table[i]))
+ continue;
+
+ SetSentErrorMessage(false);
+ // table[i].Name == "" is special case: send original command to handler
+ if ((this->*(table[i].Handler))(strlen(table[i].Name) != 0 ? text : oldtext))
+ {
+ if (table[i].SecurityLevel > SEC_PLAYER)
+ {
+ // chat case
+ if (m_session)
+ {
+ Player* p = m_session->GetPlayer();
+ uint64 sel_guid = p->GetSelection();
+ sLog.outCommand(m_session->GetAccountId(),"Command: %s [Player: %s (Account: %u) X: %f Y: %f Z: %f Map: %u Selected: %s (GUID: %u)]",
+ fullcmd.c_str(),p->GetName(),m_session->GetAccountId(),p->GetPositionX(),p->GetPositionY(),p->GetPositionZ(),p->GetMapId(),
+ GetLogNameForGuid(sel_guid),GUID_LOPART(sel_guid));
+ }
+ }
+ }
+ // some commands have custom error messages. Don't send the default one in these cases.
+ else if (!sentErrorMessage)
+ {
+ if (!table[i].Help.empty())
+ SendSysMessage(table[i].Help.c_str());
+ else
+ SendSysMessage(LANG_CMD_SYNTAX);
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+bool ChatHandler::SetDataForCommandInTable(ChatCommand *table, const char* text, uint32 security, std::string const& help, std::string const& fullcommand)
+{
+ std::string cmd = "";
+
+ while (*text != ' ' && *text != '\0')
+ {
+ cmd += *text;
+ ++text;
+ }
+
+ while (*text == ' ') ++text;
+
+ for (uint32 i = 0; table[i].Name != NULL; i++)
+ {
+ // for data fill use full explicit command names
+ if (table[i].Name != cmd)
+ continue;
+
+ // select subcommand from child commands list (including "")
+ if (table[i].ChildCommands != NULL)
+ {
+ if (SetDataForCommandInTable(table[i].ChildCommands, text, security, help, fullcommand))
+ return true;
+ else if (*text)
+ return false;
+
+ // fail with "" subcommands, then use normal level up command instead
+ }
+ // expected subcommand by full name DB content
+ else if (*text)
+ {
+ sLog.outErrorDb("Table `command` have unexpected subcommand '%s' in command '%s', skip.",text,fullcommand.c_str());
+ return false;
+ }
+
+ if (table[i].SecurityLevel != security)
+ sLog.outDetail("Table `command` overwrite for command '%s' default security (%u) by %u",fullcommand.c_str(),table[i].SecurityLevel,security);
+
+ table[i].SecurityLevel = security;
+ table[i].Help = help;
+ return true;
+ }
+
+ // in case "" command let process by caller
+ if (!cmd.empty())
+ {
+ if (table == getCommandTable())
+ sLog.outErrorDb("Table `command` have not existed command '%s', skip.",cmd.c_str());
+ else
+ sLog.outErrorDb("Table `command` have not existed subcommand '%s' in command '%s', skip.",cmd.c_str(),fullcommand.c_str());
+ }
+
+ return false;
+}
+
+int ChatHandler::ParseCommands(const char* text)
+{
+ ASSERT(text);
+ ASSERT(*text);
+
+ std::string fullcmd = text;
+
+ if (m_session && m_session->GetSecurity() <= SEC_PLAYER && sWorld.getConfig(CONFIG_ALLOW_PLAYER_COMMANDS) == 0)
+ return 0;
+
+ if (m_session && !m_session->HandleOnPlayerChat(text))
+ return 0;
+
+ /// chat case (.command or !command format)
+ if (m_session)
+ {
+ if (text[0] != '!' && text[0] != '.')
+ return 0;
+ }
+
+ /// ignore single . and ! in line
+ if (strlen(text) < 2)
+ return 0;
+ // original `text` can't be used. It content destroyed in command code processing.
+
+ /// ignore messages staring from many dots.
+ if ((text[0] == '.' && text[1] == '.') || (text[0] == '!' && text[1] == '!'))
+ return 0;
+
+ /// skip first . or ! (in console allowed use command with . and ! and without its)
+ if (text[0] == '!' || text[0] == '.')
+ ++text;
+
+ if (!ExecuteCommandInTable(getCommandTable(), text, fullcmd))
+ {
+ if (m_session && m_session->GetSecurity() == SEC_PLAYER)
+ return 0;
+ SendSysMessage(LANG_NO_CMD);
+ }
+ return 1;
+}
+
+bool ChatHandler::isValidChatMessage(const char* message)
+{
+/*
+
+valid examples:
+|cffa335ee|Hitem:812:0:0:0:0:0:0:0:70|h[Glowing Brightwood Staff]|h|r
+|cff808080|Hquest:2278:47|h[The Platinum Discs]|h|r
+|cffffd000|Htrade:4037:1:150:1:6AAAAAAAAAAAAAAAAAAAAAAOAADAAAAAAAAAAAAAAAAIAAAAAAAAA|h[Engineering]|h|r
+|cff4e96f7|Htalent:2232:-1|h[Taste for Blood]|h|r
+|cff71d5ff|Hspell:21563|h[Command]|h|r
+|cffffd000|Henchant:3919|h[Engineering: Rough Dynamite]|h|r
+|cffffff00|Hachievement:546:0000000000000001:0:0:0:-1:0:0:0:0|h[Safe Deposit]|h|r
+|cff66bbff|Hglyph:21:762|h[Glyph of Bladestorm]|h|r
+
+| will be escaped to ||
+*/
+
+ if (strlen(message) > 255)
+ return false;
+
+ const char validSequence[6] = "cHhhr";
+ const char* validSequenceIterator = validSequence;
+
+ // more simple checks
+ if (sWorld.getConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_SEVERITY) < 3)
+ {
+ const std::string validCommands = "cHhr|";
+
+ while (*message)
+ {
+ // find next pipe command
+ message = strchr(message, '|');
+
+ if (!message)
+ return true;
+
+ ++message;
+ char commandChar = *message;
+ if (validCommands.find(commandChar) == std::string::npos)
+ return false;
+
+ ++message;
+ // validate sequence
+ if (sWorld.getConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_SEVERITY) == 2)
+ {
+ if (commandChar == *validSequenceIterator)
+ {
+ if (validSequenceIterator == validSequence+4)
+ validSequenceIterator = validSequence;
+ else
+ ++validSequenceIterator;
+ }
+ else
+ return false;
+ }
+ }
+ return true;
+ }
+
+ std::istringstream reader(message);
+ char buffer[256];
+
+ uint32 color;
+
+ ItemPrototype const* linkedItem;
+ Quest const* linkedQuest;
+ SpellEntry const *linkedSpell;
+ AchievementEntry const* linkedAchievement;
+ ItemRandomPropertiesEntry const* itemProperty;
+ ItemRandomSuffixEntry const* itemSuffix;
+
+ while (!reader.eof())
+ {
+ if (validSequence == validSequenceIterator)
+ {
+ linkedItem = NULL;
+ linkedQuest = NULL;
+ linkedSpell = NULL;
+ linkedAchievement = NULL;
+ itemProperty = NULL;
+ itemSuffix = NULL;
+
+ reader.ignore(255, '|');
+ }
+ else if (reader.get() != '|')
+ {
+#ifdef TRINITY_DEBUG
+ sLog.outBasic("ChatHandler::isValidChatMessage sequence aborted unexpectedly");
+#endif
+ return false;
+ }
+
+ // pipe has always to be followed by at least one char
+ if (reader.peek() == '\0')
+ {
+#ifdef TRINITY_DEBUG
+ sLog.outBasic("ChatHandler::isValidChatMessage pipe followed by \\0");
+#endif
+ return false;
+ }
+
+ // no further pipe commands
+ if (reader.eof())
+ break;
+
+ char commandChar;
+ reader >> commandChar;
+
+ // | in normal messages is escaped by ||
+ if (commandChar != '|')
+ {
+ if (commandChar == *validSequenceIterator)
+ {
+ if (validSequenceIterator == validSequence+4)
+ validSequenceIterator = validSequence;
+ else
+ ++validSequenceIterator;
+ }
+ else
+ {
+#ifdef TRINITY_DEBUG
+ sLog.outBasic("ChatHandler::isValidChatMessage invalid sequence, expected %c but got %c", *validSequenceIterator, commandChar);
+#endif
+ return false;
+ }
+ }
+ else if (validSequence != validSequenceIterator)
+ {
+ // no escaped pipes in sequences
+#ifdef TRINITY_DEBUG
+ sLog.outBasic("ChatHandler::isValidChatMessage got escaped pipe in sequence");
+#endif
+ return false;
+ }
+
+ switch (commandChar)
+ {
+ case 'c':
+ color = 0;
+ // validate color, expect 8 hex chars
+ for (int i=0; i<8; i++)
+ {
+ char c;
+ reader >> c;
+ if (!c)
+ {
+#ifdef TRINITY_DEBUG
+ sLog.outBasic("ChatHandler::isValidChatMessage got \\0 while reading color in |c command");
+#endif
+ return false;
+ }
+
+ color <<= 4;
+ // check for hex char
+ if (c >= '0' && c <= '9')
+ {
+ color |= c-'0';
+ continue;
+ }
+ if (c >= 'a' && c <= 'f')
+ {
+ color |= 10+c-'a';
+ continue;
+ }
+#ifdef TRINITY_DEBUG
+ sLog.outBasic("ChatHandler::isValidChatMessage got non hex char '%c' while reading color", c);
+#endif
+ return false;
+ }
+ break;
+ case 'H':
+ // read chars up to colon = link type
+ reader.getline(buffer, 256, ':');
+
+ if (strcmp(buffer, "item") == 0)
+ {
+ // read item entry
+ reader.getline(buffer, 256, ':');
+
+ linkedItem= objmgr.GetItemPrototype(atoi(buffer));
+ if (!linkedItem)
+ {
+#ifdef TRINITY_DEBUG
+ sLog.outBasic("ChatHandler::isValidChatMessage got invalid itemID %u in |item command", atoi(buffer));
+#endif
+ return false;
+ }
+
+ if (color != ItemQualityColors[linkedItem->Quality])
+ {
+#ifdef TRINITY_DEBUG
+ sLog.outBasic("ChatHandler::isValidChatMessage linked item has color %u, but user claims %u", ItemQualityColors[linkedItem->Quality],
+ color);
+#endif
+ return false;
+ }
+
+ // the itementry is followed by several integers which describe an instance of this item
+
+ // position relative after itemEntry
+ const uint8 randomPropertyPosition = 6;
+
+ int32 propertyId = 0;
+ bool negativeNumber = false;
+ char c;
+ for (uint8 i=0; i<randomPropertyPosition; ++i)
+ {
+ propertyId = 0;
+ negativeNumber = false;
+ while ((c = reader.get()) != ':')
+ {
+ if (c >='0' && c <= '9')
+ {
+ propertyId*=10;
+ propertyId += c-'0';
+ } else if (c == '-')
+ negativeNumber = true;
+ else
+ return false;
+ }
+ }
+ if (negativeNumber)
+ propertyId *= -1;
+
+ if (propertyId > 0)
+ {
+ itemProperty = sItemRandomPropertiesStore.LookupEntry(propertyId);
+ if (!itemProperty)
+ return false;
+ }
+ else if (propertyId < 0)
+ {
+ itemSuffix = sItemRandomSuffixStore.LookupEntry(-propertyId);
+ if (!itemSuffix)
+ return false;
+ }
+
+ // ignore other integers
+ while ((c >='0' && c <= '9') || c == ':')
+ {
+ reader.ignore(1);
+ c = reader.peek();
+ }
+ }
+ else if (strcmp(buffer, "quest") == 0)
+ {
+ // no color check for questlinks, each client will adapt it anyway
+ uint32 questid= 0;
+ // read questid
+ char c = reader.peek();
+ while (c >='0' && c <= '9')
+ {
+ reader.ignore(1);
+ questid *= 10;
+ questid += c-'0';
+ c = reader.peek();
+ }
+
+ linkedQuest = objmgr.GetQuestTemplate(questid);
+
+ if (!linkedQuest)
+ {
+#ifdef MANOGS_DEBUG
+ sLog.outBasic("ChatHandler::isValidChatMessage Questtemplate %u not found", questid);
+#endif
+ return false;
+ }
+ c = reader.peek();
+ // level
+ while (c !='|' && c != '\0')
+ {
+ reader.ignore(1);
+ c = reader.peek();
+ }
+ }
+ else if (strcmp(buffer, "trade") == 0)
+ {
+ if (color != CHAT_LINK_COLOR_TRADE)
+ return false;
+
+ // read spell entry
+ reader.getline(buffer, 256, ':');
+ linkedSpell = sSpellStore.LookupEntry(atoi(buffer));
+ if (!linkedSpell)
+ return false;
+
+ char c = reader.peek();
+ // base64 encoded stuff
+ while (c !='|' && c != '\0')
+ {
+ reader.ignore(1);
+ c = reader.peek();
+ }
+ }
+ else if (strcmp(buffer, "talent") == 0)
+ {
+ // talent links are always supposed to be blue
+ if (color != CHAT_LINK_COLOR_TALENT)
+ return false;
+
+ // read talent entry
+ reader.getline(buffer, 256, ':');
+ TalentEntry const *talentInfo = sTalentStore.LookupEntry(atoi(buffer));
+ if (!talentInfo)
+ return false;
+
+ linkedSpell = sSpellStore.LookupEntry(talentInfo->RankID[0]);
+ if (!linkedSpell)
+ return false;
+
+ char c = reader.peek();
+ // skillpoints? whatever, drop it
+ while (c !='|' && c != '\0')
+ {
+ reader.ignore(1);
+ c = reader.peek();
+ }
+ }
+ else if (strcmp(buffer, "spell") == 0)
+ {
+ if (color != CHAT_LINK_COLOR_SPELL)
+ return false;
+
+ uint32 spellid = 0;
+ // read spell entry
+ char c = reader.peek();
+ while (c >='0' && c <= '9')
+ {
+ reader.ignore(1);
+ spellid *= 10;
+ spellid += c-'0';
+ c = reader.peek();
+ }
+ linkedSpell = sSpellStore.LookupEntry(spellid);
+ if (!linkedSpell)
+ return false;
+ }
+ else if (strcmp(buffer, "enchant") == 0)
+ {
+ if (color != CHAT_LINK_COLOR_ENCHANT)
+ return false;
+
+ uint32 spellid = 0;
+ // read spell entry
+ char c = reader.peek();
+ while (c >='0' && c <= '9')
+ {
+ reader.ignore(1);
+ spellid *= 10;
+ spellid += c-'0';
+ c = reader.peek();
+ }
+ linkedSpell = sSpellStore.LookupEntry(spellid);
+ if (!linkedSpell)
+ return false;
+ }
+ else if (strcmp(buffer, "achievement") == 0)
+ {
+ if (color != CHAT_LINK_COLOR_ACHIEVEMENT)
+ return false;
+ reader.getline(buffer, 256, ':');
+ uint32 achievementId = atoi(buffer);
+ linkedAchievement = sAchievementStore.LookupEntry(achievementId);
+
+ if (!linkedAchievement)
+ return false;
+
+ char c = reader.peek();
+ // skip progress
+ while (c !='|' && c != '\0')
+ {
+ reader.ignore(1);
+ c = reader.peek();
+ }
+ }
+ else if (strcmp(buffer, "glyph") == 0)
+ {
+ if (color != CHAT_LINK_COLOR_GLYPH)
+ return false;
+
+ // first id is slot, drop it
+ reader.getline(buffer, 256, ':');
+ uint32 glyphId = 0;
+ char c = reader.peek();
+ while (c >= '0' && c <= '9')
+ {
+ glyphId *= 10;
+ glyphId += c-'0';
+ reader.ignore(1);
+ c = reader.peek();
+ }
+ GlyphPropertiesEntry const* glyph = sGlyphPropertiesStore.LookupEntry(glyphId);
+ if (!glyph)
+ return false;
+
+ linkedSpell = sSpellStore.LookupEntry(glyph->SpellId);
+
+ if (!linkedSpell)
+ return false;
+ }
+ else
+ {
+#ifdef TRINITY_DEBUG
+ sLog.outBasic("ChatHandler::isValidChatMessage user sent unsupported link type '%s'", buffer);
+#endif
+ return false;
+ }
+ break;
+ case 'h':
+ // if h is next element in sequence, this one must contain the linked text :)
+ if (*validSequenceIterator == 'h')
+ {
+ // links start with '['
+ if (reader.get() != '[')
+ {
+#ifdef TRINITY_DEBUG
+ sLog.outBasic("ChatHandler::isValidChatMessage link caption doesn't start with '['");
+#endif
+ return false;
+ }
+ reader.getline(buffer, 256, ']');
+
+ // verify the link name
+ if (linkedSpell)
+ {
+ // spells with that flag have a prefix of "$PROFESSION: "
+ if (linkedSpell->Attributes & SPELL_ATTR_TRADESPELL)
+ {
+ // lookup skillid
+ SkillLineAbilityMapBounds bounds = spellmgr.GetSkillLineAbilityMapBounds(linkedSpell->Id);
+ if (bounds.first == bounds.second)
+ {
+ return false;
+ }
+
+ SkillLineAbilityEntry const *skillInfo = bounds.first->second;
+
+ if (!skillInfo)
+ {
+ return false;
+ }
+
+ SkillLineEntry const *skillLine = sSkillLineStore.LookupEntry(skillInfo->skillId);
+ if (!skillLine)
+ {
+ return false;
+ }
+
+ for (uint8 i=0; i<MAX_LOCALE; ++i)
+ {
+ uint32 skillLineNameLength = strlen(skillLine->name[i]);
+ if (skillLineNameLength > 0 && strncmp(skillLine->name[i], buffer, skillLineNameLength) == 0)
+ {
+ // found the prefix, remove it to perform spellname validation below
+ // -2 = strlen(": ")
+ uint32 spellNameLength = strlen(buffer)-skillLineNameLength-2;
+ memmove(buffer, buffer+skillLineNameLength+2, spellNameLength+1);
+ }
+ }
+ }
+ bool foundName = false;
+ for (uint8 i=0; i<MAX_LOCALE; ++i)
+ {
+ if (*linkedSpell->SpellName[i] && strcmp(linkedSpell->SpellName[i], buffer) == 0)
+ {
+ foundName = true;
+ break;
+ }
+ }
+ if (!foundName)
+ return false;
+ }
+ else if (linkedQuest)
+ {
+ if (linkedQuest->GetTitle() != buffer)
+ {
+ QuestLocale const *ql = objmgr.GetQuestLocale(linkedQuest->GetQuestId());
+
+ if (!ql)
+ {
+#ifdef MANOGS_DEBUG
+ sLog.outBasic("ChatHandler::isValidChatMessage default questname didn't match and there is no locale");
+#endif
+ return false;
+ }
+
+ bool foundName = false;
+ for (uint8 i=0; i<ql->Title.size(); i++)
+ {
+ if (ql->Title[i] == buffer)
+ {
+ foundName = true;
+ break;
+ }
+ }
+ if (!foundName)
+ {
+#ifdef MANOGS_DEBUG
+ sLog.outBasic("ChatHandler::isValidChatMessage no quest locale title matched")
+#endif
+ return false;
+ }
+ }
+ }
+ else if (linkedItem)
+ {
+ char* const* suffix = itemSuffix?itemSuffix->nameSuffix:(itemProperty?itemProperty->nameSuffix:NULL);
+
+ std::string expectedName = std::string(linkedItem->Name1);
+ if (suffix)
+ {
+ expectedName += " ";
+ expectedName += suffix[LOCALE_enUS];
+ }
+
+ if (expectedName != buffer)
+ {
+ ItemLocale const *il = objmgr.GetItemLocale(linkedItem->ItemId);
+
+ bool foundName = false;
+ for (uint8 i=LOCALE_koKR; i<MAX_LOCALE; ++i)
+ {
+ int8 dbIndex = objmgr.GetIndexForLocale(LocaleConstant(i));
+ if (dbIndex == -1 || il == NULL || dbIndex >= il->Name.size())
+ // using strange database/client combinations can lead to this case
+ expectedName = linkedItem->Name1;
+ else
+ expectedName = il->Name[dbIndex];
+ if (suffix)
+ {
+ expectedName += " ";
+ expectedName += suffix[i];
+ }
+ if (expectedName == buffer)
+ {
+ foundName = true;
+ break;
+ }
+ }
+ if (!foundName)
+ {
+#ifdef TRINITY_DEBUG
+ sLog.outBasic("ChatHandler::isValidChatMessage linked item name wasn't found in any localization");
+#endif
+ return false;
+ }
+ }
+ }
+ else if (linkedAchievement)
+ {
+ bool foundName = false;
+ for (uint8 i=0; i<MAX_LOCALE; ++i)
+ {
+ if (*linkedAchievement->name[i] && strcmp(linkedAchievement->name[i], buffer) == 0)
+ {
+ foundName = true;
+ break;
+ }
+ }
+ if (!foundName)
+ return false;
+ }
+ // that place should never be reached - if nothing linked has been set in |H
+ // it will return false before
+ else
+ return false;
+ }
+ break;
+ case 'r':
+ case '|':
+ // no further payload
+ break;
+ default:
+#ifdef TRINITY_DEBUG
+ sLog.outBasic("ChatHandler::isValidChatMessage got invalid command |%c", commandChar);
+#endif
+ return false;
+ }
+ }
+
+ // check if every opened sequence was also closed properly
+#ifdef TRINITY_DEBUG
+ if (validSequence != validSequenceIterator)
+ sLog.outBasic("ChatHandler::isValidChatMessage EOF in active sequence");
+#endif
+ return validSequence == validSequenceIterator;
+}
+
+bool ChatHandler::ShowHelpForSubCommands(ChatCommand *table, char const* cmd, char const* subcmd)
+{
+ std::string list;
+ for (uint32 i = 0; table[i].Name != NULL; ++i)
+ {
+ // must be available (ignore handler existence for show command with possibe avalable subcomands
+ if (!isAvailable(table[i]))
+ continue;
+
+ /// for empty subcmd show all available
+ if (*subcmd && !hasStringAbbr(table[i].Name, subcmd))
+ continue;
+
+ if (m_session)
+ list += "\n ";
+ else
+ list += "\n\r ";
+
+ list += table[i].Name;
+
+ if (table[i].ChildCommands)
+ list += " ...";
+ }
+
+ if (list.empty())
+ return false;
+
+ if (table == getCommandTable())
+ {
+ SendSysMessage(LANG_AVIABLE_CMD);
+ PSendSysMessage("%s",list.c_str());
+ }
+ else
+ PSendSysMessage(LANG_SUBCMDS_LIST,cmd,list.c_str());
+
+ return true;
+}
+
+bool ChatHandler::ShowHelpForCommand(ChatCommand *table, const char* cmd)
+{
+ if (*cmd)
+ {
+ for (uint32 i = 0; table[i].Name != NULL; ++i)
+ {
+ // must be available (ignore handler existence for show command with possibe avalable subcomands
+ if (!isAvailable(table[i]))
+ continue;
+
+ if (!hasStringAbbr(table[i].Name, cmd))
+ continue;
+
+ // have subcommand
+ char const* subcmd = (*cmd) ? strtok(NULL, " ") : "";
+
+ if (table[i].ChildCommands && subcmd && *subcmd)
+ {
+ if (ShowHelpForCommand(table[i].ChildCommands, subcmd))
+ return true;
+ }
+
+ if (!table[i].Help.empty())
+ SendSysMessage(table[i].Help.c_str());
+
+ if (table[i].ChildCommands)
+ if (ShowHelpForSubCommands(table[i].ChildCommands,table[i].Name,subcmd ? subcmd : ""))
+ return true;
+
+ return !table[i].Help.empty();
+ }
+ }
+ else
+ {
+ for (uint32 i = 0; table[i].Name != NULL; ++i)
+ {
+ // must be available (ignore handler existence for show command with possibe avalable subcomands
+ if (!isAvailable(table[i]))
+ continue;
+
+ if (strlen(table[i].Name))
+ continue;
+
+ if (!table[i].Help.empty())
+ SendSysMessage(table[i].Help.c_str());
+
+ if (table[i].ChildCommands)
+ if (ShowHelpForSubCommands(table[i].ChildCommands,"",""))
+ return true;
+
+ return !table[i].Help.empty();
+ }
+ }
+
+ return ShowHelpForSubCommands(table,"",cmd);
+}
+
+//Note: target_guid used only in CHAT_MSG_WHISPER_INFORM mode (in this case channelName ignored)
+void ChatHandler::FillMessageData(WorldPacket *data, WorldSession* session, uint8 type, uint32 language, const char *channelName, uint64 target_guid, const char *message, Unit *speaker)
+{
+ uint32 messageLength = (message ? strlen(message) : 0) + 1;
+
+ data->Initialize(SMSG_MESSAGECHAT, 100); // guess size
+ *data << uint8(type);
+ if ((type != CHAT_MSG_CHANNEL && type != CHAT_MSG_WHISPER) || language == LANG_ADDON)
+ *data << uint32(language);
+ else
+ *data << uint32(LANG_UNIVERSAL);
+
+ switch(type)
+ {
+ case CHAT_MSG_SAY:
+ case CHAT_MSG_PARTY:
+ case CHAT_MSG_PARTY_LEADER:
+ case CHAT_MSG_RAID:
+ case CHAT_MSG_GUILD:
+ case CHAT_MSG_OFFICER:
+ case CHAT_MSG_YELL:
+ case CHAT_MSG_WHISPER:
+ case CHAT_MSG_CHANNEL:
+ case CHAT_MSG_RAID_LEADER:
+ case CHAT_MSG_RAID_WARNING:
+ case CHAT_MSG_BG_SYSTEM_NEUTRAL:
+ case CHAT_MSG_BG_SYSTEM_ALLIANCE:
+ case CHAT_MSG_BG_SYSTEM_HORDE:
+ case CHAT_MSG_BATTLEGROUND:
+ case CHAT_MSG_BATTLEGROUND_LEADER:
+ target_guid = session ? session->GetPlayer()->GetGUID() : 0;
+ break;
+ case CHAT_MSG_MONSTER_SAY:
+ case CHAT_MSG_MONSTER_PARTY:
+ case CHAT_MSG_MONSTER_YELL:
+ case CHAT_MSG_MONSTER_WHISPER:
+ case CHAT_MSG_MONSTER_EMOTE:
+ case CHAT_MSG_RAID_BOSS_WHISPER:
+ case CHAT_MSG_RAID_BOSS_EMOTE:
+ case CHAT_MSG_BATTLENET:
+ {
+ *data << uint64(speaker->GetGUID());
+ *data << uint32(0); // 2.1.0
+ *data << uint32(strlen(speaker->GetName()) + 1);
+ *data << speaker->GetName();
+ uint64 listener_guid = 0;
+ *data << uint64(listener_guid);
+ if (listener_guid && !IS_PLAYER_GUID(listener_guid))
+ {
+ *data << uint32(1); // string listener_name_length
+ *data << uint8(0); // string listener_name
+ }
+ *data << uint32(messageLength);
+ *data << message;
+ *data << uint8(0);
+ return;
+ }
+ default:
+ if (type != CHAT_MSG_WHISPER_INFORM && type != CHAT_MSG_IGNORED && type != CHAT_MSG_DND && type != CHAT_MSG_AFK)
+ target_guid = 0; // only for CHAT_MSG_WHISPER_INFORM used original value target_guid
+ break;
+ }
+
+ *data << uint64(target_guid); // there 0 for BG messages
+ *data << uint32(0); // can be chat msg group or something
+
+ if (type == CHAT_MSG_CHANNEL)
+ {
+ ASSERT(channelName);
+ *data << channelName;
+ }
+
+ *data << uint64(target_guid);
+ *data << uint32(messageLength);
+ *data << message;
+ if (session != 0 && type != CHAT_MSG_WHISPER_INFORM && type != CHAT_MSG_DND && type != CHAT_MSG_AFK)
+ *data << uint8(session->GetPlayer()->chatTag());
+ else
+ *data << uint8(0);
+}
+
+Player * ChatHandler::getSelectedPlayer()
+{
+ if (!m_session)
+ return NULL;
+
+ uint64 guid = m_session->GetPlayer()->GetSelection();
+
+ if (guid == 0)
+ return m_session->GetPlayer();
+
+ return objmgr.GetPlayer(guid);
+}
+
+Unit* ChatHandler::getSelectedUnit()
+{
+ if (!m_session)
+ return NULL;
+
+ uint64 guid = m_session->GetPlayer()->GetSelection();
+
+ if (guid == 0)
+ return m_session->GetPlayer();
+
+ return ObjectAccessor::GetUnit(*m_session->GetPlayer(),guid);
+}
+
+WorldObject *ChatHandler::getSelectedObject()
+{
+ if (!m_session)
+ return NULL;
+
+ uint64 guid = m_session->GetPlayer()->GetSelection();
+
+ if (guid == 0)
+ return GetNearbyGameObject();
+
+ return ObjectAccessor::GetUnit(*m_session->GetPlayer(),guid);
+}
+
+Creature* ChatHandler::getSelectedCreature()
+{
+ if (!m_session)
+ return NULL;
+
+ return ObjectAccessor::GetCreatureOrPetOrVehicle(*m_session->GetPlayer(),m_session->GetPlayer()->GetSelection());
+}
+
+char* ChatHandler::extractKeyFromLink(char* text, char const* linkType, char** something1)
+{
+ // skip empty
+ if (!text)
+ return NULL;
+
+ // skip spaces
+ while (*text == ' '||*text == '\t'||*text == '\b')
+ ++text;
+
+ if (!*text)
+ return NULL;
+
+ // return non link case
+ if (text[0] != '|')
+ return strtok(text, " ");
+
+ // [name] Shift-click form |color|linkType:key|h[name]|h|r
+ // or
+ // [name] Shift-click form |color|linkType:key:something1:...:somethingN|h[name]|h|r
+
+ char* check = strtok(text, "|"); // skip color
+ if (!check)
+ return NULL; // end of data
+
+ char* cLinkType = strtok(NULL, ":"); // linktype
+ if (!cLinkType)
+ return NULL; // end of data
+
+ if (strcmp(cLinkType,linkType) != 0)
+ {
+ strtok(NULL, " "); // skip link tail (to allow continue strtok(NULL,s) use after retturn from function
+ SendSysMessage(LANG_WRONG_LINK_TYPE);
+ return NULL;
+ }
+
+ char* cKeys = strtok(NULL, "|"); // extract keys and values
+ char* cKeysTail = strtok(NULL, "");
+
+ char* cKey = strtok(cKeys, ":|"); // extract key
+ if (something1)
+ *something1 = strtok(NULL, ":|"); // extract something
+
+ strtok(cKeysTail, "]"); // restart scan tail and skip name with possible spaces
+ strtok(NULL, " "); // skip link tail (to allow continue strtok(NULL,s) use after return from function
+ return cKey;
+}
+
+char* ChatHandler::extractKeyFromLink(char* text, char const* const* linkTypes, int* found_idx, char** something1)
+{
+ // skip empty
+ if (!text)
+ return NULL;
+
+ // skip spaces
+ while (*text == ' '||*text == '\t'||*text == '\b')
+ ++text;
+
+ if (!*text)
+ return NULL;
+
+ // return non link case
+ if (text[0] != '|')
+ return strtok(text, " ");
+
+ // [name] Shift-click form |color|linkType:key|h[name]|h|r
+ // or
+ // [name] Shift-click form |color|linkType:key:something1:...:somethingN|h[name]|h|r
+ // or
+ // [name] Shift-click form |linkType:key|h[name]|h|r
+
+ char* tail;
+
+ if (text[1] == 'c')
+ {
+ char* check = strtok(text, "|"); // skip color
+ if (!check)
+ return NULL; // end of data
+
+ tail = strtok(NULL, ""); // tail
+ }
+ else
+ tail = text+1; // skip first |
+
+ char* cLinkType = strtok(tail, ":"); // linktype
+ if (!cLinkType)
+ return NULL; // end of data
+
+ for (int i = 0; linkTypes[i]; ++i)
+ {
+ if (strcmp(cLinkType,linkTypes[i]) == 0)
+ {
+ char* cKeys = strtok(NULL, "|"); // extract keys and values
+ char* cKeysTail = strtok(NULL, "");
+
+ char* cKey = strtok(cKeys, ":|"); // extract key
+ if (something1)
+ *something1 = strtok(NULL, ":|"); // extract something
+
+ strtok(cKeysTail, "]"); // restart scan tail and skip name with possible spaces
+ strtok(NULL, " "); // skip link tail (to allow continue strtok(NULL,s) use after return from function
+ if (found_idx)
+ *found_idx = i;
+ return cKey;
+ }
+ }
+
+ strtok(NULL, " "); // skip link tail (to allow continue strtok(NULL,s) use after return from function
+ SendSysMessage(LANG_WRONG_LINK_TYPE);
+ return NULL;
+}
+
+char const *fmtstring(char const *format, ...)
+{
+ va_list argptr;
+ #define MAX_FMT_STRING 32000
+ static char temp_buffer[MAX_FMT_STRING];
+ static char string[MAX_FMT_STRING];
+ static int index = 0;
+ char *buf;
+ int len;
+
+ va_start(argptr, format);
+ vsnprintf(temp_buffer,MAX_FMT_STRING, format, argptr);
+ va_end(argptr);
+
+ len = strlen(temp_buffer);
+
+ if (len >= MAX_FMT_STRING)
+ return "ERROR";
+
+ if (len + index >= MAX_FMT_STRING-1)
+ {
+ index = 0;
+ }
+
+ buf = &string[index];
+ memcpy(buf, temp_buffer, len+1);
+
+ index += len + 1;
+
+ return buf;
+}
+
+GameObject* ChatHandler::GetNearbyGameObject()
+{
+ if (!m_session)
+ return NULL;
+
+ Player* pl = m_session->GetPlayer();
+ GameObject* obj = NULL;
+ Trinity::NearestGameObjectCheck check(*pl);
+ Trinity::GameObjectLastSearcher<Trinity::NearestGameObjectCheck> searcher(pl, obj, check);
+ pl->VisitNearbyGridObject(999, searcher);
+ return obj;
+}
+
+GameObject* ChatHandler::GetObjectGlobalyWithGuidOrNearWithDbGuid(uint32 lowguid,uint32 entry)
+{
+ if (!m_session)
+ return NULL;
+
+ Player* pl = m_session->GetPlayer();
+
+ GameObject* obj = pl->GetMap()->GetGameObject(MAKE_NEW_GUID(lowguid, entry, HIGHGUID_GAMEOBJECT));
+
+ if (!obj && objmgr.GetGOData(lowguid)) // guid is DB guid of object
+ {
+ // search near player then
+ CellPair p(Trinity::ComputeCellPair(pl->GetPositionX(), pl->GetPositionY()));
+ Cell cell(p);
+ cell.data.Part.reserved = ALL_DISTRICT;
+
+ Trinity::GameObjectWithDbGUIDCheck go_check(*pl,lowguid);
+ Trinity::GameObjectSearcher<Trinity::GameObjectWithDbGUIDCheck> checker(pl,obj,go_check);
+
+ TypeContainerVisitor<Trinity::GameObjectSearcher<Trinity::GameObjectWithDbGUIDCheck>, GridTypeMapContainer > object_checker(checker);
+ cell.Visit(p, object_checker, *pl->GetMap());
+ }
+
+ return obj;
+}
+
+enum SpellLinkType
+{
+ SPELL_LINK_SPELL = 0,
+ SPELL_LINK_TALENT = 1,
+ SPELL_LINK_ENCHANT = 2,
+ SPELL_LINK_TRADE = 3,
+ SPELL_LINK_GLYPH = 4
+};
+
+static char const* const spellKeys[] =
+{
+ "Hspell", // normal spell
+ "Htalent", // talent spell
+ "Henchant", // enchanting recipe spell
+ "Htrade", // profession/skill spell
+ "Hglyph", // glyph
+ 0
+};
+
+uint32 ChatHandler::extractSpellIdFromLink(char* text)
+{
+ // number or [name] Shift-click form |color|Henchant:recipe_spell_id|h[prof_name: recipe_name]|h|r
+ // number or [name] Shift-click form |color|Hglyph:glyph_slot_id:glyph_prop_id|h[%s]|h|r
+ // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
+ // number or [name] Shift-click form |color|Htalent:talent_id,rank|h[name]|h|r
+ // number or [name] Shift-click form |color|Htrade:spell_id,skill_id,max_value,cur_value|h[name]|h|r
+ int type = 0;
+ char* param1_str = NULL;
+ char* idS = extractKeyFromLink(text,spellKeys,&type,&param1_str);
+ if (!idS)
+ return 0;
+
+ uint32 id = (uint32)atol(idS);
+
+ switch(type)
+ {
+ case SPELL_LINK_SPELL:
+ return id;
+ case SPELL_LINK_TALENT:
+ {
+ // talent
+ TalentEntry const* talentEntry = sTalentStore.LookupEntry(id);
+ if (!talentEntry)
+ return 0;
+
+ int32 rank = param1_str ? (uint32)atol(param1_str) : 0;
+ if (rank >= MAX_TALENT_RANK)
+ return 0;
+
+ if (rank < 0)
+ rank = 0;
+
+ return talentEntry->RankID[rank];
+ }
+ case SPELL_LINK_ENCHANT:
+ case SPELL_LINK_TRADE:
+ return id;
+ case SPELL_LINK_GLYPH:
+ {
+ uint32 glyph_prop_id = param1_str ? (uint32)atol(param1_str) : 0;
+
+ GlyphPropertiesEntry const* glyphPropEntry = sGlyphPropertiesStore.LookupEntry(glyph_prop_id);
+ if (!glyphPropEntry)
+ return 0;
+
+ return glyphPropEntry->SpellId;
+ }
+ }
+
+ // unknown type?
+ return 0;
+}
+
+GameTele const* ChatHandler::extractGameTeleFromLink(char* text)
+{
+ // id, or string, or [name] Shift-click form |color|Htele:id|h[name]|h|r
+ char* cId = extractKeyFromLink(text,"Htele");
+ if (!cId)
+ return false;
+
+ // id case (explicit or from shift link)
+ if (cId[0] >= '0' || cId[0] >= '9')
+ if (uint32 id = atoi(cId))
+ return objmgr.GetGameTele(id);
+
+ return objmgr.GetGameTele(cId);
+}
+
+enum GuidLinkType
+{
+ SPELL_LINK_PLAYER = 0, // must be first for selection in not link case
+ SPELL_LINK_CREATURE = 1,
+ SPELL_LINK_GAMEOBJECT = 2
+};
+
+static char const* const guidKeys[] =
+{
+ "Hplayer",
+ "Hcreature",
+ "Hgameobject",
+ 0
+};
+
+uint64 ChatHandler::extractGuidFromLink(char* text)
+{
+ int type = 0;
+
+ // |color|Hcreature:creature_guid|h[name]|h|r
+ // |color|Hgameobject:go_guid|h[name]|h|r
+ // |color|Hplayer:name|h[name]|h|r
+ char* idS = extractKeyFromLink(text,guidKeys,&type);
+ if (!idS)
+ return 0;
+
+ switch(type)
+ {
+ case SPELL_LINK_PLAYER:
+ {
+ std::string name = idS;
+ if (!normalizePlayerName(name))
+ return 0;
+
+ if (Player* player = objmgr.GetPlayer(name.c_str()))
+ return player->GetGUID();
+
+ if (uint64 guid = objmgr.GetPlayerGUIDByName(name))
+ return guid;
+
+ return 0;
+ }
+ case SPELL_LINK_CREATURE:
+ {
+ uint32 lowguid = (uint32)atol(idS);
+
+ if (CreatureData const* data = objmgr.GetCreatureData(lowguid))
+ return MAKE_NEW_GUID(lowguid,data->id,HIGHGUID_UNIT);
+ else
+ return 0;
+ }
+ case SPELL_LINK_GAMEOBJECT:
+ {
+ uint32 lowguid = (uint32)atol(idS);
+
+ if (GameObjectData const* data = objmgr.GetGOData(lowguid))
+ return MAKE_NEW_GUID(lowguid,data->id,HIGHGUID_GAMEOBJECT);
+ else
+ return 0;
+ }
+ }
+
+ // unknown type?
+ return 0;
+}
+
+std::string ChatHandler::extractPlayerNameFromLink(char* text)
+{
+ // |color|Hplayer:name|h[name]|h|r
+ char* name_str = extractKeyFromLink(text,"Hplayer");
+ if (!name_str)
+ return "";
+
+ std::string name = name_str;
+ if (!normalizePlayerName(name))
+ return "";
+
+ return name;
+}
+
+bool ChatHandler::extractPlayerTarget(char* args, Player** player, uint64* player_guid /*=NULL*/,std::string* player_name /*= NULL*/)
+{
+ if (args && *args)
+ {
+ std::string name = extractPlayerNameFromLink(args);
+ if (name.empty())
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Player* pl = objmgr.GetPlayer(name.c_str());
+
+ // if allowed player pointer
+ if (player)
+ *player = pl;
+
+ // if need guid value from DB (in name case for check player existence)
+ uint64 guid = !pl && (player_guid || player_name) ? objmgr.GetPlayerGUIDByName(name) : 0;
+
+ // if allowed player guid (if no then only online players allowed)
+ if (player_guid)
+ *player_guid = pl ? pl->GetGUID() : guid;
+
+ if (player_name)
+ *player_name = pl || guid ? name : "";
+ }
+ else
+ {
+ Player* pl = getSelectedPlayer();
+ // if allowed player pointer
+ if (player)
+ *player = pl;
+ // if allowed player guid (if no then only online players allowed)
+ if (player_guid)
+ *player_guid = pl ? pl->GetGUID() : 0;
+
+ if (player_name)
+ *player_name = pl ? pl->GetName() : "";
+ }
+
+ // some from req. data must be provided (note: name is empty if player not exist)
+ if ((!player || !*player) && (!player_guid || !*player_guid) && (!player_name || player_name->empty()))
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ return true;
+}
+
+void ChatHandler::extractOptFirstArg(char* args, char** arg1, char** arg2)
+{
+ char* p1 = strtok(args, " ");
+ char* p2 = strtok(NULL, " ");
+
+ if (!p2)
+ {
+ p2 = p1;
+ p1 = NULL;
+ }
+
+ if (arg1)
+ *arg1 = p1;
+
+ if (arg2)
+ *arg2 = p2;
+}
+
+char* ChatHandler::extractQuotedArg(char* args)
+{
+ if (!*args)
+ return NULL;
+
+ if (*args == '"')
+ return strtok(args+1, "\"");
+ else
+ {
+ char* space = strtok(args, "\"");
+ if (!space)
+ return false;
+ return strtok(NULL, "\"");
+ }
+}
+
+bool ChatHandler::needReportToTarget(Player* chr) const
+{
+ Player* pl = m_session->GetPlayer();
+ return pl != chr && pl->IsVisibleGloballyFor(chr);
+}
+
+LocaleConstant ChatHandler::GetSessionDbcLocale() const
+{
+ return m_session->GetSessionDbcLocale();
+}
+
+int ChatHandler::GetSessionDbLocaleIndex() const
+{
+ return m_session->GetSessionDbLocaleIndex();
+}
+
+const char *CliHandler::GetTrinityString(int32 entry) const
+{
+ return objmgr.GetTrinityStringForDBCLocale(entry);
+}
+
+bool CliHandler::isAvailable(ChatCommand const& cmd) const
+{
+ // skip non-console commands in console case
+ return cmd.AllowConsole;
+}
+
+void CliHandler::SendSysMessage(const char *str)
+{
+ m_print(str);
+ m_print("\r\n");
+}
+
+std::string CliHandler::GetNameLink() const
+{
+ return GetTrinityString(LANG_CONSOLE_COMMAND);
+}
+
+bool CliHandler::needReportToTarget(Player* /*chr*/) const
+{
+ return true;
+}
+
+bool ChatHandler::GetPlayerGroupAndGUIDByName(const char* cname, Player* &plr, Group* &group, uint64 &guid, bool offline)
+{
+ plr = NULL;
+ guid = 0;
+
+ if (cname)
+ {
+ std::string name = cname;
+ if (!name.empty())
+ {
+ if (!normalizePlayerName(name))
+ {
+ PSendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ plr = objmgr.GetPlayer(name.c_str());
+ if (offline)
+ guid = objmgr.GetPlayerGUIDByName(name.c_str());
+ }
+ }
+
+ if (plr)
+ {
+ group = plr->GetGroup();
+ if (!guid || !offline)
+ guid = plr->GetGUID();
+ }
+ else
+ {
+ if (getSelectedPlayer())
+ plr = getSelectedPlayer();
+ else
+ plr = m_session->GetPlayer();
+
+ if (!guid || !offline)
+ guid = plr->GetGUID();
+ group = plr->GetGroup();
+ }
+
+ return true;
+}
+
+LocaleConstant CliHandler::GetSessionDbcLocale() const
+{
+ return sWorld.GetDefaultDbcLocale();
+}
+
+int CliHandler::GetSessionDbLocaleIndex() const
+{
+ return objmgr.GetDBCLocaleIndex();
+}
diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h
new file mode 100644
index 00000000000..58e6f6214c8
--- /dev/null
+++ b/src/server/game/Chat/Chat.h
@@ -0,0 +1,654 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef TRINITYCORE_CHAT_H
+#define TRINITYCORE_CHAT_H
+
+#include "SharedDefines.h"
+
+class ChatHandler;
+class WorldSession;
+class Creature;
+class Player;
+class Unit;
+struct GameTele;
+
+class ChatCommand
+{
+ public:
+ const char * Name;
+ uint32 SecurityLevel; // function pointer required correct align (use uint32)
+ bool AllowConsole;
+ bool (ChatHandler::*Handler)(const char* args);
+ std::string Help;
+ ChatCommand * ChildCommands;
+};
+
+class ChatHandler
+{
+ public:
+ explicit ChatHandler(WorldSession* session) : m_session(session) {}
+ explicit ChatHandler(Player* player) : m_session(player->GetSession()) {}
+ ~ChatHandler() {}
+
+ static void FillMessageData(WorldPacket *data, WorldSession* session, uint8 type, uint32 language, const char *channelName, uint64 target_guid, const char *message, Unit *speaker);
+
+ void FillMessageData(WorldPacket *data, uint8 type, uint32 language, uint64 target_guid, const char* message)
+ {
+ FillMessageData(data, m_session, type, language, NULL, target_guid, message, NULL);
+ }
+
+ void FillSystemMessageData(WorldPacket *data, const char* message)
+ {
+ FillMessageData(data, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, 0, message);
+ }
+
+ static char* LineFromMessage(char*& pos) { char* start = strtok(pos,"\n"); pos = NULL; return start; }
+
+ // function with different implementation for chat/console
+ virtual const char *GetTrinityString(int32 entry) const;
+ virtual void SendSysMessage(const char *str);
+
+ void SendSysMessage(int32 entry);
+ void PSendSysMessage(const char *format, ...) ATTR_PRINTF(2,3);
+ void PSendSysMessage(int32 entry, ...);
+ std::string PGetParseString(int32 entry, ...);
+
+ int ParseCommands(const char* text);
+
+ static ChatCommand* getCommandTable();
+
+ bool isValidChatMessage(const char* msg);
+ void SendGlobalSysMessage(const char *str);
+ protected:
+ explicit ChatHandler() : m_session(NULL) {} // for CLI subclass
+
+ bool hasStringAbbr(const char* name, const char* part);
+
+ // function with different implementation for chat/console
+ virtual bool isAvailable(ChatCommand const& cmd) const;
+ virtual std::string GetNameLink() const { return GetNameLink(m_session->GetPlayer()); }
+ virtual bool needReportToTarget(Player* chr) const;
+ virtual LocaleConstant GetSessionDbcLocale() const;
+ virtual int GetSessionDbLocaleIndex() const;
+
+ bool HasLowerSecurity(Player* target, uint64 guid, bool strong = false);
+ bool HasLowerSecurityAccount(WorldSession* target, uint32 account, bool strong = false);
+
+ void SendGlobalGMSysMessage(const char *str);
+
+ static bool SetDataForCommandInTable(ChatCommand *table, const char* text, uint32 security, std::string const& help, std::string const& fullcommand);
+ bool ExecuteCommandInTable(ChatCommand *table, const char* text, const std::string& fullcommand);
+ bool ShowHelpForCommand(ChatCommand *table, const char* cmd);
+ bool ShowHelpForSubCommands(ChatCommand *table, char const* cmd, char const* subcmd);
+
+ bool HandleAccountCommand(const char* args);
+ bool HandleAccountAddonCommand(const char* args);
+ bool HandleAccountCreateCommand(const char* args);
+ bool HandleAccountDeleteCommand(const char* args);
+ bool HandleAccountLockCommand(const char* args);
+ bool HandleAccountOnlineListCommand(const char* args);
+ bool HandleAccountPasswordCommand(const char* args);
+ bool HandleAccountSetAddonCommand(const char* args);
+ bool HandleAccountSetGmLevelCommand(const char* args);
+ bool HandleAccountSetPasswordCommand(const char* args);
+
+ bool HandleAHBotOptionsCommand(const char * args);
+ bool HandleNameAnnounceCommand(const char* args);
+ bool HandleGMNameAnnounceCommand(const char* args);
+ bool HandleGMAnnounceCommand(const char* args);
+ bool HandleGMNotifyCommand(const char* args);
+
+ bool HandleBanAccountCommand(const char* args);
+ bool HandleBanCharacterCommand(const char* args);
+ bool HandleBanIPCommand(const char* args);
+ bool HandleBanInfoAccountCommand(const char* args);
+ bool HandleBanInfoCharacterCommand(const char* args);
+ bool HandleBanInfoIPCommand(const char* args);
+ bool HandleBanListAccountCommand(const char* args);
+ bool HandleBanListCharacterCommand(const char* args);
+ bool HandleBanListIPCommand(const char* args);
+
+ bool HandleCastCommand(const char *args);
+ bool HandleCastBackCommand(const char *args);
+ bool HandleCastDistCommand(const char *args);
+ bool HandleCastSelfCommand(const char *args);
+ bool HandleCastTargetCommand(const char *args);
+
+ bool HandleCharacterCustomizeCommand(const char * args);
+ bool HandleCharacterDeleteCommand(const char* args);
+ bool HandleCharacterLevelCommand(const char* args);
+ bool HandleCharacterRenameCommand(const char * args);
+ bool HandleCharacterReputationCommand(const char* args);
+ bool HandleCharacterTitlesCommand(const char* args);
+
+ bool HandleChannelSetPublic(const char *args);
+
+ bool HandleDebugAnimCommand(const char* args);
+ bool HandleDebugArenaCommand(const char * args);
+ bool HandleDebugBattlegroundCommand(const char * args);
+ bool HandleDebugGetItemStateCommand(const char * args);
+ bool HandleDebugGetLootRecipientCommand(const char * args);
+ bool HandleDebugGetValueCommand(const char* args);
+ bool HandleDebugGetItemValueCommand(const char* args);
+ bool HandleDebugMod32ValueCommand(const char* args);
+ bool HandleDebugSetAuraStateCommand(const char * args);
+ bool HandleDebugSetItemValueCommand(const char * args);
+ bool HandleDebugItemExpireCommand(const char * args);
+ bool HandleDebugSetVehicleId(const char * args);
+ bool HandleDebugEnterVehicle(const char * args);
+ bool HandleDebugSetValueCommand(const char* args);
+ bool HandleDebugSpawnVehicle(const char * args);
+ bool HandleDebugSpellCheckCommand(const char* args);
+ bool HandleDebugUpdateCommand(const char* args);
+ bool HandleDebugUpdateWorldStateCommand(const char* args);
+
+ bool HandleDebugSet32Bit(const char* args);
+ bool HandleDebugThreatList(const char * args);
+ bool HandleDebugHostileRefList(const char * args);
+ bool HandlePossessCommand(const char* args);
+ bool HandleUnPossessCommand(const char* args);
+ bool HandleBindSightCommand(const char* args);
+ bool HandleUnbindSightCommand(const char* args);
+
+ bool HandleDebugPlayCinematicCommand(const char* args);
+ bool HandleDebugPlayMovieCommand(const char* args);
+ bool HandleDebugPlaySoundCommand(const char* args);
+
+ bool HandleDebugSendBuyErrorCommand(const char* args);
+ bool HandleDebugSendChannelNotifyCommand(const char* args);
+ bool HandleDebugSendChatMsgCommand(const char* args);
+ bool HandleDebugSendEquipErrorCommand(const char* args);
+ bool HandleDebugSendLargePacketCommand(const char * args);
+ bool HandleDebugSendOpcodeCommand(const char* args);
+ bool HandleDebugSendPoiCommand(const char* args);
+ bool HandleDebugSendQuestPartyMsgCommand(const char* args);
+ bool HandleDebugSendQuestInvalidMsgCommand(const char* args);
+ bool HandleDebugSendSellErrorCommand(const char* args);
+ bool HandleDebugSendSetPhaseShiftCommand(const char * args);
+ bool HandleDebugSendSpellFailCommand(const char* args);
+
+ bool HandleEventActiveListCommand(const char* args);
+ bool HandleEventStartCommand(const char* args);
+ bool HandleEventStopCommand(const char* args);
+ bool HandleEventInfoCommand(const char* args);
+
+ bool HandleGameObjectAddCommand(const char* args);
+ bool HandleGameObjectDeleteCommand(const char* args);
+ bool HandleGOInfoCommand(const char* args);
+ bool HandleGameObjectMoveCommand(const char* args);
+ bool HandleGameObjectNearCommand(const char* args);
+ bool HandleGameObjectPhaseCommand(const char* args);
+ bool HandleGameObjectStateCommand(const char* args);
+ bool HandleGameObjectTargetCommand(const char* args);
+ bool HandleGameObjectTurnCommand(const char* args);
+
+ bool HandleGMCommand(const char* args);
+ bool HandleGMChatCommand(const char* args);
+ bool HandleGMFlyCommand(const char* args);
+ bool HandleGMListFullCommand(const char* args);
+ bool HandleGMListIngameCommand(const char* args);
+ bool HandleGMVisibleCommand(const char* args);
+
+ bool HandleGoCommand(const char* args);
+ bool HandleGoCreatureCommand(const char* args);
+ bool HandleGoGraveyardCommand(const char* args);
+ bool HandleGoGridCommand(const char* args);
+ bool HandleGoObjectCommand(const char* args);
+ bool HandleGoTaxinodeCommand(const char* args);
+ bool HandleGoTriggerCommand(const char* args);
+ bool HandleGoXYCommand(const char* args);
+ bool HandleGoXYZCommand(const char* args);
+ bool HandleGoZoneXYCommand(const char* args);
+
+ bool HandleGoTicketCommand(const char* args);
+
+ bool HandleGuildCreateCommand(const char* args);
+ bool HandleGuildInviteCommand(const char* args);
+ bool HandleGuildUninviteCommand(const char* args);
+ bool HandleGuildRankCommand(const char* args);
+ bool HandleGuildDeleteCommand(const char* args);
+
+ bool HandleHonorAddCommand(const char* args);
+ bool HandleHonorAddKillCommand(const char* args);
+ bool HandleHonorUpdateCommand(const char* args);
+
+ bool HandleInstanceListBindsCommand(const char* args);
+ bool HandleInstanceUnbindCommand(const char* args);
+ bool HandleInstanceStatsCommand(const char* args);
+ bool HandleInstanceSaveDataCommand(const char * args);
+ bool HandleInstanceOpenCommand(const char * args);
+ bool HandleInstanceCloseCommand(const char * args);
+ bool HandleInstanceOpenCloseCommand(const char * args, bool open);
+
+ bool HandleLearnCommand(const char* args);
+ bool HandleLearnAllCommand(const char* args);
+ bool HandleLearnAllGMCommand(const char* args);
+ bool HandleLearnAllCraftsCommand(const char* args);
+ bool HandleLearnAllRecipesCommand(const char* args);
+ bool HandleLearnAllDefaultCommand(const char* args);
+ bool HandleLearnAllLangCommand(const char* args);
+ bool HandleLearnAllMyClassCommand(const char* args);
+ bool HandleLearnAllMyPetTalentsCommand(const char* args);
+ bool HandleLearnAllMySpellsCommand(const char* args);
+ bool HandleLearnAllMyTalentsCommand(const char* args);
+
+ bool HandleListAurasCommand(const char * args);
+ bool HandleListCreatureCommand(const char* args);
+ bool HandleListItemCommand(const char* args);
+ bool HandleListObjectCommand(const char* args);
+
+ bool HandleLookupAreaCommand(const char* args);
+ bool HandleLookupCreatureCommand(const char* args);
+ bool HandleLookupEventCommand(const char* args);
+ bool HandleLookupFactionCommand(const char * args);
+ bool HandleLookupItemCommand(const char * args);
+ bool HandleLookupItemSetCommand(const char * args);
+ bool HandleLookupObjectCommand(const char* args);
+ bool HandleLookupPlayerIpCommand(const char* args);
+ bool HandleLookupPlayerAccountCommand(const char* args);
+ bool HandleLookupPlayerEmailCommand(const char* args);
+ bool HandleLookupQuestCommand(const char* args);
+ bool HandleLookupSkillCommand(const char* args);
+ bool HandleLookupSpellCommand(const char* args);
+ bool HandleLookupTaxiNodeCommand(const char * args);
+ bool HandleLookupTeleCommand(const char * args);
+ bool HandleLookupMapCommand(const char* args);
+ bool HandleLookupTitleCommand(const char * args);
+
+ bool HandleModifyHPCommand(const char* args);
+ bool HandleModifyManaCommand(const char* args);
+ bool HandleModifyRageCommand(const char* args);
+ bool HandleModifyRunicPowerCommand(const char* args);
+ bool HandleModifyEnergyCommand(const char* args);
+ bool HandleModifyMoneyCommand(const char* args);
+ bool HandleModifyASpeedCommand(const char* args);
+ bool HandleModifySpeedCommand(const char* args);
+ bool HandleModifyBWalkCommand(const char* args);
+ bool HandleModifyFlyCommand(const char* args);
+ bool HandleModifySwimCommand(const char* args);
+ bool HandleModifyScaleCommand(const char* args);
+ bool HandleModifyMountCommand(const char* args);
+ bool HandleModifyBitCommand(const char* args);
+ bool HandleModifyFactionCommand(const char* args);
+ bool HandleModifySpellCommand(const char* args);
+ bool HandleModifyTalentCommand (const char* args);
+ bool HandleModifyHonorCommand (const char* args);
+ bool HandleModifyRepCommand(const char* args);
+ bool HandleModifyArenaCommand(const char* args);
+ bool HandleModifyPhaseCommand(const char* args);
+ bool HandleModifyGenderCommand(const char* args);
+
+ //-----------------------Npc Commands-----------------------
+ bool HandleNpcAddCommand(const char* args);
+ bool HandleNpcAddMoveCommand(const char* args);
+ bool HandleNpcAddVendorItemCommand(const char* args);
+ bool HandleNpcAllowMovementCommand(const char* args);
+ bool HandleNpcChangeEntryCommand(const char *args);
+ bool HandleNpcChangeLevelCommand(const char* args);
+ bool HandleNpcDeleteCommand(const char* args);
+ bool HandleNpcDelVendorItemCommand(const char* args);
+ bool HandleNpcFactionIdCommand(const char* args);
+ bool HandleNpcFlagCommand(const char* args);
+ bool HandleNpcFollowCommand(const char* args);
+ bool HandleNpcInfoCommand(const char* args);
+ bool HandleNpcMoveCommand(const char* args);
+ bool HandleNpcPlayEmoteCommand(const char* args);
+ bool HandleNpcSayCommand(const char* args);
+ bool HandleNpcSetDeathStateCommand(const char* args);
+ bool HandleNpcSetModelCommand(const char* args);
+ bool HandleNpcSetMoveTypeCommand(const char* args);
+ bool HandleNpcSetPhaseCommand(const char* args);
+ bool HandleNpcSpawnDistCommand(const char* args);
+ bool HandleNpcSpawnTimeCommand(const char* args);
+ bool HandleNpcTameCommand(const char* args);
+ bool HandleNpcTextEmoteCommand(const char* args);
+ bool HandleNpcUnFollowCommand(const char* args);
+ bool HandleNpcWhisperCommand(const char* args);
+ bool HandleNpcYellCommand(const char* args);
+ bool HandleNpcAddFormationCommand(const char* args);
+ bool HandleNpcSetLinkCommand(const char* args);
+
+ //TODO: NpcCommands that needs to be fixed :
+ bool HandleNpcAddWeaponCommand(const char* args);
+ bool HandleNpcNameCommand(const char* args);
+ bool HandleNpcSubNameCommand(const char* args);
+ //----------------------------------------------------------
+
+ bool HandlePDumpLoadCommand(const char *args);
+ bool HandlePDumpWriteCommand(const char *args);
+
+ bool HandleQuestAdd(const char * args);
+ bool HandleQuestRemove(const char * args);
+ bool HandleQuestComplete(const char * args);
+
+ bool HandleReloadAllCommand(const char* args);
+ bool HandleReloadAllAchievementCommand(const char* args);
+ bool HandleReloadAllAreaCommand(const char* args);
+ bool HandleReloadAllItemCommand(const char* args);
+ bool HandleReloadAllLootCommand(const char* args);
+ bool HandleReloadAllNpcCommand(const char* args);
+ bool HandleReloadAllQuestCommand(const char* args);
+ bool HandleReloadAllScriptsCommand(const char* args);
+ bool HandleReloadAllEventAICommand(const char* args);
+ bool HandleReloadAllSpellCommand(const char* args);
+ bool HandleReloadAllLocalesCommand(const char* args);
+
+ bool HandleReloadConfigCommand(const char* args);
+
+ bool HandleReloadAccessRequirementCommand(const char* args);
+ bool HandleReloadAchievementCriteriaDataCommand(const char* args);
+ bool HandleReloadAchievementRewardCommand(const char* args);
+ bool HandleReloadAreaTriggerTavernCommand(const char* args);
+ bool HandleReloadAreaTriggerTeleportCommand(const char* args);
+ bool HandleReloadAutobroadcastCommand(const char* args);
+ bool HandleReloadEventScriptsCommand(const char* args);
+ bool HandleReloadEventAITextsCommand(const char* args);
+ bool HandleReloadEventAISummonsCommand(const char* args);
+ bool HandleReloadEventAIScriptsCommand(const char* args);
+ bool HandleReloadCommandCommand(const char* args);
+ bool HandleReloadCreatureTemplateCommand(const char* args);
+ bool HandleReloadCreatureQuestRelationsCommand(const char* args);
+ bool HandleReloadCreatureQuestInvRelationsCommand(const char* args);
+ bool HandleReloadCreatureLinkedRespawnCommand(const char* args);
+ bool HandleReloadDbScriptStringCommand(const char* args);
+ bool HandleReloadGameGraveyardZoneCommand(const char* args);
+ bool HandleReloadGameObjectScriptsCommand(const char* args);
+ bool HandleReloadGameTeleCommand(const char* args);
+ bool HandleReloadGossipMenuCommand(const char* args);
+ bool HandleReloadGossipMenuOptionCommand(const char* args);
+ bool HandleReloadGOQuestRelationsCommand(const char* args);
+ bool HandleReloadGOQuestInvRelationsCommand(const char* args);
+ bool HandleReloadItemEnchantementsCommand(const char* args);
+ bool HandleReloadLocalesAchievementRewardCommand(const char* args);
+ bool HandleReloadLocalesCreatureCommand(const char* args);
+ bool HandleReloadLocalesGameobjectCommand(const char* args);
+ bool HandleReloadLocalesItemCommand(const char* args);
+ bool HandleReloadLocalesNpcTextCommand(const char* args);
+ bool HandleReloadLocalesPageTextCommand(const char* args);
+ bool HandleReloadLocalesPointsOfInterestCommand(const char* args);
+ bool HandleReloadLocalesQuestCommand(const char* args);
+// bool HandleReloadAuctionsCommand(const char* args);
+ bool HandleReloadLootTemplatesCreatureCommand(const char* args);
+ bool HandleReloadLootTemplatesDisenchantCommand(const char* args);
+ bool HandleReloadLootTemplatesFishingCommand(const char* args);
+ bool HandleReloadLootTemplatesGameobjectCommand(const char* args);
+ bool HandleReloadLootTemplatesItemCommand(const char* args);
+ bool HandleReloadLootTemplatesMailCommand(const char* args);
+ bool HandleReloadMailLevelRewardCommand(const char* args);
+ bool HandleReloadLootTemplatesMillingCommand(const char* args);
+ bool HandleReloadLootTemplatesPickpocketingCommand(const char* args);
+ bool HandleReloadLootTemplatesProspectingCommand(const char* args);
+ bool HandleReloadLootTemplatesReferenceCommand(const char* args);
+ bool HandleReloadLootTemplatesSkinningCommand(const char* args);
+ bool HandleReloadLootTemplatesSpellCommand(const char* args);
+ bool HandleReloadTrinityStringCommand(const char* args);
+ bool HandleReloadNpcGossipCommand(const char* args);
+ bool HandleReloadNpcTrainerCommand(const char* args);
+ bool HandleReloadNpcVendorCommand(const char* args);
+ bool HandleReloadPageTextsCommand(const char* args);
+ bool HandleReloadPointsOfInterestCommand(const char* args);
+ bool HandleReloadSpellClickSpellsCommand(const char* args);
+ bool HandleReloadQuestAreaTriggersCommand(const char* args);
+ bool HandleReloadQuestEndScriptsCommand(const char* args);
+ bool HandleReloadQuestStartScriptsCommand(const char* args);
+ bool HandleReloadQuestTemplateCommand(const char* args);
+ bool HandleReloadReservedNameCommand(const char*);
+ bool HandleReloadSkillDiscoveryTemplateCommand(const char* args);
+ bool HandleReloadSkillExtraItemTemplateCommand(const char* args);
+ bool HandleReloadSkillFishingBaseLevelCommand(const char* args);
+ bool HandleReloadSpellRequiredCommand(const char* args);
+ bool HandleReloadSpellAreaCommand(const char* args);
+ bool HandleReloadSpellGroupsCommand(const char* args);
+ bool HandleReloadSpellLearnSpellCommand(const char* args);
+ bool HandleReloadSpellLinkedSpellCommand(const char* args);
+ bool HandleReloadSpellProcEventCommand(const char* args);
+ bool HandleReloadSpellBonusesCommand(const char* args);
+ bool HandleReloadSpellScriptsCommand(const char* args);
+ bool HandleReloadSpellTargetPositionCommand(const char* args);
+ bool HandleReloadSpellThreatsCommand(const char* args);
+ bool HandleReloadSpellPetAurasCommand(const char* args);
+ bool HandleReloadSpellDisabledCommand(const char* args);
+ bool HandleReloadSpellGroupStackRulesCommand(const char* args);
+ bool HandleReloadAuctionsCommand(const char* args);
+ bool HandleReloadWpScriptsCommand(const char* args);
+ bool HandleReloadConditions(const char* args);
+
+ bool HandleResetAchievementsCommand(const char * args);
+ bool HandleResetAllCommand(const char * args);
+ bool HandleResetHonorCommand(const char * args);
+ bool HandleResetLevelCommand(const char * args);
+ bool HandleResetSpellsCommand(const char * args);
+ bool HandleResetStatsCommand(const char * args);
+ bool HandleResetTalentsCommand(const char * args);
+
+ bool HandleSendItemsCommand(const char* args);
+ bool HandleSendMailCommand(const char* args);
+ bool HandleSendMessageCommand(const char * args);
+ bool HandleSendMoneyCommand(const char* args);
+
+ bool HandleServerCorpsesCommand(const char* args);
+ bool HandleServerExitCommand(const char* args);
+ bool HandleServerIdleRestartCommand(const char* args);
+ bool HandleServerIdleShutDownCommand(const char* args);
+ bool HandleServerInfoCommand(const char* args);
+ bool HandleServerMotdCommand(const char* args);
+ bool HandleServerPLimitCommand(const char* args);
+ bool HandleServerRestartCommand(const char* args);
+ bool HandleServerSetLogLevelCommand(const char* args);
+ bool HandleServerSetMotdCommand(const char* args);
+ bool HandleServerShutDownCommand(const char* args);
+ bool HandleServerShutDownCancelCommand(const char* args);
+ bool HandleServerSetClosedCommand(const char* args);
+
+ bool HandleServerSetLogFileLevelCommand(const char* args);
+ bool HandleServerSetDiffTimeCommand(const char* args);
+
+ bool HandleTeleCommand(const char * args);
+ bool HandleTeleAddCommand(const char * args);
+ bool HandleTeleDelCommand(const char * args);
+ bool HandleTeleGroupCommand(const char* args);
+ bool HandleTeleNameCommand(const char* args);
+
+ bool HandleTitlesAddCommand(const char* args);
+ bool HandleTitlesCurrentCommand(const char* args);
+ bool HandleTitlesRemoveCommand(const char* args);
+ bool HandleTitlesSetMaskCommand(const char* args);
+
+ bool HandleUnBanAccountCommand(const char* args);
+ bool HandleUnBanCharacterCommand(const char* args);
+ bool HandleUnBanIPCommand(const char* args);
+
+ bool HandleWpAddCommand(const char* args);
+ bool HandleWpLoadPathCommand(const char* args);
+ bool HandleWpUnLoadPathCommand(const char* args);
+ bool HandleWpModifyCommand(const char* args);
+ bool HandleWpEventCommand(const char* args);
+ bool HandleWpShowCommand(const char* args);
+ bool HandleReloadAllPaths(const char *args);
+
+ bool HandleHelpCommand(const char* args);
+ bool HandleCommandsCommand(const char* args);
+ bool HandleStartCommand(const char* args);
+ bool HandleDismountCommand(const char* args);
+ bool HandleSaveCommand(const char* args);
+
+ bool HandleNamegoCommand(const char* args);
+ bool HandleGonameCommand(const char* args);
+ bool HandleGroupgoCommand(const char* args);
+ bool HandleRecallCommand(const char* args);
+ bool HandleAnnounceCommand(const char* args);
+ bool HandleNotifyCommand(const char* args);
+ bool HandleGPSCommand(const char* args);
+ bool HandleTaxiCheatCommand(const char* args);
+ bool HandleWhispersCommand(const char* args);
+ bool HandleModifyDrunkCommand(const char* args);
+
+ bool HandleGUIDCommand(const char* args);
+ bool HandleItemMoveCommand(const char* args);
+ bool HandleDeMorphCommand(const char* args);
+ bool HandlePInfoCommand(const char* args);
+ bool HandleMuteCommand(const char* args);
+ bool HandleUnmuteCommand(const char* args);
+ bool HandleMovegensCommand(const char* args);
+ bool HandleFreezeCommand(const char *args);
+ bool HandleUnFreezeCommand(const char *args);
+ bool HandleListFreezeCommand(const char* args);
+
+ bool HandleCooldownCommand(const char* args);
+ bool HandleUnLearnCommand(const char* args);
+ bool HandleGetDistanceCommand(const char* args);
+ bool HandleModifyStandStateCommand(const char* args);
+ bool HandleDieCommand(const char* args);
+ bool HandleDamageCommand(const char *args);
+ bool HandleReviveCommand(const char* args);
+ bool HandleModifyMorphCommand(const char* args);
+ bool HandleAuraCommand(const char* args);
+ bool HandleUnAuraCommand(const char* args);
+ bool HandleLinkGraveCommand(const char* args);
+ bool HandleNearGraveCommand(const char* args);
+ bool HandleActivateObjectCommand(const char* args);
+ bool HandleSpawnTransportCommand(const char* args);
+ bool HandleExploreCheatCommand(const char* args);
+ bool HandleHoverCommand(const char* args);
+ bool HandleWaterwalkCommand(const char* args);
+ bool HandleLevelUpCommand(const char* args);
+ bool HandleShowAreaCommand(const char* args);
+ bool HandleHideAreaCommand(const char* args);
+ bool HandleAddItemCommand(const char* args);
+ bool HandleAddItemSetCommand(const char* args);
+ bool HandlePetTpCommand(const char* args);
+ bool HandlePetUnlearnCommand(const char* args);
+ bool HandlePetLearnCommand(const char* args);
+ bool HandleCreatePetCommand(const char* args);
+
+ bool HandleGroupLeaderCommand(const char* args);
+ bool HandleGroupDisbandCommand(const char* args);
+ bool HandleGroupRemoveCommand(const char* args);
+
+ bool HandleBankCommand(const char* args);
+ bool HandleChangeWeather(const char* args);
+ bool HandleKickPlayerCommand(const char * args);
+
+ // GM ticket command handlers
+ bool HandleGMTicketListCommand(const char* args);
+ bool HandleGMTicketListOnlineCommand(const char* args);
+ bool HandleGMTicketListClosedCommand(const char* args);
+ bool HandleGMTicketGetByIdCommand(const char* args);
+ bool HandleGMTicketGetByNameCommand(const char* args);
+ bool HandleGMTicketCloseByIdCommand(const char* args);
+ bool HandleGMTicketAssignToCommand(const char* args);
+ bool HandleGMTicketUnAssignCommand(const char* args);
+ bool HandleGMTicketCommentCommand(const char* args);
+ bool HandleGMTicketDeleteByIdCommand(const char* args);
+ bool HandleGMTicketReloadCommand(const char*);
+
+ bool HandleMaxSkillCommand(const char* args);
+ bool HandleSetSkillCommand(const char* args);
+ bool HandleRespawnCommand(const char* args);
+ bool HandleComeToMeCommand(const char *args);
+ bool HandleCombatStopCommand(const char *args);
+
+ /*bool HandleCharDeleteCommand(const char *args);
+ bool HandleSendMessageCommand(const char * args);*/
+
+ bool HandleFlushArenaPointsCommand(const char *args);
+ bool HandlePlayAllCommand(const char* args);
+ bool HandleRepairitemsCommand(const char* args);
+
+ bool HandleTempGameObjectCommand(const char* args);
+ bool HandleTempAddSpwCommand(const char* args);
+
+ //! Development Commands
+
+ /*bool HandleQuestAdd(const char * args);
+ bool HandleQuestRemove(const char * args);
+ bool HandleQuestComplete(const char * args);*/
+
+ //bool HandleSet32Bit(const char* args);
+ bool HandleSaveAllCommand(const char* args);
+
+ Player* getSelectedPlayer();
+ Creature* getSelectedCreature();
+ Unit* getSelectedUnit();
+ WorldObject* getSelectedObject();
+
+ char* extractKeyFromLink(char* text, char const* linkType, char** something1 = NULL);
+ char* extractKeyFromLink(char* text, char const* const* linkTypes, int* found_idx, char** something1 = NULL);
+
+ // if args have single value then it return in arg2 and arg1 == NULL
+ void extractOptFirstArg(char* args, char** arg1, char** arg2);
+ char* extractQuotedArg(char* args);
+
+ uint32 extractSpellIdFromLink(char* text);
+ uint64 extractGuidFromLink(char* text);
+ GameTele const* extractGameTeleFromLink(char* text);
+ bool GetPlayerGroupAndGUIDByName(const char* cname, Player* &plr, Group* &group, uint64 &guid, bool offline = false);
+ std::string extractPlayerNameFromLink(char* text);
+ // select by arg (name/link) or in-game selection online/offline player
+ bool extractPlayerTarget(char* args, Player** player, uint64* player_guid = NULL, std::string* player_name = NULL);
+
+ std::string playerLink(std::string const& name) const { return m_session ? "|cffffffff|Hplayer:"+name+"|h["+name+"]|h|r" : name; }
+ std::string GetNameLink(Player* chr) const { return playerLink(chr->GetName()); }
+
+ GameObject* GetNearbyGameObject();
+ GameObject* GetObjectGlobalyWithGuidOrNearWithDbGuid(uint32 lowguid,uint32 entry);
+
+ // Utility methods for commands
+ bool LookupPlayerSearchCommand(QueryResult_AutoPtr result, int32 limit);
+ bool HandleBanListHelper(QueryResult_AutoPtr result);
+ bool HandleBanHelper(BanMode mode,char const* args);
+ bool HandleBanInfoHelper(uint32 accountid, char const* accountname);
+ bool HandleUnBanHelper(BanMode mode,char const* args);
+ void HandleCharacterLevel(Player* player, uint64 player_guid, uint32 oldlevel, uint32 newlevel);
+ void HandleLearnSkillRecipesHelper(Player* player,uint32 skill_id);
+
+ void SetSentErrorMessage(bool val){ sentErrorMessage = val;};
+ private:
+ WorldSession * m_session; // != NULL for chat command call and NULL for CLI command
+
+ // common global flag
+ static bool load_command_table;
+ bool sentErrorMessage;
+};
+
+class CliHandler : public ChatHandler
+{
+ public:
+ typedef void Print(char const*);
+ explicit CliHandler(Print* zprint) : m_print(zprint) {}
+
+ // overwrite functions
+ const char *GetTrinityString(int32 entry) const;
+ bool isAvailable(ChatCommand const& cmd) const;
+ void SendSysMessage(const char *str);
+ std::string GetNameLink() const;
+ bool needReportToTarget(Player* chr) const;
+ LocaleConstant GetSessionDbcLocale() const;
+ int GetSessionDbLocaleIndex() const;
+
+ private:
+ Print* m_print;
+};
+
+char const *fmtstring(char const *format, ...);
+
+#endif
+
diff --git a/src/server/game/Chat/ChatHandler.cpp b/src/server/game/Chat/ChatHandler.cpp
new file mode 100644
index 00000000000..88e2b5473a5
--- /dev/null
+++ b/src/server/game/Chat/ChatHandler.cpp
@@ -0,0 +1,756 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "Common.h"
+#include "ObjectAccessor.h"
+#include "ObjectMgr.h"
+#include "World.h"
+#include "WorldPacket.h"
+#include "WorldSession.h"
+#include "Database/DatabaseEnv.h"
+
+#include "CellImpl.h"
+#include "Chat.h"
+#include "ChannelMgr.h"
+#include "GridNotifiersImpl.h"
+#include "Group.h"
+#include "Guild.h"
+#include "Language.h"
+#include "Log.h"
+#include "Opcodes.h"
+#include "Player.h"
+#include "SpellAuras.h"
+#include "SpellAuraEffects.h"
+#include "Util.h"
+
+bool WorldSession::processChatmessageFurtherAfterSecurityChecks(std::string& msg, uint32 lang)
+{
+ if (lang != LANG_ADDON)
+ {
+ // strip invisible characters for non-addon messages
+ if (sWorld.getConfig(CONFIG_CHAT_FAKE_MESSAGE_PREVENTING))
+ stripLineInvisibleChars(msg);
+
+ if (sWorld.getConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_SEVERITY) && GetSecurity() < SEC_MODERATOR
+ && !ChatHandler(this).isValidChatMessage(msg.c_str()))
+ {
+ sLog.outError("Player %s (GUID: %u) sent a chatmessage with an invalid link: %s", GetPlayer()->GetName(),
+ GetPlayer()->GetGUIDLow(), msg.c_str());
+ if (sWorld.getConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_KICK))
+ KickPlayer();
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void WorldSession::HandleMessagechatOpcode(WorldPacket & recv_data)
+{
+ uint32 type;
+ uint32 lang;
+
+ recv_data >> type;
+ recv_data >> lang;
+
+ if (type >= MAX_CHAT_MSG_TYPE)
+ {
+ sLog.outError("CHAT: Wrong message type received: %u", type);
+ return;
+ }
+
+ //sLog.outDebug("CHAT: packet received. type %u, lang %u", type, lang);
+
+ // prevent talking at unknown language (cheating)
+ LanguageDesc const* langDesc = GetLanguageDescByID(lang);
+ if (!langDesc)
+ {
+ SendNotification(LANG_UNKNOWN_LANGUAGE);
+ return;
+ }
+ if (langDesc->skill_id != 0 && !_player->HasSkill(langDesc->skill_id))
+ {
+ // also check SPELL_AURA_COMPREHEND_LANGUAGE (client offers option to speak in that language)
+ Unit::AuraEffectList const& langAuras = _player->GetAuraEffectsByType(SPELL_AURA_COMPREHEND_LANGUAGE);
+ bool foundAura = false;
+ for (Unit::AuraEffectList::const_iterator i = langAuras.begin(); i != langAuras.end(); ++i)
+ {
+ if ((*i)->GetMiscValue() == int32(lang))
+ {
+ foundAura = true;
+ break;
+ }
+ }
+ if (!foundAura)
+ {
+ SendNotification(LANG_NOT_LEARNED_LANGUAGE);
+ return;
+ }
+ }
+
+ if (lang == LANG_ADDON)
+ {
+ if (sWorld.getConfig(CONFIG_CHATLOG_ADDON))
+ {
+ std::string msg = "";
+ recv_data >> msg;
+
+ if (msg.empty())
+ {
+ sLog.outDebug("Player %s send empty addon msg", GetPlayer()->GetName());
+ return;
+ }
+
+ sLog.outChat("[ADDON] Player %s sends: %s",
+ GetPlayer()->GetName(), msg.c_str());
+ }
+
+ // Disabled addon channel?
+ if (!sWorld.getConfig(CONFIG_ADDON_CHANNEL))
+ return;
+ }
+ // LANG_ADDON should not be changed nor be affected by flood control
+ else
+ {
+ // send in universal language if player in .gmon mode (ignore spell effects)
+ if (_player->isGameMaster())
+ lang = LANG_UNIVERSAL;
+ else
+ {
+ // send in universal language in two side iteration allowed mode
+ if (sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT))
+ lang = LANG_UNIVERSAL;
+ else
+ {
+ switch(type)
+ {
+ case CHAT_MSG_PARTY:
+ case CHAT_MSG_RAID:
+ case CHAT_MSG_RAID_LEADER:
+ case CHAT_MSG_RAID_WARNING:
+ // allow two side chat at group channel if two side group allowed
+ if (sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP))
+ lang = LANG_UNIVERSAL;
+ break;
+ case CHAT_MSG_GUILD:
+ case CHAT_MSG_OFFICER:
+ // allow two side chat at guild channel if two side guild allowed
+ if (sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD))
+ lang = LANG_UNIVERSAL;
+ break;
+ }
+ }
+
+ // but overwrite it by SPELL_AURA_MOD_LANGUAGE auras (only single case used)
+ Unit::AuraEffectList const& ModLangAuras = _player->GetAuraEffectsByType(SPELL_AURA_MOD_LANGUAGE);
+ if (!ModLangAuras.empty())
+ lang = ModLangAuras.front()->GetMiscValue();
+ }
+
+ if (!_player->CanSpeak())
+ {
+ std::string timeStr = secsToTimeString(m_muteTime - time(NULL));
+ SendNotification(GetTrinityString(LANG_WAIT_BEFORE_SPEAKING),timeStr.c_str());
+ return;
+ }
+
+ if (type != CHAT_MSG_AFK && type != CHAT_MSG_DND)
+ GetPlayer()->UpdateSpeakTime();
+ }
+
+ if (GetPlayer()->HasAura(1852) && type != CHAT_MSG_WHISPER)
+ {
+ std::string msg="";
+ recv_data >> msg;
+
+ SendNotification(GetTrinityString(LANG_GM_SILENCE), GetPlayer()->GetName());
+ return;
+ }
+
+ switch(type)
+ {
+ case CHAT_MSG_SAY:
+ case CHAT_MSG_EMOTE:
+ case CHAT_MSG_YELL:
+ {
+ std::string msg;
+ recv_data >> msg;
+
+ if (msg.empty())
+ break;
+
+ if (ChatHandler(this).ParseCommands(msg.c_str()) > 0)
+ break;
+
+ if (_player->getLevel() < sWorld.getConfig(CONFIG_CHAT_SAY_LEVEL_REQ))
+ {
+ SendNotification(GetTrinityString(LANG_SAY_REQ), sWorld.getConfig(CONFIG_CHAT_SAY_LEVEL_REQ));
+ return;
+ }
+
+ if (!processChatmessageFurtherAfterSecurityChecks(msg, lang))
+ return;
+
+ if (msg.empty())
+ break;
+
+ if (type == CHAT_MSG_SAY)
+ GetPlayer()->Say(msg, lang);
+ else if (type == CHAT_MSG_EMOTE)
+ GetPlayer()->TextEmote(msg);
+ else if (type == CHAT_MSG_YELL)
+ GetPlayer()->Yell(msg, lang);
+ } break;
+
+ case CHAT_MSG_WHISPER:
+ {
+ std::string to, msg;
+ recv_data >> to;
+ recv_data >> msg;
+
+ if (_player->getLevel() < sWorld.getConfig(CONFIG_CHAT_WHISPER_LEVEL_REQ))
+ {
+ SendNotification(GetTrinityString(LANG_WHISPER_REQ), sWorld.getConfig(CONFIG_CHAT_WHISPER_LEVEL_REQ));
+ return;
+ }
+
+ if (!processChatmessageFurtherAfterSecurityChecks(msg, lang))
+ return;
+
+ if (msg.empty())
+ break;
+
+ if (!normalizePlayerName(to))
+ {
+ SendPlayerNotFoundNotice(to);
+ break;
+ }
+
+ Player *player = objmgr.GetPlayer(to.c_str());
+ uint32 tSecurity = GetSecurity();
+ uint32 pSecurity = player ? player->GetSession()->GetSecurity() : SEC_PLAYER;
+ if (!player || (tSecurity == SEC_PLAYER && pSecurity > SEC_PLAYER && !player->isAcceptWhispers()))
+ {
+ SendPlayerNotFoundNotice(to);
+ return;
+ }
+
+ if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT) && tSecurity == SEC_PLAYER && pSecurity == SEC_PLAYER)
+ {
+ uint32 sidea = GetPlayer()->GetTeam();
+ uint32 sideb = player->GetTeam();
+ if (sidea != sideb)
+ {
+ SendWrongFactionNotice();
+ return;
+ }
+ }
+
+ if (GetPlayer()->HasAura(1852) && !player->isGameMaster())
+ {
+ SendNotification(GetTrinityString(LANG_GM_SILENCE), GetPlayer()->GetName());
+ return;
+ }
+
+ GetPlayer()->Whisper(msg, lang, player->GetGUID());
+ } break;
+
+ case CHAT_MSG_PARTY:
+ case CHAT_MSG_PARTY_LEADER:
+ {
+ std::string msg;
+ recv_data >> msg;
+
+ if (msg.empty())
+ break;
+
+ if (ChatHandler(this).ParseCommands(msg.c_str()) > 0)
+ break;
+
+ if (!processChatmessageFurtherAfterSecurityChecks(msg, lang))
+ return;
+
+ if (msg.empty())
+ break;
+
+ // if player is in battleground, he cannot say to battleground members by /p
+ Group *group = GetPlayer()->GetOriginalGroup();
+ if (!group)
+ {
+ group = _player->GetGroup();
+ if (!group || group->isBGGroup())
+ return;
+ }
+
+ if ((type == CHAT_MSG_PARTY_LEADER) && !group->IsLeader(_player->GetGUID()))
+ return;
+
+ WorldPacket data;
+ ChatHandler::FillMessageData(&data, this, type, lang, NULL, 0, msg.c_str(), NULL);
+ group->BroadcastPacket(&data, false, group->GetMemberGroup(GetPlayer()->GetGUID()));
+
+ if (sWorld.getConfig(CONFIG_CHATLOG_PARTY))
+ sLog.outChat("[PARTY] Player %s tells group with leader %s: %s",
+ GetPlayer()->GetName(), group->GetLeaderName(), msg.c_str());
+ } break;
+
+ case CHAT_MSG_GUILD:
+ {
+ std::string msg;
+ recv_data >> msg;
+
+ if (msg.empty())
+ break;
+
+ if (ChatHandler(this).ParseCommands(msg.c_str()) > 0)
+ break;
+
+ if (!processChatmessageFurtherAfterSecurityChecks(msg, lang))
+ return;
+
+ if (msg.empty())
+ break;
+
+ if (GetPlayer()->GetGuildId())
+ {
+ Guild *guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
+
+ if (guild)
+ guild->BroadcastToGuild(this, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL);
+
+ if (lang != LANG_ADDON && sWorld.getConfig(CONFIG_CHATLOG_GUILD))
+ {
+ sLog.outChat("[GUILD] Player %s tells guild %s: %s",
+ GetPlayer()->GetName(), guild->GetName().c_str(), msg.c_str());
+ }
+ else if (lang == LANG_ADDON && sWorld.getConfig(CONFIG_CHATLOG_ADDON))
+ {
+ sLog.outChat("[ADDON] Player %s sends to guild %s: %s",
+ GetPlayer()->GetName(), guild->GetName().c_str(), msg.c_str());
+ }
+ }
+
+ break;
+ }
+ case CHAT_MSG_OFFICER:
+ {
+ std::string msg;
+ recv_data >> msg;
+
+ if (msg.empty())
+ break;
+
+ if (ChatHandler(this).ParseCommands(msg.c_str()) > 0)
+ break;
+
+ if (!processChatmessageFurtherAfterSecurityChecks(msg, lang))
+ return;
+
+ if (msg.empty())
+ break;
+
+ if (GetPlayer()->GetGuildId())
+ {
+ Guild *guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
+
+ if (guild)
+ guild->BroadcastToOfficers(this, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL);
+
+ if (sWorld.getConfig(CONFIG_CHATLOG_GUILD))
+ sLog.outChat("[OFFICER] Player %s tells guild %s officers: %s",
+ GetPlayer()->GetName(), guild->GetName().c_str(), msg.c_str());
+ }
+ break;
+ }
+ case CHAT_MSG_RAID:
+ {
+ std::string msg;
+ recv_data >> msg;
+
+ if (msg.empty())
+ break;
+
+ if (ChatHandler(this).ParseCommands(msg.c_str()) > 0)
+ break;
+
+ if (!processChatmessageFurtherAfterSecurityChecks(msg, lang))
+ return;
+
+ if (msg.empty())
+ break;
+
+ // if player is in battleground, he cannot say to battleground members by /ra
+ Group *group = GetPlayer()->GetOriginalGroup();
+ if (!group)
+ {
+ group = GetPlayer()->GetGroup();
+ if (!group || group->isBGGroup() || !group->isRaidGroup())
+ return;
+ }
+
+ WorldPacket data;
+ ChatHandler::FillMessageData(&data, this, CHAT_MSG_RAID, lang, "", 0, msg.c_str(), NULL);
+ group->BroadcastPacket(&data, false);
+
+ if (sWorld.getConfig(CONFIG_CHATLOG_RAID))
+ sLog.outChat("[RAID] Player %s tells raid with leader %s: %s",
+ GetPlayer()->GetName(), group->GetLeaderName(), msg.c_str());
+ } break;
+ case CHAT_MSG_RAID_LEADER:
+ {
+ std::string msg;
+ recv_data >> msg;
+
+ if (msg.empty())
+ break;
+
+ if (ChatHandler(this).ParseCommands(msg.c_str()) > 0)
+ break;
+
+ if (!processChatmessageFurtherAfterSecurityChecks(msg, lang))
+ return;
+
+ if (msg.empty())
+ break;
+
+ // if player is in battleground, he cannot say to battleground members by /ra
+ Group *group = GetPlayer()->GetOriginalGroup();
+ if (!group)
+ {
+ group = GetPlayer()->GetGroup();
+ if (!group || group->isBGGroup() || !group->isRaidGroup() || !group->IsLeader(_player->GetGUID()))
+ return;
+ }
+
+ WorldPacket data;
+ ChatHandler::FillMessageData(&data, this, CHAT_MSG_RAID_LEADER, lang, "", 0, msg.c_str(), NULL);
+ group->BroadcastPacket(&data, false);
+
+ if (sWorld.getConfig(CONFIG_CHATLOG_RAID))
+ sLog.outChat("[RAID] Leader player %s tells raid: %s",
+ GetPlayer()->GetName(), msg.c_str());
+ } break;
+ case CHAT_MSG_RAID_WARNING:
+ {
+ std::string msg;
+ recv_data >> msg;
+
+ if (!processChatmessageFurtherAfterSecurityChecks(msg, lang))
+ return;
+
+ if (msg.empty())
+ break;
+
+ Group *group = GetPlayer()->GetGroup();
+ if (!group || !group->isRaidGroup() || !(group->IsLeader(GetPlayer()->GetGUID()) || group->IsAssistant(GetPlayer()->GetGUID())) || group->isBGGroup())
+ return;
+
+ WorldPacket data;
+ //in battleground, raid warning is sent only to players in battleground - code is ok
+ ChatHandler::FillMessageData(&data, this, CHAT_MSG_RAID_WARNING, lang, "", 0, msg.c_str(), NULL);
+ group->BroadcastPacket(&data, false);
+
+ if (sWorld.getConfig(CONFIG_CHATLOG_RAID))
+ sLog.outChat("[RAID] Leader player %s warns raid with: %s",
+ GetPlayer()->GetName(), msg.c_str());
+ } break;
+
+ case CHAT_MSG_BATTLEGROUND:
+ {
+ std::string msg;
+ recv_data >> msg;
+
+ if (!processChatmessageFurtherAfterSecurityChecks(msg, lang))
+ return;
+
+ if (msg.empty())
+ break;
+
+ //battleground raid is always in Player->GetGroup(), never in GetOriginalGroup()
+ Group *group = GetPlayer()->GetGroup();
+ if (!group || !group->isBGGroup())
+ return;
+
+ WorldPacket data;
+ ChatHandler::FillMessageData(&data, this, CHAT_MSG_BATTLEGROUND, lang, "", 0, msg.c_str(), NULL);
+ group->BroadcastPacket(&data, false);
+
+ if (sWorld.getConfig(CONFIG_CHATLOG_BGROUND))
+ sLog.outChat("[BATTLEGROUND] Player %s tells battleground with leader %s: %s",
+ GetPlayer()->GetName(), group->GetLeaderName(), msg.c_str());
+ } break;
+
+ case CHAT_MSG_BATTLEGROUND_LEADER:
+ {
+ std::string msg;
+ recv_data >> msg;
+
+ if (!processChatmessageFurtherAfterSecurityChecks(msg, lang))
+ return;
+
+ if (msg.empty())
+ break;
+
+ // battleground raid is always in Player->GetGroup(), never in GetOriginalGroup()
+ Group *group = GetPlayer()->GetGroup();
+ if (!group || !group->isBGGroup() || !group->IsLeader(GetPlayer()->GetGUID()))
+ return;
+
+ WorldPacket data;
+ ChatHandler::FillMessageData(&data, this, CHAT_MSG_BATTLEGROUND_LEADER, lang, "", 0, msg.c_str(), NULL);
+ group->BroadcastPacket(&data, false);
+
+ if (sWorld.getConfig(CONFIG_CHATLOG_BGROUND))
+ sLog.outChat("[RAID] Leader player %s tells battleground: %s",
+ GetPlayer()->GetName(), msg.c_str());
+ } break;
+
+ case CHAT_MSG_CHANNEL:
+ {
+ std::string channel, msg;
+ recv_data >> channel;
+ recv_data >> msg;
+
+ if (!processChatmessageFurtherAfterSecurityChecks(msg, lang))
+ return;
+
+ if (_player->getLevel() < sWorld.getConfig(CONFIG_CHAT_CHANNEL_LEVEL_REQ))
+ {
+ SendNotification(GetTrinityString(LANG_CHANNEL_REQ), sWorld.getConfig(CONFIG_CHAT_CHANNEL_LEVEL_REQ));
+ return;
+ }
+
+ if (msg.empty())
+ break;
+
+ if (ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
+ {
+
+ if (Channel *chn = cMgr->GetChannel(channel, _player))
+ {
+ chn->Say(_player->GetGUID(), msg.c_str(), lang);
+
+ if ((chn->HasFlag(CHANNEL_FLAG_TRADE) ||
+ chn->HasFlag(CHANNEL_FLAG_GENERAL) ||
+ chn->HasFlag(CHANNEL_FLAG_CITY) ||
+ chn->HasFlag(CHANNEL_FLAG_LFG)) &&
+ sWorld.getConfig(CONFIG_CHATLOG_SYSCHAN))
+ sLog.outChat("[SYSCHAN] Player %s tells channel %s: %s",
+ GetPlayer()->GetName(), chn->GetName().c_str(), msg.c_str());
+ else if (sWorld.getConfig(CONFIG_CHATLOG_CHANNEL))
+ sLog.outChat("[CHANNEL] Player %s tells channel %s: %s",
+ GetPlayer()->GetName(), chn->GetName().c_str(), msg.c_str());
+ }
+ }
+ } break;
+
+ case CHAT_MSG_AFK:
+ {
+ std::string msg;
+ recv_data >> msg;
+
+ if ((msg.empty() || !_player->isAFK()) && !_player->isInCombat())
+ {
+ if (!_player->isAFK())
+ {
+ if (msg.empty())
+ msg = GetTrinityString(LANG_PLAYER_AFK_DEFAULT);
+ _player->afkMsg = msg;
+ }
+ _player->ToggleAFK();
+ if (_player->isAFK() && _player->isDND())
+ _player->ToggleDND();
+ }
+ } break;
+
+ case CHAT_MSG_DND:
+ {
+ std::string msg;
+ recv_data >> msg;
+
+ if (msg.empty() || !_player->isDND())
+ {
+ if (!_player->isDND())
+ {
+ if (msg.empty())
+ msg = GetTrinityString(LANG_PLAYER_DND_DEFAULT);
+ _player->dndMsg = msg;
+ }
+ _player->ToggleDND();
+ if (_player->isDND() && _player->isAFK())
+ _player->ToggleAFK();
+ }
+ } break;
+
+ default:
+ sLog.outError("CHAT: unknown message type %u, lang: %u", type, lang);
+ break;
+ }
+}
+
+void WorldSession::HandleEmoteOpcode(WorldPacket & recv_data)
+{
+ if (!GetPlayer()->isAlive())
+ return;
+
+ uint32 emote;
+ recv_data >> emote;
+ GetPlayer()->HandleEmoteCommand(emote);
+}
+
+namespace Trinity
+{
+ class EmoteChatBuilder
+ {
+ public:
+ EmoteChatBuilder(Player const& pl, uint32 text_emote, uint32 emote_num, Unit const* target)
+ : i_player(pl), i_text_emote(text_emote), i_emote_num(emote_num), i_target(target) {}
+
+ void operator()(WorldPacket& data, int32 loc_idx)
+ {
+ char const* nam = i_target ? i_target->GetNameForLocaleIdx(loc_idx) : NULL;
+ uint32 namlen = (nam ? strlen(nam) : 0) + 1;
+
+ data.Initialize(SMSG_TEXT_EMOTE, (20+namlen));
+ data << i_player.GetGUID();
+ data << (uint32)i_text_emote;
+ data << i_emote_num;
+ data << (uint32)namlen;
+ if (namlen > 1)
+ data.append(nam, namlen);
+ else
+ data << (uint8)0x00;
+ }
+
+ private:
+ Player const& i_player;
+ uint32 i_text_emote;
+ uint32 i_emote_num;
+ Unit const* i_target;
+ };
+} // namespace Trinity
+
+void WorldSession::HandleTextEmoteOpcode(WorldPacket & recv_data)
+{
+ if (!GetPlayer()->isAlive())
+ return;
+
+ if (!GetPlayer()->CanSpeak())
+ {
+ std::string timeStr = secsToTimeString(m_muteTime - time(NULL));
+ SendNotification(GetTrinityString(LANG_WAIT_BEFORE_SPEAKING),timeStr.c_str());
+ return;
+ }
+
+ uint32 text_emote, emoteNum;
+ uint64 guid;
+
+ recv_data >> text_emote;
+ recv_data >> emoteNum;
+ recv_data >> guid;
+
+ EmotesTextEntry const *em = sEmotesTextStore.LookupEntry(text_emote);
+ if (!em)
+ return;
+
+ uint32 emote_anim = em->textid;
+
+ switch(emote_anim)
+ {
+ case EMOTE_STATE_SLEEP:
+ case EMOTE_STATE_SIT:
+ case EMOTE_STATE_KNEEL:
+ case EMOTE_ONESHOT_NONE:
+ break;
+ default:
+ GetPlayer()->HandleEmoteCommand(emote_anim);
+ break;
+ }
+
+ Unit* unit = ObjectAccessor::GetUnit(*_player, guid);
+
+ CellPair p = Trinity::ComputeCellPair(GetPlayer()->GetPositionX(), GetPlayer()->GetPositionY());
+
+ Cell cell(p);
+ cell.data.Part.reserved = ALL_DISTRICT;
+ cell.SetNoCreate();
+
+ Trinity::EmoteChatBuilder emote_builder(*GetPlayer(), text_emote, emoteNum, unit);
+ Trinity::LocalizedPacketDo<Trinity::EmoteChatBuilder > emote_do(emote_builder);
+ Trinity::PlayerDistWorker<Trinity::LocalizedPacketDo<Trinity::EmoteChatBuilder > > emote_worker(GetPlayer(), sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), emote_do);
+ TypeContainerVisitor<Trinity::PlayerDistWorker<Trinity::LocalizedPacketDo<Trinity::EmoteChatBuilder> >, WorldTypeMapContainer> message(emote_worker);
+ cell.Visit(p, message, *GetPlayer()->GetMap(), *GetPlayer(), sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE));
+
+ GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE, text_emote, 0, unit);
+
+ //Send scripted event call
+ if (unit && unit->GetTypeId() == TYPEID_UNIT && ((Creature*)unit)->AI())
+ ((Creature*)unit)->AI()->ReceiveEmote(GetPlayer(), text_emote);
+}
+
+void WorldSession::HandleChatIgnoredOpcode(WorldPacket& recv_data)
+{
+ uint64 iguid;
+ uint8 unk;
+ //sLog.outDebug("WORLD: Received CMSG_CHAT_IGNORED");
+
+ recv_data >> iguid;
+ recv_data >> unk; // probably related to spam reporting
+
+ Player *player = objmgr.GetPlayer(iguid);
+ if (!player || !player->GetSession())
+ return;
+
+ WorldPacket data;
+ ChatHandler::FillMessageData(&data, this, CHAT_MSG_IGNORED, LANG_UNIVERSAL, NULL, GetPlayer()->GetGUID(), GetPlayer()->GetName(), NULL);
+ player->GetSession()->SendPacket(&data);
+}
+
+void WorldSession::HandleChannelDeclineInvite(WorldPacket &recvPacket)
+{
+ sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
+}
+
+void WorldSession::SendPlayerNotFoundNotice(std::string name)
+{
+ WorldPacket data(SMSG_CHAT_PLAYER_NOT_FOUND, name.size()+1);
+ data << name;
+ SendPacket(&data);
+}
+
+void WorldSession::SendPlayerAmbiguousNotice(std::string name)
+{
+ WorldPacket data(SMSG_CHAT_PLAYER_AMBIGUOUS, name.size()+1);
+ data << name;
+ SendPacket(&data);
+}
+
+void WorldSession::SendWrongFactionNotice()
+{
+ WorldPacket data(SMSG_CHAT_WRONG_FACTION, 0);
+ SendPacket(&data);
+}
+
+void WorldSession::SendChatRestrictedNotice(ChatRestrictionType restriction)
+{
+ WorldPacket data(SMSG_CHAT_RESTRICTED, 1);
+ data << uint8(restriction);
+ SendPacket(&data);
+}
diff --git a/src/server/game/Chat/Debugcmds.cpp b/src/server/game/Chat/Debugcmds.cpp
new file mode 100644
index 00000000000..ee8c623c3d0
--- /dev/null
+++ b/src/server/game/Chat/Debugcmds.cpp
@@ -0,0 +1,1127 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "Common.h"
+#include "Database/DatabaseEnv.h"
+#include "WorldPacket.h"
+#include "Vehicle.h"
+#include "Player.h"
+#include "Opcodes.h"
+#include "Chat.h"
+#include "Log.h"
+#include "Unit.h"
+#include "GossipDef.h"
+#include "Language.h"
+#include "BattleGroundMgr.h"
+#include <fstream>
+#include "ObjectMgr.h"
+#include "Cell.h"
+#include "CellImpl.h"
+#include "GridNotifiers.h"
+#include "GridNotifiersImpl.h"
+#include "SpellMgr.h"
+#include "ScriptMgr.h"
+
+bool ChatHandler::HandleDebugSendSpellFailCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ char* px = strtok((char*)args, " ");
+ if (!px)
+ return false;
+
+ uint8 failnum = (uint8)atoi(px);
+ if (failnum == 0 && *px != '0')
+ return false;
+
+ char* p1 = strtok(NULL, " ");
+ uint8 failarg1 = p1 ? (uint8)atoi(p1) : 0;
+
+ char* p2 = strtok(NULL, " ");
+ uint8 failarg2 = p2 ? (uint8)atoi(p2) : 0;
+
+ WorldPacket data(SMSG_CAST_FAILED, 5);
+ data << uint8(0);
+ data << uint32(133);
+ data << uint8(failnum);
+ if (p1 || p2)
+ data << uint32(failarg1);
+ if (p2)
+ data << uint32(failarg2);
+
+ m_session->SendPacket(&data);
+
+ return true;
+}
+
+bool ChatHandler::HandleDebugSendPoiCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ Player *pPlayer = m_session->GetPlayer();
+ Unit* target = getSelectedUnit();
+ if (!target)
+ {
+ SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
+ return true;
+ }
+
+ char* icon_text = strtok((char*)args, " ");
+ char* flags_text = strtok(NULL, " ");
+ if (!icon_text || !flags_text)
+ return false;
+
+ uint32 icon = atol(icon_text);
+ uint32 flags = atol(flags_text);
+
+ sLog.outDetail("Command : POI, NPC = %u, icon = %u flags = %u", target->GetGUIDLow(), icon,flags);
+ pPlayer->PlayerTalkClass->SendPointOfInterest(target->GetPositionX(), target->GetPositionY(), Poi_Icon(icon), flags, 30, "Test POI");
+ return true;
+}
+
+bool ChatHandler::HandleDebugSendEquipErrorCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ uint8 msg = atoi(args);
+ m_session->GetPlayer()->SendEquipError(msg, 0, 0);
+ return true;
+}
+
+bool ChatHandler::HandleDebugSendSellErrorCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ uint8 msg = atoi(args);
+ m_session->GetPlayer()->SendSellError(msg, 0, 0, 0);
+ return true;
+}
+
+bool ChatHandler::HandleDebugSendBuyErrorCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ uint8 msg = atoi(args);
+ m_session->GetPlayer()->SendBuyError(msg, 0, 0, 0);
+ return true;
+}
+
+bool ChatHandler::HandleDebugSendOpcodeCommand(const char* /*args*/)
+{
+ Unit *unit = getSelectedUnit();
+ Player *player = NULL;
+ if (!unit || (unit->GetTypeId() != TYPEID_PLAYER))
+ player = m_session->GetPlayer();
+ else
+ player = (Player*)unit;
+ if (!unit) unit = player;
+
+ std::ifstream ifs("opcode.txt");
+ if (ifs.bad())
+ return false;
+
+ uint32 opcode;
+ ifs >> opcode;
+
+ WorldPacket data(opcode, 0);
+
+ while (!ifs.eof())
+ {
+ std::string type;
+ ifs >> type;
+
+ if (type == "")
+ break;
+
+ if (type == "uint8")
+ {
+ uint16 val1;
+ ifs >> val1;
+ data << uint8(val1);
+ }
+ else if (type == "uint16")
+ {
+ uint16 val2;
+ ifs >> val2;
+ data << val2;
+ }
+ else if (type == "uint32")
+ {
+ uint32 val3;
+ ifs >> val3;
+ data << val3;
+ }
+ else if (type == "uint64")
+ {
+ uint64 val4;
+ ifs >> val4;
+ data << val4;
+ }
+ else if (type == "float")
+ {
+ float val5;
+ ifs >> val5;
+ data << val5;
+ }
+ else if (type == "string")
+ {
+ std::string val6;
+ ifs >> val6;
+ data << val6;
+ }
+ else if (type == "appitsguid")
+ {
+ data.append(unit->GetPackGUID());
+ }
+ else if (type == "appmyguid")
+ {
+ data.append(player->GetPackGUID());
+ }
+ else if (type == "appgoguid")
+ {
+ GameObject *obj = GetNearbyGameObject();
+ if (!obj)
+ {
+ PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, 0);
+ SetSentErrorMessage(true);
+ ifs.close();
+ return false;
+ }
+ data.append(obj->GetPackGUID());
+ }
+ else if (type == "goguid")
+ {
+ GameObject *obj = GetNearbyGameObject();
+ if (!obj)
+ {
+ PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, 0);
+ SetSentErrorMessage(true);
+ ifs.close();
+ return false;
+ }
+ data << uint64(obj->GetGUID());
+ }
+ else if (type == "myguid")
+ {
+ data << uint64(player->GetGUID());
+ }
+ else if (type == "itsguid")
+ {
+ data << uint64(unit->GetGUID());
+ }
+ else if (type == "pos")
+ {
+ data << unit->GetPositionX();
+ data << unit->GetPositionY();
+ data << unit->GetPositionZ();
+ }
+ else if (type == "mypos")
+ {
+ data << player->GetPositionX();
+ data << player->GetPositionY();
+ data << player->GetPositionZ();
+ }
+ else
+ {
+ sLog.outDebug("Sending opcode: unknown type '%s'", type.c_str());
+ break;
+ }
+ }
+ ifs.close();
+ sLog.outDebug("Sending opcode %u", data.GetOpcode());
+ data.hexlike();
+ player->GetSession()->SendPacket(&data);
+ PSendSysMessage(LANG_COMMAND_OPCODESENT, data.GetOpcode(), unit->GetName());
+ return true;
+}
+
+bool ChatHandler::HandleDebugUpdateWorldStateCommand(const char* args)
+{
+ char* w = strtok((char*)args, " ");
+ char* s = strtok(NULL, " ");
+
+ if (!w || !s)
+ return false;
+
+ uint32 world = (uint32)atoi(w);
+ uint32 state = (uint32)atoi(s);
+ m_session->GetPlayer()->SendUpdateWorldState(world, state);
+ return true;
+}
+
+bool ChatHandler::HandleDebugPlayCinematicCommand(const char* args)
+{
+ // USAGE: .debug play cinematic #cinematicid
+ // #cinematicid - ID decimal number from CinemaicSequences.dbc (1st column)
+ if (!*args)
+ {
+ SendSysMessage(LANG_BAD_VALUE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ uint32 dwId = atoi((char*)args);
+
+ if (!sCinematicSequencesStore.LookupEntry(dwId))
+ {
+ PSendSysMessage(LANG_CINEMATIC_NOT_EXIST, dwId);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ m_session->GetPlayer()->SendCinematicStart(dwId);
+ return true;
+}
+
+bool ChatHandler::HandleDebugPlayMovieCommand(const char* args)
+{
+ // USAGE: .debug play movie #movieid
+ // #movieid - ID decimal number from Movie.dbc (1st column)
+ if (!*args)
+ {
+ SendSysMessage(LANG_BAD_VALUE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ uint32 dwId = atoi((char*)args);
+
+ if (!sMovieStore.LookupEntry(dwId))
+ {
+ PSendSysMessage(LANG_MOVIE_NOT_EXIST, dwId);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ m_session->GetPlayer()->SendMovieStart(dwId);
+ return true;
+}
+
+//Play sound
+bool ChatHandler::HandleDebugPlaySoundCommand(const char* args)
+{
+ // USAGE: .debug playsound #soundid
+ // #soundid - ID decimal number from SoundEntries.dbc (1st column)
+ if (!*args)
+ {
+ SendSysMessage(LANG_BAD_VALUE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ uint32 dwSoundId = atoi((char*)args);
+
+ if (!sSoundEntriesStore.LookupEntry(dwSoundId))
+ {
+ PSendSysMessage(LANG_SOUND_NOT_EXIST, dwSoundId);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Unit* unit = getSelectedUnit();
+ if (!unit)
+ {
+ SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (m_session->GetPlayer()->GetSelection())
+ unit->PlayDistanceSound(dwSoundId,m_session->GetPlayer());
+ else
+ unit->PlayDirectSound(dwSoundId,m_session->GetPlayer());
+
+ PSendSysMessage(LANG_YOU_HEAR_SOUND, dwSoundId);
+ return true;
+}
+
+//Send notification in channel
+bool ChatHandler::HandleDebugSendChannelNotifyCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ const char *name = "test";
+ uint8 code = atoi(args);
+
+ WorldPacket data(SMSG_CHANNEL_NOTIFY, (1+10));
+ data << code; // notify type
+ data << name; // channel name
+ data << uint32(0);
+ data << uint32(0);
+ m_session->SendPacket(&data);
+ return true;
+}
+
+//Send notification in chat
+bool ChatHandler::HandleDebugSendChatMsgCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ const char *msg = "testtest";
+ uint8 type = atoi(args);
+ WorldPacket data;
+ ChatHandler::FillMessageData(&data, m_session, type, 0, "chan", m_session->GetPlayer()->GetGUID(), msg, m_session->GetPlayer());
+ m_session->SendPacket(&data);
+ return true;
+}
+
+bool ChatHandler::HandleDebugSendQuestPartyMsgCommand(const char* args)
+{
+ uint32 msg = atol((char*)args);
+ m_session->GetPlayer()->SendPushToPartyResponse(m_session->GetPlayer(), msg);
+ return true;
+}
+
+bool ChatHandler::HandleDebugGetLootRecipientCommand(const char* /*args*/)
+{
+ Creature* target = getSelectedCreature();
+ if (!target)
+ return false;
+
+ PSendSysMessage("loot recipient: %s", target->hasLootRecipient()?(target->GetLootRecipient()?target->GetLootRecipient()->GetName():"offline"):"no loot recipient");
+ return true;
+}
+
+bool ChatHandler::HandleDebugSendQuestInvalidMsgCommand(const char* args)
+{
+ uint32 msg = atol((char*)args);
+ m_session->GetPlayer()->SendCanTakeQuestResponse(msg);
+ return true;
+}
+
+bool ChatHandler::HandleDebugGetItemStateCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ std::string state_str = args;
+
+ ItemUpdateState state = ITEM_UNCHANGED;
+ bool list_queue = false, check_all = false;
+ if (state_str == "unchanged") state = ITEM_UNCHANGED;
+ else if (state_str == "changed") state = ITEM_CHANGED;
+ else if (state_str == "new") state = ITEM_NEW;
+ else if (state_str == "removed") state = ITEM_REMOVED;
+ else if (state_str == "queue") list_queue = true;
+ else if (state_str == "check_all") check_all = true;
+ else return false;
+
+ Player* player = getSelectedPlayer();
+ if (!player) player = m_session->GetPlayer();
+
+ if (!list_queue && !check_all)
+ {
+ state_str = "The player has the following " + state_str + " items: ";
+ SendSysMessage(state_str.c_str());
+ for (uint8 i = PLAYER_SLOT_START; i < PLAYER_SLOT_END; ++i)
+ {
+ if (i >= BUYBACK_SLOT_START && i < BUYBACK_SLOT_END)
+ continue;
+
+ Item *item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, i);
+ if (!item) continue;
+ if (!item->IsBag())
+ {
+ if (item->GetState() == state)
+ PSendSysMessage("bag: 255 slot: %d guid: %d owner: %d", item->GetSlot(), item->GetGUIDLow(), GUID_LOPART(item->GetOwnerGUID()));
+ }
+ else
+ {
+ Bag *bag = (Bag*)item;
+ for (uint8 j = 0; j < bag->GetBagSize(); ++j)
+ {
+ Item* item2 = bag->GetItemByPos(j);
+ if (item2 && item2->GetState() == state)
+ PSendSysMessage("bag: 255 slot: %d guid: %d owner: %d", item2->GetSlot(), item2->GetGUIDLow(), GUID_LOPART(item2->GetOwnerGUID()));
+ }
+ }
+ }
+ }
+
+ if (list_queue)
+ {
+ std::vector<Item *> &updateQueue = player->GetItemUpdateQueue();
+ for (size_t i = 0; i < updateQueue.size(); ++i)
+ {
+ Item *item = updateQueue[i];
+ if (!item) continue;
+
+ Bag *container = item->GetContainer();
+ uint8 bag_slot = container ? container->GetSlot() : uint8(INVENTORY_SLOT_BAG_0);
+
+ std::string st;
+ switch(item->GetState())
+ {
+ case ITEM_UNCHANGED: st = "unchanged"; break;
+ case ITEM_CHANGED: st = "changed"; break;
+ case ITEM_NEW: st = "new"; break;
+ case ITEM_REMOVED: st = "removed"; break;
+ }
+
+ PSendSysMessage("bag: %d slot: %d guid: %d - state: %s", bag_slot, item->GetSlot(), item->GetGUIDLow(), st.c_str());
+ }
+ if (updateQueue.empty())
+ PSendSysMessage("updatequeue empty");
+ }
+
+ if (check_all)
+ {
+ bool error = false;
+ std::vector<Item *> &updateQueue = player->GetItemUpdateQueue();
+ for (uint8 i = PLAYER_SLOT_START; i < PLAYER_SLOT_END; ++i)
+ {
+ if (i >= BUYBACK_SLOT_START && i < BUYBACK_SLOT_END)
+ continue;
+
+ Item *item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, i);
+ if (!item) continue;
+
+ if (item->GetSlot() != i)
+ {
+ PSendSysMessage("item at slot %d, guid %d has an incorrect slot value: %d", i, item->GetGUIDLow(), item->GetSlot());
+ error = true; continue;
+ }
+
+ if (item->GetOwnerGUID() != player->GetGUID())
+ {
+ PSendSysMessage("for the item at slot %d and itemguid %d, owner's guid (%d) and player's guid (%d) don't match!", item->GetSlot(), item->GetGUIDLow(), GUID_LOPART(item->GetOwnerGUID()), player->GetGUIDLow());
+ error = true; continue;
+ }
+
+ if (Bag *container = item->GetContainer())
+ {
+ PSendSysMessage("item at slot: %d guid: %d has a container (slot: %d, guid: %d) but shouldnt!", item->GetSlot(), item->GetGUIDLow(), container->GetSlot(), container->GetGUIDLow());
+ error = true; continue;
+ }
+
+ if (item->IsInUpdateQueue())
+ {
+ uint16 qp = item->GetQueuePos();
+ if (qp > updateQueue.size())
+ {
+ PSendSysMessage("item at slot: %d guid: %d has a queuepos (%d) larger than the update queue size! ", item->GetSlot(), item->GetGUIDLow(), qp);
+ error = true; continue;
+ }
+
+ if (updateQueue[qp] == NULL)
+ {
+ PSendSysMessage("item at slot: %d guid: %d has a queuepos (%d) that points to NULL in the queue!", item->GetSlot(), item->GetGUIDLow(), qp);
+ error = true; continue;
+ }
+
+ if (updateQueue[qp] != item)
+ {
+ PSendSysMessage("item at slot: %d guid: %d has has a queuepos (%d) that points to another item in the queue (bag: %d, slot: %d, guid: %d)", item->GetSlot(), item->GetGUIDLow(), qp, updateQueue[qp]->GetBagSlot(), updateQueue[qp]->GetSlot(), updateQueue[qp]->GetGUIDLow());
+ error = true; continue;
+ }
+ }
+ else if (item->GetState() != ITEM_UNCHANGED)
+ {
+ PSendSysMessage("item at slot: %d guid: %d is not in queue but should be (state: %d)!", item->GetSlot(), item->GetGUIDLow(), item->GetState());
+ error = true; continue;
+ }
+
+ if (item->IsBag())
+ {
+ Bag *bag = (Bag*)item;
+ for (uint8 j = 0; j < bag->GetBagSize(); ++j)
+ {
+ Item* item2 = bag->GetItemByPos(j);
+ if (!item2) continue;
+
+ if (item2->GetSlot() != j)
+ {
+ PSendSysMessage("the item in bag %d slot %d, guid %d has an incorrect slot value: %d", bag->GetSlot(), j, item2->GetGUIDLow(), item2->GetSlot());
+ error = true; continue;
+ }
+
+ if (item2->GetOwnerGUID() != player->GetGUID())
+ {
+ PSendSysMessage("for the item in bag %d at slot %d and itemguid %d, owner's guid (%d) and player's guid (%d) don't match!", bag->GetSlot(), item2->GetSlot(), item2->GetGUIDLow(), GUID_LOPART(item2->GetOwnerGUID()), player->GetGUIDLow());
+ error = true; continue;
+ }
+
+ Bag *container = item2->GetContainer();
+ if (!container)
+ {
+ PSendSysMessage("the item in bag %d at slot %d with guid %d has no container!", bag->GetSlot(), item2->GetSlot(), item2->GetGUIDLow());
+ error = true; continue;
+ }
+
+ if (container != bag)
+ {
+ PSendSysMessage("the item in bag %d at slot %d with guid %d has a different container(slot %d guid %d)!", bag->GetSlot(), item2->GetSlot(), item2->GetGUIDLow(), container->GetSlot(), container->GetGUIDLow());
+ error = true; continue;
+ }
+
+ if (item2->IsInUpdateQueue())
+ {
+ uint16 qp = item2->GetQueuePos();
+ if (qp > updateQueue.size())
+ {
+ PSendSysMessage("item in bag: %d at slot: %d guid: %d has a queuepos (%d) larger than the update queue size! ", bag->GetSlot(), item2->GetSlot(), item2->GetGUIDLow(), qp);
+ error = true; continue;
+ }
+
+ if (updateQueue[qp] == NULL)
+ {
+ PSendSysMessage("item in bag: %d at slot: %d guid: %d has a queuepos (%d) that points to NULL in the queue!", bag->GetSlot(), item2->GetSlot(), item2->GetGUIDLow(), qp);
+ error = true; continue;
+ }
+
+ if (updateQueue[qp] != item2)
+ {
+ PSendSysMessage("item in bag: %d at slot: %d guid: %d has has a queuepos (%d) that points to another item in the queue (bag: %d, slot: %d, guid: %d)", bag->GetSlot(), item2->GetSlot(), item2->GetGUIDLow(), qp, updateQueue[qp]->GetBagSlot(), updateQueue[qp]->GetSlot(), updateQueue[qp]->GetGUIDLow());
+ error = true; continue;
+ }
+ }
+ else if (item2->GetState() != ITEM_UNCHANGED)
+ {
+ PSendSysMessage("item in bag: %d at slot: %d guid: %d is not in queue but should be (state: %d)!", bag->GetSlot(), item2->GetSlot(), item2->GetGUIDLow(), item2->GetState());
+ error = true; continue;
+ }
+ }
+ }
+ }
+
+ for (size_t i = 0; i < updateQueue.size(); ++i)
+ {
+ Item *item = updateQueue[i];
+ if (!item) continue;
+
+ if (item->GetOwnerGUID() != player->GetGUID())
+ {
+ PSendSysMessage("queue(" SIZEFMTD "): for the an item (guid %d), the owner's guid (%d) and player's guid (%d) don't match!", i, item->GetGUIDLow(), GUID_LOPART(item->GetOwnerGUID()), player->GetGUIDLow());
+ error = true; continue;
+ }
+
+ if (item->GetQueuePos() != i)
+ {
+ PSendSysMessage("queue(" SIZEFMTD "): for the an item (guid %d), the queuepos doesn't match it's position in the queue!", i, item->GetGUIDLow());
+ error = true; continue;
+ }
+
+ if (item->GetState() == ITEM_REMOVED) continue;
+ Item *test = player->GetItemByPos(item->GetBagSlot(), item->GetSlot());
+
+ if (test == NULL)
+ {
+ PSendSysMessage("queue(" SIZEFMTD "): the bag(%d) and slot(%d) values for the item with guid %d are incorrect, the player doesn't have an item at that position!", i, item->GetBagSlot(), item->GetSlot(), item->GetGUIDLow());
+ error = true; continue;
+ }
+
+ if (test != item)
+ {
+ PSendSysMessage("queue(" SIZEFMTD "): the bag(%d) and slot(%d) values for the item with guid %d are incorrect, the item with guid %d is there instead!", i, item->GetBagSlot(), item->GetSlot(), item->GetGUIDLow(), test->GetGUIDLow());
+ error = true; continue;
+ }
+ }
+ if (!error)
+ SendSysMessage("All OK!");
+ }
+
+ return true;
+}
+
+bool ChatHandler::HandleDebugBattlegroundCommand(const char * /*args*/)
+{
+ sBattleGroundMgr.ToggleTesting();
+ return true;
+}
+
+bool ChatHandler::HandleDebugArenaCommand(const char * /*args*/)
+{
+ sBattleGroundMgr.ToggleArenaTesting();
+ return true;
+}
+
+bool ChatHandler::HandleDebugThreatList(const char * /*args*/)
+{
+ Creature* target = getSelectedCreature();
+ if (!target || target->isTotem() || target->isPet())
+ return false;
+
+ std::list<HostileReference*>& tlist = target->getThreatManager().getThreatList();
+ std::list<HostileReference*>::iterator itr;
+ uint32 cnt = 0;
+ PSendSysMessage("Threat list of %s (guid %u)",target->GetName(), target->GetGUIDLow());
+ for (itr = tlist.begin(); itr != tlist.end(); ++itr)
+ {
+ Unit* unit = (*itr)->getTarget();
+ if (!unit)
+ continue;
+ ++cnt;
+ PSendSysMessage(" %u. %s (guid %u) - threat %f",cnt,unit->GetName(), unit->GetGUIDLow(), (*itr)->getThreat());
+ }
+ SendSysMessage("End of threat list.");
+ return true;
+}
+
+bool ChatHandler::HandleDebugHostileRefList(const char * /*args*/)
+{
+ Unit* target = getSelectedUnit();
+ if (!target)
+ target = m_session->GetPlayer();
+ HostileReference* ref = target->getHostileRefManager().getFirst();
+ uint32 cnt = 0;
+ PSendSysMessage("Hostil reference list of %s (guid %u)",target->GetName(), target->GetGUIDLow());
+ while (ref)
+ {
+ if (Unit * unit = ref->getSource()->getOwner())
+ {
+ ++cnt;
+ PSendSysMessage(" %u. %s (guid %u) - threat %f",cnt,unit->GetName(), unit->GetGUIDLow(), ref->getThreat());
+ }
+ ref = ref->next();
+ }
+ SendSysMessage("End of hostil reference list.");
+ return true;
+}
+
+bool ChatHandler::HandleDebugSetVehicleId(const char *args)
+{
+ Unit* target = getSelectedUnit();
+ if (!target || target->IsVehicle())
+ return false;
+
+ if (!args)
+ return false;
+
+ char* i = strtok((char*)args, " ");
+ if (!i)
+ return false;
+
+ uint32 id = (uint32)atoi(i);
+ //target->SetVehicleId(id);
+ PSendSysMessage("Vehicle id set to %u", id);
+ return true;
+}
+
+bool ChatHandler::HandleDebugEnterVehicle(const char * args)
+{
+ Unit* target = getSelectedUnit();
+ if (!target || !target->IsVehicle())
+ return false;
+
+ if (!args)
+ return false;
+
+ char* i = strtok((char*)args, " ");
+ if (!i)
+ return false;
+
+ char* j = strtok(NULL, " ");
+
+ uint32 entry = (uint32)atoi(i);
+ int8 seatId = j ? (int8)atoi(j) : -1;
+
+ if (!entry)
+ m_session->GetPlayer()->EnterVehicle(target, seatId);
+ else
+ {
+ Creature *passenger = NULL;
+ Trinity::AllCreaturesOfEntryInRange check(m_session->GetPlayer(), entry, 20.0f);
+ Trinity::CreatureSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(m_session->GetPlayer(), passenger, check);
+ m_session->GetPlayer()->VisitNearbyObject(30.0f, searcher);
+ if (!passenger || passenger == target)
+ return false;
+ passenger->EnterVehicle(target, seatId);
+ }
+
+ PSendSysMessage("Unit %u entered vehicle %d", entry, (int32)seatId);
+ return true;
+}
+
+bool ChatHandler::HandleDebugSpawnVehicle(const char* args)
+{
+ if (!*args)
+ return false;
+
+ char* e = strtok((char*)args, " ");
+ char* i = strtok(NULL, " ");
+
+ if (!e)
+ return false;
+
+ uint32 entry = (uint32)atoi(e);
+
+ float x, y, z, o = m_session->GetPlayer()->GetOrientation();
+ m_session->GetPlayer()->GetClosePoint(x, y, z, m_session->GetPlayer()->GetObjectSize());
+
+ if (!i)
+ return m_session->GetPlayer()->SummonCreature(entry, x, y, z, o);
+
+ uint32 id = (uint32)atoi(i);
+
+ CreatureInfo const *ci = objmgr.GetCreatureTemplate(entry);
+
+ if (!ci)
+ return false;
+
+ VehicleEntry const *ve = sVehicleStore.LookupEntry(id);
+
+ if (!ve)
+ return false;
+
+ Creature *v = new Creature;
+
+ Map *map = m_session->GetPlayer()->GetMap();
+
+ if (!v->Create(objmgr.GenerateLowGuid(HIGHGUID_VEHICLE), map, m_session->GetPlayer()->GetPhaseMask(), entry, id, m_session->GetPlayer()->GetTeam(), x, y, z, o))
+ {
+ delete v;
+ return false;
+ }
+
+ map->Add(v->ToCreature());
+
+ return true;
+}
+
+bool ChatHandler::HandleDebugSendLargePacketCommand(const char* /*args*/)
+{
+ const char* stuffingString = "This is a dummy string to push the packet's size beyond 128000 bytes. ";
+ std::ostringstream ss;
+ while (ss.str().size() < 128000)
+ ss << stuffingString;
+ SendSysMessage(ss.str().c_str());
+ return true;
+}
+
+bool ChatHandler::HandleDebugSendSetPhaseShiftCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ uint32 PhaseShift = atoi(args);
+ m_session->SendSetPhaseShift(PhaseShift);
+ return true;
+}
+
+bool ChatHandler::HandleDebugGetItemValueCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ char* e = strtok((char*)args, " ");
+ char* f = strtok(NULL, " ");
+
+ if (!e || !f)
+ return false;
+
+ uint32 guid = (uint32)atoi(e);
+ uint32 index = (uint32)atoi(f);
+
+ Item *i = m_session->GetPlayer()->GetItemByGuid(MAKE_NEW_GUID(guid, 0, HIGHGUID_ITEM));
+
+ if (!i)
+ return false;
+
+ if (index >= i->GetValuesCount())
+ return false;
+
+ uint32 value = i->GetUInt32Value(index);
+
+ PSendSysMessage("Item %u: value at %u is %u", guid, index, value);
+
+ return true;
+}
+
+bool ChatHandler::HandleDebugSetItemValueCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ char* e = strtok((char*)args, " ");
+ char* f = strtok(NULL, " ");
+ char* g = strtok(NULL, " ");
+
+ if (!e || !f || !g)
+ return false;
+
+ uint32 guid = (uint32)atoi(e);
+ uint32 index = (uint32)atoi(f);
+ uint32 value = (uint32)atoi(g);
+
+ Item *i = m_session->GetPlayer()->GetItemByGuid(MAKE_NEW_GUID(guid, 0, HIGHGUID_ITEM));
+
+ if (!i)
+ return false;
+
+ if (index >= i->GetValuesCount())
+ return false;
+
+ i->SetUInt32Value(index, value);
+
+ return true;
+}
+
+bool ChatHandler::HandleDebugItemExpireCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ char* e = strtok((char*)args, " ");
+ if (!e)
+ return false;
+
+ uint32 guid = (uint32)atoi(e);
+
+ Item *i = m_session->GetPlayer()->GetItemByGuid(MAKE_NEW_GUID(guid, 0, HIGHGUID_ITEM));
+
+ if (!i)
+ return false;
+
+ m_session->GetPlayer()->DestroyItem(i->GetBagSlot(),i->GetSlot(), true);
+ sScriptMgr.ItemExpire(m_session->GetPlayer(),i->GetProto());
+
+ return true;
+}
+
+//show animation
+bool ChatHandler::HandleDebugAnimCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ uint32 anim_id = atoi((char*)args);
+ m_session->GetPlayer()->HandleEmoteCommand(anim_id);
+ return true;
+}
+
+bool ChatHandler::HandleDebugSetAuraStateCommand(const char* args)
+{
+ if (!*args)
+ {
+ SendSysMessage(LANG_BAD_VALUE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Unit* unit = getSelectedUnit();
+ if (!unit)
+ {
+ SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ int32 state = atoi((char*)args);
+ if (!state)
+ {
+ // reset all states
+ for (int i = 1; i <= 32; ++i)
+ unit->ModifyAuraState(AuraState(i),false);
+ return true;
+ }
+
+ unit->ModifyAuraState(AuraState(abs(state)),state > 0);
+ return true;
+}
+
+bool ChatHandler::HandleDebugSetValueCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ char* px = strtok((char*)args, " ");
+ char* py = strtok(NULL, " ");
+ char* pz = strtok(NULL, " ");
+
+ if (!px || !py)
+ return false;
+
+ WorldObject* target = getSelectedObject();
+ if (!target)
+ {
+ SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ uint64 guid = target->GetGUID();
+
+ uint32 Opcode = (uint32)atoi(px);
+ if (Opcode >= target->GetValuesCount())
+ {
+ PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, GUID_LOPART(guid), target->GetValuesCount());
+ return false;
+ }
+ uint32 iValue;
+ float fValue;
+ bool isint32 = true;
+ if (pz)
+ isint32 = (bool)atoi(pz);
+ if (isint32)
+ {
+ iValue = (uint32)atoi(py);
+ sLog.outDebug(GetTrinityString(LANG_SET_UINT), GUID_LOPART(guid), Opcode, iValue);
+ target->SetUInt32Value(Opcode , iValue);
+ PSendSysMessage(LANG_SET_UINT_FIELD, GUID_LOPART(guid), Opcode,iValue);
+ }
+ else
+ {
+ fValue = (float)atof(py);
+ sLog.outDebug(GetTrinityString(LANG_SET_FLOAT), GUID_LOPART(guid), Opcode, fValue);
+ target->SetFloatValue(Opcode , fValue);
+ PSendSysMessage(LANG_SET_FLOAT_FIELD, GUID_LOPART(guid), Opcode,fValue);
+ }
+
+ return true;
+}
+
+bool ChatHandler::HandleDebugGetValueCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ char* px = strtok((char*)args, " ");
+ char* pz = strtok(NULL, " ");
+
+ if (!px)
+ return false;
+
+ Unit* target = getSelectedUnit();
+ if (!target)
+ {
+ SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ uint64 guid = target->GetGUID();
+
+ uint32 Opcode = (uint32)atoi(px);
+ if (Opcode >= target->GetValuesCount())
+ {
+ PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, GUID_LOPART(guid), target->GetValuesCount());
+ return false;
+ }
+ uint32 iValue;
+ float fValue;
+ bool isint32 = true;
+ if (pz)
+ isint32 = (bool)atoi(pz);
+
+ if (isint32)
+ {
+ iValue = target->GetUInt32Value(Opcode);
+ sLog.outDebug(GetTrinityString(LANG_GET_UINT), GUID_LOPART(guid), Opcode, iValue);
+ PSendSysMessage(LANG_GET_UINT_FIELD, GUID_LOPART(guid), Opcode, iValue);
+ }
+ else
+ {
+ fValue = target->GetFloatValue(Opcode);
+ sLog.outDebug(GetTrinityString(LANG_GET_FLOAT), GUID_LOPART(guid), Opcode, fValue);
+ PSendSysMessage(LANG_GET_FLOAT_FIELD, GUID_LOPART(guid), Opcode, fValue);
+ }
+
+ return true;
+}
+
+bool ChatHandler::HandleDebugMod32ValueCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ char* px = strtok((char*)args, " ");
+ char* py = strtok(NULL, " ");
+
+ if (!px || !py)
+ return false;
+
+ uint32 Opcode = (uint32)atoi(px);
+ int Value = atoi(py);
+
+ if (Opcode >= m_session->GetPlayer()->GetValuesCount())
+ {
+ PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, m_session->GetPlayer()->GetGUIDLow(), m_session->GetPlayer()->GetValuesCount());
+ return false;
+ }
+
+ sLog.outDebug(GetTrinityString(LANG_CHANGE_32BIT), Opcode, Value);
+
+ int CurrentValue = (int)m_session->GetPlayer()->GetUInt32Value(Opcode);
+
+ CurrentValue += Value;
+ m_session->GetPlayer()->SetUInt32Value(Opcode , (uint32)CurrentValue);
+
+ PSendSysMessage(LANG_CHANGE_32BIT_FIELD, Opcode,CurrentValue);
+
+ return true;
+}
+
+bool ChatHandler::HandleDebugUpdateCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ uint32 updateIndex;
+ uint32 value;
+
+ char* pUpdateIndex = strtok((char*)args, " ");
+
+ Unit* chr = getSelectedUnit();
+ if (chr == NULL)
+ {
+ SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (!pUpdateIndex)
+ {
+ return true;
+ }
+ updateIndex = atoi(pUpdateIndex);
+ //check updateIndex
+ if (chr->GetTypeId() == TYPEID_PLAYER)
+ {
+ if (updateIndex >= PLAYER_END) return true;
+ }
+ else
+ {
+ if (updateIndex >= UNIT_END) return true;
+ }
+
+ char* pvalue = strtok(NULL, " ");
+ if (!pvalue)
+ {
+ value=chr->GetUInt32Value(updateIndex);
+
+ PSendSysMessage(LANG_UPDATE, chr->GetGUIDLow(),updateIndex,value);
+ return true;
+ }
+
+ value=atoi(pvalue);
+
+ PSendSysMessage(LANG_UPDATE_CHANGE, chr->GetGUIDLow(),updateIndex,value);
+
+ chr->SetUInt32Value(updateIndex,value);
+
+ return true;
+}
diff --git a/src/server/game/Chat/Level0.cpp b/src/server/game/Chat/Level0.cpp
new file mode 100644
index 00000000000..ed021ac00d4
--- /dev/null
+++ b/src/server/game/Chat/Level0.cpp
@@ -0,0 +1,295 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "Common.h"
+#include "Database/DatabaseEnv.h"
+#include "World.h"
+#include "Player.h"
+#include "Opcodes.h"
+#include "Chat.h"
+#include "ObjectAccessor.h"
+#include "Language.h"
+#include "AccountMgr.h"
+#include "SystemConfig.h"
+#include "revision.h"
+#include "Util.h"
+
+bool ChatHandler::HandleHelpCommand(const char* args)
+{
+ char* cmd = strtok((char*)args, " ");
+ if (!cmd)
+ {
+ ShowHelpForCommand(getCommandTable(), "help");
+ ShowHelpForCommand(getCommandTable(), "");
+ }
+ else
+ {
+ if (!ShowHelpForCommand(getCommandTable(), cmd))
+ SendSysMessage(LANG_NO_HELP_CMD);
+ }
+
+ return true;
+}
+
+bool ChatHandler::HandleCommandsCommand(const char* /*args*/)
+{
+ ShowHelpForCommand(getCommandTable(), "");
+ return true;
+}
+
+bool ChatHandler::HandleAccountCommand(const char* /*args*/)
+{
+ AccountTypes gmlevel = m_session->GetSecurity();
+ PSendSysMessage(LANG_ACCOUNT_LEVEL, uint32(gmlevel));
+ return true;
+}
+
+bool ChatHandler::HandleStartCommand(const char* /*args*/)
+{
+ Player *chr = m_session->GetPlayer();
+
+ if (chr->isInFlight())
+ {
+ SendSysMessage(LANG_YOU_IN_FLIGHT);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (chr->isInCombat())
+ {
+ SendSysMessage(LANG_YOU_IN_COMBAT);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if ((chr->isDead()) || (chr->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST)))
+ {
+ // if player is dead and stuck, send ghost to graveyard
+ chr->RepopAtGraveyard();
+ return true;
+ }
+
+ // cast spell Stuck
+ chr->CastSpell(chr,7355,false);
+ return true;
+}
+
+bool ChatHandler::HandleServerInfoCommand(const char* /*args*/)
+{
+ uint32 PlayersNum = sWorld.GetPlayerCount();
+ uint32 MaxPlayersNum = sWorld.GetMaxPlayerCount();
+ uint32 activeClientsNum = sWorld.GetActiveSessionCount();
+ uint32 queuedClientsNum = sWorld.GetQueuedSessionCount();
+ uint32 maxActiveClientsNum = sWorld.GetMaxActiveSessionCount();
+ uint32 maxQueuedClientsNum = sWorld.GetMaxQueuedSessionCount();
+ std::string uptime = secsToTimeString(sWorld.GetUptime());
+ uint32 updateTime = sWorld.GetUpdateTime();
+
+ PSendSysMessage(_FULLVERSION);
+ //if (m_session)
+ // full = _FULLVERSION(REVISION_DATE,REVISION_TIME,"|cffffffff|Hurl:" REVISION_ID "|h" REVISION_ID "|h|r");
+ //else
+ // full = _FULLVERSION(REVISION_DATE,REVISION_TIME,REVISION_ID);
+
+ //SendSysMessage(full);
+ //PSendSysMessage(LANG_USING_WORLD_DB,sWorld.GetDBVersion());
+ //PSendSysMessage(LANG_USING_EVENT_AI,sWorld.GetCreatureEventAIVersion());
+ PSendSysMessage(LANG_CONNECTED_PLAYERS, PlayersNum, MaxPlayersNum);
+ PSendSysMessage(LANG_CONNECTED_USERS, activeClientsNum, maxActiveClientsNum, queuedClientsNum, maxQueuedClientsNum);
+ PSendSysMessage(LANG_UPTIME, uptime.c_str());
+ PSendSysMessage("Update time diff: %u.", updateTime);
+
+ return true;
+}
+
+bool ChatHandler::HandleDismountCommand(const char* /*args*/)
+{
+ //If player is not mounted, so go out :)
+ if (!m_session->GetPlayer()->IsMounted())
+ {
+ SendSysMessage(LANG_CHAR_NON_MOUNTED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (m_session->GetPlayer()->isInFlight())
+ {
+ SendSysMessage(LANG_YOU_IN_FLIGHT);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ m_session->GetPlayer()->Unmount();
+ m_session->GetPlayer()->RemoveAurasByType(SPELL_AURA_MOUNTED);
+ return true;
+}
+
+bool ChatHandler::HandleSaveCommand(const char* /*args*/)
+{
+ Player *player=m_session->GetPlayer();
+
+ // save GM account without delay and output message (testing, etc)
+ if (m_session->GetSecurity() > SEC_PLAYER)
+ {
+ player->SaveToDB();
+ SendSysMessage(LANG_PLAYER_SAVED);
+ return true;
+ }
+
+ // save or plan save after 20 sec (logout delay) if current next save time more this value and _not_ output any messages to prevent cheat planning
+ uint32 save_interval = sWorld.getConfig(CONFIG_INTERVAL_SAVE);
+ if ((save_interval == 0 || save_interval > 20*IN_MILISECONDS && player->GetSaveTimer() <= save_interval - 20*IN_MILISECONDS))
+ player->SaveToDB();
+
+ return true;
+}
+
+bool ChatHandler::HandleGMListIngameCommand(const char* /*args*/)
+{
+ bool first = true;
+
+ ObjectAccessor::Guard guard(*HashMapHolder<Player>::GetLock());
+ HashMapHolder<Player>::MapType &m = ObjectAccessor::Instance().GetPlayers();
+ for (HashMapHolder<Player>::MapType::const_iterator itr = m.begin(); itr != m.end(); ++itr)
+ {
+ AccountTypes itr_sec = itr->second->GetSession()->GetSecurity();
+ if ((itr->second->isGameMaster() || (itr_sec > SEC_PLAYER && itr_sec <= sWorld.getConfig(CONFIG_GM_LEVEL_IN_GM_LIST))) &&
+ (!m_session || itr->second->IsVisibleGloballyFor(m_session->GetPlayer())))
+ {
+ if (first)
+ {
+ SendSysMessage(LANG_GMS_ON_SRV);
+ first = false;
+ }
+
+ SendSysMessage(GetNameLink(itr->second).c_str());
+ }
+ }
+
+ if (first)
+ SendSysMessage(LANG_GMS_NOT_LOGGED);
+
+ return true;
+}
+
+bool ChatHandler::HandleAccountPasswordCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ char *old_pass = strtok ((char*)args, " ");
+ char *new_pass = strtok (NULL, " ");
+ char *new_pass_c = strtok (NULL, " ");
+
+ if (!old_pass || !new_pass || !new_pass_c)
+ return false;
+
+ std::string password_old = old_pass;
+ std::string password_new = new_pass;
+ std::string password_new_c = new_pass_c;
+
+ if (strcmp(new_pass, new_pass_c) != 0)
+ {
+ SendSysMessage (LANG_NEW_PASSWORDS_NOT_MATCH);
+ SetSentErrorMessage (true);
+ return false;
+ }
+
+ if (!accmgr.CheckPassword (m_session->GetAccountId(), password_old))
+ {
+ SendSysMessage (LANG_COMMAND_WRONGOLDPASSWORD);
+ SetSentErrorMessage (true);
+ return false;
+ }
+
+ AccountOpResult result = accmgr.ChangePassword(m_session->GetAccountId(), password_new);
+
+ switch(result)
+ {
+ case AOR_OK:
+ SendSysMessage(LANG_COMMAND_PASSWORD);
+ break;
+ case AOR_PASS_TOO_LONG:
+ SendSysMessage(LANG_PASSWORD_TOO_LONG);
+ SetSentErrorMessage(true);
+ return false;
+ case AOR_NAME_NOT_EXIST: // not possible case, don't want get account name for output
+ default:
+ SendSysMessage(LANG_COMMAND_NOTCHANGEPASSWORD);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ return true;
+}
+
+bool ChatHandler::HandleAccountAddonCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ char *szExp = strtok((char*)args," ");
+
+ uint32 account_id = m_session->GetAccountId();
+
+ int expansion=atoi(szExp); //get int anyway (0 if error)
+ if (expansion < 0 || expansion > sWorld.getConfig(CONFIG_EXPANSION))
+ return false;
+
+ // No SQL injection
+ LoginDatabase.PExecute("UPDATE account SET expansion = '%d' WHERE id = '%u'", expansion, account_id);
+ PSendSysMessage(LANG_ACCOUNT_ADDON, expansion);
+ return true;
+}
+
+bool ChatHandler::HandleAccountLockCommand(const char* args)
+{
+ if (!*args)
+ {
+ SendSysMessage(LANG_USE_BOL);
+ return true;
+ }
+
+ std::string argstr = (char*)args;
+ if (argstr == "on")
+ {
+ LoginDatabase.PExecute("UPDATE account SET locked = '1' WHERE id = '%d'",m_session->GetAccountId());
+ PSendSysMessage(LANG_COMMAND_ACCLOCKLOCKED);
+ return true;
+ }
+
+ if (argstr == "off")
+ {
+ LoginDatabase.PExecute("UPDATE account SET locked = '0' WHERE id = '%d'",m_session->GetAccountId());
+ PSendSysMessage(LANG_COMMAND_ACCLOCKUNLOCKED);
+ return true;
+ }
+
+ SendSysMessage(LANG_USE_BOL);
+ return true;
+}
+
+/// Display the 'Message of the day' for the realm
+bool ChatHandler::HandleServerMotdCommand(const char* /*args*/)
+{
+ PSendSysMessage(LANG_MOTD_CURRENT, sWorld.GetMotd());
+ return true;
+}
+
diff --git a/src/server/game/Chat/Level1.cpp b/src/server/game/Chat/Level1.cpp
new file mode 100644
index 00000000000..11189d519a0
--- /dev/null
+++ b/src/server/game/Chat/Level1.cpp
@@ -0,0 +1,2960 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "Common.h"
+#include "Database/DatabaseEnv.h"
+#include "WorldPacket.h"
+#include "WorldSession.h"
+#include "World.h"
+#include "ObjectMgr.h"
+#include "Player.h"
+#include "AccountMgr.h"
+#include "Opcodes.h"
+#include "Chat.h"
+#include "Log.h"
+#include "MapManager.h"
+#include "ObjectAccessor.h"
+#include "Language.h"
+#include "CellImpl.h"
+#include "InstanceSaveMgr.h"
+#include "Util.h"
+
+#ifdef _DEBUG_VMAPS
+#include "VMapFactory.h"
+#endif
+
+//-----------------------Npc Commands-----------------------
+bool ChatHandler::HandleNpcSayCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ Creature* pCreature = getSelectedCreature();
+ if (!pCreature)
+ {
+ SendSysMessage(LANG_SELECT_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ pCreature->MonsterSay(args, LANG_UNIVERSAL, 0);
+
+ // make some emotes
+ char lastchar = args[strlen(args) - 1];
+ switch(lastchar)
+ {
+ case '?': pCreature->HandleEmoteCommand(EMOTE_ONESHOT_QUESTION); break;
+ case '!': pCreature->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION); break;
+ default: pCreature->HandleEmoteCommand(EMOTE_ONESHOT_TALK); break;
+ }
+
+ return true;
+}
+
+bool ChatHandler::HandleNpcYellCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ Creature* pCreature = getSelectedCreature();
+ if (!pCreature)
+ {
+ SendSysMessage(LANG_SELECT_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ pCreature->MonsterYell(args, LANG_UNIVERSAL, 0);
+
+ // make an emote
+ pCreature->HandleEmoteCommand(EMOTE_ONESHOT_SHOUT);
+
+ return true;
+}
+
+//show text emote by creature in chat
+bool ChatHandler::HandleNpcTextEmoteCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ Creature* pCreature = getSelectedCreature();
+
+ if (!pCreature)
+ {
+ SendSysMessage(LANG_SELECT_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ pCreature->MonsterTextEmote(args, 0);
+
+ return true;
+}
+
+// make npc whisper to player
+bool ChatHandler::HandleNpcWhisperCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ char* receiver_str = strtok((char*)args, " ");
+ char* text = strtok(NULL, "");
+
+ uint64 guid = m_session->GetPlayer()->GetSelection();
+ Creature* pCreature = m_session->GetPlayer()->GetMap()->GetCreature(guid);
+
+ if (!pCreature || !receiver_str || !text)
+ {
+ return false;
+ }
+
+ uint64 receiver_guid= atol(receiver_str);
+
+ // check online security
+ if (HasLowerSecurity(objmgr.GetPlayer(receiver_guid), 0))
+ return false;
+
+ pCreature->MonsterWhisper(text,receiver_guid);
+
+ return true;
+}
+//----------------------------------------------------------
+
+bool ChatHandler::HandleNameAnnounceCommand(const char* args)
+{
+ WorldPacket data;
+ if (!*args)
+ return false;
+
+ sWorld.SendWorldText(LANG_ANNOUNCE_COLOR, m_session->GetPlayer()->GetName(), args);
+ return true;
+}
+
+bool ChatHandler::HandleGMNameAnnounceCommand(const char* args)
+{
+ WorldPacket data;
+ if (!*args)
+ return false;
+
+ sWorld.SendGMText(LANG_GM_ANNOUNCE_COLOR, m_session->GetPlayer()->GetName(), args);
+ return true;
+}
+
+// global announce
+bool ChatHandler::HandleAnnounceCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ sWorld.SendWorldText(LANG_SYSTEMMESSAGE,args);
+ return true;
+}
+
+// announce to logged in GMs
+bool ChatHandler::HandleGMAnnounceCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ sWorld.SendGMText(LANG_GM_BROADCAST,args);
+ return true;
+}
+
+//notification player at the screen
+bool ChatHandler::HandleNotifyCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ std::string str = GetTrinityString(LANG_GLOBAL_NOTIFY);
+ str += args;
+
+ WorldPacket data(SMSG_NOTIFICATION, (str.size()+1));
+ data << str;
+ sWorld.SendGlobalMessage(&data);
+
+ return true;
+}
+
+//notification GM at the screen
+bool ChatHandler::HandleGMNotifyCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ std::string str = GetTrinityString(LANG_GM_NOTIFY);
+ str += args;
+
+ WorldPacket data(SMSG_NOTIFICATION, (str.size()+1));
+ data << str;
+ sWorld.SendGlobalGMMessage(&data);
+
+ return true;
+}
+
+//Enable\Dissable GM Mode
+bool ChatHandler::HandleGMCommand(const char* args)
+{
+ if (!*args)
+ {
+ if (m_session->GetPlayer()->isGameMaster())
+ m_session->SendNotification(LANG_GM_ON);
+ else
+ m_session->SendNotification(LANG_GM_OFF);
+ return true;
+ }
+
+ std::string argstr = (char*)args;
+
+ if (argstr == "on")
+ {
+ m_session->GetPlayer()->SetGameMaster(true);
+ m_session->SendNotification(LANG_GM_ON);
+ m_session->GetPlayer()->UpdateTriggerVisibility();
+ #ifdef _DEBUG_VMAPS
+ VMAP::IVMapManager *vMapManager = VMAP::VMapFactory::createOrGetVMapManager();
+ vMapManager->processCommand("stoplog");
+ #endif
+ return true;
+ }
+
+ if (argstr == "off")
+ {
+ m_session->GetPlayer()->SetGameMaster(false);
+ m_session->SendNotification(LANG_GM_OFF);
+ m_session->GetPlayer()->UpdateTriggerVisibility();
+ #ifdef _DEBUG_VMAPS
+ VMAP::IVMapManager *vMapManager = VMAP::VMapFactory::createOrGetVMapManager();
+ vMapManager->processCommand("startlog");
+ #endif
+ return true;
+ }
+
+ SendSysMessage(LANG_USE_BOL);
+ SetSentErrorMessage(true);
+ return false;
+}
+
+// Enables or disables hiding of the staff badge
+bool ChatHandler::HandleGMChatCommand(const char* args)
+{
+ if (!*args)
+ {
+ if (m_session->GetPlayer()->isGMChat())
+ m_session->SendNotification(LANG_GM_CHAT_ON);
+ else
+ m_session->SendNotification(LANG_GM_CHAT_OFF);
+ return true;
+ }
+
+ std::string argstr = (char*)args;
+
+ if (argstr == "on")
+ {
+ m_session->GetPlayer()->SetGMChat(true);
+ m_session->SendNotification(LANG_GM_CHAT_ON);
+ return true;
+ }
+
+ if (argstr == "off")
+ {
+ m_session->GetPlayer()->SetGMChat(false);
+ m_session->SendNotification(LANG_GM_CHAT_OFF);
+ return true;
+ }
+
+ SendSysMessage(LANG_USE_BOL);
+ SetSentErrorMessage(true);
+ return false;
+}
+
+std::string ChatHandler::PGetParseString(int32 entry, ...)
+{
+ const char *format = GetTrinityString(entry);
+ va_list ap;
+ char str [1024];
+ va_start(ap, entry);
+ vsnprintf(str,1024,format, ap);
+ va_end(ap);
+ return (std::string)str;
+}
+
+bool ChatHandler::HandleGMTicketListCommand(const char* /*args*/)
+{
+ SendSysMessage(LANG_COMMAND_TICKETSHOWLIST);
+ for (GmTicketList::iterator itr = objmgr.m_GMTicketList.begin(); itr != objmgr.m_GMTicketList.end(); ++itr)
+ {
+ if ((*itr)->closed != 0)
+ continue;
+ std::string gmname;
+ std::stringstream ss;
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTGUID, (*itr)->guid);
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTNAME, (*itr)->name.c_str());
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTAGECREATE, (secsToTimeString(time(NULL) - (*itr)->createtime, true, false)).c_str());
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTAGE, (secsToTimeString(time(NULL) - (*itr)->timestamp, true, false)).c_str());
+ if (objmgr.GetPlayerNameByGUID((*itr)->assignedToGM, gmname))
+ {
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTASSIGNEDTO, gmname.c_str());
+ }
+ SendSysMessage(ss.str().c_str());
+ }
+ return true;
+}
+
+bool ChatHandler::HandleGMTicketListOnlineCommand(const char* /*args*/)
+{
+ SendSysMessage(LANG_COMMAND_TICKETSHOWONLINELIST);
+ for (GmTicketList::iterator itr = objmgr.m_GMTicketList.begin(); itr != objmgr.m_GMTicketList.end(); ++itr)
+ {
+ if ((*itr)->closed != 0 || !objmgr.GetPlayer((*itr)->playerGuid))
+ continue;
+
+ std::string gmname;
+ std::stringstream ss;
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTGUID, (*itr)->guid);
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTNAME, (*itr)->name.c_str());
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTAGECREATE, (secsToTimeString(time(NULL) - (*itr)->createtime, true, false)).c_str());
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTAGE, (secsToTimeString(time(NULL) - (*itr)->timestamp, true, false)).c_str());
+ if (objmgr.GetPlayerNameByGUID((*itr)->assignedToGM, gmname))
+ {
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTASSIGNEDTO, gmname.c_str());
+ }
+ SendSysMessage(ss.str().c_str());
+ }
+ return true;
+}
+
+bool ChatHandler::HandleGMTicketListClosedCommand(const char* /*args*/)
+{
+ SendSysMessage(LANG_COMMAND_TICKETSHOWCLOSEDLIST);
+ for (GmTicketList::iterator itr = objmgr.m_GMTicketList.begin(); itr != objmgr.m_GMTicketList.end(); ++itr)
+ {
+ if ((*itr)->closed == 0)
+ continue;
+
+ std::string gmname;
+ std::stringstream ss;
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTGUID, (*itr)->guid);
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTNAME, (*itr)->name.c_str());
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTAGECREATE, (secsToTimeString(time(NULL) - (*itr)->createtime, true, false)).c_str());
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTAGE, (secsToTimeString(time(NULL) - (*itr)->timestamp, true, false)).c_str());
+ if (objmgr.GetPlayerNameByGUID((*itr)->assignedToGM, gmname))
+ {
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTASSIGNEDTO, gmname.c_str());
+ }
+ SendSysMessage(ss.str().c_str());
+ }
+ return true;
+}
+
+bool ChatHandler::HandleGMTicketGetByIdCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ uint64 tguid = atoi(args);
+ GM_Ticket *ticket = objmgr.GetGMTicket(tguid);
+ if (!ticket || ticket->closed != 0)
+ {
+ SendSysMessage(LANG_COMMAND_TICKETNOTEXIST);
+ return true;
+ }
+
+ std::string gmname;
+ std::stringstream ss;
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTGUID, ticket->guid);
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTNAME, ticket->name.c_str());
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTAGECREATE, (secsToTimeString(time(NULL) - ticket->createtime, true, false)).c_str());
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTAGE, (secsToTimeString(time(NULL) - ticket->timestamp, true, false)).c_str());
+ if (objmgr.GetPlayerNameByGUID(ticket->assignedToGM, gmname))
+ {
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTASSIGNEDTO, gmname.c_str());
+ }
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTMESSAGE, ticket->message.c_str());
+ if (ticket->comment != "")
+ {
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTCOMMENT, ticket->comment.c_str());
+ }
+ SendSysMessage(ss.str().c_str());
+ return true;
+}
+
+bool ChatHandler::HandleGMTicketGetByNameCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ std::string name = (char*)args;
+ normalizePlayerName(name);
+
+ Player *plr = objmgr.GetPlayer(name.c_str());
+ if (!plr)
+ {
+ SendSysMessage(LANG_NO_PLAYERS_FOUND);
+ return true;
+ }
+
+ GM_Ticket *ticket = objmgr.GetGMTicketByPlayer(plr->GetGUID());
+ if (!ticket)
+ {
+ SendSysMessage(LANG_COMMAND_TICKETNOTEXIST);
+ return true;
+ }
+
+ std::string gmname;
+ std::stringstream ss;
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTGUID, ticket->guid);
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTNAME, ticket->name.c_str());
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTAGECREATE, (secsToTimeString(time(NULL) - ticket->createtime, true, false)).c_str());
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTAGE, (secsToTimeString(time(NULL) - ticket->timestamp, true, false)).c_str());
+ if (objmgr.GetPlayerNameByGUID(ticket->assignedToGM, gmname))
+ {
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTASSIGNEDTO, gmname.c_str());
+ }
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTMESSAGE, ticket->message.c_str());
+ if (ticket->comment != "")
+ {
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTCOMMENT, ticket->comment.c_str());
+ }
+ SendSysMessage(ss.str().c_str());
+ return true;
+}
+
+bool ChatHandler::HandleGMTicketCloseByIdCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ uint64 tguid = atoi(args);
+ GM_Ticket *ticket = objmgr.GetGMTicket(tguid);
+ if (!ticket || ticket->closed != 0)
+ {
+ SendSysMessage(LANG_COMMAND_TICKETNOTEXIST);
+ return true;
+ }
+ if (ticket && ticket->assignedToGM != 0 && ticket->assignedToGM != m_session->GetPlayer()->GetGUID())
+ {
+ PSendSysMessage(LANG_COMMAND_TICKETCANNOTCLOSE, ticket->guid);
+ return true;
+ }
+ std::stringstream ss;
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTGUID, ticket->guid);
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTNAME, ticket->name.c_str());
+ ss << PGetParseString(LANG_COMMAND_TICKETCLOSED, m_session->GetPlayer()->GetName());
+ SendGlobalGMSysMessage(ss.str().c_str());
+ Player *plr = objmgr.GetPlayer(ticket->playerGuid);
+ objmgr.RemoveGMTicket(ticket, m_session->GetPlayer()->GetGUID());
+
+ if (!plr || !plr->IsInWorld())
+ return true;
+
+ // send abandon ticket
+ WorldPacket data(SMSG_GMTICKET_DELETETICKET, 4);
+ data << uint32(9);
+ plr->GetSession()->SendPacket(&data);
+ return true;
+}
+
+bool ChatHandler::HandleGMTicketAssignToCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ char* tguid = strtok((char*)args, " ");
+ uint64 ticketGuid = atoi(tguid);
+ char* targetgm = strtok(NULL, " ");
+
+ if (!targetgm)
+ return false;
+
+ std::string targm = targetgm;
+ if (!normalizePlayerName(targm))
+ return false;
+
+ Player *cplr = m_session->GetPlayer();
+ GM_Ticket *ticket = objmgr.GetGMTicket(ticketGuid);
+
+ if (!ticket || ticket->closed != 0)
+ {
+ SendSysMessage(LANG_COMMAND_TICKETNOTEXIST);
+ return true;
+ }
+
+ uint64 tarGUID = objmgr.GetPlayerGUIDByName(targm.c_str());
+ uint64 accid = objmgr.GetPlayerAccountIdByGUID(tarGUID);
+ uint32 gmlevel = accmgr.GetSecurity(accid, realmID);
+
+ if (!tarGUID || gmlevel == SEC_PLAYER)
+ {
+ SendSysMessage(LANG_COMMAND_TICKETASSIGNERROR_A);
+ return true;
+ }
+
+ if (ticket->assignedToGM == tarGUID)
+ {
+ PSendSysMessage(LANG_COMMAND_TICKETASSIGNERROR_B, ticket->guid);
+ return true;
+ }
+
+ std::string gmname;
+ objmgr.GetPlayerNameByGUID(tarGUID, gmname);
+ if (ticket->assignedToGM != 0 && ticket->assignedToGM != cplr->GetGUID())
+ {
+ PSendSysMessage(LANG_COMMAND_TICKETALREADYASSIGNED, ticket->guid, gmname.c_str());
+ return true;
+ }
+
+ ticket->assignedToGM = tarGUID;
+ objmgr.AddOrUpdateGMTicket(*ticket);
+ std::stringstream ss;
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTGUID, ticket->guid);
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTNAME, ticket->name.c_str());
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTASSIGNEDTO, gmname.c_str());
+ SendGlobalGMSysMessage(ss.str().c_str());
+ return true;
+}
+
+bool ChatHandler::HandleGMTicketUnAssignCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ uint64 ticketGuid = atoi(args);
+ Player *cplr = m_session->GetPlayer();
+ GM_Ticket *ticket = objmgr.GetGMTicket(ticketGuid);
+
+ if (!ticket|| ticket->closed != 0)
+ {
+ SendSysMessage(LANG_COMMAND_TICKETNOTEXIST);
+ return true;
+ }
+ if (ticket->assignedToGM == 0)
+ {
+ PSendSysMessage(LANG_COMMAND_TICKETNOTASSIGNED, ticket->guid);
+ return true;
+ }
+
+ std::string gmname;
+ objmgr.GetPlayerNameByGUID(ticket->assignedToGM, gmname);
+ Player *plr = objmgr.GetPlayer(ticket->assignedToGM);
+ if (plr && plr->IsInWorld() && plr->GetSession()->GetSecurity() > cplr->GetSession()->GetSecurity())
+ {
+ SendSysMessage(LANG_COMMAND_TICKETUNASSIGNSECURITY);
+ return true;
+ }
+
+ std::stringstream ss;
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTGUID, ticket->guid);
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTNAME, ticket->name.c_str());
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTASSIGNEDTO, gmname.c_str());
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTUNASSIGNED, cplr->GetName());
+ SendGlobalGMSysMessage(ss.str().c_str());
+ ticket->assignedToGM = 0;
+ objmgr.AddOrUpdateGMTicket(*ticket);
+ return true;
+}
+
+bool ChatHandler::HandleGMTicketCommentCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ char* tguid = strtok((char*)args, " ");
+ uint64 ticketGuid = atoi(tguid);
+ char* comment = strtok(NULL, "\n");
+
+ if (!comment)
+ return false;
+
+ Player *cplr = m_session->GetPlayer();
+ GM_Ticket *ticket = objmgr.GetGMTicket(ticketGuid);
+
+ if (!ticket || ticket->closed != 0)
+ {
+ PSendSysMessage(LANG_COMMAND_TICKETNOTEXIST);
+ return true;
+ }
+ if (ticket->assignedToGM != 0 && ticket->assignedToGM != cplr->GetGUID())
+ {
+ PSendSysMessage(LANG_COMMAND_TICKETALREADYASSIGNED, ticket->guid);
+ return true;
+ }
+
+ std::string gmname;
+ objmgr.GetPlayerNameByGUID(ticket->assignedToGM, gmname);
+ ticket->comment = comment;
+ objmgr.AddOrUpdateGMTicket(*ticket);
+ std::stringstream ss;
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTGUID, ticket->guid);
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTNAME, ticket->name.c_str());
+ if (objmgr.GetPlayerNameByGUID(ticket->assignedToGM, gmname))
+ {
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTASSIGNEDTO, gmname.c_str());
+ }
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTADDCOMMENT, cplr->GetName(), ticket->comment.c_str());
+ SendGlobalGMSysMessage(ss.str().c_str());
+ return true;
+}
+
+bool ChatHandler::HandleGMTicketDeleteByIdCommand(const char* args)
+{
+ if (!*args)
+ return false;
+ uint64 ticketGuid = atoi(args);
+ GM_Ticket *ticket = objmgr.GetGMTicket(ticketGuid);
+
+ if (!ticket)
+ {
+ SendSysMessage(LANG_COMMAND_TICKETNOTEXIST);
+ return true;
+ }
+ if (ticket->closed == 0)
+ {
+ SendSysMessage(LANG_COMMAND_TICKETCLOSEFIRST);
+ return true;
+ }
+
+ std::stringstream ss;
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTGUID, ticket->guid);
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTNAME, ticket->name.c_str());
+ ss << PGetParseString(LANG_COMMAND_TICKETDELETED, m_session->GetPlayer()->GetName());
+ SendGlobalGMSysMessage(ss.str().c_str());
+ Player *plr = objmgr.GetPlayer(ticket->playerGuid);
+ objmgr.RemoveGMTicket(ticket, -1, true);
+ if (plr && plr->IsInWorld())
+ {
+ // Force abandon ticket
+ WorldPacket data(SMSG_GMTICKET_DELETETICKET, 4);
+ data << uint32(9);
+ plr->GetSession()->SendPacket(&data);
+ }
+
+ ticket = NULL;
+ return true;
+}
+
+bool ChatHandler::HandleGMTicketReloadCommand(const char*)
+{
+ objmgr.LoadGMTickets();
+ return true;
+}
+
+//Enable\Dissable Invisible mode
+bool ChatHandler::HandleGMVisibleCommand(const char* args)
+{
+ if (!*args)
+ {
+ PSendSysMessage(LANG_YOU_ARE, m_session->GetPlayer()->isGMVisible() ? GetTrinityString(LANG_VISIBLE) : GetTrinityString(LANG_INVISIBLE));
+ return true;
+ }
+
+ std::string argstr = (char*)args;
+
+ if (argstr == "on")
+ {
+ m_session->GetPlayer()->SetGMVisible(true);
+ m_session->SendNotification(LANG_INVISIBLE_VISIBLE);
+ return true;
+ }
+
+ if (argstr == "off")
+ {
+ m_session->SendNotification(LANG_INVISIBLE_INVISIBLE);
+ m_session->GetPlayer()->SetGMVisible(false);
+ return true;
+ }
+
+ SendSysMessage(LANG_USE_BOL);
+ SetSentErrorMessage(true);
+ return false;
+}
+
+bool ChatHandler::HandleGPSCommand(const char* args)
+{
+ WorldObject *obj = NULL;
+ if (*args)
+ {
+ uint64 guid = extractGuidFromLink((char*)args);
+ if (guid)
+ obj = (WorldObject*)ObjectAccessor::GetObjectByTypeMask(*m_session->GetPlayer(),guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
+
+ if (!obj)
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+ }
+ else
+ {
+ obj = getSelectedUnit();
+
+ if (!obj)
+ {
+ SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+ }
+ CellPair cell_val = Trinity::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY());
+ Cell cell(cell_val);
+
+ uint32 zone_id, area_id;
+ obj->GetZoneAndAreaId(zone_id,area_id);
+
+ MapEntry const* mapEntry = sMapStore.LookupEntry(obj->GetMapId());
+ AreaTableEntry const* zoneEntry = GetAreaEntryByAreaID(zone_id);
+ AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(area_id);
+
+ float zone_x = obj->GetPositionX();
+ float zone_y = obj->GetPositionY();
+
+ Map2ZoneCoordinates(zone_x,zone_y,zone_id);
+
+ Map const *map = obj->GetMap();
+ float ground_z = map->GetHeight(obj->GetPositionX(), obj->GetPositionY(), MAX_HEIGHT);
+ float floor_z = map->GetHeight(obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ());
+
+ GridPair p = Trinity::ComputeGridPair(obj->GetPositionX(), obj->GetPositionY());
+
+ int gx=63-p.x_coord;
+ int gy=63-p.y_coord;
+
+ uint32 have_map = Map::ExistMap(obj->GetMapId(),gx,gy) ? 1 : 0;
+ uint32 have_vmap = Map::ExistVMap(obj->GetMapId(),gx,gy) ? 1 : 0;
+
+ if(have_vmap)
+ {
+ if(map->IsOutdoors(obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ()))
+ PSendSysMessage("You are outdoors");
+ else
+ PSendSysMessage("You are indoor");
+ }
+ else PSendSysMessage("no VMAP available for area info");
+
+ PSendSysMessage(LANG_MAP_POSITION,
+ obj->GetMapId(), (mapEntry ? mapEntry->name[GetSessionDbcLocale()] : "<unknown>"),
+ zone_id, (zoneEntry ? zoneEntry->area_name[GetSessionDbcLocale()] : "<unknown>"),
+ area_id, (areaEntry ? areaEntry->area_name[GetSessionDbcLocale()] : "<unknown>"),
+ obj->GetPhaseMask(),
+ obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), obj->GetOrientation(),
+ cell.GridX(), cell.GridY(), cell.CellX(), cell.CellY(), obj->GetInstanceId(),
+ zone_x, zone_y, ground_z, floor_z, have_map, have_vmap);
+
+ sLog.outDebug("Player %s GPS call for %s '%s' (%s: %u):",
+ m_session ? GetNameLink().c_str() : GetTrinityString(LANG_CONSOLE_COMMAND),
+ (obj->GetTypeId() == TYPEID_PLAYER ? "player" : "creature"), obj->GetName(),
+ (obj->GetTypeId() == TYPEID_PLAYER ? "GUID" : "Entry"), (obj->GetTypeId() == TYPEID_PLAYER ? obj->GetGUIDLow(): obj->GetEntry()));
+ sLog.outDebug(GetTrinityString(LANG_MAP_POSITION),
+ obj->GetMapId(), (mapEntry ? mapEntry->name[sWorld.GetDefaultDbcLocale()] : "<unknown>"),
+ zone_id, (zoneEntry ? zoneEntry->area_name[sWorld.GetDefaultDbcLocale()] : "<unknown>"),
+ area_id, (areaEntry ? areaEntry->area_name[sWorld.GetDefaultDbcLocale()] : "<unknown>"),
+ obj->GetPhaseMask(),
+ obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), obj->GetOrientation(),
+ cell.GridX(), cell.GridY(), cell.CellX(), cell.CellY(), obj->GetInstanceId(),
+ zone_x, zone_y, ground_z, floor_z, have_map, have_vmap);
+
+ LiquidData liquid_status;
+ ZLiquidStatus res = map->getLiquidStatus(obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), MAP_ALL_LIQUIDS, &liquid_status);
+ if (res)
+ {
+ PSendSysMessage(LANG_LIQUID_STATUS, liquid_status.level, liquid_status.depth_level, liquid_status.type, res);
+ }
+ return true;
+}
+
+//Summon Player
+bool ChatHandler::HandleNamegoCommand(const char* args)
+{
+ Player* target;
+ uint64 target_guid;
+ std::string target_name;
+ if (!extractPlayerTarget((char*)args,&target,&target_guid,&target_name))
+ return false;
+
+ Player* _player = m_session->GetPlayer();
+ if (target == _player || target_guid == _player->GetGUID())
+ {
+ PSendSysMessage(LANG_CANT_TELEPORT_SELF);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (target)
+ {
+ std::string nameLink = playerLink(target_name);
+ // check online security
+ if (HasLowerSecurity(target, 0))
+ return false;
+
+ if (target->IsBeingTeleported())
+ {
+ PSendSysMessage(LANG_IS_TELEPORTED, nameLink.c_str());
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Map* pMap = m_session->GetPlayer()->GetMap();
+
+ if (pMap->IsBattleGroundOrArena())
+ {
+ // only allow if gm mode is on
+ if (!target->isGameMaster())
+ {
+ PSendSysMessage(LANG_CANNOT_GO_TO_BG_GM,nameLink.c_str());
+ SetSentErrorMessage(true);
+ return false;
+ }
+ // if both players are in different bgs
+ else if (target->GetBattleGroundId() && m_session->GetPlayer()->GetBattleGroundId() != target->GetBattleGroundId())
+ {
+ target->LeaveBattleground(false); // Note: should be changed so target gets no Deserter debuff
+ //PSendSysMessage(LANG_CANNOT_GO_TO_BG_FROM_BG,nameLink.c_str());
+ //SetSentErrorMessage(true);
+ //return false;
+ }
+ // all's well, set bg id
+ // when porting out from the bg, it will be reset to 0
+ target->SetBattleGroundId(m_session->GetPlayer()->GetBattleGroundId(), m_session->GetPlayer()->GetBattleGroundTypeId());
+ // remember current position as entry point for return at bg end teleportation
+ if (!target->GetMap()->IsBattleGroundOrArena())
+ target->SetBattleGroundEntryPoint();
+ }
+ else if (pMap->IsDungeon())
+ {
+ Map* cMap = target->GetMap();
+ if (cMap->Instanceable() && cMap->GetInstanceId() != pMap->GetInstanceId())
+ {
+ target->UnbindInstance(pMap->GetInstanceId(), target->GetDungeonDifficulty(), true);
+ // cannot summon from instance to instance
+ //PSendSysMessage(LANG_CANNOT_SUMMON_TO_INST,nameLink.c_str());
+ //SetSentErrorMessage(true);
+ //return false;
+ }
+
+ // we are in instance, and can summon only player in our group with us as lead
+ if (!m_session->GetPlayer()->GetGroup() || !target->GetGroup() ||
+ (target->GetGroup()->GetLeaderGUID() != m_session->GetPlayer()->GetGUID()) ||
+ (m_session->GetPlayer()->GetGroup()->GetLeaderGUID() != m_session->GetPlayer()->GetGUID()))
+ // the last check is a bit excessive, but let it be, just in case
+ {
+ PSendSysMessage(LANG_CANNOT_SUMMON_TO_INST,nameLink.c_str());
+ SetSentErrorMessage(true);
+ return false;
+ }
+ }
+
+ PSendSysMessage(LANG_SUMMONING, nameLink.c_str(),"");
+ if (needReportToTarget(target))
+ ChatHandler(target).PSendSysMessage(LANG_SUMMONED_BY, playerLink(_player->GetName()).c_str());
+
+ // stop flight if need
+ if (target->isInFlight())
+ {
+ target->GetMotionMaster()->MovementExpired();
+ target->CleanupAfterTaxiFlight();
+ }
+ // save only in non-flight case
+ else
+ target->SaveRecallPosition();
+
+ // before GM
+ float x,y,z;
+ m_session->GetPlayer()->GetClosePoint(x,y,z,target->GetObjectSize());
+ target->TeleportTo(m_session->GetPlayer()->GetMapId(),x,y,z,target->GetOrientation());
+ target->SetPhaseMask(m_session->GetPlayer()->GetPhaseMask(), true);
+ }
+ else
+ {
+ // check offline security
+ if (HasLowerSecurity(NULL, target_guid))
+ return false;
+
+ std::string nameLink = playerLink(target_name);
+
+ PSendSysMessage(LANG_SUMMONING, nameLink.c_str(),GetTrinityString(LANG_OFFLINE));
+
+ // in point where GM stay
+ Player::SavePositionInDB(m_session->GetPlayer()->GetMapId(),
+ m_session->GetPlayer()->GetPositionX(),
+ m_session->GetPlayer()->GetPositionY(),
+ m_session->GetPlayer()->GetPositionZ(),
+ m_session->GetPlayer()->GetOrientation(),
+ m_session->GetPlayer()->GetZoneId(),
+ target_guid);
+ }
+
+ return true;
+}
+
+//Teleport to Player
+bool ChatHandler::HandleGonameCommand(const char* args)
+{
+ Player* target;
+ uint64 target_guid;
+ std::string target_name;
+ if (!extractPlayerTarget((char*)args,&target,&target_guid,&target_name))
+ return false;
+
+ Player* _player = m_session->GetPlayer();
+ if (target == _player || target_guid == _player->GetGUID())
+ {
+ SendSysMessage(LANG_CANT_TELEPORT_SELF);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (target)
+ {
+ // check online security
+ if (HasLowerSecurity(target, 0))
+ return false;
+
+ std::string chrNameLink = playerLink(target_name);
+
+ Map* cMap = target->GetMap();
+ if (cMap->IsBattleGroundOrArena())
+ {
+ // only allow if gm mode is on
+ if (!_player->isGameMaster())
+ {
+ PSendSysMessage(LANG_CANNOT_GO_TO_BG_GM,chrNameLink.c_str());
+ SetSentErrorMessage(true);
+ return false;
+ }
+ // if both players are in different bgs
+ else if (_player->GetBattleGroundId() && _player->GetBattleGroundId() != target->GetBattleGroundId())
+ {
+ _player->LeaveBattleground(false); // Note: should be changed so _player gets no Deserter debuff
+ //PSendSysMessage(LANG_CANNOT_GO_TO_BG_FROM_BG,chrNameLink.c_str());
+ //SetSentErrorMessage(true);
+ //return false;
+ }
+ // all's well, set bg id
+ // when porting out from the bg, it will be reset to 0
+ _player->SetBattleGroundId(target->GetBattleGroundId(), target->GetBattleGroundTypeId());
+ // remember current position as entry point for return at bg end teleportation
+ if (!_player->GetMap()->IsBattleGroundOrArena())
+ _player->SetBattleGroundEntryPoint();
+ }
+ else if (cMap->IsDungeon())
+ {
+ //Map* pMap = _player->GetMap();
+
+ // we have to go to instance, and can go to player only if:
+ // 1) we are in his group (either as leader or as member)
+ // 2) we are not bound to any group and have GM mode on
+ if (_player->GetGroup())
+ {
+ // we are in group, we can go only if we are in the player group
+ if (_player->GetGroup() != target->GetGroup())
+ {
+ PSendSysMessage(LANG_CANNOT_GO_TO_INST_PARTY,chrNameLink.c_str());
+ SetSentErrorMessage(true);
+ return false;
+ }
+ }
+ else
+ {
+ // we are not in group, let's verify our GM mode
+ if (!_player->isGameMaster())
+ {
+ PSendSysMessage(LANG_CANNOT_GO_TO_INST_GM,chrNameLink.c_str());
+ SetSentErrorMessage(true);
+ return false;
+ }
+ }
+
+ // if the player or the player's group is bound to another instance
+ // the player will not be bound to another one
+ InstancePlayerBind *pBind = _player->GetBoundInstance(target->GetMapId(), target->GetDifficulty(cMap->IsRaid()));
+ if (!pBind)
+ {
+ Group *group = _player->GetGroup();
+ // if no bind exists, create a solo bind
+ InstanceGroupBind *gBind = group ? group->GetBoundInstance(target) : NULL; // if no bind exists, create a solo bind
+ if (!gBind)
+ if (InstanceSave *save = sInstanceSaveManager.GetInstanceSave(target->GetInstanceId()))
+ _player->BindToInstance(save, !save->CanReset());
+ }
+
+ if (cMap->IsRaid())
+ _player->SetRaidDifficulty(target->GetRaidDifficulty());
+ else
+ _player->SetDungeonDifficulty(target->GetDungeonDifficulty());
+ }
+
+ PSendSysMessage(LANG_APPEARING_AT, chrNameLink.c_str());
+ //if (needReportToTarget(target))
+ // ChatHandler(target).PSendSysMessage(LANG_APPEARING_TO, GetNameLink().c_str());
+
+ // stop flight if need
+ if (_player->isInFlight())
+ {
+ _player->GetMotionMaster()->MovementExpired();
+ _player->CleanupAfterTaxiFlight();
+ }
+ // save only in non-flight case
+ else
+ _player->SaveRecallPosition();
+
+ // to point to see at target with same orientation
+ float x,y,z;
+ target->GetContactPoint(_player,x,y,z);
+
+ _player->TeleportTo(target->GetMapId(), x, y, z, _player->GetAngle(target), TELE_TO_GM_MODE);
+ _player->SetPhaseMask(target->GetPhaseMask(), true);
+ }
+ else
+ {
+ // check offline security
+ if (HasLowerSecurity(NULL, target_guid))
+ return false;
+
+ std::string nameLink = playerLink(target_name);
+
+ PSendSysMessage(LANG_APPEARING_AT, nameLink.c_str());
+
+ // to point where player stay (if loaded)
+ float x,y,z,o;
+ uint32 map;
+ bool in_flight;
+ if (!Player::LoadPositionFromDB(map,x,y,z,o,in_flight,target_guid))
+ return false;
+
+ // stop flight if need
+ if (_player->isInFlight())
+ {
+ _player->GetMotionMaster()->MovementExpired();
+ _player->CleanupAfterTaxiFlight();
+ }
+ // save only in non-flight case
+ else
+ _player->SaveRecallPosition();
+
+ _player->TeleportTo(map, x, y, z,_player->GetOrientation());
+ }
+
+ return true;
+}
+
+// Teleport player to last position
+bool ChatHandler::HandleRecallCommand(const char* args)
+{
+ Player* target;
+ if (!extractPlayerTarget((char*)args,&target))
+ return false;
+
+ // check online security
+ if (HasLowerSecurity(target, 0))
+ return false;
+
+ if (target->IsBeingTeleported())
+ {
+ PSendSysMessage(LANG_IS_TELEPORTED, GetNameLink(target).c_str());
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // stop flight if need
+ if (target->isInFlight())
+ {
+ target->GetMotionMaster()->MovementExpired();
+ target->CleanupAfterTaxiFlight();
+ }
+
+ target->TeleportTo(target->m_recallMap, target->m_recallX, target->m_recallY, target->m_recallZ, target->m_recallO);
+ return true;
+}
+
+//Edit Player HP
+bool ChatHandler::HandleModifyHPCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ int32 hp = atoi((char*)args);
+ int32 hpm = atoi((char*)args);
+
+ if (hp < 1 || hpm < 1 || hpm < hp)
+ {
+ SendSysMessage(LANG_BAD_VALUE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Player *chr = getSelectedPlayer();
+ if (chr == NULL)
+ {
+ SendSysMessage(LANG_NO_CHAR_SELECTED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
+ PSendSysMessage(LANG_YOU_CHANGE_HP, GetNameLink(chr).c_str(), hp, hpm);
+ if (needReportToTarget(chr))
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_HP_CHANGED, GetNameLink().c_str(), hp, hpm);
+
+ chr->SetMaxHealth(hpm);
+ chr->SetHealth(hp);
+
+ return true;
+}
+
+//Edit Player Mana
+bool ChatHandler::HandleModifyManaCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ // char* pmana = strtok((char*)args, " ");
+ // if (!pmana)
+ // return false;
+
+ // char* pmanaMax = strtok(NULL, " ");
+ // if (!pmanaMax)
+ // return false;
+
+ // int32 manam = atoi(pmanaMax);
+ // int32 mana = atoi(pmana);
+ int32 mana = atoi((char*)args);
+ int32 manam = atoi((char*)args);
+
+ if (mana <= 0 || manam <= 0 || manam < mana)
+ {
+ SendSysMessage(LANG_BAD_VALUE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Player *chr = getSelectedPlayer();
+ if (chr == NULL)
+ {
+ SendSysMessage(LANG_NO_CHAR_SELECTED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
+ PSendSysMessage(LANG_YOU_CHANGE_MANA, GetNameLink(chr).c_str(), mana, manam);
+ if (needReportToTarget(chr))
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_MANA_CHANGED, GetNameLink().c_str(), mana, manam);
+
+ chr->SetMaxPower(POWER_MANA,manam);
+ chr->SetPower(POWER_MANA, mana);
+
+ return true;
+}
+
+//Edit Player Energy
+bool ChatHandler::HandleModifyEnergyCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ // char* pmana = strtok((char*)args, " ");
+ // if (!pmana)
+ // return false;
+
+ // char* pmanaMax = strtok(NULL, " ");
+ // if (!pmanaMax)
+ // return false;
+
+ // int32 manam = atoi(pmanaMax);
+ // int32 mana = atoi(pmana);
+
+ int32 energy = atoi((char*)args)*10;
+ int32 energym = atoi((char*)args)*10;
+
+ if (energy <= 0 || energym <= 0 || energym < energy)
+ {
+ SendSysMessage(LANG_BAD_VALUE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Player *chr = getSelectedPlayer();
+ if (!chr)
+ {
+ SendSysMessage(LANG_NO_CHAR_SELECTED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
+ PSendSysMessage(LANG_YOU_CHANGE_ENERGY, GetNameLink(chr).c_str(), energy/10, energym/10);
+ if (needReportToTarget(chr))
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_ENERGY_CHANGED, GetNameLink().c_str(), energy/10, energym/10);
+
+ chr->SetMaxPower(POWER_ENERGY,energym);
+ chr->SetPower(POWER_ENERGY, energy);
+
+ sLog.outDetail(GetTrinityString(LANG_CURRENT_ENERGY),chr->GetMaxPower(POWER_ENERGY));
+
+ return true;
+}
+
+//Edit Player Rage
+bool ChatHandler::HandleModifyRageCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ // char* pmana = strtok((char*)args, " ");
+ // if (!pmana)
+ // return false;
+
+ // char* pmanaMax = strtok(NULL, " ");
+ // if (!pmanaMax)
+ // return false;
+
+ // int32 manam = atoi(pmanaMax);
+ // int32 mana = atoi(pmana);
+
+ int32 rage = atoi((char*)args)*10;
+ int32 ragem = atoi((char*)args)*10;
+
+ if (rage <= 0 || ragem <= 0 || ragem < rage)
+ {
+ SendSysMessage(LANG_BAD_VALUE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Player *chr = getSelectedPlayer();
+ if (chr == NULL)
+ {
+ SendSysMessage(LANG_NO_CHAR_SELECTED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
+ PSendSysMessage(LANG_YOU_CHANGE_RAGE, GetNameLink(chr).c_str(), rage/10, ragem/10);
+ if (needReportToTarget(chr))
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_RAGE_CHANGED, GetNameLink().c_str(), rage/10, ragem/10);
+
+ chr->SetMaxPower(POWER_RAGE,ragem);
+ chr->SetPower(POWER_RAGE, rage);
+
+ return true;
+}
+
+// Edit Player Runic Power
+bool ChatHandler::HandleModifyRunicPowerCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ int32 rune = atoi((char*)args)*10;
+ int32 runem = atoi((char*)args)*10;
+
+ if (rune <= 0 || runem <= 0 || runem < rune)
+ {
+ SendSysMessage(LANG_BAD_VALUE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Player *chr = getSelectedPlayer();
+ if (chr == NULL)
+ {
+ SendSysMessage(LANG_NO_CHAR_SELECTED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ PSendSysMessage(LANG_YOU_CHANGE_RUNIC_POWER, GetNameLink(chr).c_str(), rune/10, runem/10);
+ if (needReportToTarget(chr))
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_RUNIC_POWER_CHANGED, GetNameLink().c_str(), rune/10, runem/10);
+
+ chr->SetMaxPower(POWER_RUNIC_POWER,runem);
+ chr->SetPower(POWER_RUNIC_POWER, rune);
+
+ return true;
+}
+
+//Edit Player Faction
+bool ChatHandler::HandleModifyFactionCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ char* pfactionid = extractKeyFromLink((char*)args,"Hfaction");
+
+ Creature* chr = getSelectedCreature();
+ if (!chr)
+ {
+ SendSysMessage(LANG_SELECT_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (!pfactionid)
+ {
+ if (chr)
+ {
+ uint32 factionid = chr->getFaction();
+ uint32 flag = chr->GetUInt32Value(UNIT_FIELD_FLAGS);
+ uint32 npcflag = chr->GetUInt32Value(UNIT_NPC_FLAGS);
+ uint32 dyflag = chr->GetUInt32Value(UNIT_DYNAMIC_FLAGS);
+ PSendSysMessage(LANG_CURRENT_FACTION,chr->GetGUIDLow(),factionid,flag,npcflag,dyflag);
+ }
+ return true;
+ }
+
+ if (!chr)
+ {
+ SendSysMessage(LANG_NO_CHAR_SELECTED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ uint32 factionid = atoi(pfactionid);
+ uint32 flag;
+
+ char *pflag = strtok(NULL, " ");
+ if (!pflag)
+ flag = chr->GetUInt32Value(UNIT_FIELD_FLAGS);
+ else
+ flag = atoi(pflag);
+
+ char* pnpcflag = strtok(NULL, " ");
+
+ uint32 npcflag;
+ if (!pnpcflag)
+ npcflag = chr->GetUInt32Value(UNIT_NPC_FLAGS);
+ else
+ npcflag = atoi(pnpcflag);
+
+ char* pdyflag = strtok(NULL, " ");
+
+ uint32 dyflag;
+ if (!pdyflag)
+ dyflag = chr->GetUInt32Value(UNIT_DYNAMIC_FLAGS);
+ else
+ dyflag = atoi(pdyflag);
+
+ if (!sFactionTemplateStore.LookupEntry(factionid))
+ {
+ PSendSysMessage(LANG_WRONG_FACTION, factionid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ PSendSysMessage(LANG_YOU_CHANGE_FACTION, chr->GetGUIDLow(),factionid,flag,npcflag,dyflag);
+
+ chr->setFaction(factionid);
+ chr->SetUInt32Value(UNIT_FIELD_FLAGS,flag);
+ chr->SetUInt32Value(UNIT_NPC_FLAGS,npcflag);
+ chr->SetUInt32Value(UNIT_DYNAMIC_FLAGS,dyflag);
+
+ return true;
+}
+
+//Edit Player Spell
+bool ChatHandler::HandleModifySpellCommand(const char* args)
+{
+ if (!*args) return false;
+ char* pspellflatid = strtok((char*)args, " ");
+ if (!pspellflatid)
+ return false;
+
+ char* pop = strtok(NULL, " ");
+ if (!pop)
+ return false;
+
+ char* pval = strtok(NULL, " ");
+ if (!pval)
+ return false;
+
+ uint16 mark;
+
+ char* pmark = strtok(NULL, " ");
+
+ uint8 spellflatid = atoi(pspellflatid);
+ uint8 op = atoi(pop);
+ uint16 val = atoi(pval);
+ if (!pmark)
+ mark = 65535;
+ else
+ mark = atoi(pmark);
+
+ Player *chr = getSelectedPlayer();
+ if (chr == NULL)
+ {
+ SendSysMessage(LANG_NO_CHAR_SELECTED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
+ PSendSysMessage(LANG_YOU_CHANGE_SPELLFLATID, spellflatid, val, mark, GetNameLink(chr).c_str());
+ if (needReportToTarget(chr))
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_SPELLFLATID_CHANGED, GetNameLink().c_str(), spellflatid, val, mark);
+
+ WorldPacket data(SMSG_SET_FLAT_SPELL_MODIFIER, (1+1+2+2));
+ data << uint8(spellflatid);
+ data << uint8(op);
+ data << uint16(val);
+ data << uint16(mark);
+ chr->GetSession()->SendPacket(&data);
+
+ return true;
+}
+
+//Edit Player TP
+bool ChatHandler::HandleModifyTalentCommand (const char* args)
+{
+ if (!*args)
+ return false;
+
+ int tp = atoi((char*)args);
+ if (tp < 0)
+ return false;
+
+ Unit* target = getSelectedUnit();
+ if (!target)
+ {
+ SendSysMessage(LANG_NO_CHAR_SELECTED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (target->GetTypeId() == TYPEID_PLAYER)
+ {
+ // check online security
+ if (HasLowerSecurity((Player*)target, 0))
+ return false;
+ target->ToPlayer()->SetFreeTalentPoints(tp);
+ target->ToPlayer()->SendTalentsInfoData(false);
+ return true;
+ }
+ else if (target->ToCreature()->isPet())
+ {
+ Unit *owner = target->GetOwner();
+ if (owner && owner->GetTypeId() == TYPEID_PLAYER && ((Pet *)target)->IsPermanentPetFor(owner->ToPlayer()))
+ {
+ // check online security
+ if (HasLowerSecurity((Player*)owner, 0))
+ return false;
+ ((Pet *)target)->SetFreeTalentPoints(tp);
+ owner->ToPlayer()->SendTalentsInfoData(true);
+ return true;
+ }
+ }
+
+ SendSysMessage(LANG_NO_CHAR_SELECTED);
+ SetSentErrorMessage(true);
+ return false;
+}
+
+//Enable On\OFF all taxi paths
+bool ChatHandler::HandleTaxiCheatCommand(const char* args)
+{
+ if (!*args)
+ {
+ SendSysMessage(LANG_USE_BOL);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ std::string argstr = (char*)args;
+
+ Player *chr = getSelectedPlayer();
+ if (!chr)
+ {
+ chr=m_session->GetPlayer();
+ }
+
+ // check online security
+ else if (HasLowerSecurity(chr, 0))
+ return false;
+
+ if (argstr == "on")
+ {
+ chr->SetTaxiCheater(true);
+ PSendSysMessage(LANG_YOU_GIVE_TAXIS, GetNameLink(chr).c_str());
+ if (needReportToTarget(chr))
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_TAXIS_ADDED, GetNameLink().c_str());
+ return true;
+ }
+
+ if (argstr == "off")
+ {
+ chr->SetTaxiCheater(false);
+ PSendSysMessage(LANG_YOU_REMOVE_TAXIS, GetNameLink(chr).c_str());
+ if (needReportToTarget(chr))
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_TAXIS_REMOVED, GetNameLink().c_str());
+
+ return true;
+ }
+
+ SendSysMessage(LANG_USE_BOL);
+ SetSentErrorMessage(true);
+ return false;
+}
+
+//Edit Player Aspeed
+bool ChatHandler::HandleModifyASpeedCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ float ASpeed = (float)atof((char*)args);
+
+ if (ASpeed > 50.0f || ASpeed < 0.1f)
+ {
+ SendSysMessage(LANG_BAD_VALUE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Player *chr = getSelectedPlayer();
+ if (chr == NULL)
+ {
+ SendSysMessage(LANG_NO_CHAR_SELECTED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
+ std::string chrNameLink = GetNameLink(chr);
+
+ if (chr->isInFlight())
+ {
+ PSendSysMessage(LANG_CHAR_IN_FLIGHT,chrNameLink.c_str());
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ PSendSysMessage(LANG_YOU_CHANGE_ASPEED, ASpeed, chrNameLink.c_str());
+ if (needReportToTarget(chr))
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_ASPEED_CHANGED, GetNameLink().c_str(), ASpeed);
+
+ chr->SetSpeed(MOVE_WALK, ASpeed,true);
+ chr->SetSpeed(MOVE_RUN, ASpeed,true);
+ chr->SetSpeed(MOVE_SWIM, ASpeed,true);
+ //chr->SetSpeed(MOVE_TURN, ASpeed,true);
+ chr->SetSpeed(MOVE_FLIGHT, ASpeed,true);
+ return true;
+}
+
+//Edit Player Speed
+bool ChatHandler::HandleModifySpeedCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ float Speed = (float)atof((char*)args);
+
+ if (Speed > 50.0f || Speed < 0.1f)
+ {
+ SendSysMessage(LANG_BAD_VALUE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Player *chr = getSelectedPlayer();
+ if (chr == NULL)
+ {
+ SendSysMessage(LANG_NO_CHAR_SELECTED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
+ std::string chrNameLink = GetNameLink(chr);
+
+ if (chr->isInFlight())
+ {
+ PSendSysMessage(LANG_CHAR_IN_FLIGHT,chrNameLink.c_str());
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ PSendSysMessage(LANG_YOU_CHANGE_SPEED, Speed, chrNameLink.c_str());
+ if (needReportToTarget(chr))
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_SPEED_CHANGED, GetNameLink().c_str(), Speed);
+
+ chr->SetSpeed(MOVE_RUN,Speed,true);
+
+ return true;
+}
+
+//Edit Player Swim Speed
+bool ChatHandler::HandleModifySwimCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ float Swim = (float)atof((char*)args);
+
+ if (Swim > 50.0f || Swim < 0.1f)
+ {
+ SendSysMessage(LANG_BAD_VALUE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Player *chr = getSelectedPlayer();
+ if (chr == NULL)
+ {
+ SendSysMessage(LANG_NO_CHAR_SELECTED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
+ std::string chrNameLink = GetNameLink(chr);
+
+ if (chr->isInFlight())
+ {
+ PSendSysMessage(LANG_CHAR_IN_FLIGHT,chrNameLink.c_str());
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ PSendSysMessage(LANG_YOU_CHANGE_SWIM_SPEED, Swim, chrNameLink.c_str());
+ if (needReportToTarget(chr))
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_SWIM_SPEED_CHANGED, GetNameLink().c_str(), Swim);
+
+ chr->SetSpeed(MOVE_SWIM,Swim,true);
+
+ return true;
+}
+
+//Edit Player Walk Speed
+bool ChatHandler::HandleModifyBWalkCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ float BSpeed = (float)atof((char*)args);
+
+ if (BSpeed > 50.0f || BSpeed < 0.1f)
+ {
+ SendSysMessage(LANG_BAD_VALUE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Player *chr = getSelectedPlayer();
+ if (chr == NULL)
+ {
+ SendSysMessage(LANG_NO_CHAR_SELECTED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
+ std::string chrNameLink = GetNameLink(chr);
+
+ if (chr->isInFlight())
+ {
+ PSendSysMessage(LANG_CHAR_IN_FLIGHT,chrNameLink.c_str());
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ PSendSysMessage(LANG_YOU_CHANGE_BACK_SPEED, BSpeed, chrNameLink.c_str());
+ if (needReportToTarget(chr))
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_BACK_SPEED_CHANGED, GetNameLink().c_str(), BSpeed);
+
+ chr->SetSpeed(MOVE_RUN_BACK,BSpeed,true);
+
+ return true;
+}
+
+//Edit Player Fly
+bool ChatHandler::HandleModifyFlyCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ float FSpeed = (float)atof((char*)args);
+
+ if (FSpeed > 50.0f || FSpeed < 0.1f)
+ {
+ SendSysMessage(LANG_BAD_VALUE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Player *chr = getSelectedPlayer();
+ if (chr == NULL)
+ {
+ SendSysMessage(LANG_NO_CHAR_SELECTED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
+ PSendSysMessage(LANG_YOU_CHANGE_FLY_SPEED, FSpeed, GetNameLink(chr).c_str());
+ if (needReportToTarget(chr))
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_FLY_SPEED_CHANGED, GetNameLink().c_str(), FSpeed);
+
+ chr->SetSpeed(MOVE_FLIGHT,FSpeed,true);
+
+ return true;
+}
+
+//Edit Player Scale
+bool ChatHandler::HandleModifyScaleCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ float Scale = (float)atof((char*)args);
+ if (Scale > 10.0f || Scale < 0.1f)
+ {
+ SendSysMessage(LANG_BAD_VALUE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Player *chr = getSelectedPlayer();
+ if (chr == NULL)
+ {
+ SendSysMessage(LANG_NO_CHAR_SELECTED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
+ PSendSysMessage(LANG_YOU_CHANGE_SIZE, Scale, GetNameLink(chr).c_str());
+ if (needReportToTarget(chr))
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_SIZE_CHANGED, GetNameLink().c_str(), Scale);
+
+ chr->SetFloatValue(OBJECT_FIELD_SCALE_X, Scale);
+
+ return true;
+}
+
+//Enable Player mount
+bool ChatHandler::HandleModifyMountCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ uint16 mId = 1147;
+ float speed = (float)15;
+ uint32 num = 0;
+
+ num = atoi((char*)args);
+ switch(num)
+ {
+ case 1:
+ mId=14340;
+ break;
+ case 2:
+ mId=4806;
+ break;
+ case 3:
+ mId=6471;
+ break;
+ case 4:
+ mId=12345;
+ break;
+ case 5:
+ mId=6472;
+ break;
+ case 6:
+ mId=6473;
+ break;
+ case 7:
+ mId=10670;
+ break;
+ case 8:
+ mId=10719;
+ break;
+ case 9:
+ mId=10671;
+ break;
+ case 10:
+ mId=10672;
+ break;
+ case 11:
+ mId=10720;
+ break;
+ case 12:
+ mId=14349;
+ break;
+ case 13:
+ mId=11641;
+ break;
+ case 14:
+ mId=12244;
+ break;
+ case 15:
+ mId=12242;
+ break;
+ case 16:
+ mId=14578;
+ break;
+ case 17:
+ mId=14579;
+ break;
+ case 18:
+ mId=14349;
+ break;
+ case 19:
+ mId=12245;
+ break;
+ case 20:
+ mId=14335;
+ break;
+ case 21:
+ mId=207;
+ break;
+ case 22:
+ mId=2328;
+ break;
+ case 23:
+ mId=2327;
+ break;
+ case 24:
+ mId=2326;
+ break;
+ case 25:
+ mId=14573;
+ break;
+ case 26:
+ mId=14574;
+ break;
+ case 27:
+ mId=14575;
+ break;
+ case 28:
+ mId=604;
+ break;
+ case 29:
+ mId=1166;
+ break;
+ case 30:
+ mId=2402;
+ break;
+ case 31:
+ mId=2410;
+ break;
+ case 32:
+ mId=2409;
+ break;
+ case 33:
+ mId=2408;
+ break;
+ case 34:
+ mId=2405;
+ break;
+ case 35:
+ mId=14337;
+ break;
+ case 36:
+ mId=6569;
+ break;
+ case 37:
+ mId=10661;
+ break;
+ case 38:
+ mId=10666;
+ break;
+ case 39:
+ mId=9473;
+ break;
+ case 40:
+ mId=9476;
+ break;
+ case 41:
+ mId=9474;
+ break;
+ case 42:
+ mId=14374;
+ break;
+ case 43:
+ mId=14376;
+ break;
+ case 44:
+ mId=14377;
+ break;
+ case 45:
+ mId=2404;
+ break;
+ case 46:
+ mId=2784;
+ break;
+ case 47:
+ mId=2787;
+ break;
+ case 48:
+ mId=2785;
+ break;
+ case 49:
+ mId=2736;
+ break;
+ case 50:
+ mId=2786;
+ break;
+ case 51:
+ mId=14347;
+ break;
+ case 52:
+ mId=14346;
+ break;
+ case 53:
+ mId=14576;
+ break;
+ case 54:
+ mId=9695;
+ break;
+ case 55:
+ mId=9991;
+ break;
+ case 56:
+ mId=6448;
+ break;
+ case 57:
+ mId=6444;
+ break;
+ case 58:
+ mId=6080;
+ break;
+ case 59:
+ mId=6447;
+ break;
+ case 60:
+ mId=4805;
+ break;
+ case 61:
+ mId=9714;
+ break;
+ case 62:
+ mId=6448;
+ break;
+ case 63:
+ mId=6442;
+ break;
+ case 64:
+ mId=14632;
+ break;
+ case 65:
+ mId=14332;
+ break;
+ case 66:
+ mId=14331;
+ break;
+ case 67:
+ mId=8469;
+ break;
+ case 68:
+ mId=2830;
+ break;
+ case 69:
+ mId=2346;
+ break;
+ default:
+ SendSysMessage(LANG_NO_MOUNT);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Player *chr = getSelectedPlayer();
+ if (chr == NULL)
+ {
+ SendSysMessage(LANG_NO_CHAR_SELECTED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
+ PSendSysMessage(LANG_YOU_GIVE_MOUNT, GetNameLink(chr).c_str());
+ if (needReportToTarget(chr))
+ ChatHandler(chr).PSendSysMessage(LANG_MOUNT_GIVED, GetNameLink().c_str());
+
+ chr->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP);
+ chr->Mount(mId);
+
+ WorldPacket data(SMSG_FORCE_RUN_SPEED_CHANGE, (8+4+1+4));
+ data.append(chr->GetPackGUID());
+ data << (uint32)0;
+ data << (uint8)0; //new 2.1.0
+ data << float(speed);
+ chr->SendMessageToSet(&data, true);
+
+ data.Initialize(SMSG_FORCE_SWIM_SPEED_CHANGE, (8+4+4));
+ data.append(chr->GetPackGUID());
+ data << (uint32)0;
+ data << float(speed);
+ chr->SendMessageToSet(&data, true);
+
+ return true;
+}
+
+//Edit Player money
+bool ChatHandler::HandleModifyMoneyCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ Player *chr = getSelectedPlayer();
+ if (chr == NULL)
+ {
+ SendSysMessage(LANG_NO_CHAR_SELECTED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
+ int32 addmoney = atoi((char*)args);
+
+ uint32 moneyuser = chr->GetMoney();
+
+ if (addmoney < 0)
+ {
+ int32 newmoney = int32(moneyuser) + addmoney;
+
+ sLog.outDetail(GetTrinityString(LANG_CURRENT_MONEY), moneyuser, addmoney, newmoney);
+ if (newmoney <= 0)
+ {
+ PSendSysMessage(LANG_YOU_TAKE_ALL_MONEY, GetNameLink(chr).c_str());
+ if (needReportToTarget(chr))
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_ALL_MONEY_GONE, GetNameLink().c_str());
+
+ chr->SetMoney(0);
+ }
+ else
+ {
+ if (newmoney > MAX_MONEY_AMOUNT)
+ newmoney = MAX_MONEY_AMOUNT;
+
+ PSendSysMessage(LANG_YOU_TAKE_MONEY, abs(addmoney), GetNameLink(chr).c_str());
+ if (needReportToTarget(chr))
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_MONEY_TAKEN, GetNameLink().c_str(), abs(addmoney));
+ chr->SetMoney(newmoney);
+ }
+ }
+ else
+ {
+ PSendSysMessage(LANG_YOU_GIVE_MONEY, addmoney, GetNameLink(chr).c_str());
+ if (needReportToTarget(chr))
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_MONEY_GIVEN, GetNameLink().c_str(), addmoney);
+
+ if (addmoney >=MAX_MONEY_AMOUNT)
+ chr->SetMoney(MAX_MONEY_AMOUNT);
+ else
+ chr->ModifyMoney(addmoney);
+ }
+
+ sLog.outDetail(GetTrinityString(LANG_NEW_MONEY), moneyuser, addmoney, chr->GetMoney());
+
+ return true;
+}
+
+//Edit Unit field
+bool ChatHandler::HandleModifyBitCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ Unit *unit = getSelectedUnit();
+ if (!unit)
+ {
+ SendSysMessage(LANG_NO_CHAR_SELECTED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // check online security
+ if (unit->GetTypeId() == TYPEID_PLAYER && HasLowerSecurity(unit->ToPlayer(), 0))
+ return false;
+
+ char* pField = strtok((char*)args, " ");
+ if (!pField)
+ return false;
+
+ char* pBit = strtok(NULL, " ");
+ if (!pBit)
+ return false;
+
+ uint16 field = atoi(pField);
+ uint32 bit = atoi(pBit);
+
+ if (field < OBJECT_END || field >= unit->GetValuesCount())
+ {
+ SendSysMessage(LANG_BAD_VALUE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+ if (bit < 1 || bit > 32)
+ {
+ SendSysMessage(LANG_BAD_VALUE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (unit->HasFlag(field, (1<<(bit-1))))
+ {
+ unit->RemoveFlag(field, (1<<(bit-1)));
+ PSendSysMessage(LANG_REMOVE_BIT, bit, field);
+ }
+ else
+ {
+ unit->SetFlag(field, (1<<(bit-1)));
+ PSendSysMessage(LANG_SET_BIT, bit, field);
+ }
+ return true;
+}
+
+bool ChatHandler::HandleModifyHonorCommand (const char* args)
+{
+ if (!*args)
+ return false;
+
+ Player *target = getSelectedPlayer();
+ if (!target)
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // check online security
+ if (HasLowerSecurity(target, 0))
+ return false;
+
+ int32 amount = (uint32)atoi(args);
+
+ target->ModifyHonorPoints(amount);
+
+ PSendSysMessage(LANG_COMMAND_MODIFY_HONOR, GetNameLink(target).c_str(), target->GetHonorPoints());
+
+ return true;
+}
+
+bool ChatHandler::HandleTeleCommand(const char * args)
+{
+ if (!*args)
+ return false;
+
+ Player* _player = m_session->GetPlayer();
+
+ // id, or string, or [name] Shift-click form |color|Htele:id|h[name]|h|r
+ GameTele const* tele = extractGameTeleFromLink((char*)args);
+
+ if (!tele)
+ {
+ SendSysMessage(LANG_COMMAND_TELE_NOTFOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (_player->isInCombat())
+ {
+ SendSysMessage(LANG_YOU_IN_COMBAT);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ MapEntry const * me = sMapStore.LookupEntry(tele->mapId);
+ if (!me || me->IsBattleGroundOrArena())
+ {
+ SendSysMessage(LANG_CANNOT_TELE_TO_BG);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // stop flight if need
+ if (_player->isInFlight())
+ {
+ _player->GetMotionMaster()->MovementExpired();
+ _player->CleanupAfterTaxiFlight();
+ }
+ // save only in non-flight case
+ else
+ _player->SaveRecallPosition();
+
+ _player->TeleportTo(tele->mapId, tele->position_x, tele->position_y, tele->position_z, tele->orientation);
+ return true;
+}
+
+bool ChatHandler::HandleLookupAreaCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ std::string namepart = args;
+ std::wstring wnamepart;
+
+ if (!Utf8toWStr (namepart,wnamepart))
+ return false;
+
+ bool found = false;
+
+ // converting string that we try to find to lower case
+ wstrToLower (wnamepart);
+
+ // Search in AreaTable.dbc
+ for (uint32 areaflag = 0; areaflag < sAreaStore.GetNumRows (); ++areaflag)
+ {
+ AreaTableEntry const *areaEntry = sAreaStore.LookupEntry (areaflag);
+ if (areaEntry)
+ {
+ int loc = GetSessionDbcLocale ();
+ std::string name = areaEntry->area_name[loc];
+ if (name.empty())
+ continue;
+
+ if (!Utf8FitTo (name, wnamepart))
+ {
+ loc = 0;
+ for (; loc < MAX_LOCALE; ++loc)
+ {
+ if (loc == GetSessionDbcLocale ())
+ continue;
+
+ name = areaEntry->area_name[loc];
+ if (name.empty ())
+ continue;
+
+ if (Utf8FitTo (name, wnamepart))
+ break;
+ }
+ }
+
+ if (loc < MAX_LOCALE)
+ {
+ // send area in "id - [name]" format
+ std::ostringstream ss;
+ if (m_session)
+ ss << areaEntry->ID << " - |cffffffff|Harea:" << areaEntry->ID << "|h[" << name << " " << localeNames[loc]<< "]|h|r";
+ else
+ ss << areaEntry->ID << " - " << name << " " << localeNames[loc];
+
+ SendSysMessage (ss.str ().c_str());
+
+ if (!found)
+ found = true;
+ }
+ }
+ }
+
+ if (!found)
+ SendSysMessage (LANG_COMMAND_NOAREAFOUND);
+
+ return true;
+}
+
+//Find tele in game_tele order by name
+bool ChatHandler::HandleLookupTeleCommand(const char * args)
+{
+ if (!*args)
+ {
+ SendSysMessage(LANG_COMMAND_TELE_PARAMETER);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ char const* str = strtok((char*)args, " ");
+ if (!str)
+ return false;
+
+ std::string namepart = str;
+ std::wstring wnamepart;
+
+ if (!Utf8toWStr(namepart,wnamepart))
+ return false;
+
+ // converting string that we try to find to lower case
+ wstrToLower(wnamepart);
+
+ std::ostringstream reply;
+
+ GameTeleMap const & teleMap = objmgr.GetGameTeleMap();
+ for (GameTeleMap::const_iterator itr = teleMap.begin(); itr != teleMap.end(); ++itr)
+ {
+ GameTele const* tele = &itr->second;
+
+ if (tele->wnameLow.find(wnamepart) == std::wstring::npos)
+ continue;
+
+ if (m_session)
+ reply << " |cffffffff|Htele:" << itr->first << "|h[" << tele->name << "]|h|r\n";
+ else
+ reply << " " << itr->first << " " << tele->name << "\n";
+ }
+
+ if (reply.str().empty())
+ SendSysMessage(LANG_COMMAND_TELE_NOLOCATION);
+ else
+ PSendSysMessage(LANG_COMMAND_TELE_LOCATION,reply.str().c_str());
+
+ return true;
+}
+
+//Enable\Dissable accept whispers (for GM)
+bool ChatHandler::HandleWhispersCommand(const char* args)
+{
+ if (!*args)
+ {
+ PSendSysMessage(LANG_COMMAND_WHISPERACCEPTING, m_session->GetPlayer()->isAcceptWhispers() ? GetTrinityString(LANG_ON) : GetTrinityString(LANG_OFF));
+ return true;
+ }
+
+ std::string argstr = (char*)args;
+ // whisper on
+ if (argstr == "on")
+ {
+ m_session->GetPlayer()->SetAcceptWhispers(true);
+ SendSysMessage(LANG_COMMAND_WHISPERON);
+ return true;
+ }
+
+ // whisper off
+ if (argstr == "off")
+ {
+ m_session->GetPlayer()->SetAcceptWhispers(false);
+ SendSysMessage(LANG_COMMAND_WHISPEROFF);
+ return true;
+ }
+
+ SendSysMessage(LANG_USE_BOL);
+ SetSentErrorMessage(true);
+ return false;
+}
+
+//Save all players in the world
+bool ChatHandler::HandleSaveAllCommand(const char* /*args*/)
+{
+ ObjectAccessor::Instance().SaveAllPlayers();
+ SendSysMessage(LANG_PLAYERS_SAVED);
+ return true;
+}
+
+//Send mail by command
+bool ChatHandler::HandleSendMailCommand(const char* args)
+{
+ // format: name "subject text" "mail text"
+ Player* target;
+ uint64 target_guid;
+ std::string target_name;
+ if (!extractPlayerTarget((char*)args,&target,&target_guid,&target_name))
+ return false;
+
+ char* tail1 = strtok(NULL, "");
+ if (!tail1)
+ return false;
+
+ char* msgSubject = extractQuotedArg(tail1);
+ if (!msgSubject)
+ return false;
+
+ char* tail2 = strtok(NULL, "");
+ if (!tail2)
+ return false;
+
+ char* msgText = extractQuotedArg(tail2);
+ if (!msgText)
+ return false;
+
+ // msgSubject, msgText isn't NUL after prev. check
+ std::string subject = msgSubject;
+ std::string text = msgText;
+
+ // from console show not existed sender
+ MailSender sender(MAIL_NORMAL,m_session ? m_session->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM);
+
+ MailDraft(subject, text)
+ .SendMailTo(MailReceiver(target,GUID_LOPART(target_guid)),sender);
+
+ std::string nameLink = playerLink(target_name);
+ PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
+ return true;
+}
+
+// teleport player to given game_tele.entry
+bool ChatHandler::HandleTeleNameCommand(const char * args)
+{
+ char* nameStr;
+ char* teleStr;
+ extractOptFirstArg((char*)args,&nameStr,&teleStr);
+ if (!teleStr)
+ return false;
+
+ Player* target;
+ uint64 target_guid;
+ std::string target_name;
+ if (!extractPlayerTarget(nameStr,&target,&target_guid,&target_name))
+ return false;
+
+ // id, or string, or [name] Shift-click form |color|Htele:id|h[name]|h|r
+ GameTele const* tele = extractGameTeleFromLink(teleStr);
+ if (!tele)
+ {
+ SendSysMessage(LANG_COMMAND_TELE_NOTFOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+/* MapEntry const * me = sMapStore.LookupEntry(tele->mapId);
+ if (!me || me->IsBattleGroundOrArena())
+ {
+ SendSysMessage(LANG_CANNOT_TELE_TO_BG);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Player *chr = objmgr.GetPlayer(name.c_str());*/
+
+ if (target)
+ {
+ // check online security
+ if (HasLowerSecurity(target, 0))
+ return false;
+
+ std::string chrNameLink = playerLink(target_name);
+
+ if (target->IsBeingTeleported() == true)
+ {
+ PSendSysMessage(LANG_IS_TELEPORTED, chrNameLink.c_str());
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ PSendSysMessage(LANG_TELEPORTING_TO, chrNameLink.c_str(),"", tele->name.c_str());
+ if (needReportToTarget(target))
+ ChatHandler(target).PSendSysMessage(LANG_TELEPORTED_TO_BY, GetNameLink().c_str());
+
+ // stop flight if need
+ if (target->isInFlight())
+ {
+ target->GetMotionMaster()->MovementExpired();
+ target->CleanupAfterTaxiFlight();
+ }
+ // save only in non-flight case
+ else
+ target->SaveRecallPosition();
+
+ target->TeleportTo(tele->mapId,tele->position_x,tele->position_y,tele->position_z,tele->orientation);
+ }
+ else
+ {
+ // check offline security
+ if (HasLowerSecurity(NULL, target_guid))
+ return false;
+
+ std::string nameLink = playerLink(target_name);
+
+ PSendSysMessage(LANG_TELEPORTING_TO, nameLink.c_str(), GetTrinityString(LANG_OFFLINE), tele->name.c_str());
+ Player::SavePositionInDB(tele->mapId,tele->position_x,tele->position_y,tele->position_z,tele->orientation,
+ MapManager::Instance().GetZoneId(tele->mapId,tele->position_x,tele->position_y,tele->position_z),target_guid);
+ }
+
+ return true;
+}
+
+//Teleport group to given game_tele.entry
+bool ChatHandler::HandleTeleGroupCommand(const char * args)
+{
+ if (!*args)
+ return false;
+
+ Player *player = getSelectedPlayer();
+ if (!player)
+ {
+ SendSysMessage(LANG_NO_CHAR_SELECTED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // check online security
+ if (HasLowerSecurity(player, 0))
+ return false;
+
+ // id, or string, or [name] Shift-click form |color|Htele:id|h[name]|h|r
+ GameTele const* tele = extractGameTeleFromLink((char*)args);
+ if (!tele)
+ {
+ SendSysMessage(LANG_COMMAND_TELE_NOTFOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ MapEntry const * me = sMapStore.LookupEntry(tele->mapId);
+ if (!me || me->IsBattleGroundOrArena())
+ {
+ SendSysMessage(LANG_CANNOT_TELE_TO_BG);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ std::string nameLink = GetNameLink(player);
+
+ Group *grp = player->GetGroup();
+ if (!grp)
+ {
+ PSendSysMessage(LANG_NOT_IN_GROUP,nameLink.c_str());
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ for (GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
+ {
+ Player *pl = itr->getSource();
+
+ if (!pl || !pl->GetSession())
+ continue;
+
+ // check online security
+ if (HasLowerSecurity(pl, 0))
+ return false;
+
+ std::string plNameLink = GetNameLink(pl);
+
+ if (pl->IsBeingTeleported())
+ {
+ PSendSysMessage(LANG_IS_TELEPORTED, plNameLink.c_str());
+ continue;
+ }
+
+ PSendSysMessage(LANG_TELEPORTING_TO, plNameLink.c_str(),"", tele->name.c_str());
+ if (needReportToTarget(pl))
+ ChatHandler(pl).PSendSysMessage(LANG_TELEPORTED_TO_BY, nameLink.c_str());
+
+ // stop flight if need
+ if (pl->isInFlight())
+ {
+ pl->GetMotionMaster()->MovementExpired();
+ pl->CleanupAfterTaxiFlight();
+ }
+ // save only in non-flight case
+ else
+ pl->SaveRecallPosition();
+
+ pl->TeleportTo(tele->mapId, tele->position_x, tele->position_y, tele->position_z, tele->orientation);
+ }
+
+ return true;
+}
+
+//Summon group of player
+bool ChatHandler::HandleGroupgoCommand(const char* args)
+{
+ Player* target;
+ if (!extractPlayerTarget((char*)args,&target))
+ return false;
+
+ // check online security
+ if (HasLowerSecurity(target, 0))
+ return false;
+
+ Group *grp = target->GetGroup();
+
+ std::string nameLink = GetNameLink(target);
+
+ if (!grp)
+ {
+ PSendSysMessage(LANG_NOT_IN_GROUP,nameLink.c_str());
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Map* gmMap = m_session->GetPlayer()->GetMap();
+ bool to_instance = gmMap->Instanceable();
+
+ // we are in instance, and can summon only player in our group with us as lead
+ if (to_instance && (
+ !m_session->GetPlayer()->GetGroup() || (grp->GetLeaderGUID() != m_session->GetPlayer()->GetGUID()) ||
+ (m_session->GetPlayer()->GetGroup()->GetLeaderGUID() != m_session->GetPlayer()->GetGUID())))
+ // the last check is a bit excessive, but let it be, just in case
+ {
+ SendSysMessage(LANG_CANNOT_SUMMON_TO_INST);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ for (GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
+ {
+ Player *pl = itr->getSource();
+
+ if (!pl || pl == m_session->GetPlayer() || !pl->GetSession())
+ continue;
+
+ // check online security
+ if (HasLowerSecurity(pl, 0))
+ return false;
+
+ std::string plNameLink = GetNameLink(pl);
+
+ if (pl->IsBeingTeleported() == true)
+ {
+ PSendSysMessage(LANG_IS_TELEPORTED, plNameLink.c_str());
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (to_instance)
+ {
+ Map* plMap = pl->GetMap();
+
+ if (plMap->Instanceable() && plMap->GetInstanceId() != gmMap->GetInstanceId())
+ {
+ // cannot summon from instance to instance
+ PSendSysMessage(LANG_CANNOT_SUMMON_TO_INST,plNameLink.c_str());
+ SetSentErrorMessage(true);
+ return false;
+ }
+ }
+
+ PSendSysMessage(LANG_SUMMONING, plNameLink.c_str(),"");
+ if (needReportToTarget(pl))
+ ChatHandler(pl).PSendSysMessage(LANG_SUMMONED_BY, GetNameLink().c_str());
+
+ // stop flight if need
+ if (pl->isInFlight())
+ {
+ pl->GetMotionMaster()->MovementExpired();
+ pl->CleanupAfterTaxiFlight();
+ }
+ // save only in non-flight case
+ else
+ pl->SaveRecallPosition();
+
+ // before GM
+ float x,y,z;
+ m_session->GetPlayer()->GetClosePoint(x,y,z,pl->GetObjectSize());
+ pl->TeleportTo(m_session->GetPlayer()->GetMapId(),x,y,z,pl->GetOrientation());
+ }
+
+ return true;
+}
+
+bool ChatHandler::HandleGoTaxinodeCommand(const char* args)
+{
+ Player* _player = m_session->GetPlayer();
+
+ if (!*args)
+ return false;
+
+ char* cNodeId = extractKeyFromLink((char*)args,"Htaxinode");
+ if (!cNodeId)
+ return false;
+
+ int32 i_nodeId = atoi(cNodeId);
+ if (!i_nodeId)
+ return false;
+
+ TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(i_nodeId);
+ if (!node)
+ {
+ PSendSysMessage(LANG_COMMAND_GOTAXINODENOTFOUND,i_nodeId);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if ((node->x == 0.0f && node->y == 0.0f && node->z == 0.0f) ||
+ !MapManager::IsValidMapCoord(node->map_id,node->x,node->y,node->z))
+ {
+ PSendSysMessage(LANG_INVALID_TARGET_COORD,node->x,node->y,node->map_id);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // stop flight if need
+ if (_player->isInFlight())
+ {
+ _player->GetMotionMaster()->MovementExpired();
+ _player->CleanupAfterTaxiFlight();
+ }
+ // save only in non-flight case
+ else
+ _player->SaveRecallPosition();
+
+ _player->TeleportTo(node->map_id, node->x, node->y, node->z, _player->GetOrientation());
+ return true;
+}
+
+//teleport at coordinates
+bool ChatHandler::HandleGoXYCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ Player* _player = m_session->GetPlayer();
+
+ char* px = strtok((char*)args, " ");
+ char* py = strtok(NULL, " ");
+ char* pmapid = strtok(NULL, " ");
+
+ if (!px || !py)
+ return false;
+
+ float x = (float)atof(px);
+ float y = (float)atof(py);
+ uint32 mapid;
+ if (pmapid)
+ mapid = (uint32)atoi(pmapid);
+ else mapid = _player->GetMapId();
+
+ if (!MapManager::IsValidMapCoord(mapid,x,y))
+ {
+ PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // stop flight if need
+ if (_player->isInFlight())
+ {
+ _player->GetMotionMaster()->MovementExpired();
+ _player->CleanupAfterTaxiFlight();
+ }
+ // save only in non-flight case
+ else
+ _player->SaveRecallPosition();
+
+ Map const *map = MapManager::Instance().CreateBaseMap(mapid);
+ float z = std::max(map->GetHeight(x, y, MAX_HEIGHT), map->GetWaterLevel(x, y));
+
+ _player->TeleportTo(mapid, x, y, z, _player->GetOrientation());
+
+ return true;
+}
+
+//teleport at coordinates, including Z
+bool ChatHandler::HandleGoXYZCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ Player* _player = m_session->GetPlayer();
+
+ char* px = strtok((char*)args, " ");
+ char* py = strtok(NULL, " ");
+ char* pz = strtok(NULL, " ");
+ char* pmapid = strtok(NULL, " ");
+
+ if (!px || !py || !pz)
+ return false;
+
+ float x = (float)atof(px);
+ float y = (float)atof(py);
+ float z = (float)atof(pz);
+ uint32 mapid;
+ if (pmapid)
+ mapid = (uint32)atoi(pmapid);
+ else
+ mapid = _player->GetMapId();
+
+ if (!MapManager::IsValidMapCoord(mapid,x,y,z))
+ {
+ PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // stop flight if need
+ if (_player->isInFlight())
+ {
+ _player->GetMotionMaster()->MovementExpired();
+ _player->CleanupAfterTaxiFlight();
+ }
+ // save only in non-flight case
+ else
+ _player->SaveRecallPosition();
+
+ _player->TeleportTo(mapid, x, y, z, _player->GetOrientation());
+
+ return true;
+}
+
+//teleport at coordinates
+bool ChatHandler::HandleGoZoneXYCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ Player* _player = m_session->GetPlayer();
+
+ char* px = strtok((char*)args, " ");
+ char* py = strtok(NULL, " ");
+ char* tail = strtok(NULL,"");
+
+ char* cAreaId = extractKeyFromLink(tail,"Harea"); // string or [name] Shift-click form |color|Harea:area_id|h[name]|h|r
+
+ if (!px || !py)
+ return false;
+
+ float x = (float)atof(px);
+ float y = (float)atof(py);
+
+ // prevent accept wrong numeric args
+ if ((x == 0.0f && *px != '0') || (y == 0.0f && *py != '0'))
+ return false;
+
+ uint32 areaid = cAreaId ? (uint32)atoi(cAreaId) : _player->GetZoneId();
+
+ AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(areaid);
+
+ if (x<0 || x>100 || y<0 || y>100 || !areaEntry)
+ {
+ PSendSysMessage(LANG_INVALID_ZONE_COORD,x,y,areaid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // update to parent zone if exist (client map show only zones without parents)
+ AreaTableEntry const* zoneEntry = areaEntry->zone ? GetAreaEntryByAreaID(areaEntry->zone) : areaEntry;
+
+ Map const *map = MapManager::Instance().CreateBaseMap(zoneEntry->mapid);
+
+ if (map->Instanceable())
+ {
+ PSendSysMessage(LANG_INVALID_ZONE_MAP,areaEntry->ID,areaEntry->area_name[GetSessionDbcLocale()],map->GetId(),map->GetMapName());
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Zone2MapCoordinates(x,y,zoneEntry->ID);
+
+ if (!MapManager::IsValidMapCoord(zoneEntry->mapid,x,y))
+ {
+ PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,zoneEntry->mapid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // stop flight if need
+ if (_player->isInFlight())
+ {
+ _player->GetMotionMaster()->MovementExpired();
+ _player->CleanupAfterTaxiFlight();
+ }
+ // save only in non-flight case
+ else
+ _player->SaveRecallPosition();
+
+ float z = std::max(map->GetHeight(x, y, MAX_HEIGHT), map->GetWaterLevel(x, y));
+ _player->TeleportTo(zoneEntry->mapid, x, y, z, _player->GetOrientation());
+
+ return true;
+}
+
+//teleport to grid
+bool ChatHandler::HandleGoGridCommand(const char* args)
+{
+ if (!*args) return false;
+ Player* _player = m_session->GetPlayer();
+
+ char* px = strtok((char*)args, " ");
+ char* py = strtok(NULL, " ");
+ char* pmapid = strtok(NULL, " ");
+
+ if (!px || !py)
+ return false;
+
+ float grid_x = (float)atof(px);
+ float grid_y = (float)atof(py);
+ uint32 mapid;
+ if (pmapid)
+ mapid = (uint32)atoi(pmapid);
+ else mapid = _player->GetMapId();
+
+ // center of grid
+ float x = (grid_x-CENTER_GRID_ID+0.5f)*SIZE_OF_GRIDS;
+ float y = (grid_y-CENTER_GRID_ID+0.5f)*SIZE_OF_GRIDS;
+
+ if (!MapManager::IsValidMapCoord(mapid,x,y))
+ {
+ PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // stop flight if need
+ if (_player->isInFlight())
+ {
+ _player->GetMotionMaster()->MovementExpired();
+ _player->CleanupAfterTaxiFlight();
+ }
+ // save only in non-flight case
+ else
+ _player->SaveRecallPosition();
+
+ Map const *map = MapManager::Instance().CreateBaseMap(mapid);
+ float z = std::max(map->GetHeight(x, y, MAX_HEIGHT), map->GetWaterLevel(x, y));
+ _player->TeleportTo(mapid, x, y, z, _player->GetOrientation());
+
+ return true;
+}
+
+bool ChatHandler::HandleModifyDrunkCommand(const char* args)
+{
+ if (!*args) return false;
+
+ uint32 drunklevel = (uint32)atoi(args);
+ if (drunklevel > 100)
+ drunklevel = 100;
+
+ uint16 drunkMod = drunklevel * 0xFFFF / 100;
+
+ m_session->GetPlayer()->SetDrunkValue(drunkMod);
+
+ return true;
+}
+
diff --git a/src/server/game/Chat/Level2.cpp b/src/server/game/Chat/Level2.cpp
new file mode 100644
index 00000000000..4f299c932e8
--- /dev/null
+++ b/src/server/game/Chat/Level2.cpp
@@ -0,0 +1,4526 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "Common.h"
+#include "Database/DatabaseEnv.h"
+#include "DBCStores.h"
+#include "ObjectMgr.h"
+#include "Player.h"
+#include "Item.h"
+#include "GameObject.h"
+#include "Opcodes.h"
+#include "Chat.h"
+#include "MapManager.h"
+#include "Language.h"
+#include "World.h"
+#include "GameEventMgr.h"
+#include "SpellMgr.h"
+#include "PoolHandler.h"
+#include "AccountMgr.h"
+#include "WaypointManager.h"
+#include "Util.h"
+#include <cctype>
+#include <iostream>
+#include <fstream>
+#include <map>
+#include "GlobalEvents.h"
+#include "OutdoorPvPMgr.h"
+
+#include "TargetedMovementGenerator.h" // for HandleNpcUnFollowCommand
+#include "CreatureGroups.h"
+
+//mute player for some times
+bool ChatHandler::HandleMuteCommand(const char* args)
+{
+ char* nameStr;
+ char* delayStr;
+ extractOptFirstArg((char*)args,&nameStr,&delayStr);
+ if (!delayStr)
+ return false;
+
+ char *mutereason = strtok(NULL, "\r");
+ std::string mutereasonstr = "No reason";
+ if (mutereason != NULL)
+ mutereasonstr = mutereason;
+
+ Player* target;
+ uint64 target_guid;
+ std::string target_name;
+ if (!extractPlayerTarget(nameStr,&target,&target_guid,&target_name))
+ return false;
+
+ uint32 account_id = target ? target->GetSession()->GetAccountId() : objmgr.GetPlayerAccountIdByGUID(target_guid);
+
+ // find only player from same account if any
+ if (!target)
+ if (WorldSession* session = sWorld.FindSession(account_id))
+ target = session->GetPlayer();
+
+ uint32 notspeaktime = (uint32) atoi(delayStr);
+
+ // must have strong lesser security level
+ if (HasLowerSecurity (target,target_guid,true))
+ return false;
+
+ time_t mutetime = time(NULL) + notspeaktime*60;
+
+ if (target)
+ target->GetSession()->m_muteTime = mutetime;
+
+ LoginDatabase.PExecute("UPDATE account SET mutetime = " UI64FMTD " WHERE id = '%u'",uint64(mutetime), account_id);
+
+ if (target)
+ ChatHandler(target).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notspeaktime, mutereasonstr.c_str());
+
+ std::string nameLink = playerLink(target_name);
+
+ PSendSysMessage(LANG_YOU_DISABLE_CHAT, nameLink.c_str(), notspeaktime, mutereasonstr.c_str());
+
+ return true;
+}
+
+//unmute player
+bool ChatHandler::HandleUnmuteCommand(const char* args)
+{
+ Player* target;
+ uint64 target_guid;
+ std::string target_name;
+ if (!extractPlayerTarget((char*)args,&target,&target_guid,&target_name))
+ return false;
+
+ uint32 account_id = target ? target->GetSession()->GetAccountId() : objmgr.GetPlayerAccountIdByGUID(target_guid);
+
+ // find only player from same account if any
+ if (!target)
+ if (WorldSession* session = sWorld.FindSession(account_id))
+ target = session->GetPlayer();
+
+ // must have strong lesser security level
+ if (HasLowerSecurity (target,target_guid,true))
+ return false;
+
+ if (target)
+ {
+ if (target->CanSpeak())
+ {
+ SendSysMessage(LANG_CHAT_ALREADY_ENABLED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ target->GetSession()->m_muteTime = 0;
+ }
+
+ LoginDatabase.PExecute("UPDATE account SET mutetime = '0' WHERE id = '%u'", account_id);
+
+ if (target)
+ ChatHandler(target).PSendSysMessage(LANG_YOUR_CHAT_ENABLED);
+
+ std::string nameLink = playerLink(target_name);
+
+ PSendSysMessage(LANG_YOU_ENABLE_CHAT, nameLink.c_str());
+ return true;
+}
+
+bool ChatHandler::HandleGoTicketCommand(const char * args)
+{
+ if (!*args)
+ return false;
+
+ char *cstrticket_id = strtok((char*)args, " ");
+
+ if (!cstrticket_id)
+ return false;
+
+ uint64 ticket_id = atoi(cstrticket_id);
+ if (!ticket_id)
+ return false;
+
+ GM_Ticket *ticket = objmgr.GetGMTicket(ticket_id);
+ if (!ticket)
+ {
+ SendSysMessage(LANG_COMMAND_TICKETNOTEXIST);
+ return true;
+ }
+
+ float x, y, z;
+ int mapid;
+
+ x = ticket->pos_x;
+ y = ticket->pos_y;
+ z = ticket->pos_z;
+ mapid = ticket->map;
+
+ Player* _player = m_session->GetPlayer();
+ if (_player->isInFlight())
+ {
+ _player->GetMotionMaster()->MovementExpired();
+ _player->CleanupAfterTaxiFlight();
+ }
+ else
+ _player->SaveRecallPosition();
+
+ _player->TeleportTo(mapid, x, y, z, 1, 0);
+ return true;
+}
+
+bool ChatHandler::HandleGoTriggerCommand(const char* args)
+{
+ Player* _player = m_session->GetPlayer();
+
+ if (!*args)
+ return false;
+
+ char *atId = strtok((char*)args, " ");
+ if (!atId)
+ return false;
+
+ int32 i_atId = atoi(atId);
+
+ if (!i_atId)
+ return false;
+
+ AreaTriggerEntry const* at = sAreaTriggerStore.LookupEntry(i_atId);
+ if (!at)
+ {
+ PSendSysMessage(LANG_COMMAND_GOAREATRNOTFOUND,i_atId);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (!MapManager::IsValidMapCoord(at->mapid,at->x,at->y,at->z))
+ {
+ PSendSysMessage(LANG_INVALID_TARGET_COORD,at->x,at->y,at->mapid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // stop flight if need
+ if (_player->isInFlight())
+ {
+ _player->GetMotionMaster()->MovementExpired();
+ _player->CleanupAfterTaxiFlight();
+ }
+ // save only in non-flight case
+ else
+ _player->SaveRecallPosition();
+
+ _player->TeleportTo(at->mapid, at->x, at->y, at->z, _player->GetOrientation());
+ return true;
+}
+
+bool ChatHandler::HandleGoGraveyardCommand(const char* args)
+{
+ Player* _player = m_session->GetPlayer();
+
+ if (!*args)
+ return false;
+
+ char *gyId = strtok((char*)args, " ");
+ if (!gyId)
+ return false;
+
+ int32 i_gyId = atoi(gyId);
+
+ if (!i_gyId)
+ return false;
+
+ WorldSafeLocsEntry const* gy = sWorldSafeLocsStore.LookupEntry(i_gyId);
+ if (!gy)
+ {
+ PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST,i_gyId);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (!MapManager::IsValidMapCoord(gy->map_id,gy->x,gy->y,gy->z))
+ {
+ PSendSysMessage(LANG_INVALID_TARGET_COORD,gy->x,gy->y,gy->map_id);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // stop flight if need
+ if (_player->isInFlight())
+ {
+ _player->GetMotionMaster()->MovementExpired();
+ _player->CleanupAfterTaxiFlight();
+ }
+ // save only in non-flight case
+ else
+ _player->SaveRecallPosition();
+
+ _player->TeleportTo(gy->map_id, gy->x, gy->y, gy->z, _player->GetOrientation());
+ return true;
+}
+
+/** \brief Teleport the GM to the specified creature
+*
+* .gocreature <GUID> --> TP using creature.guid
+* .gocreature azuregos --> TP player to the mob with this name
+* Warning: If there is more than one mob with this name
+* you will be teleported to the first one that is found.
+* .gocreature id 6109 --> TP player to the mob, that has this creature_template.entry
+* Warning: If there is more than one mob with this "id"
+* you will be teleported to the first one that is found.
+*/
+//teleport to creature
+bool ChatHandler::HandleGoCreatureCommand(const char* args)
+{
+ if (!*args)
+ return false;
+ Player* _player = m_session->GetPlayer();
+
+ // "id" or number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
+ char* pParam1 = extractKeyFromLink((char*)args,"Hcreature");
+ if (!pParam1)
+ return false;
+
+ std::ostringstream whereClause;
+
+ // User wants to teleport to the NPC's template entry
+ if (strcmp(pParam1, "id") == 0)
+ {
+ //sLog.outError("DEBUG: ID found");
+
+ // Get the "creature_template.entry"
+ // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
+ char* tail = strtok(NULL,"");
+ if (!tail)
+ return false;
+ char* cId = extractKeyFromLink(tail,"Hcreature_entry");
+ if (!cId)
+ return false;
+
+ int32 tEntry = atoi(cId);
+ //sLog.outError("DEBUG: ID value: %d", tEntry);
+ if (!tEntry)
+ return false;
+
+ whereClause << "WHERE id = '" << tEntry << "'";
+ }
+ else
+ {
+ //sLog.outError("DEBUG: ID *not found*");
+
+ int32 guid = atoi(pParam1);
+
+ // Number is invalid - maybe the user specified the mob's name
+ if (!guid)
+ {
+ std::string name = pParam1;
+ WorldDatabase.escape_string(name);
+ whereClause << ", creature_template WHERE creature.id = creature_template.entry AND creature_template.name "_LIKE_" '" << name << "'";
+ }
+ else
+ {
+ whereClause << "WHERE guid = '" << guid << "'";
+ }
+ }
+ //sLog.outError("DEBUG: %s", whereClause.c_str());
+
+ QueryResult_AutoPtr result = WorldDatabase.PQuery("SELECT position_x,position_y,position_z,orientation,map FROM creature %s", whereClause.str().c_str());
+ if (!result)
+ {
+ SendSysMessage(LANG_COMMAND_GOCREATNOTFOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+ if (result->GetRowCount() > 1)
+ SendSysMessage(LANG_COMMAND_GOCREATMULTIPLE);
+
+ Field *fields = result->Fetch();
+ float x = fields[0].GetFloat();
+ float y = fields[1].GetFloat();
+ float z = fields[2].GetFloat();
+ float ort = fields[3].GetFloat();
+ int mapid = fields[4].GetUInt16();
+
+ if (!MapManager::IsValidMapCoord(mapid,x,y,z,ort))
+ {
+ PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // stop flight if need
+ if (_player->isInFlight())
+ {
+ _player->GetMotionMaster()->MovementExpired();
+ _player->CleanupAfterTaxiFlight();
+ }
+ // save only in non-flight case
+ else
+ _player->SaveRecallPosition();
+
+ _player->TeleportTo(mapid, x, y, z, ort);
+ return true;
+}
+
+//teleport to gameobject
+bool ChatHandler::HandleGoObjectCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ Player* _player = m_session->GetPlayer();
+
+ // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
+ char* cId = extractKeyFromLink((char*)args,"Hgameobject");
+ if (!cId)
+ return false;
+
+ int32 guid = atoi(cId);
+ if (!guid)
+ return false;
+
+ float x, y, z, ort;
+ int mapid;
+
+ // by DB guid
+ if (GameObjectData const* go_data = objmgr.GetGOData(guid))
+ {
+ x = go_data->posX;
+ y = go_data->posY;
+ z = go_data->posZ;
+ ort = go_data->orientation;
+ mapid = go_data->mapid;
+ }
+ else
+ {
+ SendSysMessage(LANG_COMMAND_GOOBJNOTFOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (!MapManager::IsValidMapCoord(mapid,x,y,z,ort))
+ {
+ PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // stop flight if need
+ if (_player->isInFlight())
+ {
+ _player->GetMotionMaster()->MovementExpired();
+ _player->CleanupAfterTaxiFlight();
+ }
+ // save only in non-flight case
+ else
+ _player->SaveRecallPosition();
+
+ _player->TeleportTo(mapid, x, y, z, ort);
+ return true;
+}
+
+bool ChatHandler::HandleGameObjectTargetCommand(const char* args)
+{
+ Player* pl = m_session->GetPlayer();
+ QueryResult_AutoPtr result;
+ GameEventMgr::ActiveEvents const& activeEventsList = gameeventmgr.GetActiveEventList();
+ if (*args)
+ {
+ // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r
+ char* cId = extractKeyFromLink((char*)args,"Hgameobject_entry");
+ if (!cId)
+ return false;
+
+ uint32 id = atol(cId);
+
+ if (id)
+ result = WorldDatabase.PQuery("SELECT guid, id, position_x, position_y, position_z, orientation, map, phaseMask, (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",
+ pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), pl->GetMapId(),id);
+ else
+ {
+ std::string name = cId;
+ WorldDatabase.escape_string(name);
+ result = WorldDatabase.PQuery(
+ "SELECT guid, id, position_x, position_y, position_z, orientation, map, phaseMask, (POW(position_x - %f, 2) + POW(position_y - %f, 2) + POW(position_z - %f, 2)) AS order_ "
+ "FROM gameobject,gameobject_template WHERE gameobject_template.entry = gameobject.id AND map = %i AND name "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")" ORDER BY order_ ASC LIMIT 1",
+ pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), pl->GetMapId(),name.c_str());
+ }
+ }
+ else
+ {
+ std::ostringstream eventFilter;
+ eventFilter << " AND (event IS NULL ";
+ bool initString = true;
+
+ for (GameEventMgr::ActiveEvents::const_iterator itr = activeEventsList.begin(); itr != activeEventsList.end(); ++itr)
+ {
+ if (initString)
+ {
+ eventFilter << "OR event IN (" <<*itr;
+ initString =false;
+ }
+ else
+ eventFilter << "," << *itr;
+ }
+
+ if (!initString)
+ eventFilter << "))";
+ else
+ eventFilter << ")";
+
+ result = WorldDatabase.PQuery("SELECT gameobject.guid, id, position_x, position_y, position_z, orientation, map, phaseMask, "
+ "(POW(position_x - %f, 2) + POW(position_y - %f, 2) + POW(position_z - %f, 2)) AS order_ FROM gameobject "
+ "LEFT OUTER JOIN game_event_gameobject on gameobject.guid=game_event_gameobject.guid WHERE map = '%i' %s ORDER BY order_ ASC LIMIT 10",
+ m_session->GetPlayer()->GetPositionX(), m_session->GetPlayer()->GetPositionY(), m_session->GetPlayer()->GetPositionZ(), m_session->GetPlayer()->GetMapId(),eventFilter.str().c_str());
+ }
+
+ if (!result)
+ {
+ SendSysMessage(LANG_COMMAND_TARGETOBJNOTFOUND);
+ return true;
+ }
+
+ bool found = false;
+ float x, y, z, o;
+ uint32 lowguid, id;
+ uint16 mapid, pool_id, phase;
+
+ do
+ {
+ Field *fields = result->Fetch();
+ lowguid = fields[0].GetUInt32();
+ id = fields[1].GetUInt32();
+ x = fields[2].GetFloat();
+ y = fields[3].GetFloat();
+ z = fields[4].GetFloat();
+ o = fields[5].GetFloat();
+ mapid = fields[6].GetUInt16();
+ phase = fields[7].GetUInt16();
+ pool_id = poolhandler.IsPartOfAPool<GameObject>(lowguid);
+ if (!pool_id || poolhandler.IsSpawnedObject<GameObject>(lowguid))
+ found = true;
+ } while (result->NextRow() && (!found));
+
+ if (!found)
+ {
+ PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST,id);
+ return false;
+ }
+
+ GameObjectInfo const* goI = objmgr.GetGameObjectInfo(id);
+
+ if (!goI)
+ {
+ PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST,id);
+ return false;
+ }
+
+ GameObject* target = m_session->GetPlayer()->GetMap()->GetGameObject(MAKE_NEW_GUID(lowguid,id,HIGHGUID_GAMEOBJECT));
+
+ PSendSysMessage(LANG_GAMEOBJECT_DETAIL, lowguid, goI->name, lowguid, id, x, y, z, mapid, o, phase);
+
+ if (target)
+ {
+ int32 curRespawnDelay = target->GetRespawnTimeEx()-time(NULL);
+ if (curRespawnDelay < 0)
+ curRespawnDelay = 0;
+
+ std::string curRespawnDelayStr = secsToTimeString(curRespawnDelay,true);
+ std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(),true);
+
+ PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES, defRespawnDelayStr.c_str(),curRespawnDelayStr.c_str());
+ }
+ return true;
+}
+
+//delete object by selection or guid
+bool ChatHandler::HandleGameObjectDeleteCommand(const char* args)
+{
+ // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
+ char* cId = extractKeyFromLink((char*)args,"Hgameobject");
+ if (!cId)
+ return false;
+
+ uint32 lowguid = atoi(cId);
+ if (!lowguid)
+ return false;
+
+ GameObject* obj = NULL;
+
+ // by DB guid
+ if (GameObjectData const* go_data = objmgr.GetGOData(lowguid))
+ obj = GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid,go_data->id);
+
+ if (!obj)
+ {
+ PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ uint64 owner_guid = obj->GetOwnerGUID();
+ if (owner_guid)
+ {
+ Unit* owner = ObjectAccessor::GetUnit(*m_session->GetPlayer(),owner_guid);
+ if (!owner || !IS_PLAYER_GUID(owner_guid))
+ {
+ PSendSysMessage(LANG_COMMAND_DELOBJREFERCREATURE, GUID_LOPART(owner_guid), obj->GetGUIDLow());
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ owner->RemoveGameObject(obj,false);
+ }
+
+ obj->SetRespawnTime(0); // not save respawn time
+ obj->Delete();
+ obj->DeleteFromDB();
+
+ PSendSysMessage(LANG_COMMAND_DELOBJMESSAGE, obj->GetGUIDLow());
+
+ return true;
+}
+
+//turn selected object
+bool ChatHandler::HandleGameObjectTurnCommand(const char* args)
+{
+ // number or [name] Shift-click form |color|Hgameobject:go_id|h[name]|h|r
+ char* cId = extractKeyFromLink((char*)args,"Hgameobject");
+ if (!cId)
+ return false;
+
+ uint32 lowguid = atoi(cId);
+ if (!lowguid)
+ return false;
+
+ GameObject* obj = NULL;
+
+ // by DB guid
+ if (GameObjectData const* go_data = objmgr.GetGOData(lowguid))
+ obj = GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid,go_data->id);
+
+ if (!obj)
+ {
+ PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ char* po = strtok(NULL, " ");
+ float o;
+
+ if (po)
+ {
+ o = (float)atof(po);
+ }
+ else
+ {
+ Player *chr = m_session->GetPlayer();
+ o = chr->GetOrientation();
+ }
+
+ obj->Relocate(obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), o);
+ obj->UpdateRotationFields();
+ obj->DestroyForNearbyPlayers();
+ obj->UpdateObjectVisibility();
+
+ obj->SaveToDB();
+ obj->Refresh();
+
+ PSendSysMessage(LANG_COMMAND_TURNOBJMESSAGE, obj->GetGUIDLow(), obj->GetGOInfo()->name, obj->GetGUIDLow(), o);
+
+ return true;
+}
+
+//move selected object
+bool ChatHandler::HandleGameObjectMoveCommand(const char* args)
+{
+ // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
+ char* cId = extractKeyFromLink((char*)args,"Hgameobject");
+ if (!cId)
+ return false;
+
+ uint32 lowguid = atoi(cId);
+ if (!lowguid)
+ return false;
+
+ GameObject* obj = NULL;
+
+ // by DB guid
+ if (GameObjectData const* go_data = objmgr.GetGOData(lowguid))
+ obj = GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid,go_data->id);
+
+ if (!obj)
+ {
+ PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ char* px = strtok(NULL, " ");
+ char* py = strtok(NULL, " ");
+ char* pz = strtok(NULL, " ");
+
+ if (!px)
+ {
+ Player *chr = m_session->GetPlayer();
+ obj->Relocate(chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), obj->GetOrientation());
+ obj->DestroyForNearbyPlayers();
+ obj->UpdateObjectVisibility();
+ }
+ else
+ {
+ if (!py || !pz)
+ return false;
+
+ float x = (float)atof(px);
+ float y = (float)atof(py);
+ float z = (float)atof(pz);
+
+ if (!MapManager::IsValidMapCoord(obj->GetMapId(),x,y,z))
+ {
+ PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,obj->GetMapId());
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ obj->Relocate(x, y, z, obj->GetOrientation());
+ obj->DestroyForNearbyPlayers();
+ obj->UpdateObjectVisibility();
+ }
+
+ obj->SaveToDB();
+ obj->Refresh();
+
+ PSendSysMessage(LANG_COMMAND_MOVEOBJMESSAGE, obj->GetGUIDLow(), obj->GetGOInfo()->name, obj->GetGUIDLow());
+
+ return true;
+}
+
+//spawn go
+bool ChatHandler::HandleGameObjectAddCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r
+ char* cId = extractKeyFromLink((char*)args,"Hgameobject_entry");
+ if (!cId)
+ return false;
+
+ uint32 id = atol(cId);
+ if (!id)
+ return false;
+
+ char* spawntimeSecs = strtok(NULL, " ");
+
+ const GameObjectInfo *gInfo = objmgr.GetGameObjectInfo(id);
+
+ if (!gInfo)
+ {
+ PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST,id);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (gInfo->displayId && !sGameObjectDisplayInfoStore.LookupEntry(gInfo->displayId))
+ {
+ // report to DB errors log as in loading case
+ sLog.outErrorDb("Gameobject (Entry %u GoType: %u) have invalid displayId (%u), not spawned.",id, gInfo->type, gInfo->displayId);
+ PSendSysMessage(LANG_GAMEOBJECT_HAVE_INVALID_DATA,id);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Player *chr = m_session->GetPlayer();
+ float x = float(chr->GetPositionX());
+ float y = float(chr->GetPositionY());
+ float z = float(chr->GetPositionZ());
+ float o = float(chr->GetOrientation());
+ Map *map = chr->GetMap();
+
+ GameObject* pGameObj = new GameObject;
+ uint32 db_lowGUID = objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT);
+
+ if (!pGameObj->Create(db_lowGUID, gInfo->id, map, chr->GetPhaseMaskForSpawn(), x, y, z, o, 0.0f, 0.0f, 0.0f, 0.0f, 0, GO_STATE_READY))
+ {
+ delete pGameObj;
+ return false;
+ }
+
+ if (spawntimeSecs)
+ {
+ uint32 value = atoi((char*)spawntimeSecs);
+ pGameObj->SetRespawnTime(value);
+ //sLog.outDebug("*** spawntimeSecs: %d", value);
+ }
+
+ // fill the gameobject data and save to the db
+ pGameObj->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()),chr->GetPhaseMaskForSpawn());
+
+ // this will generate a new guid if the object is in an instance
+ if (!pGameObj->LoadFromDB(db_lowGUID, map))
+ {
+ delete pGameObj;
+ return false;
+ }
+
+ sLog.outDebug(GetTrinityString(LANG_GAMEOBJECT_CURRENT), gInfo->name, db_lowGUID, x, y, z, o);
+
+ map->Add(pGameObj);
+
+ // TODO: is it really necessary to add both the real and DB table guid here ?
+ objmgr.AddGameobjectToGrid(db_lowGUID, objmgr.GetGOData(db_lowGUID));
+
+ PSendSysMessage(LANG_GAMEOBJECT_ADD,id,gInfo->name,db_lowGUID,x,y,z);
+ return true;
+}
+
+//set pahsemask for selected object
+bool ChatHandler::HandleGameObjectPhaseCommand(const char* args)
+{
+ // number or [name] Shift-click form |color|Hgameobject:go_id|h[name]|h|r
+ char* cId = extractKeyFromLink((char*)args,"Hgameobject");
+ if (!cId)
+ return false;
+
+ uint32 lowguid = atoi(cId);
+ if (!lowguid)
+ return false;
+
+ GameObject* obj = NULL;
+
+ // by DB guid
+ if (GameObjectData const* go_data = objmgr.GetGOData(lowguid))
+ obj = GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid,go_data->id);
+
+ if (!obj)
+ {
+ PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ char* phaseStr = strtok (NULL, " ");
+ uint32 phasemask = phaseStr? atoi(phaseStr) : 0;
+ if (phasemask == 0)
+ {
+ SendSysMessage(LANG_BAD_VALUE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ obj->SetPhaseMask(phasemask,true);
+ obj->SaveToDB();
+ return true;
+}
+
+bool ChatHandler::HandleGameObjectNearCommand(const char* args)
+{
+ float distance = (!*args) ? 10 : atol(args);
+ uint32 count = 0;
+
+ Player* pl = m_session->GetPlayer();
+ QueryResult_AutoPtr result = WorldDatabase.PQuery("SELECT guid, id, position_x, position_y, position_z, map, "
+ "(POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ "
+ "FROM gameobject WHERE map='%u' AND (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) <= '%f' ORDER BY order_",
+ pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),
+ pl->GetMapId(),pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),distance*distance);
+
+ if (result)
+ {
+ do
+ {
+ Field *fields = result->Fetch();
+ uint32 guid = fields[0].GetUInt32();
+ uint32 entry = fields[1].GetUInt32();
+ float x = fields[2].GetFloat();
+ float y = fields[3].GetFloat();
+ float z = fields[4].GetFloat();
+ int mapid = fields[5].GetUInt16();
+
+ GameObjectInfo const * gInfo = objmgr.GetGameObjectInfo(entry);
+
+ if (!gInfo)
+ continue;
+
+ PSendSysMessage(LANG_GO_LIST_CHAT, guid, guid, gInfo->name, x, y, z, mapid);
+
+ ++count;
+ } while (result->NextRow());
+ }
+
+ PSendSysMessage(LANG_COMMAND_NEAROBJMESSAGE,distance,count);
+ return true;
+}
+
+bool ChatHandler::HandleGUIDCommand(const char* /*args*/)
+{
+ uint64 guid = m_session->GetPlayer()->GetSelection();
+
+ if (guid == 0)
+ {
+ SendSysMessage(LANG_NO_SELECTION);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ PSendSysMessage(LANG_OBJECT_GUID, GUID_LOPART(guid), GUID_HIPART(guid));
+ return true;
+}
+
+bool ChatHandler::HandleModifyRepCommand(const char * args)
+{
+ if (!*args) return false;
+
+ Player* target = NULL;
+ target = getSelectedPlayer();
+
+ if (!target)
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // check online security
+ if (HasLowerSecurity(target, 0))
+ return false;
+
+ char* factionTxt = extractKeyFromLink((char*)args,"Hfaction");
+ if (!factionTxt)
+ return false;
+
+ uint32 factionId = atoi(factionTxt);
+
+ int32 amount = 0;
+ char *rankTxt = strtok(NULL, " ");
+ if (!factionTxt || !rankTxt)
+ return false;
+
+ amount = atoi(rankTxt);
+ if ((amount == 0) && (rankTxt[0] != '-') && !isdigit(rankTxt[0]))
+ {
+ std::string rankStr = rankTxt;
+ std::wstring wrankStr;
+ if (!Utf8toWStr(rankStr,wrankStr))
+ return false;
+ wstrToLower(wrankStr);
+
+ int r = 0;
+ amount = -42000;
+ for (; r < MAX_REPUTATION_RANK; ++r)
+ {
+ std::string rank = GetTrinityString(ReputationRankStrIndex[r]);
+ if (rank.empty())
+ continue;
+
+ std::wstring wrank;
+ if (!Utf8toWStr(rank,wrank))
+ continue;
+
+ wstrToLower(wrank);
+
+ if (wrank.substr(0,wrankStr.size()) == wrankStr)
+ {
+ char *deltaTxt = strtok(NULL, " ");
+ if (deltaTxt)
+ {
+ int32 delta = atoi(deltaTxt);
+ if ((delta < 0) || (delta > ReputationMgr::PointsInRank[r] -1))
+ {
+ PSendSysMessage(LANG_COMMAND_FACTION_DELTA, (ReputationMgr::PointsInRank[r]-1));
+ SetSentErrorMessage(true);
+ return false;
+ }
+ amount += delta;
+ }
+ break;
+ }
+ amount += ReputationMgr::PointsInRank[r];
+ }
+ if (r >= MAX_REPUTATION_RANK)
+ {
+ PSendSysMessage(LANG_COMMAND_FACTION_INVPARAM, rankTxt);
+ SetSentErrorMessage(true);
+ return false;
+ }
+ }
+
+ FactionEntry const *factionEntry = sFactionStore.LookupEntry(factionId);
+
+ if (!factionEntry)
+ {
+ PSendSysMessage(LANG_COMMAND_FACTION_UNKNOWN, factionId);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (factionEntry->reputationListID < 0)
+ {
+ PSendSysMessage(LANG_COMMAND_FACTION_NOREP_ERROR, factionEntry->name[GetSessionDbcLocale()], factionId);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ target->GetReputationMgr().SetReputation(factionEntry,amount);
+ PSendSysMessage(LANG_COMMAND_MODIFY_REP, factionEntry->name[GetSessionDbcLocale()], factionId,
+ GetNameLink(target).c_str(), target->GetReputationMgr().GetReputation(factionEntry));
+ return true;
+}
+
+//-----------------------Npc Commands-----------------------
+//add spawn of creature
+bool ChatHandler::HandleNpcAddCommand(const char* args)
+{
+ if (!*args)
+ return false;
+ char* charID = extractKeyFromLink((char*)args,"Hcreature_entry");
+ if (!charID)
+ return false;
+
+ char* team = strtok(NULL, " ");
+ int32 teamval = 0;
+ if (team) { teamval = atoi(team); }
+ if (teamval < 0) { teamval = 0; }
+
+ uint32 id = atoi(charID);
+
+ Player *chr = m_session->GetPlayer();
+ float x = chr->GetPositionX();
+ float y = chr->GetPositionY();
+ float z = chr->GetPositionZ();
+ float o = chr->GetOrientation();
+ Map *map = chr->GetMap();
+
+ Creature* pCreature = new Creature;
+ if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0, (uint32)teamval, x, y, z, o))
+ {
+ delete pCreature;
+ return false;
+ }
+
+ pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
+
+ uint32 db_guid = pCreature->GetDBTableGUIDLow();
+
+ // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
+ pCreature->LoadFromDB(db_guid, map);
+
+ map->Add(pCreature);
+ objmgr.AddCreatureToGrid(db_guid, objmgr.GetCreatureData(db_guid));
+ return true;
+}
+
+//add item in vendorlist
+bool ChatHandler::HandleNpcAddVendorItemCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ char* pitem = extractKeyFromLink((char*)args,"Hitem");
+ if (!pitem)
+ {
+ SendSysMessage(LANG_COMMAND_NEEDITEMSEND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ uint32 itemId = atol(pitem);
+
+ char* fmaxcount = strtok(NULL, " "); //add maxcount, default: 0
+ uint32 maxcount = 0;
+ if (fmaxcount)
+ maxcount = atol(fmaxcount);
+
+ char* fincrtime = strtok(NULL, " "); //add incrtime, default: 0
+ uint32 incrtime = 0;
+ if (fincrtime)
+ incrtime = atol(fincrtime);
+
+ char* fextendedcost = strtok(NULL, " "); //add ExtendedCost, default: 0
+ uint32 extendedcost = fextendedcost ? atol(fextendedcost) : 0;
+
+ Creature* vendor = getSelectedCreature();
+
+ uint32 vendor_entry = vendor ? vendor->GetEntry() : 0;
+
+ if (!objmgr.IsVendorItemValid(vendor_entry,itemId,maxcount,incrtime,extendedcost,m_session->GetPlayer()))
+ {
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ objmgr.AddVendorItem(vendor_entry,itemId,maxcount,incrtime,extendedcost);
+
+ ItemPrototype const* pProto = objmgr.GetItemPrototype(itemId);
+
+ PSendSysMessage(LANG_ITEM_ADDED_TO_LIST,itemId,pProto->Name1,maxcount,incrtime,extendedcost);
+ return true;
+}
+
+//del item from vendor list
+bool ChatHandler::HandleNpcDelVendorItemCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ Creature* vendor = getSelectedCreature();
+ if (!vendor || !vendor->isVendor())
+ {
+ SendSysMessage(LANG_COMMAND_VENDORSELECTION);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ char* pitem = extractKeyFromLink((char*)args,"Hitem");
+ if (!pitem)
+ {
+ SendSysMessage(LANG_COMMAND_NEEDITEMSEND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+ uint32 itemId = atol(pitem);
+
+ if (!objmgr.RemoveVendorItem(vendor->GetEntry(),itemId))
+ {
+ PSendSysMessage(LANG_ITEM_NOT_IN_LIST,itemId);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ ItemPrototype const* pProto = objmgr.GetItemPrototype(itemId);
+
+ PSendSysMessage(LANG_ITEM_DELETED_FROM_LIST,itemId,pProto->Name1);
+ return true;
+}
+
+//add move for creature
+bool ChatHandler::HandleNpcAddMoveCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ char* guid_str = strtok((char*)args, " ");
+ char* wait_str = strtok((char*)NULL, " ");
+
+ uint32 lowguid = atoi((char*)guid_str);
+
+ Creature* pCreature = NULL;
+
+ /* FIXME: impossible without entry
+ if (lowguid)
+ pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
+ */
+
+ // attempt check creature existence by DB data
+ if (!pCreature)
+ {
+ CreatureData const* data = objmgr.GetCreatureData(lowguid);
+ if (!data)
+ {
+ PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+ }
+ else
+ {
+ // obtain real GUID for DB operations
+ lowguid = pCreature->GetDBTableGUIDLow();
+ }
+
+ int wait = wait_str ? atoi(wait_str) : 0;
+
+ if (wait < 0)
+ wait = 0;
+
+ //Player* player = m_session->GetPlayer();
+
+ //WaypointMgr.AddLastNode(lowguid, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation(), wait, 0);
+
+ // update movement type
+ WorldDatabase.PExecuteLog("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE,lowguid);
+ if (pCreature && pCreature->GetWaypointPath())
+ {
+ pCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
+ pCreature->GetMotionMaster()->Initialize();
+ if (pCreature->isAlive()) // dead creature will reset movement generator at respawn
+ {
+ pCreature->setDeathState(JUST_DIED);
+ pCreature->Respawn(true);
+ }
+ pCreature->SaveToDB();
+ }
+
+ SendSysMessage(LANG_WAYPOINT_ADDED);
+
+ return true;
+}
+
+//change level of creature or pet
+bool ChatHandler::HandleNpcChangeLevelCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ uint8 lvl = (uint8) atoi((char*)args);
+ if (lvl < 1 || lvl > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL) + 3)
+ {
+ SendSysMessage(LANG_BAD_VALUE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Creature* pCreature = getSelectedCreature();
+ if (!pCreature)
+ {
+ SendSysMessage(LANG_SELECT_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (pCreature->isPet())
+ {
+ if (((Pet*)pCreature)->getPetType() == HUNTER_PET)
+ {
+ pCreature->SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, objmgr.GetXPForLevel(lvl)/4);
+ pCreature->SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, 0);
+ }
+ ((Pet*)pCreature)->GivePetLevel(lvl);
+ }
+ else
+ {
+ pCreature->SetMaxHealth(100 + 30*lvl);
+ pCreature->SetHealth(100 + 30*lvl);
+ pCreature->SetLevel(lvl);
+ pCreature->SaveToDB();
+ }
+
+ return true;
+}
+
+//set npcflag of creature
+bool ChatHandler::HandleNpcFlagCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ uint32 npcFlags = (uint32) atoi((char*)args);
+
+ Creature* pCreature = getSelectedCreature();
+
+ if (!pCreature)
+ {
+ SendSysMessage(LANG_SELECT_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ pCreature->SetUInt32Value(UNIT_NPC_FLAGS, npcFlags);
+
+ WorldDatabase.PExecuteLog("UPDATE creature_template SET npcflag = '%u' WHERE entry = '%u'", npcFlags, pCreature->GetEntry());
+
+ SendSysMessage(LANG_VALUE_SAVED_REJOIN);
+
+ return true;
+}
+
+bool ChatHandler::HandleNpcDeleteCommand(const char* args)
+{
+ Creature* unit = NULL;
+
+ if (*args)
+ {
+ // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r
+ char* cId = extractKeyFromLink((char*)args,"Hcreature");
+ if (!cId)
+ return false;
+
+ uint32 lowguid = atoi(cId);
+ if (!lowguid)
+ return false;
+
+ if (CreatureData const* cr_data = objmgr.GetCreatureData(lowguid))
+ unit = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid, cr_data->id, HIGHGUID_UNIT));
+ }
+ else
+ unit = getSelectedCreature();
+
+ if (!unit || unit->isPet() || unit->isTotem())
+ {
+ SendSysMessage(LANG_SELECT_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // Delete the creature
+ unit->CombatStop();
+ unit->DeleteFromDB();
+ unit->AddObjectToRemoveList();
+
+ SendSysMessage(LANG_COMMAND_DELCREATMESSAGE);
+
+ return true;
+}
+
+//move selected creature
+bool ChatHandler::HandleNpcMoveCommand(const char* args)
+{
+ uint32 lowguid = 0;
+
+ Creature* pCreature = getSelectedCreature();
+
+ if (!pCreature)
+ {
+ // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r
+ char* cId = extractKeyFromLink((char*)args,"Hcreature");
+ if (!cId)
+ return false;
+
+ lowguid = atoi(cId);
+
+ /* FIXME: impossibel without entry
+ if (lowguid)
+ pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
+ */
+
+ // Attempting creature load from DB data
+ if (!pCreature)
+ {
+ CreatureData const* data = objmgr.GetCreatureData(lowguid);
+ if (!data)
+ {
+ PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ uint32 map_id = data->mapid;
+
+ if (m_session->GetPlayer()->GetMapId() != map_id)
+ {
+ PSendSysMessage(LANG_COMMAND_CREATUREATSAMEMAP, lowguid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+ }
+ else
+ {
+ lowguid = pCreature->GetDBTableGUIDLow();
+ }
+ }
+ else
+ {
+ lowguid = pCreature->GetDBTableGUIDLow();
+ }
+
+ float x = m_session->GetPlayer()->GetPositionX();
+ float y = m_session->GetPlayer()->GetPositionY();
+ float z = m_session->GetPlayer()->GetPositionZ();
+ float o = m_session->GetPlayer()->GetOrientation();
+
+ if (pCreature)
+ {
+ if (CreatureData const* data = objmgr.GetCreatureData(pCreature->GetDBTableGUIDLow()))
+ {
+ const_cast<CreatureData*>(data)->posX = x;
+ const_cast<CreatureData*>(data)->posY = y;
+ const_cast<CreatureData*>(data)->posZ = z;
+ const_cast<CreatureData*>(data)->orientation = o;
+ }
+ pCreature->GetMap()->CreatureRelocation(pCreature,x, y, z,o);
+ pCreature->GetMotionMaster()->Initialize();
+ if (pCreature->isAlive()) // dead creature will reset movement generator at respawn
+ {
+ pCreature->setDeathState(JUST_DIED);
+ pCreature->Respawn();
+ }
+ }
+
+ WorldDatabase.PExecuteLog("UPDATE creature SET position_x = '%f', position_y = '%f', position_z = '%f', orientation = '%f' WHERE guid = '%u'", x, y, z, o, lowguid);
+ PSendSysMessage(LANG_COMMAND_CREATUREMOVED);
+ return true;
+}
+
+/**HandleNpcSetMoveTypeCommand
+ * Set the movement type for an NPC.<br/>
+ * <br/>
+ * Valid movement types are:
+ * <ul>
+ * <li> stay - NPC wont move </li>
+ * <li> random - NPC will move randomly according to the spawndist </li>
+ * <li> way - NPC will move with given waypoints set </li>
+ * </ul>
+ * additional parameter: NODEL - so no waypoints are deleted, if you
+ * change the movement type
+ */
+bool ChatHandler::HandleNpcSetMoveTypeCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ // 3 arguments:
+ // GUID (optional - you can also select the creature)
+ // stay|random|way (determines the kind of movement)
+ // NODEL (optional - tells the system NOT to delete any waypoints)
+ // this is very handy if you want to do waypoints, that are
+ // later switched on/off according to special events (like escort
+ // quests, etc)
+ char* guid_str = strtok((char*)args, " ");
+ char* type_str = strtok((char*)NULL, " ");
+ char* dontdel_str = strtok((char*)NULL, " ");
+
+ bool doNotDelete = false;
+
+ if (!guid_str)
+ return false;
+
+ uint32 lowguid = 0;
+ Creature* pCreature = NULL;
+
+ if (dontdel_str)
+ {
+ //sLog.outError("DEBUG: All 3 params are set");
+
+ // All 3 params are set
+ // GUID
+ // type
+ // doNotDEL
+ if (stricmp(dontdel_str, "NODEL") == 0)
+ {
+ //sLog.outError("DEBUG: doNotDelete = true;");
+ doNotDelete = true;
+ }
+ }
+ else
+ {
+ // Only 2 params - but maybe NODEL is set
+ if (type_str)
+ {
+ sLog.outError("DEBUG: Only 2 params ");
+ if (stricmp(type_str, "NODEL") == 0)
+ {
+ //sLog.outError("DEBUG: type_str, NODEL ");
+ doNotDelete = true;
+ type_str = NULL;
+ }
+ }
+ }
+
+ if (!type_str) // case .setmovetype $move_type (with selected creature)
+ {
+ type_str = guid_str;
+ pCreature = getSelectedCreature();
+ if (!pCreature || pCreature->isPet())
+ return false;
+ lowguid = pCreature->GetDBTableGUIDLow();
+ }
+ else // case .setmovetype #creature_guid $move_type (with selected creature)
+ {
+ lowguid = atoi((char*)guid_str);
+
+ /* impossible without entry
+ if (lowguid)
+ pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
+ */
+
+ // attempt check creature existence by DB data
+ if (!pCreature)
+ {
+ CreatureData const* data = objmgr.GetCreatureData(lowguid);
+ if (!data)
+ {
+ PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+ }
+ else
+ {
+ lowguid = pCreature->GetDBTableGUIDLow();
+ }
+ }
+
+ // now lowguid is low guid really existed creature
+ // and pCreature point (maybe) to this creature or NULL
+
+ MovementGeneratorType move_type;
+
+ std::string type = type_str;
+
+ if (type == "stay")
+ move_type = IDLE_MOTION_TYPE;
+ else if (type == "random")
+ move_type = RANDOM_MOTION_TYPE;
+ else if (type == "way")
+ move_type = WAYPOINT_MOTION_TYPE;
+ else
+ return false;
+
+ // update movement type
+ //if (doNotDelete == false)
+ // WaypointMgr.DeletePath(lowguid);
+
+ if (pCreature)
+ {
+ // update movement type
+ if (doNotDelete == false)
+ pCreature->LoadPath(0);
+
+ pCreature->SetDefaultMovementType(move_type);
+ pCreature->GetMotionMaster()->Initialize();
+ if (pCreature->isAlive()) // dead creature will reset movement generator at respawn
+ {
+ pCreature->setDeathState(JUST_DIED);
+ pCreature->Respawn();
+ }
+ pCreature->SaveToDB();
+ }
+ if (doNotDelete == false)
+ {
+ PSendSysMessage(LANG_MOVE_TYPE_SET,type_str);
+ }
+ else
+ {
+ PSendSysMessage(LANG_MOVE_TYPE_SET_NODEL,type_str);
+ }
+
+ return true;
+}
+
+//set model of creature
+bool ChatHandler::HandleNpcSetModelCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ uint32 displayId = (uint32) atoi((char*)args);
+
+ Creature *pCreature = getSelectedCreature();
+
+ if (!pCreature || pCreature->isPet())
+ {
+ SendSysMessage(LANG_SELECT_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ pCreature->SetDisplayId(displayId);
+ pCreature->SetNativeDisplayId(displayId);
+
+ pCreature->SaveToDB();
+
+ return true;
+}
+//set faction of creature
+bool ChatHandler::HandleNpcFactionIdCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ uint32 factionId = (uint32) atoi((char*)args);
+
+ if (!sFactionTemplateStore.LookupEntry(factionId))
+ {
+ PSendSysMessage(LANG_WRONG_FACTION, factionId);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Creature* pCreature = getSelectedCreature();
+
+ if (!pCreature)
+ {
+ SendSysMessage(LANG_SELECT_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ pCreature->setFaction(factionId);
+
+ // faction is set in creature_template - not inside creature
+
+ // update in memory
+ if (CreatureInfo const *cinfo = pCreature->GetCreatureInfo())
+ {
+ const_cast<CreatureInfo*>(cinfo)->faction_A = factionId;
+ const_cast<CreatureInfo*>(cinfo)->faction_H = factionId;
+ }
+
+ // and DB
+ WorldDatabase.PExecuteLog("UPDATE creature_template SET faction_A = '%u', faction_H = '%u' WHERE entry = '%u'", factionId, factionId, pCreature->GetEntry());
+
+ return true;
+}
+//set spawn dist of creature
+bool ChatHandler::HandleNpcSpawnDistCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ float option = atof((char*)args);
+ if (option < 0.0f)
+ {
+ SendSysMessage(LANG_BAD_VALUE);
+ return false;
+ }
+
+ MovementGeneratorType mtype = IDLE_MOTION_TYPE;
+ if (option >0.0f)
+ mtype = RANDOM_MOTION_TYPE;
+
+ Creature *pCreature = getSelectedCreature();
+ uint32 u_guidlow = 0;
+
+ if (pCreature)
+ u_guidlow = pCreature->GetDBTableGUIDLow();
+ else
+ return false;
+
+ pCreature->SetRespawnRadius((float)option);
+ pCreature->SetDefaultMovementType(mtype);
+ pCreature->GetMotionMaster()->Initialize();
+ if (pCreature->isAlive()) // dead creature will reset movement generator at respawn
+ {
+ pCreature->setDeathState(JUST_DIED);
+ pCreature->Respawn();
+ }
+
+ WorldDatabase.PExecuteLog("UPDATE creature SET spawndist=%f, MovementType=%i WHERE guid=%u",option,mtype,u_guidlow);
+ PSendSysMessage(LANG_COMMAND_SPAWNDIST,option);
+ return true;
+}
+//spawn time handling
+bool ChatHandler::HandleNpcSpawnTimeCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ char* stime = strtok((char*)args, " ");
+
+ if (!stime)
+ return false;
+
+ int i_stime = atoi((char*)stime);
+
+ if (i_stime < 0)
+ {
+ SendSysMessage(LANG_BAD_VALUE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Creature *pCreature = getSelectedCreature();
+ uint32 u_guidlow = 0;
+
+ if (pCreature)
+ u_guidlow = pCreature->GetDBTableGUIDLow();
+ else
+ return false;
+
+ WorldDatabase.PExecuteLog("UPDATE creature SET spawntimesecs=%i WHERE guid=%u",i_stime,u_guidlow);
+ pCreature->SetRespawnDelay((uint32)i_stime);
+ PSendSysMessage(LANG_COMMAND_SPAWNTIME,i_stime);
+
+ return true;
+}
+//npc follow handling
+bool ChatHandler::HandleNpcFollowCommand(const char* /*args*/)
+{
+ Player *player = m_session->GetPlayer();
+ Creature *creature = getSelectedCreature();
+
+ if (!creature)
+ {
+ PSendSysMessage(LANG_SELECT_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // Follow player - Using pet's default dist and angle
+ creature->GetMotionMaster()->MoveFollow(player, PET_FOLLOW_DIST, creature->GetFollowAngle());
+
+ PSendSysMessage(LANG_CREATURE_FOLLOW_YOU_NOW, creature->GetName());
+ return true;
+}
+//npc unfollow handling
+bool ChatHandler::HandleNpcUnFollowCommand(const char* /*args*/)
+{
+ Player *player = m_session->GetPlayer();
+ Creature *creature = getSelectedCreature();
+
+ if (!creature)
+ {
+ PSendSysMessage(LANG_SELECT_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (/*creature->GetMotionMaster()->empty() ||*/
+ creature->GetMotionMaster()->GetCurrentMovementGeneratorType () != TARGETED_MOTION_TYPE)
+ {
+ PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ TargetedMovementGenerator<Creature> const* mgen
+ = static_cast<TargetedMovementGenerator<Creature> const*>((creature->GetMotionMaster()->top()));
+
+ if (mgen->GetTarget() != player)
+ {
+ PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // reset movement
+ creature->GetMotionMaster()->MovementExpired(true);
+
+ PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU_NOW, creature->GetName());
+ return true;
+}
+//npc tame handling
+bool ChatHandler::HandleNpcTameCommand(const char* /*args*/)
+{
+ Creature *creatureTarget = getSelectedCreature ();
+ if (!creatureTarget || creatureTarget->isPet ())
+ {
+ PSendSysMessage (LANG_SELECT_CREATURE);
+ SetSentErrorMessage (true);
+ return false;
+ }
+
+ Player *player = m_session->GetPlayer ();
+
+ if (player->GetPetGUID ())
+ {
+ SendSysMessage (LANG_YOU_ALREADY_HAVE_PET);
+ SetSentErrorMessage (true);
+ return false;
+ }
+
+ CreatureInfo const* cInfo = creatureTarget->GetCreatureInfo();
+
+ if (!cInfo->isTameable (player->CanTameExoticPets()))
+ {
+ PSendSysMessage (LANG_CREATURE_NON_TAMEABLE,cInfo->Entry);
+ SetSentErrorMessage (true);
+ return false;
+ }
+
+ // Everything looks OK, create new pet
+ Pet* pet = player->CreateTamedPetFrom (creatureTarget);
+ if (!pet)
+ {
+ PSendSysMessage (LANG_CREATURE_NON_TAMEABLE,cInfo->Entry);
+ SetSentErrorMessage (true);
+ return false;
+ }
+
+ // place pet before player
+ float x,y,z;
+ player->GetClosePoint (x,y,z,creatureTarget->GetObjectSize (),CONTACT_DISTANCE);
+ pet->Relocate (x,y,z,M_PI-player->GetOrientation ());
+
+ // set pet to defensive mode by default (some classes can't control controlled pets in fact).
+ pet->SetReactState(REACT_DEFENSIVE);
+
+ // calculate proper level
+ uint8 level = (creatureTarget->getLevel() < (player->getLevel() - 5)) ? (player->getLevel() - 5) : creatureTarget->getLevel();
+
+ // prepare visual effect for levelup
+ pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1);
+
+ // add to world
+ pet->GetMap()->Add(pet->ToCreature());
+
+ // visual effect for levelup
+ pet->SetUInt32Value(UNIT_FIELD_LEVEL, level);
+
+ // caster have pet now
+ player->SetMinion(pet, true);
+
+ pet->SavePetToDB(PET_SAVE_AS_CURRENT);
+ player->PetSpellInitialize();
+
+ return true;
+}
+//npc phasemask handling
+//change phasemask of creature or pet
+bool ChatHandler::HandleNpcSetPhaseCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ uint32 phasemask = (uint32) atoi((char*)args);
+ if (phasemask == 0)
+ {
+ SendSysMessage(LANG_BAD_VALUE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Creature* pCreature = getSelectedCreature();
+ if (!pCreature)
+ {
+ SendSysMessage(LANG_SELECT_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ pCreature->SetPhaseMask(phasemask,true);
+
+ if (!pCreature->isPet())
+ pCreature->SaveToDB();
+
+ return true;
+}
+//npc deathstate handling
+bool ChatHandler::HandleNpcSetDeathStateCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ Creature* pCreature = getSelectedCreature();
+ if (!pCreature || pCreature->isPet())
+ {
+ SendSysMessage(LANG_SELECT_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (strncmp(args, "on", 3) == 0)
+ pCreature->SetDeadByDefault(true);
+ else if (strncmp(args, "off", 4) == 0)
+ pCreature->SetDeadByDefault(false);
+ else
+ {
+ SendSysMessage(LANG_USE_BOL);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ pCreature->SaveToDB();
+ pCreature->Respawn();
+
+ return true;
+}
+
+//TODO: NpcCommands that need to be fixed :
+
+bool ChatHandler::HandleNpcNameCommand(const char* /*args*/)
+{
+ /* Temp. disabled
+ if (!*args)
+ return false;
+
+ if (strlen((char*)args)>75)
+ {
+ PSendSysMessage(LANG_TOO_LONG_NAME, strlen((char*)args)-75);
+ return true;
+ }
+
+ for (uint8 i = 0; i < strlen(args); ++i)
+ {
+ if (!isalpha(args[i]) && args[i] != ' ')
+ {
+ SendSysMessage(LANG_CHARS_ONLY);
+ return false;
+ }
+ }
+
+ uint64 guid;
+ guid = m_session->GetPlayer()->GetSelection();
+ if (guid == 0)
+ {
+ SendSysMessage(LANG_NO_SELECTION);
+ return true;
+ }
+
+ Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
+
+ if (!pCreature)
+ {
+ SendSysMessage(LANG_SELECT_CREATURE);
+ return true;
+ }
+
+ pCreature->SetName(args);
+ uint32 idname = objmgr.AddCreatureTemplate(pCreature->GetName());
+ pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname);
+
+ pCreature->SaveToDB();
+ */
+
+ return true;
+}
+
+bool ChatHandler::HandleNpcSubNameCommand(const char* /*args*/)
+{
+ /* Temp. disabled
+
+ if (!*args)
+ args = "";
+
+ if (strlen((char*)args)>75)
+ {
+
+ PSendSysMessage(LANG_TOO_LONG_SUBNAME, strlen((char*)args)-75);
+ return true;
+ }
+
+ for (uint8 i = 0; i < strlen(args); i++)
+ {
+ if (!isalpha(args[i]) && args[i] != ' ')
+ {
+ SendSysMessage(LANG_CHARS_ONLY);
+ return false;
+ }
+ }
+ uint64 guid;
+ guid = m_session->GetPlayer()->GetSelection();
+ if (guid == 0)
+ {
+ SendSysMessage(LANG_NO_SELECTION);
+ return true;
+ }
+
+ Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
+
+ if (!pCreature)
+ {
+ SendSysMessage(LANG_SELECT_CREATURE);
+ return true;
+ }
+
+ uint32 idname = objmgr.AddCreatureSubName(pCreature->GetName(),args,pCreature->GetUInt32Value(UNIT_FIELD_DISPLAYID));
+ pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname);
+
+ pCreature->SaveToDB();
+ */
+ return true;
+}
+
+//move item to other slot
+bool ChatHandler::HandleItemMoveCommand(const char* args)
+{
+ if (!*args)
+ return false;
+ uint8 srcslot, dstslot;
+
+ char* pParam1 = strtok((char*)args, " ");
+ if (!pParam1)
+ return false;
+
+ char* pParam2 = strtok(NULL, " ");
+ if (!pParam2)
+ return false;
+
+ srcslot = (uint8)atoi(pParam1);
+ dstslot = (uint8)atoi(pParam2);
+
+ if (srcslot == dstslot)
+ return true;
+
+ if (!m_session->GetPlayer()->IsValidPos(INVENTORY_SLOT_BAG_0,srcslot))
+ return false;
+
+ if (!m_session->GetPlayer()->IsValidPos(INVENTORY_SLOT_BAG_0,dstslot))
+ return false;
+
+ uint16 src = ((INVENTORY_SLOT_BAG_0 << 8) | srcslot);
+ uint16 dst = ((INVENTORY_SLOT_BAG_0 << 8) | dstslot);
+
+ m_session->GetPlayer()->SwapItem(src, dst);
+
+ return true;
+}
+
+//demorph player or unit
+bool ChatHandler::HandleDeMorphCommand(const char* /*args*/)
+{
+ Unit *target = getSelectedUnit();
+ if (!target)
+ target = m_session->GetPlayer();
+
+ // check online security
+ else if (target->GetTypeId() == TYPEID_PLAYER && HasLowerSecurity((Player*)target, 0))
+ return false;
+
+ target->DeMorph();
+
+ return true;
+}
+
+//morph creature or player
+bool ChatHandler::HandleModifyMorphCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ uint16 display_id = (uint16)atoi((char*)args);
+
+ Unit *target = getSelectedUnit();
+ if (!target)
+ target = m_session->GetPlayer();
+
+ // check online security
+ else if (target->GetTypeId() == TYPEID_PLAYER && HasLowerSecurity((Player*)target, 0))
+ return false;
+
+ target->SetDisplayId(display_id);
+
+ return true;
+}
+
+//kick player
+bool ChatHandler::HandleKickPlayerCommand(const char *args)
+{
+/* const char* kickName = strtok((char*)args, " ");
+ char* kickReason = strtok(NULL, "\n");
+ std::string reason = "No Reason";
+ std::string kicker = "Console";
+ if (kickReason)
+ reason = kickReason;
+ if (m_session)
+ kicker = m_session->GetPlayer()->GetName();
+
+ if (!kickName)
+ {
+ Player* player = getSelectedPlayer();
+ if (!player)
+ {
+ SendSysMessage(LANG_NO_CHAR_SELECTED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (player == m_session->GetPlayer())
+ {
+ SendSysMessage(LANG_COMMAND_KICKSELF);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // check online security
+ if (HasLowerSecurity(player, 0))
+ return false;
+
+ if (sWorld.getConfig(CONFIG_SHOW_KICK_IN_WORLD) == 1)
+ {
+ sWorld.SendWorldText(LANG_COMMAND_KICKMESSAGE, player->GetName(), kicker.c_str(), reason.c_str());
+ }
+ else
+ {
+ PSendSysMessage(LANG_COMMAND_KICKMESSAGE, player->GetName(), kicker.c_str(), reason.c_str());
+ }
+
+ player->GetSession()->KickPlayer();
+ }
+ else
+ {
+ std::string name = extractPlayerNameFromLink((char*)kickName);
+ if (name.empty())
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (m_session && name == m_session->GetPlayer()->GetName())
+ {
+ SendSysMessage(LANG_COMMAND_KICKSELF);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Player* player = objmgr.GetPlayer(kickName);
+ if (!player)
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (HasLowerSecurity(player, 0))
+ {
+ SendSysMessage(LANG_YOURS_SECURITY_IS_LOW); //maybe replacement string for this later on
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ std::string nameLink = playerLink(name);
+
+ if (sWorld.KickPlayer(name))
+ {
+ if (sWorld.getConfig(CONFIG_SHOW_KICK_IN_WORLD) == 1)
+ {
+ sWorld.SendWorldText(LANG_COMMAND_KICKMESSAGE, nameLink.c_str(), kicker.c_str(), reason.c_str());
+ }
+ else
+ {
+ PSendSysMessage(LANG_COMMAND_KICKMESSAGE,nameLink.c_str());
+ }
+ }
+ else
+ {
+ PSendSysMessage(LANG_COMMAND_KICKNOTFOUNDPLAYER,nameLink.c_str());
+ return false;
+ }
+ }*/
+ Player* target;
+ if (!extractPlayerTarget((char*)args,&target))
+ return false;
+
+ if (m_session && target == m_session->GetPlayer())
+ {
+ SendSysMessage(LANG_COMMAND_KICKSELF);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // check online security
+ if (HasLowerSecurity(target, 0))
+ return false;
+
+ // send before target pointer invalidate
+ PSendSysMessage(LANG_COMMAND_KICKMESSAGE,GetNameLink(target).c_str());
+ target->GetSession()->KickPlayer();
+ return true;
+}
+
+//set temporary phase mask for player
+bool ChatHandler::HandleModifyPhaseCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ uint32 phasemask = (uint32)atoi((char*)args);
+
+ Unit *target = getSelectedUnit();
+ if (!target)
+ target = m_session->GetPlayer();
+
+ // check online security
+ else if (target->GetTypeId() == TYPEID_PLAYER && HasLowerSecurity((Player*)target, 0))
+ return false;
+
+ target->SetPhaseMask(phasemask,true);
+
+ return true;
+}
+//show info of gameobject
+bool ChatHandler::HandleGOInfoCommand(const char* args)
+{
+ uint32 entry = 0;
+ uint32 type = 0;
+ uint32 displayid = 0;
+ std::string name;
+
+ if (!*args)
+ {
+ if (WorldObject * obj = getSelectedObject())
+ entry = obj->GetEntry();
+ }
+ else
+ entry = atoi((char*)args);
+
+ GameObjectInfo const* goinfo = objmgr.GetGameObjectInfo(entry);
+
+ if (!goinfo)
+ return false;
+
+ type = goinfo->type;
+ displayid = goinfo->displayId;
+ name = goinfo->name;
+
+ PSendSysMessage(LANG_GOINFO_ENTRY, entry);
+ PSendSysMessage(LANG_GOINFO_TYPE, type);
+ PSendSysMessage(LANG_GOINFO_DISPLAYID, displayid);
+ PSendSysMessage(LANG_GOINFO_NAME, name.c_str());
+
+ return true;
+}
+
+//show info of player
+bool ChatHandler::HandlePInfoCommand(const char* args)
+{
+ Player* target;
+ uint64 target_guid;
+ std::string target_name;
+ if (!extractPlayerTarget((char*)args,&target,&target_guid,&target_name))
+ return false;
+
+ uint32 accId = 0;
+ uint32 money = 0;
+ uint32 total_player_time = 0;
+ uint8 level = 0;
+ uint32 latency = 0;
+ uint8 race;
+ uint8 Class;
+
+ // get additional information from Player object
+ if (target)
+ {
+ // check online security
+ if (HasLowerSecurity(target, 0))
+ return false;
+
+ accId = target->GetSession()->GetAccountId();
+ money = target->GetMoney();
+ total_player_time = target->GetTotalPlayedTime();
+ level = target->getLevel();
+ latency = target->GetSession()->GetLatency();
+ race = target->getRace();
+ Class = target->getClass();
+ }
+ // get additional information from DB
+ else
+ {
+ // check offline security
+ if (HasLowerSecurity(NULL, target_guid))
+ return false;
+
+ // 0 1 2 3 4 5
+ QueryResult_AutoPtr result = CharacterDatabase.PQuery("SELECT totaltime, level, money, account, race, class FROM characters WHERE guid = '%u'", GUID_LOPART(target_guid));
+ if (!result)
+ return false;
+
+ Field *fields = result->Fetch();
+ total_player_time = fields[0].GetUInt32();
+ level = fields[1].GetUInt32();
+ money = fields[2].GetUInt32();
+ accId = fields[3].GetUInt32();
+ race = fields[4].GetUInt8();
+ Class = fields[5].GetUInt8();
+ }
+
+ std::string username = GetTrinityString(LANG_ERROR);
+ std::string email = GetTrinityString(LANG_ERROR);
+ std::string last_ip = GetTrinityString(LANG_ERROR);
+ uint32 security = 0;
+ std::string last_login = GetTrinityString(LANG_ERROR);
+
+ QueryResult_AutoPtr result = LoginDatabase.PQuery("SELECT a.username,aa.gmlevel,a.email,a.last_ip,a.last_login "
+ "FROM account a "
+ "LEFT JOIN account_access aa "
+ "ON (a.id = aa.id) "
+ "WHERE a.id = '%u'",accId);
+ if (result)
+ {
+ Field* fields = result->Fetch();
+ username = fields[0].GetCppString();
+ security = fields[1].GetUInt32();
+ email = fields[2].GetCppString();
+
+ if (email.empty())
+ email = "-";
+
+ if (!m_session || m_session->GetSecurity() >= security)
+ {
+ last_ip = fields[3].GetCppString();
+ last_login = fields[4].GetCppString();
+ }
+ else
+ {
+ last_ip = "-";
+ last_login = "-";
+ }
+ }
+
+ std::string nameLink = playerLink(target_name);
+
+ PSendSysMessage(LANG_PINFO_ACCOUNT, (target?"":GetTrinityString(LANG_OFFLINE)), nameLink.c_str(), GUID_LOPART(target_guid), username.c_str(), accId, email.c_str(), security, last_ip.c_str(), last_login.c_str(), latency);
+
+ std::string race_s, Class_s;
+ switch(race)
+ {
+ case RACE_HUMAN: race_s = "Human"; break;
+ case RACE_ORC: race_s = "Orc"; break;
+ case RACE_DWARF: race_s = "Dwarf"; break;
+ case RACE_NIGHTELF: race_s = "Night Elf"; break;
+ case RACE_UNDEAD_PLAYER: race_s = "Undead"; break;
+ case RACE_TAUREN: race_s = "Tauren"; break;
+ case RACE_GNOME: race_s = "Gnome"; break;
+ case RACE_TROLL: race_s = "Troll"; break;
+ case RACE_BLOODELF: race_s = "Blood Elf"; break;
+ case RACE_DRAENEI: race_s = "Draenei"; break;
+ }
+ switch(Class)
+ {
+ case CLASS_WARRIOR: Class_s = "Warrior"; break;
+ case CLASS_PALADIN: Class_s = "Paladin"; break;
+ case CLASS_HUNTER: Class_s = "Hunter"; break;
+ case CLASS_ROGUE: Class_s = "Rogue"; break;
+ case CLASS_PRIEST: Class_s = "Priest"; break;
+ case CLASS_DEATH_KNIGHT: Class_s = "Death Knight"; break;
+ case CLASS_SHAMAN: Class_s = "Shaman"; break;
+ case CLASS_MAGE: Class_s = "Mage"; break;
+ case CLASS_WARLOCK: Class_s = "Warlock"; break;
+ case CLASS_DRUID: Class_s = "Druid"; break;
+ }
+
+ std::string timeStr = secsToTimeString(total_player_time,true,true);
+ uint32 gold = money /GOLD;
+ uint32 silv = (money % GOLD) / SILVER;
+ uint32 copp = (money % GOLD) % SILVER;
+ PSendSysMessage(LANG_PINFO_LEVEL, race_s.c_str(), Class_s.c_str(), timeStr.c_str(), level, gold, silv, copp);
+
+ return true;
+}
+
+/////WAYPOINT COMMANDS
+
+/**
+ * Add a waypoint to a creature.
+ *
+ * The user can either select an npc or provide its GUID.
+ *
+ * The user can even select a visual waypoint - then the new waypoint
+ * is placed *after* the selected one - this makes insertion of new
+ * waypoints possible.
+ *
+ * eg:
+ * .wp add 12345
+ * -> adds a waypoint to the npc with the GUID 12345
+ *
+ * .wp add
+ * -> adds a waypoint to the currently selected creature
+ *
+ *
+ * @param args if the user did not provide a GUID, it is NULL
+ *
+ * @return true - command did succeed, false - something went wrong
+ */
+bool ChatHandler::HandleWpAddCommand(const char* args)
+{
+ sLog.outDebug("DEBUG: HandleWpAddCommand");
+
+ // optional
+ char* path_number = NULL;
+ uint32 pathid = 0;
+
+ if (*args)
+ path_number = strtok((char*)args, " ");
+
+ uint32 point = 0;
+ Creature* target = getSelectedCreature();
+
+ if (!path_number)
+ {
+ if (target)
+ pathid = target->GetWaypointPath();
+ else
+ {
+ QueryResult_AutoPtr result = WorldDatabase.Query("SELECT MAX(id) FROM waypoint_data");
+ uint32 maxpathid = result->Fetch()->GetInt32();
+ pathid = maxpathid+1;
+ sLog.outDebug("DEBUG: HandleWpAddCommand - New path started.");
+ PSendSysMessage("%s%s|r", "|cff00ff00", "New path started.");
+ }
+ }
+ else
+ pathid = atoi(path_number);
+
+ // path_id -> ID of the Path
+ // point -> number of the waypoint (if not 0)
+
+ if (!pathid)
+ {
+ sLog.outDebug("DEBUG: HandleWpAddCommand - Current creature haven't loaded path.");
+ PSendSysMessage("%s%s|r", "|cffff33ff", "Current creature haven't loaded path.");
+ return true;
+ }
+
+ sLog.outDebug("DEBUG: HandleWpAddCommand - point == 0");
+
+ QueryResult_AutoPtr result = WorldDatabase.PQuery("SELECT MAX(point) FROM waypoint_data WHERE id = '%u'",pathid);
+
+ if (result)
+ point = (*result)[0].GetUInt32();
+
+ Player* player = m_session->GetPlayer();
+ //Map *map = player->GetMap();
+
+ WorldDatabase.PExecuteLog("INSERT INTO waypoint_data (id, point, position_x, position_y, position_z) VALUES ('%u','%u','%f', '%f', '%f')",
+ pathid, point+1, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ());
+
+ PSendSysMessage("%s%s%u%s%u%s|r", "|cff00ff00", "PathID: |r|cff00ffff", pathid, "|r|cff00ff00: Waypoint |r|cff00ffff", point+1,"|r|cff00ff00 created. ");
+ return true;
+} // HandleWpAddCommand
+
+bool ChatHandler::HandleWpLoadPathCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ // optional
+ char* path_number = NULL;
+
+ if (*args)
+ path_number = strtok((char*)args, " ");
+
+ uint32 pathid = 0;
+ uint32 guidlow = 0;
+ Creature* target = getSelectedCreature();
+
+ // Did player provide a path_id?
+ if (!path_number)
+ sLog.outDebug("DEBUG: HandleWpLoadPathCommand - No path number provided");
+
+ if (!target)
+ {
+ SendSysMessage(LANG_SELECT_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (target->GetEntry() == 1)
+ {
+ PSendSysMessage("%s%s|r", "|cffff33ff", "You want to load path to a waypoint? Aren't you?");
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ pathid = atoi(path_number);
+
+ if (!pathid)
+ {
+ PSendSysMessage("%s%s|r", "|cffff33ff", "No vallid path number provided.");
+ return true;
+ }
+
+ guidlow = target->GetDBTableGUIDLow();
+ QueryResult_AutoPtr result = WorldDatabase.PQuery("SELECT guid FROM creature_addon WHERE guid = '%u'",guidlow);
+
+ if (result)
+ WorldDatabase.PExecute("UPDATE creature_addon SET path_id = '%u' WHERE guid = '%u'", pathid, guidlow);
+ else
+ WorldDatabase.PExecute("INSERT INTO creature_addon(guid,path_id) VALUES ('%u','%u')", guidlow, pathid);
+
+ WorldDatabase.PExecute("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE, guidlow);
+
+ target->LoadPath(pathid);
+ target->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
+ target->GetMotionMaster()->Initialize();
+ target->MonsterSay("Path loaded.",0,0);
+
+ return true;
+}
+
+bool ChatHandler::HandleReloadAllPaths(const char* args)
+{
+ if (!*args)
+ return false;
+
+ uint32 id = atoi(args);
+
+ if (!id)
+ return false;
+
+ PSendSysMessage("%s%s|r|cff00ffff%u|r", "|cff00ff00", "Loading Path: ", id);
+ sWaypointMgr->UpdatePath(id);
+ return true;
+}
+
+bool ChatHandler::HandleWpUnLoadPathCommand(const char * /*args*/)
+{
+ uint32 guidlow = 0;
+ Creature* target = getSelectedCreature();
+
+ if (!target)
+ {
+ PSendSysMessage("%s%s|r", "|cff33ffff", "You must select target.");
+ return true;
+ }
+
+ if (target->GetCreatureAddon())
+ {
+ if (target->GetCreatureAddon()->path_id != 0)
+ {
+ WorldDatabase.PExecute("DELETE FROM creature_addon WHERE guid = %u", target->GetGUIDLow());
+ target->UpdateWaypointID(0);
+ WorldDatabase.PExecute("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", IDLE_MOTION_TYPE, guidlow);
+ target->LoadPath(0);
+ target->SetDefaultMovementType(IDLE_MOTION_TYPE);
+ target->GetMotionMaster()->MoveTargetedHome();
+ target->GetMotionMaster()->Initialize();
+ target->MonsterSay("Path unloaded.",0,0);
+ return true;
+ }
+ PSendSysMessage("%s%s|r", "|cffff33ff", "Target have no loaded path.");
+ }
+ return true;
+}
+
+bool ChatHandler::HandleWpEventCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ char* show_str = strtok((char*)args, " ");
+ std::string show = show_str;
+
+ // Check
+ if ((show != "add") && (show != "mod") && (show != "del") && (show != "listid")) return false;
+
+ char* arg_id = strtok(NULL, " ");
+ uint32 id = 0;
+
+ if (show == "add")
+ {
+ if (arg_id)
+ id = atoi(arg_id);
+
+ if (id)
+ {
+ QueryResult_AutoPtr result = WorldDatabase.PQuery("SELECT id FROM waypoint_scripts WHERE guid = %u", id);
+
+ if (!result)
+ {
+ WorldDatabase.PExecute("INSERT INTO waypoint_scripts(guid)VALUES(%u)", id);
+ PSendSysMessage("%s%s%u|r", "|cff00ff00", "Wp Event: New waypoint event added: ", id);
+ }
+ else
+ PSendSysMessage("|cff00ff00Wp Event: You have choosed an existing waypoint script guid: %u|r", id);
+ }
+ else
+ {
+ QueryResult_AutoPtr result = WorldDatabase.Query("SELECT MAX(guid) FROM waypoint_scripts");
+ id = result->Fetch()->GetUInt32();
+ WorldDatabase.PExecute("INSERT INTO waypoint_scripts(guid)VALUES(%u)", id+1);
+ PSendSysMessage("%s%s%u|r", "|cff00ff00","Wp Event: New waypoint event added: |r|cff00ffff", id+1);
+ }
+
+ return true;
+ }
+
+ if (show == "listid")
+ {
+ if (!arg_id)
+ {
+ PSendSysMessage("%s%s|r", "|cff33ffff","Wp Event: You must provide waypoint script id.");
+ return true;
+ }
+
+ id = atoi(arg_id);
+
+ uint32 a2, a3, a4, a5, a6;
+ float a8, a9, a10, a11;
+ char const* a7;
+
+ QueryResult_AutoPtr result = WorldDatabase.PQuery("SELECT guid, delay, command, datalong, datalong2, dataint, x, y, z, o FROM waypoint_scripts WHERE id = %u", id);
+
+ if (!result)
+ {
+ PSendSysMessage("%s%s%u|r", "|cff33ffff", "Wp Event: No waypoint scripts found on id: ", id);
+ return true;
+ }
+
+ Field *fields;
+
+ do
+ {
+ fields = result->Fetch();
+ a2 = fields[0].GetUInt32();
+ a3 = fields[1].GetUInt32();
+ a4 = fields[2].GetUInt32();
+ a5 = fields[3].GetUInt32();
+ a6 = fields[4].GetUInt32();
+ a7 = fields[5].GetString();
+ a8 = fields[6].GetFloat();
+ a9 = fields[7].GetFloat();
+ a10 = fields[8].GetFloat();
+ a11 = fields[9].GetFloat();
+
+ PSendSysMessage("|cffff33ffid:|r|cff00ffff %u|r|cff00ff00, guid: |r|cff00ffff%u|r|cff00ff00, delay: |r|cff00ffff%u|r|cff00ff00, command: |r|cff00ffff%u|r|cff00ff00, datalong: |r|cff00ffff%u|r|cff00ff00, datalong2: |r|cff00ffff%u|r|cff00ff00, datatext: |r|cff00ffff%s|r|cff00ff00, posx: |r|cff00ffff%f|r|cff00ff00, posy: |r|cff00ffff%f|r|cff00ff00, posz: |r|cff00ffff%f|r|cff00ff00, orientation: |r|cff00ffff%f|r", id, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);
+ }
+ while (result->NextRow());
+ }
+
+ if (show == "del")
+ {
+ id = atoi(arg_id);
+
+ QueryResult_AutoPtr result = WorldDatabase.PQuery("SELECT guid FROM waypoint_scripts WHERE guid = %u", id);
+
+ if (result)
+ {
+ WorldDatabase.PExecuteLog("DELETE FROM waypoint_scripts WHERE guid = %u", id);
+ PSendSysMessage("%s%s%u|r","|cff00ff00","Wp Event: Waypoint script removed: ", id);
+ }
+ else
+ PSendSysMessage("|cffff33ffWp Event: ERROR: you have selected a non existing script: %u|r", id);
+
+ return true;
+ }
+
+ if (show == "mod")
+ {
+ if (!arg_id)
+ {
+ SendSysMessage("|cffff33ffERROR: Waypoint script guid not present.|r");
+ return true;
+ }
+
+ id = atoi(arg_id);
+
+ if (!id)
+ {
+ SendSysMessage("|cffff33ffERROR: No vallid waypoint script id not present.|r");
+ return true;
+ }
+
+ char* arg_2 = strtok(NULL," ");
+
+ if (!arg_2)
+ {
+ SendSysMessage("|cffff33ffERROR: No argument present.|r");
+ return true;
+ }
+
+ std::string arg_string = arg_2;
+
+ if ((arg_string != "setid") && (arg_string != "delay") && (arg_string != "command")
+ && (arg_string != "datalong") && (arg_string != "datalong2") && (arg_string != "dataint") && (arg_string != "posx")
+ && (arg_string != "posy") && (arg_string != "posz") && (arg_string != "orientation"))
+ {
+ SendSysMessage("|cffff33ffERROR: No valid argument present.|r");
+ return true;
+ }
+
+ char* arg_3;
+ std::string arg_str_2 = arg_2;
+ arg_3 = strtok(NULL," ");
+
+ if (!arg_3)
+ {
+ SendSysMessage("|cffff33ffERROR: No additional argument present.|r");
+ return true;
+ }
+
+ float coord;
+
+ if (arg_str_2 == "setid")
+ {
+ uint32 newid = atoi(arg_3);
+ PSendSysMessage("%s%s|r|cff00ffff%u|r|cff00ff00%s|r|cff00ffff%u|r","|cff00ff00","Wp Event: Wypoint scipt guid: ", newid," id changed: ", id);
+ WorldDatabase.PExecuteLog("UPDATE waypoint_scripts SET id='%u' WHERE guid='%u'",
+ newid, id); return true;
+ }
+ else
+ {
+ QueryResult_AutoPtr result = WorldDatabase.PQuery("SELECT id FROM waypoint_scripts WHERE guid='%u'",id);
+
+ if (!result)
+ {
+ SendSysMessage("|cffff33ffERROR: You have selected an non existing waypoint script guid.|r");
+ return true;
+ }
+
+ if (arg_str_2 == "posx")
+ {
+ coord = atof(arg_3);
+ WorldDatabase.PExecuteLog("UPDATE waypoint_scripts SET x='%f' WHERE guid='%u'",
+ coord, id);
+ PSendSysMessage("|cff00ff00Waypoint script:|r|cff00ffff %u|r|cff00ff00 position_x updated.|r", id);
+ return true;
+ }
+ else if (arg_str_2 == "posy")
+ {
+ coord = atof(arg_3);
+ WorldDatabase.PExecuteLog("UPDATE waypoint_scripts SET y='%f' WHERE guid='%u'",
+ coord, id);
+ PSendSysMessage("|cff00ff00Waypoint script: %u position_y updated.|r", id);
+ return true;
+ }
+ else if (arg_str_2 == "posz")
+ {
+ coord = atof(arg_3);
+ WorldDatabase.PExecuteLog("UPDATE waypoint_scripts SET z='%f' WHERE guid='%u'",
+ coord, id);
+ PSendSysMessage("|cff00ff00Waypoint script: |r|cff00ffff%u|r|cff00ff00 position_z updated.|r", id);
+ return true;
+ }
+ else if (arg_str_2 == "orientation")
+ {
+ coord = atof(arg_3);
+ WorldDatabase.PExecuteLog("UPDATE waypoint_scripts SET o='%f' WHERE guid='%u'",
+ coord, id);
+ PSendSysMessage("|cff00ff00Waypoint script: |r|cff00ffff%u|r|cff00ff00 orientation updated.|r", id);
+ return true;
+ }
+ else if (arg_str_2 == "dataint")
+ {
+ WorldDatabase.PExecuteLog("UPDATE waypoint_scripts SET %s='%u' WHERE guid='%u'",
+ arg_2, atoi(arg_3), id);
+ PSendSysMessage("|cff00ff00Waypoint script: |r|cff00ffff%u|r|cff00ff00 dataint updated.|r", id);
+ return true;
+ }
+ else
+ {
+ std::string arg_str_3 = arg_3;
+ WorldDatabase.escape_string(arg_str_3);
+ WorldDatabase.PExecuteLog("UPDATE waypoint_scripts SET %s='%s' WHERE guid='%u'",
+ arg_2, arg_str_3.c_str(), id);
+ }
+ }
+ PSendSysMessage("%s%s|r|cff00ffff%u:|r|cff00ff00 %s %s|r","|cff00ff00","Waypoint script:", id, arg_2,"updated.");
+ }
+ return true;
+}
+
+bool ChatHandler::HandleWpModifyCommand(const char* args)
+{
+ sLog.outDebug("DEBUG: HandleWpModifyCommand");
+
+ if (!*args)
+ return false;
+
+ // first arg: add del text emote spell waittime move
+ char* show_str = strtok((char*)args, " ");
+ if (!show_str)
+ {
+ return false;
+ }
+
+ std::string show = show_str;
+ // Check
+ // Remember: "show" must also be the name of a column!
+ if ((show != "delay") && (show != "action") && (show != "action_chance")
+ && (show != "move_flag") && (show != "del") && (show != "move") && (show != "wpadd")
+)
+ {
+ return false;
+ }
+
+ // Next arg is: <PATHID> <WPNUM> <ARGUMENT>
+ char* arg_str = NULL;
+
+ // Did user provide a GUID
+ // or did the user select a creature?
+ // -> variable lowguid is filled with the GUID of the NPC
+ uint32 pathid = 0;
+ uint32 point = 0;
+ uint32 wpGuid = 0;
+ Creature* target = getSelectedCreature();
+
+ if (!target || target->GetEntry() != VISUAL_WAYPOINT)
+ {
+ SendSysMessage("|cffff33ffERROR: You must select a waypoint.|r");
+ return false;
+ }
+
+ sLog.outDebug("DEBUG: HandleWpModifyCommand - User did select an NPC");
+ // The visual waypoint
+ Creature* wpCreature = NULL;
+ wpGuid = target->GetGUIDLow();
+
+ // Did the user select a visual spawnpoint?
+ if (wpGuid)
+ wpCreature = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT));
+ // attempt check creature existence by DB data
+ else
+ {
+ PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, wpGuid);
+ return false;
+ }
+ // User did select a visual waypoint?
+ // Check the creature
+ if (wpCreature->GetEntry() == VISUAL_WAYPOINT)
+ {
+ QueryResult_AutoPtr result = WorldDatabase.PQuery("SELECT id, point FROM waypoint_data WHERE wpguid = %u", wpGuid);
+
+ if (!result)
+ {
+ sLog.outDebug("DEBUG: HandleWpModifyCommand - No waypoint found - used 'wpguid'");
+
+ PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, target->GetGUIDLow());
+ // Select waypoint number from database
+ // Since we compare float values, we have to deal with
+ // some difficulties.
+ // Here we search for all waypoints that only differ in one from 1 thousand
+ // (0.001) - There is no other way to compare C++ floats with mySQL floats
+ // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
+ const char* maxDIFF = "0.01";
+ result = WorldDatabase.PQuery("SELECT id, point FROM waypoint_data WHERE (abs(position_x - %f) <= %s) and (abs(position_y - %f) <= %s) and (abs(position_z - %f) <= %s)",
+ wpCreature->GetPositionX(), maxDIFF, wpCreature->GetPositionY(), maxDIFF, wpCreature->GetPositionZ(), maxDIFF);
+ if (!result)
+ {
+ PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, wpGuid);
+ return true;
+ }
+ }
+ sLog.outDebug("DEBUG: HandleWpModifyCommand - After getting wpGuid");
+
+ do
+ {
+ Field *fields = result->Fetch();
+ pathid = fields[0].GetUInt32();
+ point = fields[1].GetUInt32();
+ }
+ while (result->NextRow());
+
+ // We have the waypoint number and the GUID of the "master npc"
+ // Text is enclosed in "<>", all other arguments not
+ arg_str = strtok((char*)NULL, " ");
+ }
+
+ sLog.outDebug("DEBUG: HandleWpModifyCommand - Parameters parsed - now execute the command");
+
+ // Check for argument
+ if (show != "del" && show != "move" && arg_str == NULL)
+ {
+ PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ, show_str);
+ return false;
+ }
+
+ if (show == "del" && target)
+ {
+ PSendSysMessage("|cff00ff00DEBUG: wp modify del, PathID: |r|cff00ffff%u|r", pathid);
+
+ // wpCreature
+ Creature* wpCreature = NULL;
+
+ if (wpGuid != 0)
+ {
+ wpCreature = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT));
+ wpCreature->CombatStop();
+ wpCreature->DeleteFromDB();
+ wpCreature->AddObjectToRemoveList();
+ }
+
+ WorldDatabase.PExecuteLog("DELETE FROM waypoint_data WHERE id='%u' AND point='%u'",
+ pathid, point);
+ WorldDatabase.PExecuteLog("UPDATE waypoint_data SET point=point-1 WHERE id='%u' AND point>'%u'",
+ pathid, point);
+
+ PSendSysMessage(LANG_WAYPOINT_REMOVED);
+ return true;
+ } // del
+
+ if (show == "move" && target)
+ {
+ PSendSysMessage("|cff00ff00DEBUG: wp move, PathID: |r|cff00ffff%u|r", pathid);
+
+ Player *chr = m_session->GetPlayer();
+ Map *map = chr->GetMap();
+ {
+ // wpCreature
+ Creature* wpCreature = NULL;
+ // What to do:
+ // Move the visual spawnpoint
+ // Respawn the owner of the waypoints
+ if (wpGuid != 0)
+ {
+ wpCreature = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT));
+ wpCreature->CombatStop();
+ wpCreature->DeleteFromDB();
+ wpCreature->AddObjectToRemoveList();
+ // re-create
+ Creature* wpCreature2 = new Creature;
+ if (!wpCreature2->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), VISUAL_WAYPOINT, 0, 0, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation()))
+ {
+ PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT);
+ delete wpCreature2;
+ return false;
+ }
+
+ wpCreature2->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
+ // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
+ wpCreature2->LoadFromDB(wpCreature2->GetDBTableGUIDLow(), map);
+ map->Add(wpCreature2);
+ //MapManager::Instance().GetMap(npcCreature->GetMapId())->Add(wpCreature2);
+ }
+
+ WorldDatabase.PExecuteLog("UPDATE waypoint_data SET position_x = '%f',position_y = '%f',position_z = '%f' where id = '%u' AND point='%u'",
+ chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), pathid, point);
+
+ PSendSysMessage(LANG_WAYPOINT_CHANGED);
+ }
+ return true;
+ } // move
+
+ const char *text = arg_str;
+
+ if (text == 0)
+ {
+ // show_str check for present in list of correct values, no sql injection possible
+ WorldDatabase.PExecuteLog("UPDATE waypoint_data SET %s=NULL WHERE id='%u' AND point='%u'",
+ show_str, pathid, point);
+ }
+ else
+ {
+ // show_str check for present in list of correct values, no sql injection possible
+ std::string text2 = text;
+ WorldDatabase.escape_string(text2);
+ WorldDatabase.PExecuteLog("UPDATE waypoint_data SET %s='%s' WHERE id='%u' AND point='%u'",
+ show_str, text2.c_str(), pathid, point);
+ }
+
+ PSendSysMessage(LANG_WAYPOINT_CHANGED_NO, show_str);
+ return true;
+}
+
+bool ChatHandler::HandleWpShowCommand(const char* args)
+{
+ sLog.outDebug("DEBUG: HandleWpShowCommand");
+
+ if (!*args)
+ return false;
+
+ // first arg: on, off, first, last
+ char* show_str = strtok((char*)args, " ");
+ if (!show_str)
+ return false;
+
+ // second arg: GUID (optional, if a creature is selected)
+ char* guid_str = strtok((char*)NULL, " ");
+ sLog.outDebug("DEBUG: HandleWpShowCommand: show_str: %s guid_str: %s", show_str, guid_str);
+
+ uint32 pathid = 0;
+ Creature* target = getSelectedCreature();
+
+ // Did player provide a PathID?
+
+ if (!guid_str)
+ {
+ sLog.outDebug("DEBUG: HandleWpShowCommand: !guid_str");
+ // No PathID provided
+ // -> Player must have selected a creature
+
+ if (!target)
+ {
+ SendSysMessage(LANG_SELECT_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ pathid = target->GetWaypointPath();
+ }
+ else
+ {
+ sLog.outDebug("|cff00ff00DEBUG: HandleWpShowCommand: PathID provided|r");
+ // PathID provided
+ // Warn if player also selected a creature
+ // -> Creature selection is ignored <-
+ if (target)
+ SendSysMessage(LANG_WAYPOINT_CREATSELECTED);
+
+ pathid = atoi((char*)guid_str);
+ }
+
+ sLog.outDebug("DEBUG: HandleWpShowCommand: danach");
+
+ std::string show = show_str;
+ uint32 Maxpoint;
+
+ sLog.outDebug("DEBUG: HandleWpShowCommand: PathID: %u", pathid);
+
+ //PSendSysMessage("wpshow - show: %s", show);
+
+ // Show info for the selected waypoint
+ if (show == "info")
+ {
+ // Check if the user did specify a visual waypoint
+ if (target->GetEntry() != VISUAL_WAYPOINT)
+ {
+ PSendSysMessage(LANG_WAYPOINT_VP_SELECT);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ QueryResult_AutoPtr result = WorldDatabase.PQuery("SELECT id, point, delay, move_flag, action, action_chance FROM waypoint_data WHERE wpguid = %u", target->GetGUIDLow());
+
+ if (!result)
+ {
+ SendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM);
+ return true;
+ }
+
+ SendSysMessage("|cff00ffffDEBUG: wp show info:|r");
+ do
+ {
+ Field *fields = result->Fetch();
+ pathid = fields[0].GetUInt32();
+ uint32 point = fields[1].GetUInt32();
+ uint32 delay = fields[2].GetUInt32();
+ uint32 flag = fields[3].GetUInt32();
+ uint32 ev_id = fields[4].GetUInt32();
+ uint32 ev_chance = fields[5].GetUInt32();
+
+ PSendSysMessage("|cff00ff00Show info: for current point: |r|cff00ffff%u|r|cff00ff00, Path ID: |r|cff00ffff%u|r", point, pathid);
+ PSendSysMessage("|cff00ff00Show info: delay: |r|cff00ffff%u|r", delay);
+ PSendSysMessage("|cff00ff00Show info: Move flag: |r|cff00ffff%u|r", flag);
+ PSendSysMessage("|cff00ff00Show info: Waypoint event: |r|cff00ffff%u|r", ev_id);
+ PSendSysMessage("|cff00ff00Show info: Event chance: |r|cff00ffff%u|r", ev_chance);
+ }
+ while (result->NextRow());
+
+ return true;
+ }
+
+ if (show == "on")
+ {
+ QueryResult_AutoPtr result = WorldDatabase.PQuery("SELECT point, position_x,position_y,position_z FROM waypoint_data WHERE id = '%u'", pathid);
+
+ if (!result)
+ {
+ SendSysMessage("|cffff33ffPath no found.|r");
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ PSendSysMessage("|cff00ff00DEBUG: wp on, PathID: |cff00ffff%u|r", pathid);
+
+ // Delete all visuals for this NPC
+ QueryResult_AutoPtr result2 = WorldDatabase.PQuery("SELECT wpguid FROM waypoint_data WHERE id = '%u' and wpguid <> 0", pathid);
+
+ if (result2)
+ {
+ bool hasError = false;
+ do
+ {
+ Field *fields = result2->Fetch();
+ uint32 wpguid = fields[0].GetUInt32();
+ Creature* pCreature = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpguid,VISUAL_WAYPOINT,HIGHGUID_UNIT));
+
+ if (!pCreature)
+ {
+ PSendSysMessage(LANG_WAYPOINT_NOTREMOVED, wpguid);
+ hasError = true;
+ WorldDatabase.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", wpguid);
+ }
+ else
+ {
+ pCreature->CombatStop();
+ pCreature->DeleteFromDB();
+ pCreature->AddObjectToRemoveList();
+ }
+
+ }
+ while (result2->NextRow());
+
+ if (hasError)
+ {
+ PSendSysMessage(LANG_WAYPOINT_TOOFAR1);
+ PSendSysMessage(LANG_WAYPOINT_TOOFAR2);
+ PSendSysMessage(LANG_WAYPOINT_TOOFAR3);
+ }
+ }
+
+ do
+ {
+ Field *fields = result->Fetch();
+ uint32 point = fields[0].GetUInt32();
+ float x = fields[1].GetFloat();
+ float y = fields[2].GetFloat();
+ float z = fields[3].GetFloat();
+
+ uint32 id = VISUAL_WAYPOINT;
+
+ Player *chr = m_session->GetPlayer();
+ Map *map = chr->GetMap();
+ float o = chr->GetOrientation();
+
+ Creature* wpCreature = new Creature;
+ if (!wpCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0, 0, x, y, z, o))
+ {
+ PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);
+ delete wpCreature;
+ return false;
+ }
+
+ sLog.outDebug("DEBUG: UPDATE waypoint_data SET wpguid = '%u");
+ // set "wpguid" column to the visual waypoint
+ WorldDatabase.PExecuteLog("UPDATE waypoint_data SET wpguid = '%u' WHERE id = '%u' and point = '%u'", wpCreature->GetGUIDLow(), pathid, point);
+
+ wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
+ // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
+ wpCreature->LoadFromDB(wpCreature->GetDBTableGUIDLow(),map);
+ map->Add(wpCreature);
+
+ if (target)
+ {
+ wpCreature->SetDisplayId(target->GetDisplayId());
+ wpCreature->SetFloatValue(OBJECT_FIELD_SCALE_X, 0.5);
+ wpCreature->SetLevel(point > MAX_LEVEL ? MAX_LEVEL : point);
+ }
+ }
+ while (result->NextRow());
+
+ SendSysMessage("|cff00ff00Showing the current creature's path.|r");
+ return true;
+ }
+
+ if (show == "first")
+ {
+ PSendSysMessage("|cff00ff00DEBUG: wp first, GUID: %u|r", pathid);
+
+ QueryResult_AutoPtr result = WorldDatabase.PQuery("SELECT position_x,position_y,position_z FROM waypoint_data WHERE point='1' AND id = '%u'",pathid);
+ if (!result)
+ {
+ PSendSysMessage(LANG_WAYPOINT_NOTFOUND, pathid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Field *fields = result->Fetch();
+ float x = fields[0].GetFloat();
+ float y = fields[1].GetFloat();
+ float z = fields[2].GetFloat();
+ uint32 id = VISUAL_WAYPOINT;
+
+ Player *chr = m_session->GetPlayer();
+ float o = chr->GetOrientation();
+ Map *map = chr->GetMap();
+
+ Creature* pCreature = new Creature;
+ if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT),map, chr->GetPhaseMaskForSpawn(), id, 0, 0, x, y, z, o))
+ {
+ PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);
+ delete pCreature;
+ return false;
+ }
+
+ pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
+ pCreature->LoadFromDB(pCreature->GetDBTableGUIDLow(), map);
+ map->Add(pCreature);
+
+ if (target)
+ {
+ pCreature->SetDisplayId(target->GetDisplayId());
+ pCreature->SetFloatValue(OBJECT_FIELD_SCALE_X, 0.5);
+ }
+
+ return true;
+ }
+
+ if (show == "last")
+ {
+ PSendSysMessage("|cff00ff00DEBUG: wp last, PathID: |r|cff00ffff%u|r", pathid);
+
+ QueryResult_AutoPtr result = WorldDatabase.PQuery("SELECT MAX(point) FROM waypoint_data WHERE id = '%u'",pathid);
+ if (result)
+ Maxpoint = (*result)[0].GetUInt32();
+ else
+ Maxpoint = 0;
+
+ result = WorldDatabase.PQuery("SELECT position_x,position_y,position_z FROM waypoint_data WHERE point ='%u' AND id = '%u'",Maxpoint, pathid);
+ if (!result)
+ {
+ PSendSysMessage(LANG_WAYPOINT_NOTFOUNDLAST, pathid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+ Field *fields = result->Fetch();
+ float x = fields[0].GetFloat();
+ float y = fields[1].GetFloat();
+ float z = fields[2].GetFloat();
+ uint32 id = VISUAL_WAYPOINT;
+
+ Player *chr = m_session->GetPlayer();
+ float o = chr->GetOrientation();
+ Map *map = chr->GetMap();
+
+ Creature* pCreature = new Creature;
+ if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0, 0, x, y, z, o))
+ {
+ PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id);
+ delete pCreature;
+ return false;
+ }
+
+ pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
+ pCreature->LoadFromDB(pCreature->GetDBTableGUIDLow(), map);
+ map->Add(pCreature);
+
+ if (target)
+ {
+ pCreature->SetDisplayId(target->GetDisplayId());
+ pCreature->SetFloatValue(OBJECT_FIELD_SCALE_X, 0.5);
+ }
+
+ return true;
+ }
+
+ if (show == "off")
+ {
+ QueryResult_AutoPtr result = WorldDatabase.PQuery("SELECT guid FROM creature WHERE id = '%u'", 1);
+ if (!result)
+ {
+ SendSysMessage(LANG_WAYPOINT_VP_NOTFOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+ bool hasError = false;
+ do
+ {
+ Field *fields = result->Fetch();
+ uint32 guid = fields[0].GetUInt32();
+ Creature* pCreature = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(guid,VISUAL_WAYPOINT,HIGHGUID_UNIT));
+ if (!pCreature)
+ {
+ PSendSysMessage(LANG_WAYPOINT_NOTREMOVED, guid);
+ hasError = true;
+ WorldDatabase.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", guid);
+ }
+ else
+ {
+ pCreature->CombatStop();
+ pCreature->DeleteFromDB();
+ pCreature->AddObjectToRemoveList();
+ }
+ }
+ while (result->NextRow());
+ // set "wpguid" column to "empty" - no visual waypoint spawned
+ WorldDatabase.PExecuteLog("UPDATE waypoint_data SET wpguid = '0'");
+ //WorldDatabase.PExecuteLog("UPDATE creature_movement SET wpguid = '0' WHERE wpguid <> '0'");
+
+ if (hasError)
+ {
+ PSendSysMessage(LANG_WAYPOINT_TOOFAR1);
+ PSendSysMessage(LANG_WAYPOINT_TOOFAR2);
+ PSendSysMessage(LANG_WAYPOINT_TOOFAR3);
+ }
+
+ SendSysMessage(LANG_WAYPOINT_VP_ALLREMOVED);
+ return true;
+ }
+
+ PSendSysMessage("|cffff33ffDEBUG: wpshow - no valid command found|r");
+ return true;
+}
+
+//////////// WAYPOINT COMMANDS //
+
+//rename characters
+bool ChatHandler::HandleCharacterRenameCommand(const char* args)
+{
+ Player* target;
+ uint64 target_guid;
+ std::string target_name;
+ if (!extractPlayerTarget((char*)args,&target,&target_guid,&target_name))
+ return false;
+
+ if (target)
+ {
+ // check online security
+ if (HasLowerSecurity(target, 0))
+ return false;
+
+ PSendSysMessage(LANG_RENAME_PLAYER, GetNameLink(target).c_str());
+ target->SetAtLoginFlag(AT_LOGIN_RENAME);
+ }
+ else
+ {
+ // check offline security
+ if (HasLowerSecurity(NULL, target_guid))
+ return false;
+
+ std::string oldNameLink = playerLink(target_name);
+
+ PSendSysMessage(LANG_RENAME_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(target_guid));
+ CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", GUID_LOPART(target_guid));
+ }
+
+ return true;
+}
+
+// customize characters
+bool ChatHandler::HandleCharacterCustomizeCommand(const char* args)
+{
+ Player* target;
+ uint64 target_guid;
+ std::string target_name;
+ if (!extractPlayerTarget((char*)args,&target,&target_guid,&target_name))
+ return false;
+
+ if (target)
+ {
+ PSendSysMessage(LANG_CUSTOMIZE_PLAYER, GetNameLink(target).c_str());
+ target->SetAtLoginFlag(AT_LOGIN_CUSTOMIZE);
+ CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '8' WHERE guid = '%u'", target->GetGUIDLow());
+ }
+ else
+ {
+ std::string oldNameLink = playerLink(target_name);
+
+ PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(target_guid));
+ CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '8' WHERE guid = '%u'", GUID_LOPART(target_guid));
+ }
+
+ return true;
+}
+
+bool ChatHandler::HandleCharacterReputationCommand(const char* args)
+{
+ Player* target;
+ if (!extractPlayerTarget((char*)args,&target))
+ return false;
+
+ LocaleConstant loc = GetSessionDbcLocale();
+
+ FactionStateList const& targetFSL = target->GetReputationMgr().GetStateList();
+ for (FactionStateList::const_iterator itr = targetFSL.begin(); itr != targetFSL.end(); ++itr)
+ {
+ FactionEntry const *factionEntry = sFactionStore.LookupEntry(itr->second.ID);
+ char const* factionName = factionEntry ? factionEntry->name[loc] : "#Not found#";
+ ReputationRank rank = target->GetReputationMgr().GetRank(factionEntry);
+ std::string rankName = GetTrinityString(ReputationRankStrIndex[rank]);
+ std::ostringstream ss;
+ if (m_session)
+ ss << itr->second.ID << " - |cffffffff|Hfaction:" << itr->second.ID << "|h[" << factionName << " " << localeNames[loc] << "]|h|r";
+ else
+ ss << itr->second.ID << " - " << factionName << " " << localeNames[loc];
+
+ ss << " " << rankName << " (" << target->GetReputationMgr().GetReputation(factionEntry) << ")";
+
+ if (itr->second.Flags & FACTION_FLAG_VISIBLE)
+ ss << GetTrinityString(LANG_FACTION_VISIBLE);
+ if (itr->second.Flags & FACTION_FLAG_AT_WAR)
+ ss << GetTrinityString(LANG_FACTION_ATWAR);
+ if (itr->second.Flags & FACTION_FLAG_PEACE_FORCED)
+ ss << GetTrinityString(LANG_FACTION_PEACE_FORCED);
+ if (itr->second.Flags & FACTION_FLAG_HIDDEN)
+ ss << GetTrinityString(LANG_FACTION_HIDDEN);
+ if (itr->second.Flags & FACTION_FLAG_INVISIBLE_FORCED)
+ ss << GetTrinityString(LANG_FACTION_INVISIBLE_FORCED);
+ if (itr->second.Flags & FACTION_FLAG_INACTIVE)
+ ss << GetTrinityString(LANG_FACTION_INACTIVE);
+
+ SendSysMessage(ss.str().c_str());
+ }
+ return true;
+}
+
+//change standstate
+bool ChatHandler::HandleModifyStandStateCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ uint32 anim_id = atoi((char*)args);
+ m_session->GetPlayer()->SetUInt32Value(UNIT_NPC_EMOTESTATE , anim_id);
+
+ return true;
+}
+
+bool ChatHandler::HandleHonorAddCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ Player *target = getSelectedPlayer();
+ if (!target)
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // check online security
+ if (HasLowerSecurity(target, 0))
+ return false;
+
+ uint32 amount = (uint32)atoi(args);
+ target->RewardHonor(NULL, 1, amount);
+ return true;
+}
+
+bool ChatHandler::HandleHonorAddKillCommand(const char* /*args*/)
+{
+ Unit *target = getSelectedUnit();
+ if (!target)
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // check online security
+ if (target->GetTypeId() == TYPEID_PLAYER && HasLowerSecurity((Player*)target, 0))
+ return false;
+
+ m_session->GetPlayer()->RewardHonor(target, 1);
+ return true;
+}
+
+bool ChatHandler::HandleHonorUpdateCommand(const char* /*args*/)
+{
+ Player *target = getSelectedPlayer();
+ if (!target)
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // check online security
+ if (HasLowerSecurity(target, 0))
+ return false;
+
+ target->UpdateHonorFields();
+ return true;
+}
+
+bool ChatHandler::HandleLookupEventCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ std::string namepart = args;
+ std::wstring wnamepart;
+
+ // converting string that we try to find to lower case
+ if (!Utf8toWStr(namepart,wnamepart))
+ return false;
+
+ wstrToLower(wnamepart);
+
+ bool found = false;
+
+ GameEventMgr::GameEventDataMap const& events = gameeventmgr.GetEventMap();
+ GameEventMgr::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
+
+ for (uint32 id = 0; id < events.size(); ++id)
+ {
+ GameEventData const& eventData = events[id];
+
+ std::string descr = eventData.description;
+ if (descr.empty())
+ continue;
+
+ if (Utf8FitTo(descr, wnamepart))
+ {
+ char const* active = activeEvents.find(id) != activeEvents.end() ? GetTrinityString(LANG_ACTIVE) : "";
+
+ if (m_session)
+ PSendSysMessage(LANG_EVENT_ENTRY_LIST_CHAT,id,id,eventData.description.c_str(),active);
+ else
+ PSendSysMessage(LANG_EVENT_ENTRY_LIST_CONSOLE,id,eventData.description.c_str(),active);
+
+ if (!found)
+ found = true;
+ }
+ }
+
+ if (!found)
+ SendSysMessage(LANG_NOEVENTFOUND);
+
+ return true;
+}
+
+bool ChatHandler::HandleEventActiveListCommand(const char* /*args*/)
+{
+ uint32 counter = 0;
+
+ GameEventMgr::GameEventDataMap const& events = gameeventmgr.GetEventMap();
+ GameEventMgr::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
+
+ char const* active = GetTrinityString(LANG_ACTIVE);
+
+ for (GameEventMgr::ActiveEvents::const_iterator itr = activeEvents.begin(); itr != activeEvents.end(); ++itr)
+ {
+ uint32 event_id = *itr;
+ GameEventData const& eventData = events[event_id];
+
+ if (m_session)
+ PSendSysMessage(LANG_EVENT_ENTRY_LIST_CHAT,event_id,event_id,eventData.description.c_str(),active);
+ else
+ PSendSysMessage(LANG_EVENT_ENTRY_LIST_CONSOLE,event_id,eventData.description.c_str(),active);
+
+ ++counter;
+ }
+
+ if (counter == 0)
+ SendSysMessage(LANG_NOEVENTFOUND);
+
+ return true;
+}
+
+bool ChatHandler::HandleEventInfoCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
+ char* cId = extractKeyFromLink((char*)args,"Hgameevent");
+ if (!cId)
+ return false;
+
+ uint32 event_id = atoi(cId);
+
+ GameEventMgr::GameEventDataMap const& events = gameeventmgr.GetEventMap();
+
+ if (event_id >=events.size())
+ {
+ SendSysMessage(LANG_EVENT_NOT_EXIST);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ GameEventData const& eventData = events[event_id];
+ if (!eventData.isValid())
+ {
+ SendSysMessage(LANG_EVENT_NOT_EXIST);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ GameEventMgr::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
+ bool active = activeEvents.find(event_id) != activeEvents.end();
+ char const* activeStr = active ? GetTrinityString(LANG_ACTIVE) : "";
+
+ std::string startTimeStr = TimeToTimestampStr(eventData.start);
+ std::string endTimeStr = TimeToTimestampStr(eventData.end);
+
+ uint32 delay = gameeventmgr.NextCheck(event_id);
+ time_t nextTime = time(NULL)+delay;
+ std::string nextStr = nextTime >= eventData.start && nextTime < eventData.end ? TimeToTimestampStr(time(NULL)+delay) : "-";
+
+ std::string occurenceStr = secsToTimeString(eventData.occurence * MINUTE);
+ std::string lengthStr = secsToTimeString(eventData.length * MINUTE);
+
+ PSendSysMessage(LANG_EVENT_INFO,event_id,eventData.description.c_str(),activeStr,
+ startTimeStr.c_str(),endTimeStr.c_str(),occurenceStr.c_str(),lengthStr.c_str(),
+ nextStr.c_str());
+ return true;
+}
+
+bool ChatHandler::HandleEventStartCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
+ char* cId = extractKeyFromLink((char*)args,"Hgameevent");
+ if (!cId)
+ return false;
+
+ int32 event_id = atoi(cId);
+
+ GameEventMgr::GameEventDataMap const& events = gameeventmgr.GetEventMap();
+
+ if (event_id < 1 || event_id >=events.size())
+ {
+ SendSysMessage(LANG_EVENT_NOT_EXIST);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ GameEventData const& eventData = events[event_id];
+ if (!eventData.isValid())
+ {
+ SendSysMessage(LANG_EVENT_NOT_EXIST);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ GameEventMgr::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
+ if (activeEvents.find(event_id) != activeEvents.end())
+ {
+ PSendSysMessage(LANG_EVENT_ALREADY_ACTIVE,event_id);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ gameeventmgr.StartEvent(event_id,true);
+ return true;
+}
+
+bool ChatHandler::HandleEventStopCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
+ char* cId = extractKeyFromLink((char*)args,"Hgameevent");
+ if (!cId)
+ return false;
+
+ int32 event_id = atoi(cId);
+
+ GameEventMgr::GameEventDataMap const& events = gameeventmgr.GetEventMap();
+
+ if (event_id < 1 || event_id >=events.size())
+ {
+ SendSysMessage(LANG_EVENT_NOT_EXIST);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ GameEventData const& eventData = events[event_id];
+ if (!eventData.isValid())
+ {
+ SendSysMessage(LANG_EVENT_NOT_EXIST);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ GameEventMgr::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
+
+ if (activeEvents.find(event_id) == activeEvents.end())
+ {
+ PSendSysMessage(LANG_EVENT_NOT_ACTIVE,event_id);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ gameeventmgr.StopEvent(event_id,true);
+ return true;
+}
+
+bool ChatHandler::HandleCombatStopCommand(const char* args)
+{
+ Player* target;
+ if (!extractPlayerTarget((char*)args,&target))
+ return false;
+
+ // check online security
+ if (HasLowerSecurity(target, 0))
+ return false;
+
+ target->CombatStop();
+ target->getHostileRefManager().deleteReferences();
+ return true;
+}
+
+void ChatHandler::HandleLearnSkillRecipesHelper(Player* player,uint32 skill_id)
+{
+ uint32 classmask = player->getClassMask();
+
+ for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j)
+ {
+ SkillLineAbilityEntry const *skillLine = sSkillLineAbilityStore.LookupEntry(j);
+ if (!skillLine)
+ continue;
+
+ // wrong skill
+ if (skillLine->skillId != skill_id)
+ continue;
+
+ // not high rank
+ if (skillLine->forward_spellid)
+ continue;
+
+ // skip racial skills
+ if (skillLine->racemask != 0)
+ continue;
+
+ // skip wrong class skills
+ if (skillLine->classmask && (skillLine->classmask & classmask) == 0)
+ continue;
+
+ SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId);
+ if (!spellInfo || !SpellMgr::IsSpellValid(spellInfo,player,false))
+ continue;
+
+ player->learnSpell(skillLine->spellId, false);
+ }
+}
+
+bool ChatHandler::HandleLearnAllCraftsCommand(const char* /*args*/)
+{
+
+ for (uint32 i = 0; i < sSkillLineStore.GetNumRows(); ++i)
+ {
+ SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(i);
+ if (!skillInfo)
+ continue;
+
+ if ((skillInfo->categoryId == SKILL_CATEGORY_PROFESSION || skillInfo->categoryId == SKILL_CATEGORY_SECONDARY) &&
+ skillInfo->canLink) // only prof. with recipes have
+ {
+ HandleLearnSkillRecipesHelper(m_session->GetPlayer(),skillInfo->id);
+ }
+ }
+
+ SendSysMessage(LANG_COMMAND_LEARN_ALL_CRAFT);
+ return true;
+}
+
+bool ChatHandler::HandleLearnAllRecipesCommand(const char* args)
+{
+ // Learns all recipes of specified profession and sets skill to max
+ // Example: .learn all_recipes enchanting
+
+ Player* target = getSelectedPlayer();
+ if (!target)
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ return false;
+ }
+
+ if (!*args)
+ return false;
+
+ std::wstring wnamepart;
+
+ if (!Utf8toWStr(args,wnamepart))
+ return false;
+
+ // converting string that we try to find to lower case
+ wstrToLower(wnamepart);
+
+ std::string name;
+
+ SkillLineEntry const *targetSkillInfo = NULL;
+ for (uint32 i = 1; i < sSkillLineStore.GetNumRows(); ++i)
+ {
+ SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(i);
+ if (!skillInfo)
+ continue;
+
+ if ((skillInfo->categoryId != SKILL_CATEGORY_PROFESSION &&
+ skillInfo->categoryId != SKILL_CATEGORY_SECONDARY) ||
+ !skillInfo->canLink) // only prof with recipes have set
+ continue;
+
+ int loc = GetSessionDbcLocale();
+ name = skillInfo->name[loc];
+ if (name.empty())
+ continue;
+
+ if (!Utf8FitTo(name, wnamepart))
+ {
+ loc = 0;
+ for (; loc < MAX_LOCALE; ++loc)
+ {
+ if (loc == GetSessionDbcLocale())
+ continue;
+
+ name = skillInfo->name[loc];
+ if (name.empty())
+ continue;
+
+ if (Utf8FitTo(name, wnamepart))
+ break;
+ }
+ }
+
+ if (loc < MAX_LOCALE)
+ {
+ targetSkillInfo = skillInfo;
+ break;
+ }
+ }
+
+ if (!targetSkillInfo)
+ return false;
+
+ HandleLearnSkillRecipesHelper(target,targetSkillInfo->id);
+
+ uint16 maxLevel = target->GetPureMaxSkillValue(targetSkillInfo->id);
+ target->SetSkill(targetSkillInfo->id, target->GetSkillStep(targetSkillInfo->id), maxLevel, maxLevel);
+ PSendSysMessage(LANG_COMMAND_LEARN_ALL_RECIPES, name.c_str());
+ return true;
+}
+
+bool ChatHandler::HandleLookupPlayerIpCommand(const char* args)
+{
+
+ if (!*args)
+ return false;
+
+ std::string ip = strtok ((char*)args, " ");
+ char* limit_str = strtok (NULL, " ");
+ int32 limit = limit_str ? atoi (limit_str) : -1;
+
+ LoginDatabase.escape_string (ip);
+
+ QueryResult_AutoPtr result = LoginDatabase.PQuery ("SELECT id,username FROM account WHERE last_ip = '%s'", ip.c_str ());
+
+ return LookupPlayerSearchCommand (result,limit);
+}
+
+bool ChatHandler::HandleLookupPlayerAccountCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ std::string account = strtok ((char*)args, " ");
+ char* limit_str = strtok (NULL, " ");
+ int32 limit = limit_str ? atoi (limit_str) : -1;
+
+ if (!AccountMgr::normalizeString (account))
+ return false;
+
+ LoginDatabase.escape_string (account);
+
+ QueryResult_AutoPtr result = LoginDatabase.PQuery ("SELECT id,username FROM account WHERE username = '%s'", account.c_str ());
+
+ return LookupPlayerSearchCommand (result,limit);
+}
+
+bool ChatHandler::HandleLookupPlayerEmailCommand(const char* args)
+{
+
+ if (!*args)
+ return false;
+
+ std::string email = strtok ((char*)args, " ");
+ char* limit_str = strtok (NULL, " ");
+ int32 limit = limit_str ? atoi (limit_str) : -1;
+
+ LoginDatabase.escape_string (email);
+
+ QueryResult_AutoPtr result = LoginDatabase.PQuery ("SELECT id,username FROM account WHERE email = '%s'", email.c_str ());
+
+ return LookupPlayerSearchCommand (result,limit);
+}
+
+bool ChatHandler::LookupPlayerSearchCommand(QueryResult_AutoPtr result, int32 limit)
+{
+ if (!result)
+ {
+ PSendSysMessage(LANG_NO_PLAYERS_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ int i =0;
+ do
+ {
+ Field* fields = result->Fetch();
+ uint32 acc_id = fields[0].GetUInt32();
+ std::string acc_name = fields[1].GetCppString();
+
+ QueryResult_AutoPtr chars = CharacterDatabase.PQuery("SELECT guid,name FROM characters WHERE account = '%u'", acc_id);
+ if (chars)
+ {
+ PSendSysMessage(LANG_LOOKUP_PLAYER_ACCOUNT,acc_name.c_str(),acc_id);
+
+ uint64 guid = 0;
+ std::string name;
+
+ do
+ {
+ Field* charfields = chars->Fetch();
+ guid = charfields[0].GetUInt64();
+ name = charfields[1].GetCppString();
+
+ PSendSysMessage(LANG_LOOKUP_PLAYER_CHARACTER,name.c_str(),guid);
+ ++i;
+
+ } while (chars->NextRow() && (limit == -1 || i < limit));
+ }
+ } while (result->NextRow());
+
+ if (i == 0) // empty accounts only
+ {
+ PSendSysMessage(LANG_NO_PLAYERS_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ return true;
+}
+
+/// Triggering corpses expire check in world
+bool ChatHandler::HandleServerCorpsesCommand(const char* /*args*/)
+{
+ CorpsesErase();
+ return true;
+}
+
+bool ChatHandler::HandleRepairitemsCommand(const char* args)
+{
+ Player* target;
+ if (!extractPlayerTarget((char*)args,&target))
+ return false;
+
+ // check online security
+ if (HasLowerSecurity(target, 0))
+ return false;
+
+ // Repair items
+ target->DurabilityRepairAll(false, 0, false);
+
+ PSendSysMessage(LANG_YOU_REPAIR_ITEMS, GetNameLink(target).c_str());
+ if (needReportToTarget(target))
+ ChatHandler(target).PSendSysMessage(LANG_YOUR_ITEMS_REPAIRED, GetNameLink().c_str());
+ return true;
+}
+
+bool ChatHandler::HandleWaterwalkCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ Player *player = getSelectedPlayer();
+
+ if (!player)
+ {
+ PSendSysMessage(LANG_NO_CHAR_SELECTED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // check online security
+ if (HasLowerSecurity(player, 0))
+ return false;
+
+ if (strncmp(args, "on", 3) == 0)
+ player->SetMovement(MOVE_WATER_WALK); // ON
+ else if (strncmp(args, "off", 4) == 0)
+ player->SetMovement(MOVE_LAND_WALK); // OFF
+ else
+ {
+ SendSysMessage(LANG_USE_BOL);
+ return false;
+ }
+
+ PSendSysMessage(LANG_YOU_SET_WATERWALK, args, GetNameLink(player).c_str());
+ if (needReportToTarget(player))
+ ChatHandler(player).PSendSysMessage(LANG_YOUR_WATERWALK_SET, args, GetNameLink().c_str());
+ return true;
+}
+
+bool ChatHandler::HandleCreatePetCommand(const char* /*args*/)
+{
+ Player *player = m_session->GetPlayer();
+ Creature *creatureTarget = getSelectedCreature();
+
+ if (!creatureTarget || creatureTarget->isPet() || creatureTarget->GetTypeId() == TYPEID_PLAYER)
+ {
+ PSendSysMessage(LANG_SELECT_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ CreatureInfo const* cInfo = objmgr.GetCreatureTemplate(creatureTarget->GetEntry());
+ // Creatures with family 0 crashes the server
+ if (cInfo->family == 0)
+ {
+ PSendSysMessage("This creature cannot be tamed. (family id: 0).");
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (player->GetPetGUID())
+ {
+ PSendSysMessage("You already have a pet");
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // Everything looks OK, create new pet
+ Pet* pet = new Pet(player, HUNTER_PET);
+
+ if (!pet)
+ return false;
+
+ if (!pet->CreateBaseAtCreature(creatureTarget))
+ {
+ delete pet;
+ PSendSysMessage("Error 1");
+ return false;
+ }
+
+ creatureTarget->setDeathState(JUST_DIED);
+ creatureTarget->RemoveCorpse();
+ creatureTarget->SetHealth(0); // just for nice GM-mode view
+
+ pet->SetUInt64Value(UNIT_FIELD_CREATEDBY, player->GetGUID());
+ pet->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, player->getFaction());
+
+ if (!pet->InitStatsForLevel(creatureTarget->getLevel()))
+ {
+ sLog.outError("ERROR: InitStatsForLevel() in EffectTameCreature failed! Pet deleted.");
+ PSendSysMessage("Error 2");
+ delete pet;
+ return false;
+ }
+
+ // prepare visual effect for levelup
+ pet->SetUInt32Value(UNIT_FIELD_LEVEL,creatureTarget->getLevel()-1);
+
+ pet->GetCharmInfo()->SetPetNumber(objmgr.GeneratePetNumber(), true);
+ // this enables pet details window (Shift+P)
+ pet->InitPetCreateSpells();
+ pet->SetHealth(pet->GetMaxHealth());
+
+ pet->GetMap()->Add(pet->ToCreature());
+
+ // visual effect for levelup
+ pet->SetUInt32Value(UNIT_FIELD_LEVEL,creatureTarget->getLevel());
+
+ player->SetMinion(pet, true);
+ pet->SavePetToDB(PET_SAVE_AS_CURRENT);
+ player->PetSpellInitialize();
+
+ return true;
+}
+
+bool ChatHandler::HandlePetLearnCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ Player *plr = m_session->GetPlayer();
+ Pet *pet = plr->GetPet();
+
+ if (!pet)
+ {
+ PSendSysMessage("You have no pet");
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ uint32 spellId = extractSpellIdFromLink((char*)args);
+
+ if (!spellId || !sSpellStore.LookupEntry(spellId))
+ return false;
+
+ // Check if pet already has it
+ if (pet->HasSpell(spellId))
+ {
+ PSendSysMessage("Pet already has spell: %u", spellId);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // Check if spell is valid
+ SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellId);
+ if (!spellInfo || !SpellMgr::IsSpellValid(spellInfo))
+ {
+ PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spellId);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ pet->learnSpell(spellId);
+
+ PSendSysMessage("Pet has learned spell %u", spellId);
+ return true;
+}
+
+bool ChatHandler::HandlePetUnlearnCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ Player *plr = m_session->GetPlayer();
+ Pet *pet = plr->GetPet();
+
+ if (!pet)
+ {
+ PSendSysMessage("You have no pet");
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ uint32 spellId = extractSpellIdFromLink((char*)args);
+
+ if (pet->HasSpell(spellId))
+ pet->removeSpell(spellId, false);
+ else
+ PSendSysMessage("Pet doesn't have that spell");
+
+ return true;
+}
+
+bool ChatHandler::HandlePetTpCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ Player *plr = m_session->GetPlayer();
+ Pet *pet = plr->GetPet();
+
+ if (!pet)
+ {
+ PSendSysMessage("You have no pet");
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ uint32 tp = atol(args);
+
+ //pet->SetTP(tp);
+
+ PSendSysMessage("Pet's tp changed to %u", tp);
+ return true;
+}
+
+bool ChatHandler::HandleActivateObjectCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ char* cId = extractKeyFromLink((char*)args,"Hgameobject");
+ if (!cId)
+ return false;
+
+ uint32 lowguid = atoi(cId);
+ if (!lowguid)
+ return false;
+
+ GameObject* obj = NULL;
+
+ // by DB guid
+ if (GameObjectData const* go_data = objmgr.GetGOData(lowguid))
+ obj = GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid,go_data->id);
+
+ if (!obj)
+ {
+ PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // Activate
+ obj->SetLootState(GO_READY);
+ obj->UseDoorOrButton(10000);
+
+ PSendSysMessage("Object activated!");
+
+ return true;
+}
+
+// add creature, temp only
+bool ChatHandler::HandleTempAddSpwCommand(const char* args)
+{
+ if (!*args)
+ return false;
+ char* charID = strtok((char*)args, " ");
+ if (!charID)
+ return false;
+
+ Player *chr = m_session->GetPlayer();
+
+ uint32 id = atoi(charID);
+ if (!id)
+ return false;
+
+ chr->SummonCreature(id, *chr, TEMPSUMMON_CORPSE_DESPAWN, 120);
+
+ return true;
+}
+
+// add go, temp only
+bool ChatHandler::HandleTempGameObjectCommand(const char* args)
+{
+ if (!*args)
+ return false;
+ char* charID = strtok((char*)args, " ");
+ if (!charID)
+ return false;
+
+ Player *chr = m_session->GetPlayer();
+
+ char* spawntime = strtok(NULL, " ");
+ uint32 spawntm = 300;
+
+ if (spawntime)
+ spawntm = atoi((char*)spawntime);
+
+ float x = chr->GetPositionX();
+ float y = chr->GetPositionY();
+ float z = chr->GetPositionZ();
+ float ang = chr->GetOrientation();
+
+ float rot2 = sin(ang/2);
+ float rot3 = cos(ang/2);
+
+ uint32 id = atoi(charID);
+
+ chr->SummonGameObject(id,x,y,z,ang,0,0,rot2,rot3,spawntm);
+
+ return true;
+}
+
+bool ChatHandler::HandleNpcAddFormationCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ uint32 leaderGUID = (uint32) atoi((char*)args);
+ Creature *pCreature = getSelectedCreature();
+
+ if (!pCreature || !pCreature->GetDBTableGUIDLow())
+ {
+ SendSysMessage(LANG_SELECT_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ uint32 lowguid = pCreature->GetDBTableGUIDLow();
+ if (pCreature->GetFormation())
+ {
+ PSendSysMessage("Selected creature is already member of group %u", pCreature->GetFormation()->GetId());
+ return false;
+ }
+
+ if (!lowguid)
+ return false;
+
+ Player *chr = m_session->GetPlayer();
+ FormationInfo *group_member;
+
+ group_member = new FormationInfo;
+ group_member->follow_angle = (pCreature->GetAngle(chr) - chr->GetOrientation()) * 180 / M_PI;
+ group_member->follow_dist = sqrtf(pow(chr->GetPositionX() - pCreature->GetPositionX(),int(2))+pow(chr->GetPositionY()-pCreature->GetPositionY(),int(2)));
+ group_member->leaderGUID = leaderGUID;
+ group_member->groupAI = 0;
+
+ CreatureGroupMap[lowguid] = group_member;
+ pCreature->SearchFormation();
+
+ WorldDatabase.PExecuteLog("INSERT INTO creature_formations (leaderGUID, memberGUID, dist, angle, groupAI) VALUES ('%u','%u','%f', '%f', '%u')",
+ leaderGUID, lowguid, group_member->follow_dist, group_member->follow_angle, group_member->groupAI);
+
+ PSendSysMessage("Creature %u added to formation with leader %u", lowguid, leaderGUID);
+
+ return true;
+ }
+
+bool ChatHandler::HandleNpcSetLinkCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ uint32 linkguid = (uint32) atoi((char*)args);
+
+ Creature* pCreature = getSelectedCreature();
+
+ if (!pCreature)
+ {
+ SendSysMessage(LANG_SELECT_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (!pCreature->GetDBTableGUIDLow())
+ {
+ PSendSysMessage("Selected creature isn't in creature table", pCreature->GetGUIDLow());
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (!objmgr.SetCreatureLinkedRespawn(pCreature->GetDBTableGUIDLow(), linkguid))
+ {
+ PSendSysMessage("Selected creature can't link with guid '%u'", linkguid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ PSendSysMessage("LinkGUID '%u' added to creature with DBTableGUID: '%u'", linkguid, pCreature->GetDBTableGUIDLow());
+ return true;
+}
+
+bool ChatHandler::HandleLookupTitleCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ // can be NULL in console call
+ Player* target = getSelectedPlayer();
+
+ // title name have single string arg for player name
+ char const* targetName = target ? target->GetName() : "NAME";
+
+ std::string namepart = args;
+ std::wstring wnamepart;
+
+ if (!Utf8toWStr(namepart,wnamepart))
+ return false;
+
+ // converting string that we try to find to lower case
+ wstrToLower(wnamepart);
+
+ uint32 counter = 0; // Counter for figure out that we found smth.
+
+ // Search in CharTitles.dbc
+ for (uint32 id = 0; id < sCharTitlesStore.GetNumRows(); id++)
+ {
+ CharTitlesEntry const *titleInfo = sCharTitlesStore.LookupEntry(id);
+ if (titleInfo)
+ {
+ int loc = GetSessionDbcLocale();
+ std::string name = titleInfo->name[loc];
+ if (name.empty())
+ continue;
+
+ if (!Utf8FitTo(name, wnamepart))
+ {
+ loc = 0;
+ for (; loc < MAX_LOCALE; ++loc)
+ {
+ if (loc == GetSessionDbcLocale())
+ continue;
+
+ name = titleInfo->name[loc];
+ if (name.empty())
+ continue;
+
+ if (Utf8FitTo(name, wnamepart))
+ break;
+ }
+ }
+
+ if (loc < MAX_LOCALE)
+ {
+ char const* knownStr = target && target->HasTitle(titleInfo) ? GetTrinityString(LANG_KNOWN) : "";
+
+ char const* activeStr = target && target->GetUInt32Value(PLAYER_CHOSEN_TITLE) == titleInfo->bit_index
+ ? GetTrinityString(LANG_ACTIVE)
+ : "";
+
+ char titleNameStr[80];
+ snprintf(titleNameStr,80,name.c_str(),targetName);
+
+ // send title in "id (idx:idx) - [namedlink locale]" format
+ if (m_session)
+ PSendSysMessage(LANG_TITLE_LIST_CHAT,id,titleInfo->bit_index,id,titleNameStr,localeNames[loc],knownStr,activeStr);
+ else
+ PSendSysMessage(LANG_TITLE_LIST_CONSOLE,id,titleInfo->bit_index,titleNameStr,localeNames[loc],knownStr,activeStr);
+
+ ++counter;
+ }
+ }
+ }
+ if (counter == 0) // if counter == 0 then we found nth
+ SendSysMessage(LANG_COMMAND_NOTITLEFOUND);
+ return true;
+}
+
+bool ChatHandler::HandleTitlesAddCommand(const char* args)
+{
+ // number or [name] Shift-click form |color|Htitle:title_id|h[name]|h|r
+ char* id_p = extractKeyFromLink((char*)args,"Htitle");
+ if (!id_p)
+ return false;
+
+ int32 id = atoi(id_p);
+ if (id <= 0)
+ {
+ PSendSysMessage(LANG_INVALID_TITLE_ID, id);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Player * target = getSelectedPlayer();
+ if (!target)
+ {
+ SendSysMessage(LANG_NO_CHAR_SELECTED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // check online security
+ if (HasLowerSecurity(target, 0))
+ return false;
+
+ CharTitlesEntry const* titleInfo = sCharTitlesStore.LookupEntry(id);
+ if (!titleInfo)
+ {
+ PSendSysMessage(LANG_INVALID_TITLE_ID, id);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ std::string tNameLink = GetNameLink(target);
+
+ char const* targetName = target->GetName();
+ char titleNameStr[80];
+ snprintf(titleNameStr,80,titleInfo->name[GetSessionDbcLocale()],targetName);
+
+ target->SetTitle(titleInfo);
+ PSendSysMessage(LANG_TITLE_ADD_RES, id, titleNameStr, tNameLink.c_str());
+
+ return true;
+}
+
+bool ChatHandler::HandleTitlesRemoveCommand(const char* args)
+{
+ // number or [name] Shift-click form |color|Htitle:title_id|h[name]|h|r
+ char* id_p = extractKeyFromLink((char*)args,"Htitle");
+ if (!id_p)
+ return false;
+
+ int32 id = atoi(id_p);
+ if (id <= 0)
+ {
+ PSendSysMessage(LANG_INVALID_TITLE_ID, id);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Player * target = getSelectedPlayer();
+ if (!target)
+ {
+ SendSysMessage(LANG_NO_CHAR_SELECTED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // check online security
+ if (HasLowerSecurity(target, 0))
+ return false;
+
+ CharTitlesEntry const* titleInfo = sCharTitlesStore.LookupEntry(id);
+ if (!titleInfo)
+ {
+ PSendSysMessage(LANG_INVALID_TITLE_ID, id);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ target->SetTitle(titleInfo,true);
+
+ std::string tNameLink = GetNameLink(target);
+
+ char const* targetName = target->GetName();
+ char titleNameStr[80];
+ snprintf(titleNameStr,80,titleInfo->name[GetSessionDbcLocale()],targetName);
+
+ PSendSysMessage(LANG_TITLE_REMOVE_RES, id, titleNameStr, tNameLink.c_str());
+
+ if (!target->HasTitle(target->GetInt32Value(PLAYER_CHOSEN_TITLE)))
+ {
+ target->SetUInt32Value(PLAYER_CHOSEN_TITLE,0);
+ PSendSysMessage(LANG_CURRENT_TITLE_RESET, tNameLink.c_str());
+ }
+
+ return true;
+}
+
+//Edit Player KnownTitles
+bool ChatHandler::HandleTitlesSetMaskCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ uint64 titles = 0;
+
+ sscanf((char*)args, UI64FMTD, &titles);
+
+ Player *target = getSelectedPlayer();
+ if (!target)
+ {
+ SendSysMessage(LANG_NO_CHAR_SELECTED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // check online security
+ if (HasLowerSecurity(target, 0))
+ return false;
+
+ uint64 titles2 = titles;
+
+ for (uint32 i = 1; i < sCharTitlesStore.GetNumRows(); ++i)
+ if (CharTitlesEntry const* tEntry = sCharTitlesStore.LookupEntry(i))
+ titles2 &= ~(uint64(1) << tEntry->bit_index);
+
+ titles &= ~titles2; // remove not existed titles
+
+ target->SetUInt64Value(PLAYER__FIELD_KNOWN_TITLES, titles);
+ SendSysMessage(LANG_DONE);
+
+ if (!target->HasTitle(target->GetInt32Value(PLAYER_CHOSEN_TITLE)))
+ {
+ target->SetUInt32Value(PLAYER_CHOSEN_TITLE,0);
+ PSendSysMessage(LANG_CURRENT_TITLE_RESET,GetNameLink(target).c_str());
+ }
+
+ return true;
+}
+
+bool ChatHandler::HandleCharacterTitlesCommand(const char* args)
+{
+ Player* target;
+ if (!extractPlayerTarget((char*)args,&target))
+ return false;
+
+ LocaleConstant loc = GetSessionDbcLocale();
+ char const* targetName = target->GetName();
+ char const* knownStr = GetTrinityString(LANG_KNOWN);
+
+ // Search in CharTitles.dbc
+ for (uint32 id = 0; id < sCharTitlesStore.GetNumRows(); id++)
+ {
+ CharTitlesEntry const *titleInfo = sCharTitlesStore.LookupEntry(id);
+ if (titleInfo && target->HasTitle(titleInfo))
+ {
+ std::string name = titleInfo->name[loc];
+ if (name.empty())
+ continue;
+
+ char const* activeStr = target && target->GetUInt32Value(PLAYER_CHOSEN_TITLE) == titleInfo->bit_index
+ ? GetTrinityString(LANG_ACTIVE)
+ : "";
+
+ char titleNameStr[80];
+ snprintf(titleNameStr,80,name.c_str(),targetName);
+
+ // send title in "id (idx:idx) - [namedlink locale]" format
+ if (m_session)
+ PSendSysMessage(LANG_TITLE_LIST_CHAT,id,titleInfo->bit_index,id,titleNameStr,localeNames[loc],knownStr,activeStr);
+ else
+ PSendSysMessage(LANG_TITLE_LIST_CONSOLE,id,titleInfo->bit_index,name.c_str(),localeNames[loc],knownStr,activeStr);
+ }
+ }
+ return true;
+}
+
+bool ChatHandler::HandleTitlesCurrentCommand(const char* args)
+{
+ // number or [name] Shift-click form |color|Htitle:title_id|h[name]|h|r
+ char* id_p = extractKeyFromLink((char*)args,"Htitle");
+ if (!id_p)
+ return false;
+
+ int32 id = atoi(id_p);
+ if (id <= 0)
+ {
+ PSendSysMessage(LANG_INVALID_TITLE_ID, id);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Player * target = getSelectedPlayer();
+ if (!target)
+ {
+ SendSysMessage(LANG_NO_CHAR_SELECTED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // check online security
+ if (HasLowerSecurity(target, 0))
+ return false;
+
+ CharTitlesEntry const* titleInfo = sCharTitlesStore.LookupEntry(id);
+ if (!titleInfo)
+ {
+ PSendSysMessage(LANG_INVALID_TITLE_ID, id);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ std::string tNameLink = GetNameLink(target);
+
+ target->SetTitle(titleInfo); // to be sure that title now known
+ target->SetUInt32Value(PLAYER_CHOSEN_TITLE,titleInfo->bit_index);
+
+ PSendSysMessage(LANG_TITLE_CURRENT_RES, id, titleInfo->name[GetSessionDbcLocale()], tNameLink.c_str());
+
+ return true;
+}
diff --git a/src/server/game/Chat/Level3.cpp b/src/server/game/Chat/Level3.cpp
new file mode 100644
index 00000000000..f7ced44922b
--- /dev/null
+++ b/src/server/game/Chat/Level3.cpp
@@ -0,0 +1,7743 @@
+/*
+* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+*
+* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include "Common.h"
+#include "Database/DatabaseEnv.h"
+#include "WorldPacket.h"
+#include "WorldSession.h"
+#include "World.h"
+#include "ObjectMgr.h"
+#include "AuctionHouseMgr.h"
+#include "AccountMgr.h"
+#include "PlayerDump.h"
+#include "SpellMgr.h"
+#include "Player.h"
+#include "Opcodes.h"
+#include "GameObject.h"
+#include "Chat.h"
+#include "Log.h"
+#include "Guild.h"
+#include "ObjectAccessor.h"
+#include "MapManager.h"
+#include "Language.h"
+#include "GridNotifiersImpl.h"
+#include "CellImpl.h"
+#include "Weather.h"
+#include "PointMovementGenerator.h"
+#include "TargetedMovementGenerator.h"
+#include "SkillDiscovery.h"
+#include "SkillExtraItems.h"
+#include "SystemConfig.h"
+#include "Config/ConfigEnv.h"
+#include "Util.h"
+#include "ItemEnchantmentMgr.h"
+#include "BattleGroundMgr.h"
+#include "InstanceSaveMgr.h"
+#include "InstanceData.h"
+#include "AuctionHouseBot.h"
+#include "CreatureEventAIMgr.h"
+#include "SpellAuraEffects.h"
+#include "DBCEnums.h"
+#include "ConditionMgr.h"
+
+bool ChatHandler::HandleAHBotOptionsCommand(const char *args)
+{
+ uint32 ahMapID = 0;
+ char * opt = strtok((char*)args, " ");
+ char * ahMapIdStr = strtok(NULL, " ");
+ if (ahMapIdStr)
+ {
+ ahMapID = (uint32) strtoul(ahMapIdStr, NULL, 0);
+ switch (ahMapID)
+ {
+ case 2:
+ case 6:
+ case 7:
+ break;
+ default:
+ opt = NULL;
+ break;
+ }
+ }
+ if (!opt)
+ {
+ PSendSysMessage("Syntax is: ahbotoptions $option $ahMapID (2, 6 or 7) $parameter");
+ PSendSysMessage("Try ahbotoptions help to see a list of options.");
+ return false;
+ }
+ int l = strlen(opt);
+
+ if (strncmp(opt,"help",l) == 0)
+ {
+ PSendSysMessage("AHBot commands:");
+ PSendSysMessage("ahexpire");
+ PSendSysMessage("minitems");
+ PSendSysMessage("maxitems");
+ //PSendSysMessage("");
+ //PSendSysMessage("");
+ PSendSysMessage("percentages");
+ PSendSysMessage("minprice");
+ PSendSysMessage("maxprice");
+ PSendSysMessage("minbidprice");
+ PSendSysMessage("maxbidprice");
+ PSendSysMessage("maxstack");
+ PSendSysMessage("buyerprice");
+ PSendSysMessage("bidinterval");
+ PSendSysMessage("bidsperinterval");
+ return true;
+ }
+ else if (strncmp(opt,"ahexpire",l) == 0)
+ {
+ if (!ahMapIdStr)
+ {
+ PSendSysMessage("Syntax is: ahbotoptions ahexpire $ahMapID (2, 6 or 7)");
+ return false;
+ }
+ auctionbot.Commands(0, ahMapID, NULL, NULL);
+ }
+ else if (strncmp(opt,"minitems",l) == 0)
+ {
+ char * param1 = strtok(NULL, " ");
+ if ((!ahMapIdStr) || (!param1))
+ {
+ PSendSysMessage("Syntax is: ahbotoptions minitems $ahMapID (2, 6 or 7) $minItems");
+ return false;
+ }
+ auctionbot.Commands(1, ahMapID, NULL, param1);
+ }
+ else if (strncmp(opt,"maxitems",l) == 0)
+ {
+ char * param1 = strtok(NULL, " ");
+ if ((!ahMapIdStr) || (!param1))
+ {
+ PSendSysMessage("Syntax is: ahbotoptions maxitems $ahMapID (2, 6 or 7) $maxItems");
+ return false;
+ }
+ auctionbot.Commands(2, ahMapID, NULL, param1);
+ }
+ else if (strncmp(opt,"mintime",l) == 0)
+ {
+ PSendSysMessage("ahbotoptions mintime has been deprecated");
+ return false;
+ /*
+ char * param1 = strtok(NULL, " ");
+ if ((!ahMapIdStr) || (!param1))
+ {
+ PSendSysMessage("Syntax is: ahbotoptions mintime $ahMapID (2, 6 or 7) $mintime");
+ return false;
+ }
+ auctionbot.Commands(3, ahMapID, NULL, param1);
+ */
+ }
+ else if (strncmp(opt,"maxtime",l) == 0)
+ {
+ PSendSysMessage("ahbotoptions maxtime has been deprecated");
+ return false;
+ /*
+ char * param1 = strtok(NULL, " ");
+ if ((!ahMapIdStr) || (!param1))
+ {
+ PSendSysMessage("Syntax is: ahbotoptions maxtime $ahMapID (2, 6 or 7) $maxtime");
+ return false;
+ }
+ auctionbot.Commands(4, ahMapID, NULL, param1);
+ */
+ }
+ else if (strncmp(opt,"percentages",l) == 0)
+ {
+ char * param1 = strtok(NULL, " ");
+ char * param2 = strtok(NULL, " ");
+ char * param3 = strtok(NULL, " ");
+ char * param4 = strtok(NULL, " ");
+ char * param5 = strtok(NULL, " ");
+ char * param6 = strtok(NULL, " ");
+ char * param7 = strtok(NULL, " ");
+ char * param8 = strtok(NULL, " ");
+ char * param9 = strtok(NULL, " ");
+ char * param10 = strtok(NULL, " ");
+ char * param11 = strtok(NULL, " ");
+ char * param12 = strtok(NULL, " ");
+ char * param13 = strtok(NULL, " ");
+ char * param14 = strtok(NULL, " ");
+ if ((!ahMapIdStr) || (!param14))
+ {
+ PSendSysMessage("Syntax is: ahbotoptions percentages $ahMapID (2, 6 or 7) $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14");
+ PSendSysMessage("1 GreyTradeGoods 2 WhiteTradeGoods 3 GreenTradeGoods 4 BlueTradeGoods 5 PurpleTradeGoods");
+ PSendSysMessage("6 OrangeTradeGoods 7 YellowTradeGoods 8 GreyItems 9 WhiteItems 10 GreenItems 11 BlueItems");
+ PSendSysMessage("12 PurpleItems 13 OrangeItems 14 YellowItems");
+ PSendSysMessage("The total must add up to 100%");
+ return false;
+ }
+ uint32 greytg = (uint32) strtoul(param1, NULL, 0);
+ uint32 whitetg = (uint32) strtoul(param2, NULL, 0);
+ uint32 greentg = (uint32) strtoul(param3, NULL, 0);
+ uint32 bluetg = (uint32) strtoul(param3, NULL, 0);
+ uint32 purpletg = (uint32) strtoul(param5, NULL, 0);
+ uint32 orangetg = (uint32) strtoul(param6, NULL, 0);
+ uint32 yellowtg = (uint32) strtoul(param7, NULL, 0);
+ uint32 greyi = (uint32) strtoul(param8, NULL, 0);
+ uint32 whitei = (uint32) strtoul(param9, NULL, 0);
+ uint32 greeni = (uint32) strtoul(param10, NULL, 0);
+ uint32 bluei = (uint32) strtoul(param11, NULL, 0);
+ uint32 purplei = (uint32) strtoul(param12, NULL, 0);
+ uint32 orangei = (uint32) strtoul(param13, NULL, 0);
+ uint32 yellowi = (uint32) strtoul(param14, NULL, 0);
+ uint32 totalPercent = greytg + whitetg + greentg + bluetg + purpletg + orangetg + yellowtg + greyi + whitei + greeni + bluei + purplei + orangei + yellowi;
+ if ((totalPercent == 0) || (totalPercent != 100))
+ {
+ PSendSysMessage("Syntax is: ahbotoptions percentages $ahMapID (2, 6 or 7) $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14");
+ PSendSysMessage("1 GreyTradeGoods 2 WhiteTradeGoods 3 GreenTradeGoods 4 BlueTradeGoods 5 PurpleTradeGoods");
+ PSendSysMessage("6 OrangeTradeGoods 7 YellowTradeGoods 8 GreyItems 9 WhiteItems 10 GreenItems 11 BlueItems");
+ PSendSysMessage("12 PurpleItems 13 OrangeItems 14 YellowItems");
+ PSendSysMessage("The total must add up to 100%");
+ return false;
+ }
+ char param[100];
+ param[0] = '\0';
+ strcat(param, param1);
+ strcat(param, " ");
+ strcat(param, param2);
+ strcat(param, " ");
+ strcat(param, param3);
+ strcat(param, " ");
+ strcat(param, param4);
+ strcat(param, " ");
+ strcat(param, param5);
+ strcat(param, " ");
+ strcat(param, param6);
+ strcat(param, " ");
+ strcat(param, param7);
+ strcat(param, " ");
+ strcat(param, param8);
+ strcat(param, " ");
+ strcat(param, param9);
+ strcat(param, " ");
+ strcat(param, param10);
+ strcat(param, " ");
+ strcat(param, param11);
+ strcat(param, " ");
+ strcat(param, param12);
+ strcat(param, " ");
+ strcat(param, param13);
+ strcat(param, " ");
+ strcat(param, param14);
+ auctionbot.Commands(5, ahMapID, NULL, param);
+ }
+ else if (strncmp(opt,"minprice",l) == 0)
+ {
+ char * param1 = strtok(NULL, " ");
+ char * param2 = strtok(NULL, " ");
+ if ((!ahMapIdStr) || (!param1) || (!param2))
+ {
+ PSendSysMessage("Syntax is: ahbotoptions minprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $price");
+ return false;
+ }
+ if (strncmp(param1,"grey",l) == 0)
+ {
+ auctionbot.Commands(6, ahMapID, AHB_GREY, param2);
+ }
+ else if (strncmp(param1,"white",l) == 0)
+ {
+ auctionbot.Commands(6, ahMapID, AHB_WHITE, param2);
+ }
+ else if (strncmp(param1,"green",l) == 0)
+ {
+ auctionbot.Commands(6, ahMapID, AHB_GREEN, param2);
+ }
+ else if (strncmp(param1,"blue",l) == 0)
+ {
+ auctionbot.Commands(6, ahMapID, AHB_BLUE, param2);
+ }
+ else if (strncmp(param1,"purple",l) == 0)
+ {
+ auctionbot.Commands(6, ahMapID, AHB_PURPLE, param2);
+ }
+ else if (strncmp(param1,"orange",l) == 0)
+ {
+ auctionbot.Commands(6, ahMapID, AHB_ORANGE, param2);
+ }
+ else if (strncmp(param1,"yellow",l) == 0)
+ {
+ auctionbot.Commands(6, ahMapID, AHB_YELLOW, param2);
+ }
+ else
+ {
+ PSendSysMessage("Syntax is: ahbotoptions minprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $price");
+ return false;
+ }
+ }
+ else if (strncmp(opt,"maxprice",l) == 0)
+ {
+ char * param1 = strtok(NULL, " ");
+ char * param2 = strtok(NULL, " ");
+ if ((!ahMapIdStr) || (!param1) || (!param2))
+ {
+ PSendSysMessage("Syntax is: ahbotoptions maxprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $price");
+ return false;
+ }
+ if (strncmp(param1,"grey",l) == 0)
+ {
+ auctionbot.Commands(7, ahMapID, AHB_GREY, param2);
+ }
+ else if (strncmp(param1,"white",l) == 0)
+ {
+ auctionbot.Commands(7, ahMapID, AHB_WHITE, param2);
+ }
+ else if (strncmp(param1,"green",l) == 0)
+ {
+ auctionbot.Commands(7, ahMapID, AHB_GREEN, param2);
+ }
+ else if (strncmp(param1,"blue",l) == 0)
+ {
+ auctionbot.Commands(7, ahMapID, AHB_BLUE, param2);
+ }
+ else if (strncmp(param1,"purple",l) == 0)
+ {
+ auctionbot.Commands(7, ahMapID, AHB_PURPLE, param2);
+ }
+ else if (strncmp(param1,"orange",l) == 0)
+ {
+ auctionbot.Commands(7, ahMapID, AHB_ORANGE, param2);
+ }
+ else if (strncmp(param1,"yellow",l) == 0)
+ {
+ auctionbot.Commands(7, ahMapID, AHB_YELLOW, param2);
+ }
+ else
+ {
+ PSendSysMessage("Syntax is: ahbotoptions maxprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $price");
+ return false;
+ }
+ }
+ else if (strncmp(opt,"minbidprice",l) == 0)
+ {
+ char * param1 = strtok(NULL, " ");
+ char * param2 = strtok(NULL, " ");
+ if ((!ahMapIdStr) || (!param1) || (!param2))
+ {
+ PSendSysMessage("Syntax is: ahbotoptions minbidprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $price");
+ return false;
+ }
+ uint32 minBidPrice = (uint32) strtoul(param2, NULL, 0);
+ if ((minBidPrice < 1) || (minBidPrice > 100))
+ {
+ PSendSysMessage("The min bid price multiplier must be between 1 and 100");
+ return false;
+ }
+ if (strncmp(param1,"grey",l) == 0)
+ {
+ auctionbot.Commands(8, ahMapID, AHB_GREY, param2);
+ }
+ else if (strncmp(param1,"white",l) == 0)
+ {
+ auctionbot.Commands(8, ahMapID, AHB_WHITE, param2);
+ }
+ else if (strncmp(param1,"green",l) == 0)
+ {
+ auctionbot.Commands(8, ahMapID, AHB_GREEN, param2);
+ }
+ else if (strncmp(param1,"blue",l) == 0)
+ {
+ auctionbot.Commands(8, ahMapID, AHB_BLUE, param2);
+ }
+ else if (strncmp(param1,"purple",l) == 0)
+ {
+ auctionbot.Commands(8, ahMapID, AHB_PURPLE, param2);
+ }
+ else if (strncmp(param1,"orange",l) == 0)
+ {
+ auctionbot.Commands(8, ahMapID, AHB_ORANGE, param2);
+ }
+ else if (strncmp(param1,"yellow",l) == 0)
+ {
+ auctionbot.Commands(8, ahMapID, AHB_YELLOW, param2);
+ }
+ else
+ {
+ PSendSysMessage("Syntax is: ahbotoptions minbidprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $price");
+ return false;
+ }
+ }
+ else if (strncmp(opt,"maxbidprice",l) == 0)
+ {
+ char * param1 = strtok(NULL, " ");
+ char * param2 = strtok(NULL, " ");
+ if ((!ahMapIdStr) || (!param1) || (!param2))
+ {
+ PSendSysMessage("Syntax is: ahbotoptions maxbidprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $price");
+ return false;
+ }
+ uint32 maxBidPrice = (uint32) strtoul(param2, NULL, 0);
+ if ((maxBidPrice < 1) || (maxBidPrice > 100))
+ {
+ PSendSysMessage("The max bid price multiplier must be between 1 and 100");
+ return false;
+ }
+ if (strncmp(param1,"grey",l) == 0)
+ {
+ auctionbot.Commands(9, ahMapID, AHB_GREY, param2);
+ }
+ else if (strncmp(param1,"white",l) == 0)
+ {
+ auctionbot.Commands(9, ahMapID, AHB_WHITE, param2);
+ }
+ else if (strncmp(param1,"green",l) == 0)
+ {
+ auctionbot.Commands(9, ahMapID, AHB_GREEN, param2);
+ }
+ else if (strncmp(param1,"blue",l) == 0)
+ {
+ auctionbot.Commands(9, ahMapID, AHB_BLUE, param2);
+ }
+ else if (strncmp(param1,"purple",l) == 0)
+ {
+ auctionbot.Commands(9, ahMapID, AHB_PURPLE, param2);
+ }
+ else if (strncmp(param1,"orange",l) == 0)
+ {
+ auctionbot.Commands(9, ahMapID, AHB_ORANGE, param2);
+ }
+ else if (strncmp(param1,"yellow",l) == 0)
+ {
+ auctionbot.Commands(9, ahMapID, AHB_YELLOW, param2);
+ }
+ else
+ {
+ PSendSysMessage("Syntax is: ahbotoptions max bidprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $price");
+ return false;
+ }
+ }
+ else if (strncmp(opt,"maxstack",l) == 0)
+ {
+ char * param1 = strtok(NULL, " ");
+ char * param2 = strtok(NULL, " ");
+ if ((!ahMapIdStr) || (!param1) || (!param2))
+ {
+ PSendSysMessage("Syntax is: ahbotoptions maxstack $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $value");
+ return false;
+ }
+ uint32 maxStack = (uint32) strtoul(param2, NULL, 0);
+ if (maxStack < 0)
+ {
+ PSendSysMessage("maxstack can't be a negative number.");
+ return false;
+ }
+ if (strncmp(param1,"grey",l) == 0)
+ {
+ auctionbot.Commands(10, ahMapID, AHB_GREY, param2);
+ }
+ else if (strncmp(param1,"white",l) == 0)
+ {
+ auctionbot.Commands(10, ahMapID, AHB_WHITE, param2);
+ }
+ else if (strncmp(param1,"green",l) == 0)
+ {
+ auctionbot.Commands(10, ahMapID, AHB_GREEN, param2);
+ }
+ else if (strncmp(param1,"blue",l) == 0)
+ {
+ auctionbot.Commands(10, ahMapID, AHB_BLUE, param2);
+ }
+ else if (strncmp(param1,"purple",l) == 0)
+ {
+ auctionbot.Commands(10, ahMapID, AHB_PURPLE, param2);
+ }
+ else if (strncmp(param1,"orange",l) == 0)
+ {
+ auctionbot.Commands(10, ahMapID, AHB_ORANGE, param2);
+ }
+ else if (strncmp(param1,"yellow",l) == 0)
+ {
+ auctionbot.Commands(10, ahMapID, AHB_YELLOW, param2);
+ }
+ else
+ {
+ PSendSysMessage("Syntax is: ahbotoptions maxstack $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $value");
+ return false;
+ }
+ }
+ else if (strncmp(opt,"buyerprice",l) == 0)
+ {
+ char * param1 = strtok(NULL, " ");
+ char * param2 = strtok(NULL, " ");
+ if ((!ahMapIdStr) || (!param1) || (!param2))
+ {
+ PSendSysMessage("Syntax is: ahbotoptions buyerprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue or purple) $price");
+ return false;
+ }
+ if (strncmp(param1,"grey",l) == 0)
+ {
+ auctionbot.Commands(11, ahMapID, AHB_GREY, param2);
+ }
+ else if (strncmp(param1,"white",l) == 0)
+ {
+ auctionbot.Commands(11, ahMapID, AHB_WHITE, param2);
+ }
+ else if (strncmp(param1,"green",l) == 0)
+ {
+ auctionbot.Commands(11, ahMapID, AHB_GREEN, param2);
+ }
+ else if (strncmp(param1,"blue",l) == 0)
+ {
+ auctionbot.Commands(11, ahMapID, AHB_BLUE, param2);
+ }
+ else if (strncmp(param1,"purple",l) == 0)
+ {
+ auctionbot.Commands(11, ahMapID, AHB_PURPLE, param2);
+ }
+ else if (strncmp(param1,"orange",l) == 0)
+ {
+ auctionbot.Commands(11, ahMapID, AHB_ORANGE, param2);
+ }
+ else if (strncmp(param1,"yellow",l) == 0)
+ {
+ auctionbot.Commands(11, ahMapID, AHB_YELLOW, param2);
+ }
+ else
+ {
+ PSendSysMessage("Syntax is: ahbotoptions buyerprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue or purple) $price");
+ return false;
+ }
+ }
+ else if (strncmp(opt,"bidinterval",l) == 0)
+ {
+ char * param1 = strtok(NULL, " ");
+ if ((!ahMapIdStr) || (!param1))
+ {
+ PSendSysMessage("Syntax is: ahbotoptions bidinterval $ahMapID (2, 6 or 7) $interval(in minutes)");
+ return false;
+ }
+ auctionbot.Commands(12, ahMapID, NULL, param1);
+ }
+ else if (strncmp(opt,"bidsperinterval",l) == 0)
+ {
+ char * param1 = strtok(NULL, " ");
+ if ((!ahMapIdStr) || (!param1))
+ {
+ PSendSysMessage("Syntax is: ahbotoptions bidsperinterval $ahMapID (2, 6 or 7) $bids");
+ return false;
+ }
+ auctionbot.Commands(13, ahMapID, NULL, param1);
+ }
+ else
+ {
+ PSendSysMessage("Syntax is: ahbotoptions $option $ahMapID (2, 6 or 7) $parameter");
+ PSendSysMessage("Try ahbotoptions help to see a list of options.");
+ return false;
+ }
+ return true;
+}
+
+//reload commands
+bool ChatHandler::HandleReloadAllCommand(const char*)
+{
+ HandleReloadSkillFishingBaseLevelCommand("");
+
+ HandleReloadAllAchievementCommand("");
+ HandleReloadAllAreaCommand("");
+ HandleReloadAllEventAICommand("");
+ HandleReloadAllLootCommand("");
+ HandleReloadAllNpcCommand("");
+ HandleReloadAllQuestCommand("");
+ HandleReloadAllSpellCommand("");
+ HandleReloadAllItemCommand("");
+ HandleReloadAllLocalesCommand("");
+
+ HandleReloadAccessRequirementCommand("");
+ HandleReloadMailLevelRewardCommand("");
+ HandleReloadCommandCommand("");
+ HandleReloadReservedNameCommand("");
+ HandleReloadTrinityStringCommand("");
+ HandleReloadGameTeleCommand("");
+
+ HandleReloadAutobroadcastCommand("");
+ return true;
+}
+
+bool ChatHandler::HandleReloadAllAchievementCommand(const char*)
+{
+ HandleReloadAchievementCriteriaDataCommand("");
+ HandleReloadAchievementRewardCommand("");
+ return true;
+}
+
+bool ChatHandler::HandleReloadAllAreaCommand(const char*)
+{
+ //HandleReloadQuestAreaTriggersCommand(""); -- reloaded in HandleReloadAllQuestCommand
+ HandleReloadAreaTriggerTeleportCommand("");
+ HandleReloadAreaTriggerTavernCommand("");
+ HandleReloadGameGraveyardZoneCommand("");
+ return true;
+}
+
+bool ChatHandler::HandleReloadAllLootCommand(const char*)
+{
+ sLog.outString("Re-Loading Loot Tables...");
+ LoadLootTables();
+ SendGlobalGMSysMessage("DB tables `*_loot_template` reloaded.");
+ sConditionMgr.LoadConditions(true);
+ return true;
+}
+
+bool ChatHandler::HandleReloadAllNpcCommand(const char* /*args*/)
+{
+ HandleReloadNpcGossipCommand("a");
+ HandleReloadNpcTrainerCommand("a");
+ HandleReloadNpcVendorCommand("a");
+ HandleReloadPointsOfInterestCommand("a");
+ HandleReloadSpellClickSpellsCommand("a");
+ return true;
+}
+
+bool ChatHandler::HandleReloadAllQuestCommand(const char* /*args*/)
+{
+ HandleReloadQuestAreaTriggersCommand("a");
+ HandleReloadQuestTemplateCommand("a");
+
+ sLog.outString("Re-Loading Quests Relations...");
+ objmgr.LoadQuestRelations();
+ SendGlobalGMSysMessage("DB tables `*_questrelation` and `*_involvedrelation` reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadAllScriptsCommand(const char*)
+{
+ if (sWorld.IsScriptScheduled())
+ {
+ PSendSysMessage("DB scripts used currently, please attempt reload later.");
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ sLog.outString("Re-Loading Scripts...");
+ HandleReloadGameObjectScriptsCommand("a");
+ HandleReloadEventScriptsCommand("a");
+ HandleReloadQuestEndScriptsCommand("a");
+ HandleReloadQuestStartScriptsCommand("a");
+ HandleReloadSpellScriptsCommand("a");
+ SendGlobalGMSysMessage("DB tables `*_scripts` reloaded.");
+ HandleReloadDbScriptStringCommand("a");
+ HandleReloadWpScriptsCommand("a");
+ return true;
+}
+
+bool ChatHandler::HandleReloadAllEventAICommand(const char*)
+{
+ HandleReloadEventAITextsCommand("a");
+ HandleReloadEventAISummonsCommand("a");
+ HandleReloadEventAIScriptsCommand("a");
+ return true;
+}
+
+bool ChatHandler::HandleReloadAllSpellCommand(const char*)
+{
+ HandleReloadSkillDiscoveryTemplateCommand("a");
+ HandleReloadSkillExtraItemTemplateCommand("a");
+ HandleReloadSpellRequiredCommand("a");
+ HandleReloadSpellAreaCommand("a");
+ HandleReloadSpellGroupsCommand("a");
+ HandleReloadSpellLearnSpellCommand("a");
+ HandleReloadSpellLinkedSpellCommand("a");
+ HandleReloadSpellProcEventCommand("a");
+ HandleReloadSpellBonusesCommand("a");
+ HandleReloadSpellTargetPositionCommand("a");
+ HandleReloadSpellThreatsCommand("a");
+ HandleReloadSpellGroupStackRulesCommand("a");
+ HandleReloadSpellPetAurasCommand("a");
+ HandleReloadSpellDisabledCommand("a");
+ return true;
+}
+
+bool ChatHandler::HandleReloadAllItemCommand(const char*)
+{
+ HandleReloadPageTextsCommand("a");
+ HandleReloadItemEnchantementsCommand("a");
+ return true;
+}
+
+bool ChatHandler::HandleReloadAllLocalesCommand(const char* /*args*/)
+{
+ HandleReloadLocalesAchievementRewardCommand("a");
+ HandleReloadLocalesCreatureCommand("a");
+ HandleReloadLocalesGameobjectCommand("a");
+ HandleReloadLocalesItemCommand("a");
+ HandleReloadLocalesNpcTextCommand("a");
+ HandleReloadLocalesPageTextCommand("a");
+ HandleReloadLocalesPointsOfInterestCommand("a");
+ HandleReloadLocalesQuestCommand("a");
+ return true;
+}
+
+bool ChatHandler::HandleReloadConfigCommand(const char* /*args*/)
+{
+ sLog.outString("Re-Loading config settings...");
+ sWorld.LoadConfigSettings(true);
+ MapManager::Instance().InitializeVisibilityDistanceInfo();
+ SendGlobalGMSysMessage("World config settings reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadAccessRequirementCommand(const char*)
+{
+ sLog.outString("Re-Loading Access Requirement definitions...");
+ objmgr.LoadAccessRequirements();
+ SendGlobalGMSysMessage("DB table `access_requirement` reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadAchievementCriteriaDataCommand(const char*)
+{
+ sLog.outString("Re-Loading Additional Achievement Criteria Data...");
+ achievementmgr.LoadAchievementCriteriaData();
+ SendGlobalGMSysMessage("DB table `achievement_criteria_data` reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadAchievementRewardCommand(const char*)
+{
+ sLog.outString("Re-Loading Achievement Reward Data...");
+ achievementmgr.LoadRewards();
+ SendGlobalGMSysMessage("DB table `achievement_reward` reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadAreaTriggerTavernCommand(const char*)
+{
+ sLog.outString("Re-Loading Tavern Area Triggers...");
+ objmgr.LoadTavernAreaTriggers();
+ SendGlobalGMSysMessage("DB table `areatrigger_tavern` reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadAreaTriggerTeleportCommand(const char*)
+{
+ sLog.outString("Re-Loading AreaTrigger teleport definitions...");
+ objmgr.LoadAreaTriggerTeleports();
+ SendGlobalGMSysMessage("DB table `areatrigger_teleport` reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadAutobroadcastCommand(const char*)
+{
+ sLog.outString("Re-Loading Autobroadcast...");
+ sWorld.LoadAutobroadcasts();
+ SendGlobalGMSysMessage("DB table `autobroadcast` reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadCommandCommand(const char*)
+{
+ load_command_table = true;
+ SendGlobalGMSysMessage("DB table `command` will be reloaded at next chat command use.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadCreatureTemplateCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ uint32 entry = (uint32) atoi((char*)args);
+ QueryResult_AutoPtr result = WorldDatabase.PQuery("SELECT difficulty_entry_1,difficulty_entry_2,difficulty_entry_3,KillCredit1,KillCredit2,modelid1,modelid2,modelid3,modelid4,name,subname,IconName,gossip_menu_id,minlevel,maxlevel,exp,faction_A,faction_H,npcflag,speed_walk,speed_run,scale,rank,mindmg,maxdmg,dmgschool,attackpower,dmg_multiplier,baseattacktime,rangeattacktime,unit_class,unit_flags,dynamicflags,family,trainer_type,trainer_spell,trainer_class,trainer_race,minrangedmg,maxrangedmg,rangedattackpower,type,type_flags,lootid,pickpocketloot,skinloot,resistance1,resistance2,resistance3,resistance4,resistance5,resistance6,spell1,spell2,spell3,spell4,spell5,spell6,spell7,spell8,PetSpellDataId,VehicleId,mingold,maxgold,AIName,MovementType,InhabitType,Health_mod,Mana_mod,Armor_mod,RacialLeader,questItem1,questItem2,questItem3,questItem4,questItem5,questItem6,movementId,RegenHealth,equipment_id,mechanic_immune_mask,flags_extra,ScriptName FROM creature_template WHERE entry = %u", entry);
+ if (!result)
+ {
+ PSendSysMessage(LANG_COMMAND_CREATURETEMPLATE_NOTFOUND, entry);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo>(entry);
+ if (!cInfo)
+ {
+ PSendSysMessage(LANG_COMMAND_CREATURESTORAGE_NOTFOUND, entry);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ sLog.outString("Reloading creature template entry %u", entry);
+
+ Field *fields = result->Fetch();
+
+ const_cast<CreatureInfo*>(cInfo)->DifficultyEntry[0] = fields[0].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->DifficultyEntry[1] = fields[1].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->DifficultyEntry[2] = fields[2].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->KillCredit[0] = fields[3].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->KillCredit[1] = fields[4].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->Modelid1 = fields[5].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->Modelid2 = fields[6].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->Modelid3 = fields[7].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->Modelid4 = fields[8].GetUInt32();
+ size_t len = 0;
+ if (const char* temp = fields[9].GetString())
+ {
+ if (cInfo->Name)
+ delete cInfo->Name;
+ len = strlen(temp)+1;
+ const_cast<CreatureInfo*>(cInfo)->Name = new char[len];
+ strncpy(cInfo->Name, temp, len);
+ }
+ if (const char* temp = fields[10].GetString())
+ {
+ if (cInfo->SubName)
+ delete cInfo->SubName;
+ len = strlen(temp)+1;
+ const_cast<CreatureInfo*>(cInfo)->SubName = new char[len];
+ strncpy(cInfo->SubName, temp, len);
+ }
+ if (const char* temp = fields[11].GetString())
+ {
+ if (cInfo->IconName)
+ delete cInfo->IconName;
+ len = strlen(temp)+1;
+ const_cast<CreatureInfo*>(cInfo)->IconName = new char[len];
+ strncpy(cInfo->IconName, temp, len);
+ }
+ const_cast<CreatureInfo*>(cInfo)->GossipMenuId = fields[12].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->minlevel = fields[13].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->maxlevel = fields[14].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->expansion = fields[15].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->faction_A = fields[16].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->faction_H = fields[17].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->npcflag = fields[18].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->speed_walk = fields[19].GetFloat();
+ const_cast<CreatureInfo*>(cInfo)->speed_run = fields[20].GetFloat();
+ const_cast<CreatureInfo*>(cInfo)->scale = fields[21].GetFloat();
+ const_cast<CreatureInfo*>(cInfo)->rank = fields[22].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->mindmg = fields[23].GetFloat();
+ const_cast<CreatureInfo*>(cInfo)->maxdmg = fields[24].GetFloat();
+ const_cast<CreatureInfo*>(cInfo)->dmgschool = fields[25].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->attackpower = fields[26].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->dmg_multiplier = fields[27].GetFloat();
+ const_cast<CreatureInfo*>(cInfo)->baseattacktime = fields[28].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->rangeattacktime = fields[29].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->unit_class = fields[30].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->unit_flags = fields[31].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->dynamicflags = fields[32].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->family = fields[33].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->trainer_type = fields[34].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->trainer_spell = fields[35].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->trainer_class = fields[36].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->trainer_race = fields[37].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->minrangedmg = fields[38].GetFloat();
+ const_cast<CreatureInfo*>(cInfo)->maxrangedmg = fields[39].GetFloat();
+ const_cast<CreatureInfo*>(cInfo)->rangedattackpower = fields[40].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->type = fields[41].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->type_flags = fields[42].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->lootid = fields[43].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->pickpocketLootId = fields[44].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->SkinLootId = fields[45].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->resistance1 = fields[46].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->resistance2 = fields[47].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->resistance3 = fields[48].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->resistance4 = fields[49].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->resistance5 = fields[50].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->resistance6 = fields[51].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->spells[0] = fields[52].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->spells[1] = fields[53].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->spells[2] = fields[54].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->spells[3] = fields[55].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->spells[4] = fields[56].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->spells[5] = fields[57].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->spells[6] = fields[58].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->spells[7] = fields[59].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->PetSpellDataId = fields[60].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->VehicleId = fields[61].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->mingold = fields[62].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->maxgold = fields[63].GetUInt32();
+ if (const char* temp = fields[64].GetString())
+ {
+ if (cInfo->AIName)
+ delete cInfo->AIName;
+ len = strlen(temp)+1;
+ const_cast<CreatureInfo*>(cInfo)->AIName = new char[len];
+ strncpy(const_cast<char*>(cInfo->AIName), temp, len);
+ }
+ const_cast<CreatureInfo*>(cInfo)->MovementType = fields[65].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->InhabitType = fields[66].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->ModHealth = fields[67].GetFloat();
+ const_cast<CreatureInfo*>(cInfo)->ModMana = fields[68].GetFloat();
+ const_cast<CreatureInfo*>(cInfo)->ModArmor = fields[69].GetFloat();
+ const_cast<CreatureInfo*>(cInfo)->RacialLeader = fields[70].GetBool();
+ const_cast<CreatureInfo*>(cInfo)->questItems[0] = fields[71].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->questItems[1] = fields[72].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->questItems[2] = fields[73].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->questItems[3] = fields[74].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->questItems[4] = fields[75].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->questItems[5] = fields[76].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->movementId = fields[77].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->RegenHealth = fields[78].GetBool();
+ const_cast<CreatureInfo*>(cInfo)->equipmentId = fields[79].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->MechanicImmuneMask = fields[80].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->flags_extra = fields[81].GetUInt32();
+ const_cast<CreatureInfo*>(cInfo)->ScriptID = objmgr.GetScriptId(fields[82].GetString());
+
+ objmgr.CheckCreatureTemplate(cInfo);
+
+ SendGlobalGMSysMessage("Creature template reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadCreatureQuestRelationsCommand(const char*)
+{
+ sLog.outString("Loading Quests Relations... (`creature_questrelation`)");
+ objmgr.LoadCreatureQuestRelations();
+ SendGlobalGMSysMessage("DB table `creature_questrelation` (creature quest givers) reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadCreatureLinkedRespawnCommand(const char * /*args*/)
+{
+ sLog.outString("Loading Linked Respawns... (`creature_linked_respawn`)");
+ objmgr.LoadCreatureLinkedRespawn();
+ SendGlobalGMSysMessage("DB table `creature_linked_respawn` (creature linked respawns) reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadCreatureQuestInvRelationsCommand(const char*)
+{
+ sLog.outString("Loading Quests Relations... (`creature_involvedrelation`)");
+ objmgr.LoadCreatureInvolvedRelations();
+ SendGlobalGMSysMessage("DB table `creature_involvedrelation` (creature quest takers) reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadGossipMenuCommand(const char*)
+{
+ sLog.outString("Re-Loading `gossip_menu` Table!");
+ objmgr.LoadGossipMenu();
+ SendGlobalGMSysMessage("DB table `gossip_menu` reloaded.");
+ sConditionMgr.LoadConditions(true);
+ return true;
+}
+
+bool ChatHandler::HandleReloadGossipMenuOptionCommand(const char*)
+{
+ sLog.outString("Re-Loading `gossip_menu_option` Table!");
+ objmgr.LoadGossipMenuItems();
+ SendGlobalGMSysMessage("DB table `gossip_menu_option` reloaded.");
+ sConditionMgr.LoadConditions(true);
+ return true;
+}
+
+bool ChatHandler::HandleReloadGOQuestRelationsCommand(const char*)
+{
+ sLog.outString("Loading Quests Relations... (`gameobject_questrelation`)");
+ objmgr.LoadGameobjectQuestRelations();
+ SendGlobalGMSysMessage("DB table `gameobject_questrelation` (gameobject quest givers) reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadGOQuestInvRelationsCommand(const char*)
+{
+ sLog.outString("Loading Quests Relations... (`gameobject_involvedrelation`)");
+ objmgr.LoadGameobjectInvolvedRelations();
+ SendGlobalGMSysMessage("DB table `gameobject_involvedrelation` (gameobject quest takers) reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadQuestAreaTriggersCommand(const char*)
+{
+ sLog.outString("Re-Loading Quest Area Triggers...");
+ objmgr.LoadQuestAreaTriggers();
+ SendGlobalGMSysMessage("DB table `areatrigger_involvedrelation` (quest area triggers) reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadQuestTemplateCommand(const char*)
+{
+ sLog.outString("Re-Loading Quest Templates...");
+ objmgr.LoadQuests();
+ SendGlobalGMSysMessage("DB table `quest_template` (quest definitions) reloaded.");
+
+ /// dependent also from `gameobject` but this table not reloaded anyway
+ sLog.outString("Re-Loading GameObjects for quests...");
+ objmgr.LoadGameObjectForQuests();
+ SendGlobalGMSysMessage("Data GameObjects for quests reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadLootTemplatesCreatureCommand(const char*)
+{
+ sLog.outString("Re-Loading Loot Tables... (`creature_loot_template`)");
+ LoadLootTemplates_Creature();
+ LootTemplates_Creature.CheckLootRefs();
+ SendGlobalGMSysMessage("DB table `creature_loot_template` reloaded.");
+ sConditionMgr.LoadConditions(true);
+ return true;
+}
+
+bool ChatHandler::HandleReloadLootTemplatesDisenchantCommand(const char*)
+{
+ sLog.outString("Re-Loading Loot Tables... (`disenchant_loot_template`)");
+ LoadLootTemplates_Disenchant();
+ LootTemplates_Disenchant.CheckLootRefs();
+ SendGlobalGMSysMessage("DB table `disenchant_loot_template` reloaded.");
+ sConditionMgr.LoadConditions(true);
+ return true;
+}
+
+bool ChatHandler::HandleReloadLootTemplatesFishingCommand(const char*)
+{
+ sLog.outString("Re-Loading Loot Tables... (`fishing_loot_template`)");
+ LoadLootTemplates_Fishing();
+ LootTemplates_Fishing.CheckLootRefs();
+ SendGlobalGMSysMessage("DB table `fishing_loot_template` reloaded.");
+ sConditionMgr.LoadConditions(true);
+ return true;
+}
+
+bool ChatHandler::HandleReloadLootTemplatesGameobjectCommand(const char*)
+{
+ sLog.outString("Re-Loading Loot Tables... (`gameobject_loot_template`)");
+ LoadLootTemplates_Gameobject();
+ LootTemplates_Gameobject.CheckLootRefs();
+ SendGlobalGMSysMessage("DB table `gameobject_loot_template` reloaded.");
+ sConditionMgr.LoadConditions(true);
+ return true;
+}
+
+bool ChatHandler::HandleReloadLootTemplatesItemCommand(const char*)
+{
+ sLog.outString("Re-Loading Loot Tables... (`item_loot_template`)");
+ LoadLootTemplates_Item();
+ LootTemplates_Item.CheckLootRefs();
+ SendGlobalGMSysMessage("DB table `item_loot_template` reloaded.");
+ sConditionMgr.LoadConditions(true);
+ return true;
+}
+
+bool ChatHandler::HandleReloadLootTemplatesMillingCommand(const char*)
+{
+ sLog.outString("Re-Loading Loot Tables... (`milling_loot_template`)");
+ LoadLootTemplates_Milling();
+ LootTemplates_Milling.CheckLootRefs();
+ SendGlobalGMSysMessage("DB table `milling_loot_template` reloaded.");
+ sConditionMgr.LoadConditions(true);
+ return true;
+}
+
+bool ChatHandler::HandleReloadLootTemplatesPickpocketingCommand(const char*)
+{
+ sLog.outString("Re-Loading Loot Tables... (`pickpocketing_loot_template`)");
+ LoadLootTemplates_Pickpocketing();
+ LootTemplates_Pickpocketing.CheckLootRefs();
+ SendGlobalGMSysMessage("DB table `pickpocketing_loot_template` reloaded.");
+ sConditionMgr.LoadConditions(true);
+ return true;
+}
+
+bool ChatHandler::HandleReloadLootTemplatesProspectingCommand(const char*)
+{
+ sLog.outString("Re-Loading Loot Tables... (`prospecting_loot_template`)");
+ LoadLootTemplates_Prospecting();
+ LootTemplates_Prospecting.CheckLootRefs();
+ SendGlobalGMSysMessage("DB table `prospecting_loot_template` reloaded.");
+ sConditionMgr.LoadConditions(true);
+ return true;
+}
+
+bool ChatHandler::HandleReloadLootTemplatesMailCommand(const char*)
+{
+ sLog.outString("Re-Loading Loot Tables... (`mail_loot_template`)");
+ LoadLootTemplates_Mail();
+ LootTemplates_Mail.CheckLootRefs();
+ SendGlobalGMSysMessage("DB table `mail_loot_template` reloaded.");
+ sConditionMgr.LoadConditions(true);
+ return true;
+}
+
+bool ChatHandler::HandleReloadLootTemplatesReferenceCommand(const char*)
+{
+ sLog.outString("Re-Loading Loot Tables... (`reference_loot_template`)");
+ LoadLootTemplates_Reference();
+ SendGlobalGMSysMessage("DB table `reference_loot_template` reloaded.");
+ sConditionMgr.LoadConditions(true);
+ return true;
+}
+
+bool ChatHandler::HandleReloadLootTemplatesSkinningCommand(const char*)
+{
+ sLog.outString("Re-Loading Loot Tables... (`skinning_loot_template`)");
+ LoadLootTemplates_Skinning();
+ LootTemplates_Skinning.CheckLootRefs();
+ SendGlobalGMSysMessage("DB table `skinning_loot_template` reloaded.");
+ sConditionMgr.LoadConditions(true);
+ return true;
+}
+
+bool ChatHandler::HandleReloadLootTemplatesSpellCommand(const char*)
+{
+ sLog.outString("Re-Loading Loot Tables... (`spell_loot_template`)");
+ LoadLootTemplates_Spell();
+ LootTemplates_Spell.CheckLootRefs();
+ SendGlobalGMSysMessage("DB table `spell_loot_template` reloaded.");
+ sConditionMgr.LoadConditions(true);
+ return true;
+}
+
+bool ChatHandler::HandleReloadTrinityStringCommand(const char*)
+{
+ sLog.outString("Re-Loading trinity_string Table!");
+ objmgr.LoadTrinityStrings();
+ SendGlobalGMSysMessage("DB table `trinity_string` reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadNpcGossipCommand(const char*)
+{
+ sLog.outString("Re-Loading `npc_gossip` Table!");
+ objmgr.LoadNpcTextId();
+ SendGlobalGMSysMessage("DB table `npc_gossip` reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadNpcTrainerCommand(const char*)
+{
+ sLog.outString("Re-Loading `npc_trainer` Table!");
+ objmgr.LoadTrainerSpell();
+ SendGlobalGMSysMessage("DB table `npc_trainer` reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadNpcVendorCommand(const char*)
+{
+ sLog.outString("Re-Loading `npc_vendor` Table!");
+ objmgr.LoadVendors();
+ SendGlobalGMSysMessage("DB table `npc_vendor` reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadPointsOfInterestCommand(const char*)
+{
+ sLog.outString("Re-Loading `points_of_interest` Table!");
+ objmgr.LoadPointsOfInterest();
+ SendGlobalGMSysMessage("DB table `points_of_interest` reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadSpellClickSpellsCommand(const char*)
+{
+ sLog.outString("Re-Loading `npc_spellclick_spells` Table!");
+ objmgr.LoadNPCSpellClickSpells();
+ SendGlobalGMSysMessage("DB table `npc_spellclick_spells` reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadReservedNameCommand(const char*)
+{
+ sLog.outString("Loading ReservedNames... (`reserved_name`)");
+ objmgr.LoadReservedPlayersNames();
+ SendGlobalGMSysMessage("DB table `reserved_name` (player reserved names) reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadSkillDiscoveryTemplateCommand(const char* /*args*/)
+{
+ sLog.outString("Re-Loading Skill Discovery Table...");
+ LoadSkillDiscoveryTable();
+ SendGlobalGMSysMessage("DB table `skill_discovery_template` (recipes discovered at crafting) reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadSkillExtraItemTemplateCommand(const char* /*args*/)
+{
+ sLog.outString("Re-Loading Skill Extra Item Table...");
+ LoadSkillExtraItemTable();
+ SendGlobalGMSysMessage("DB table `skill_extra_item_template` (extra item creation when crafting) reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadSkillFishingBaseLevelCommand(const char* /*args*/)
+{
+ sLog.outString("Re-Loading Skill Fishing base level requirements...");
+ objmgr.LoadFishingBaseSkillLevel();
+ SendGlobalGMSysMessage("DB table `skill_fishing_base_level` (fishing base level for zone/subzone) reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadSpellAreaCommand(const char*)
+{
+ sLog.outString("Re-Loading SpellArea Data...");
+ spellmgr.LoadSpellAreas();
+ SendGlobalGMSysMessage("DB table `spell_area` (spell dependences from area/quest/auras state) reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadSpellRequiredCommand(const char*)
+{
+ sLog.outString("Re-Loading Spell Required Data... ");
+ spellmgr.LoadSpellRequired();
+ SendGlobalGMSysMessage("DB table `spell_required` reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadSpellGroupsCommand(const char*)
+{
+ sLog.outString("Re-Loading Spell Groups...");
+ spellmgr.LoadSpellGroups();
+ SendGlobalGMSysMessage("DB table `spell_group` (spell groups) reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadSpellLearnSpellCommand(const char*)
+{
+ sLog.outString("Re-Loading Spell Learn Spells...");
+ spellmgr.LoadSpellLearnSpells();
+ SendGlobalGMSysMessage("DB table `spell_learn_spell` reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadSpellLinkedSpellCommand(const char*)
+{
+ sLog.outString("Re-Loading Spell Linked Spells...");
+ spellmgr.LoadSpellLinked();
+ SendGlobalGMSysMessage("DB table `spell_linked_spell` reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadSpellProcEventCommand(const char*)
+{
+ sLog.outString("Re-Loading Spell Proc Event conditions...");
+ spellmgr.LoadSpellProcEvents();
+ SendGlobalGMSysMessage("DB table `spell_proc_event` (spell proc trigger requirements) reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadSpellBonusesCommand(const char*)
+{
+ sLog.outString("Re-Loading Spell Bonus Data...");
+ spellmgr.LoadSpellBonusess();
+ SendGlobalGMSysMessage("DB table `spell_bonus_data` (spell damage/healing coefficients) reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadSpellTargetPositionCommand(const char*)
+{
+ sLog.outString("Re-Loading Spell target coordinates...");
+ spellmgr.LoadSpellTargetPositions();
+ SendGlobalGMSysMessage("DB table `spell_target_position` (destination coordinates for spell targets) reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadSpellThreatsCommand(const char*)
+{
+ sLog.outString("Re-Loading Aggro Spells Definitions...");
+ spellmgr.LoadSpellThreats();
+ SendGlobalGMSysMessage("DB table `spell_threat` (spell aggro definitions) reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadSpellGroupStackRulesCommand(const char*)
+{
+ sLog.outString("Re-Loading Spell Group Stack Rules...");
+ spellmgr.LoadSpellGroupStackRules();
+ SendGlobalGMSysMessage("DB table `spell_group_stack_rules` (spell stacking definitions) reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadSpellPetAurasCommand(const char*)
+{
+ sLog.outString("Re-Loading Spell pet auras...");
+ spellmgr.LoadSpellPetAuras();
+ SendGlobalGMSysMessage("DB table `spell_pet_auras` reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadPageTextsCommand(const char*)
+{
+ sLog.outString("Re-Loading Page Texts...");
+ objmgr.LoadPageTexts();
+ SendGlobalGMSysMessage("DB table `page_texts` reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadItemEnchantementsCommand(const char*)
+{
+ sLog.outString("Re-Loading Item Random Enchantments Table...");
+ LoadRandomEnchantmentsTable();
+ SendGlobalGMSysMessage("DB table `item_enchantment_template` reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadGameObjectScriptsCommand(const char* arg)
+{
+ if (sWorld.IsScriptScheduled())
+ {
+ SendSysMessage("DB scripts used currently, please attempt reload later.");
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (*arg != 'a')
+ sLog.outString("Re-Loading Scripts from `gameobject_scripts`...");
+
+ objmgr.LoadGameObjectScripts();
+
+ if (*arg != 'a')
+ SendGlobalGMSysMessage("DB table `gameobject_scripts` reloaded.");
+
+ return true;
+}
+
+bool ChatHandler::HandleReloadEventScriptsCommand(const char* arg)
+{
+ if (sWorld.IsScriptScheduled())
+ {
+ SendSysMessage("DB scripts used currently, please attempt reload later.");
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (*arg != 'a')
+ sLog.outString("Re-Loading Scripts from `event_scripts`...");
+
+ objmgr.LoadEventScripts();
+
+ if (*arg != 'a')
+ SendGlobalGMSysMessage("DB table `event_scripts` reloaded.");
+
+ return true;
+}
+
+bool ChatHandler::HandleReloadWpScriptsCommand(const char* arg)
+{
+ if (sWorld.IsScriptScheduled())
+ {
+ SendSysMessage("DB scripts used currently, please attempt reload later.");
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (*arg != 'a')
+ sLog.outString("Re-Loading Scripts from `waypoint_scripts`...");
+
+ objmgr.LoadWaypointScripts();
+
+ if (*arg != 'a')
+ SendGlobalGMSysMessage("DB table `waypoint_scripts` reloaded.");
+
+ return true;
+}
+
+bool ChatHandler::HandleReloadEventAITextsCommand(const char* /*args*/)
+{
+
+ sLog.outString("Re-Loading Texts from `creature_ai_texts`...");
+ CreatureEAI_Mgr.LoadCreatureEventAI_Texts();
+ SendGlobalGMSysMessage("DB table `creature_ai_texts` reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadEventAISummonsCommand(const char* /*args*/)
+{
+ sLog.outString("Re-Loading Summons from `creature_ai_summons`...");
+ CreatureEAI_Mgr.LoadCreatureEventAI_Summons();
+ SendGlobalGMSysMessage("DB table `creature_ai_summons` reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadEventAIScriptsCommand(const char* /*args*/)
+{
+ sLog.outString("Re-Loading Scripts from `creature_ai_scripts`...");
+ CreatureEAI_Mgr.LoadCreatureEventAI_Scripts();
+ SendGlobalGMSysMessage("DB table `creature_ai_scripts` reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadQuestEndScriptsCommand(const char* arg)
+{
+ if (sWorld.IsScriptScheduled())
+ {
+ SendSysMessage("DB scripts used currently, please attempt reload later.");
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (*arg != 'a')
+ sLog.outString("Re-Loading Scripts from `quest_end_scripts`...");
+
+ objmgr.LoadQuestEndScripts();
+
+ if (*arg != 'a')
+ SendGlobalGMSysMessage("DB table `quest_end_scripts` reloaded.");
+
+ return true;
+}
+
+bool ChatHandler::HandleReloadQuestStartScriptsCommand(const char* arg)
+{
+ if (sWorld.IsScriptScheduled())
+ {
+ SendSysMessage("DB scripts used currently, please attempt reload later.");
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (*arg != 'a')
+ sLog.outString("Re-Loading Scripts from `quest_start_scripts`...");
+
+ objmgr.LoadQuestStartScripts();
+
+ if (*arg != 'a')
+ SendGlobalGMSysMessage("DB table `quest_start_scripts` reloaded.");
+
+ return true;
+}
+
+bool ChatHandler::HandleReloadSpellScriptsCommand(const char* arg)
+{
+ if (sWorld.IsScriptScheduled())
+ {
+ SendSysMessage("DB scripts used currently, please attempt reload later.");
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (*arg != 'a')
+ sLog.outString("Re-Loading Scripts from `spell_scripts`...");
+
+ objmgr.LoadSpellScripts();
+
+ if (*arg != 'a')
+ SendGlobalGMSysMessage("DB table `spell_scripts` reloaded.");
+
+ return true;
+}
+
+bool ChatHandler::HandleReloadDbScriptStringCommand(const char* /*arg*/)
+{
+ sLog.outString("Re-Loading Script strings from `db_script_string`...");
+ objmgr.LoadDbScriptStrings();
+ SendGlobalGMSysMessage("DB table `db_script_string` reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadGameGraveyardZoneCommand(const char* /*arg*/)
+{
+ sLog.outString("Re-Loading Graveyard-zone links...");
+
+ objmgr.LoadGraveyardZones();
+
+ SendGlobalGMSysMessage("DB table `game_graveyard_zone` reloaded.");
+
+ return true;
+}
+
+bool ChatHandler::HandleReloadGameTeleCommand(const char* /*arg*/)
+{
+ sLog.outString("Re-Loading Game Tele coordinates...");
+
+ objmgr.LoadGameTele();
+
+ SendGlobalGMSysMessage("DB table `game_tele` reloaded.");
+
+ return true;
+}
+
+bool ChatHandler::HandleReloadSpellDisabledCommand(const char* /*arg*/)
+{
+ sLog.outString("Re-Loading spell disabled table...");
+
+ objmgr.LoadSpellDisabledEntrys();
+
+ SendGlobalGMSysMessage("DB table `spell_disabled` reloaded.");
+
+ return true;
+}
+
+bool ChatHandler::HandleReloadLocalesAchievementRewardCommand(const char*)
+{
+ sLog.outString("Re-Loading Locales Achievement Reward Data...");
+ achievementmgr.LoadRewardLocales();
+ SendGlobalGMSysMessage("DB table `locales_achievement_reward` reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadLocalesCreatureCommand(const char* /*arg*/)
+{
+ sLog.outString("Re-Loading Locales Creature ...");
+ objmgr.LoadCreatureLocales();
+ SendGlobalGMSysMessage("DB table `locales_creature` reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadLocalesGameobjectCommand(const char* /*arg*/)
+{
+ sLog.outString("Re-Loading Locales Gameobject ... ");
+ objmgr.LoadGameObjectLocales();
+ SendGlobalGMSysMessage("DB table `locales_gameobject` reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadLocalesItemCommand(const char* /*arg*/)
+{
+ sLog.outString("Re-Loading Locales Item ... ");
+ objmgr.LoadItemLocales();
+ SendGlobalGMSysMessage("DB table `locales_item` reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadLocalesNpcTextCommand(const char* /*arg*/)
+{
+ sLog.outString("Re-Loading Locales NPC Text ... ");
+ objmgr.LoadNpcTextLocales();
+ SendGlobalGMSysMessage("DB table `locales_npc_text` reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadLocalesPageTextCommand(const char* /*arg*/)
+{
+ sLog.outString("Re-Loading Locales Page Text ... ");
+ objmgr.LoadPageTextLocales();
+ SendGlobalGMSysMessage("DB table `locales_page_text` reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadLocalesPointsOfInterestCommand(const char* /*arg*/)
+{
+ sLog.outString("Re-Loading Locales Points Of Interest ... ");
+ objmgr.LoadPointOfInterestLocales();
+ SendGlobalGMSysMessage("DB table `locales_points_of_interest` reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadLocalesQuestCommand(const char* /*arg*/)
+{
+ sLog.outString("Re-Loading Locales Quest ... ");
+ objmgr.LoadQuestLocales();
+ SendGlobalGMSysMessage("DB table `locales_quest` reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadMailLevelRewardCommand(const char* /*arg*/)
+{
+ sLog.outString("Re-Loading Player level dependent mail rewards...");
+ objmgr.LoadMailLevelRewards();
+ SendGlobalGMSysMessage("DB table `mail_level_reward` reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadAuctionsCommand(const char * /*args*/)
+{
+ ///- Reload dynamic data tables from the database
+ sLog.outString("Re-Loading Auctions...");
+ auctionmgr.LoadAuctionItems();
+ auctionmgr.LoadAuctions();
+ SendGlobalGMSysMessage("Auctions reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleReloadConditions(const char* args)
+{
+ sLog.outString("Re-Loading Conditions...");
+ sConditionMgr.LoadConditions(true);
+ SendGlobalGMSysMessage("Conditions reloaded.");
+ return true;
+}
+
+bool ChatHandler::HandleAccountSetGmLevelCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ std::string targetAccountName;
+ uint32 targetAccountId = 0;
+ uint32 targetSecurity = 0;
+ uint32 gm = 0;
+ char* arg1 = strtok((char*)args, " ");
+ char* arg2 = strtok(NULL, " ");
+ char* arg3 = strtok(NULL, " ");
+ bool isAccountNameGiven = true;
+
+ if (arg1 && !arg3)
+ {
+ if (!getSelectedPlayer())
+ return false;
+ isAccountNameGiven = false;
+ }
+
+ // Check for second parameter
+ if (!isAccountNameGiven && !arg2)
+ return false;
+
+ // Check for account
+ if (isAccountNameGiven)
+ {
+ targetAccountName = arg1;
+ if (!AccountMgr::normalizeString(targetAccountName))
+ {
+ PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,targetAccountName.c_str());
+ SetSentErrorMessage(true);
+ return false;
+ }
+ }
+
+ // Check for invalid specified GM level.
+ gm = (isAccountNameGiven) ? atoi(arg2) : atoi(arg1);
+ if (gm < SEC_PLAYER)
+ {
+ SendSysMessage(LANG_BAD_VALUE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // m_session == NULL only for console
+ targetAccountId = (isAccountNameGiven) ? accmgr.GetId(targetAccountName) : getSelectedPlayer()->GetSession()->GetAccountId();
+ int32 gmRealmID = (isAccountNameGiven) ? atoi(arg3) : atoi(arg2);
+ uint32 plSecurity = m_session ? accmgr.GetSecurity(m_session->GetAccountId(), gmRealmID) : SEC_CONSOLE;
+
+ // can set security level only for target with less security and to less security that we have
+ // This is also reject self apply in fact
+ targetSecurity = accmgr.GetSecurity(targetAccountId, gmRealmID);
+ if (targetSecurity >= plSecurity || gm >= plSecurity)
+ {
+ SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // Check and abort if the target gm has a higher rank on one of the realms and the new realm is -1
+ if (gmRealmID == -1)
+ {
+ QueryResult_AutoPtr result = LoginDatabase.PQuery("SELECT * FROM account_access WHERE id = '%u' AND gmlevel > '%d'", targetAccountId, gm);
+ if (result)
+ {
+ SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
+ SetSentErrorMessage(true);
+ return false;
+ }
+ }
+
+ // Check if provided realmID has a negative value other than -1
+ if (gmRealmID < -1)
+ {
+ SendSysMessage(LANG_INVALID_REALMID);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // If gmRealmID is -1, delete all values for the account id, else, insert values for the specific realmID
+ if (gmRealmID == -1)
+ LoginDatabase.PExecute("DELETE FROM account_access WHERE id = '%u'", targetAccountId);
+ else
+ LoginDatabase.PExecute("DELETE FROM account_access WHERE id = '%u' AND (RealmID = '%d' OR RealmID = '-1')", targetAccountId, realmID);
+
+ if (gm != 0)
+ LoginDatabase.PExecute("INSERT INTO account_access VALUES ('%u','%d','%d')", targetAccountId, gm, realmID);
+ PSendSysMessage(LANG_YOU_CHANGE_SECURITY, targetAccountName.c_str(), gm);
+ return true;
+}
+
+/// Set password for account
+bool ChatHandler::HandleAccountSetPasswordCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ ///- Get the command line arguments
+ char *szAccount = strtok ((char*)args," ");
+ char *szPassword1 = strtok (NULL," ");
+ char *szPassword2 = strtok (NULL," ");
+
+ if (!szAccount||!szPassword1 || !szPassword2)
+ return false;
+
+ std::string account_name = szAccount;
+ if (!AccountMgr::normalizeString(account_name))
+ {
+ PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ uint32 targetAccountId = accmgr.GetId(account_name);
+ if (!targetAccountId)
+ {
+ PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ /// can set password only for target with less security
+ /// This is also reject self apply in fact
+ if (HasLowerSecurityAccount (NULL,targetAccountId,true))
+ return false;
+
+ if (strcmp(szPassword1,szPassword2))
+ {
+ SendSysMessage (LANG_NEW_PASSWORDS_NOT_MATCH);
+ SetSentErrorMessage (true);
+ return false;
+ }
+
+ AccountOpResult result = accmgr.ChangePassword(targetAccountId, szPassword1);
+
+ switch (result)
+ {
+ case AOR_OK:
+ SendSysMessage(LANG_COMMAND_PASSWORD);
+ break;
+ case AOR_NAME_NOT_EXIST:
+ PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
+ SetSentErrorMessage(true);
+ return false;
+ case AOR_PASS_TOO_LONG:
+ SendSysMessage(LANG_PASSWORD_TOO_LONG);
+ SetSentErrorMessage(true);
+ return false;
+ default:
+ SendSysMessage(LANG_COMMAND_NOTCHANGEPASSWORD);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ return true;
+}
+
+bool ChatHandler::HandleMaxSkillCommand(const char* /*args*/)
+{
+ Player* SelectedPlayer = getSelectedPlayer();
+ if (!SelectedPlayer)
+ {
+ SendSysMessage(LANG_NO_CHAR_SELECTED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // each skills that have max skill value dependent from level seted to current level max skill value
+ SelectedPlayer->UpdateSkillsToMaxSkillsForLevel();
+ return true;
+}
+
+bool ChatHandler::HandleSetSkillCommand(const char *args)
+{
+ // number or [name] Shift-click form |color|Hskill:skill_id|h[name]|h|r
+ char* skill_p = extractKeyFromLink((char*)args,"Hskill");
+ if (!skill_p)
+ return false;
+
+ char *level_p = strtok (NULL, " ");
+
+ if (!level_p)
+ return false;
+
+ char *max_p = strtok (NULL, " ");
+
+ int32 skill = atoi(skill_p);
+ if (skill <= 0)
+ {
+ PSendSysMessage(LANG_INVALID_SKILL_ID, skill);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ int32 level = atol (level_p);
+
+ Player * target = getSelectedPlayer();
+ if (!target)
+ {
+ SendSysMessage(LANG_NO_CHAR_SELECTED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ SkillLineEntry const* sl = sSkillLineStore.LookupEntry(skill);
+ if (!sl)
+ {
+ PSendSysMessage(LANG_INVALID_SKILL_ID, skill);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ std::string tNameLink = GetNameLink(target);
+
+ if (!target->GetSkillValue(skill))
+ {
+ PSendSysMessage(LANG_SET_SKILL_ERROR, tNameLink.c_str(), skill, sl->name[GetSessionDbcLocale()]);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ int32 max = max_p ? atol (max_p) : target->GetPureMaxSkillValue(skill);
+
+ if (level <= 0 || level > max || max <= 0)
+ return false;
+
+ target->SetSkill(skill, target->GetSkillStep(skill), level, max);
+ PSendSysMessage(LANG_SET_SKILL, skill, sl->name[GetSessionDbcLocale()], tNameLink.c_str(), level, max);
+
+ return true;
+}
+
+bool ChatHandler::HandleUnLearnCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
+ uint32 spell_id = extractSpellIdFromLink((char*)args);
+ if (!spell_id)
+ return false;
+
+ char const* allStr = strtok(NULL," ");
+ bool allRanks = allStr ? (strncmp(allStr, "all", strlen(allStr)) == 0) : false;
+
+ Player* target = getSelectedPlayer();
+ if (!target)
+ {
+ SendSysMessage(LANG_NO_CHAR_SELECTED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (allRanks)
+ spell_id = spellmgr.GetFirstSpellInChain (spell_id);
+
+ if (target->HasSpell(spell_id))
+ target->removeSpell(spell_id,false,!allRanks);
+ else
+ SendSysMessage(LANG_FORGET_SPELL);
+
+ if (GetTalentSpellCost(spell_id))
+ target->SendTalentsInfoData(false);
+
+ return true;
+}
+
+bool ChatHandler::HandleCooldownCommand(const char *args)
+{
+ Player* target = getSelectedPlayer();
+ if (!target)
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ std::string tNameLink = GetNameLink(target);
+
+ if (!*args)
+ {
+ target->RemoveAllSpellCooldown();
+ PSendSysMessage(LANG_REMOVEALL_COOLDOWN, tNameLink.c_str());
+ }
+ else
+ {
+ // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
+ uint32 spell_id = extractSpellIdFromLink((char*)args);
+ if (!spell_id)
+ return false;
+
+ if (!sSpellStore.LookupEntry(spell_id))
+ {
+ PSendSysMessage(LANG_UNKNOWN_SPELL, target == m_session->GetPlayer() ? GetTrinityString(LANG_YOU) : tNameLink.c_str());
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ target->RemoveSpellCooldown(spell_id,true);
+ PSendSysMessage(LANG_REMOVE_COOLDOWN, spell_id, target == m_session->GetPlayer() ? GetTrinityString(LANG_YOU) : tNameLink.c_str());
+ }
+ return true;
+}
+
+bool ChatHandler::HandleLearnAllCommand(const char* /*args*/)
+{
+ static const char *allSpellList[] =
+ {
+ "3365",
+ "6233",
+ "6247",
+ "6246",
+ "6477",
+ "6478",
+ "22810",
+ "8386",
+ "21651",
+ "21652",
+ "522",
+ "7266",
+ "8597",
+ "2479",
+ "22027",
+ "6603",
+ "5019",
+ "133",
+ "168",
+ "227",
+ "5009",
+ "9078",
+ "668",
+ "203",
+ "20599",
+ "20600",
+ "81",
+ "20597",
+ "20598",
+ "20864",
+ "1459",
+ "5504",
+ "587",
+ "5143",
+ "118",
+ "5505",
+ "597",
+ "604",
+ "1449",
+ "1460",
+ "2855",
+ "1008",
+ "475",
+ "5506",
+ "1463",
+ "12824",
+ "8437",
+ "990",
+ "5145",
+ "8450",
+ "1461",
+ "759",
+ "8494",
+ "8455",
+ "8438",
+ "6127",
+ "8416",
+ "6129",
+ "8451",
+ "8495",
+ "8439",
+ "3552",
+ "8417",
+ "10138",
+ "12825",
+ "10169",
+ "10156",
+ "10144",
+ "10191",
+ "10201",
+ "10211",
+ "10053",
+ "10173",
+ "10139",
+ "10145",
+ "10192",
+ "10170",
+ "10202",
+ "10054",
+ "10174",
+ "10193",
+ "12826",
+ "2136",
+ "143",
+ "145",
+ "2137",
+ "2120",
+ "3140",
+ "543",
+ "2138",
+ "2948",
+ "8400",
+ "2121",
+ "8444",
+ "8412",
+ "8457",
+ "8401",
+ "8422",
+ "8445",
+ "8402",
+ "8413",
+ "8458",
+ "8423",
+ "8446",
+ "10148",
+ "10197",
+ "10205",
+ "10149",
+ "10215",
+ "10223",
+ "10206",
+ "10199",
+ "10150",
+ "10216",
+ "10207",
+ "10225",
+ "10151",
+ "116",
+ "205",
+ "7300",
+ "122",
+ "837",
+ "10",
+ "7301",
+ "7322",
+ "6143",
+ "120",
+ "865",
+ "8406",
+ "6141",
+ "7302",
+ "8461",
+ "8407",
+ "8492",
+ "8427",
+ "8408",
+ "6131",
+ "7320",
+ "10159",
+ "8462",
+ "10185",
+ "10179",
+ "10160",
+ "10180",
+ "10219",
+ "10186",
+ "10177",
+ "10230",
+ "10181",
+ "10161",
+ "10187",
+ "10220",
+ "2018",
+ "2663",
+ "12260",
+ "2660",
+ "3115",
+ "3326",
+ "2665",
+ "3116",
+ "2738",
+ "3293",
+ "2661",
+ "3319",
+ "2662",
+ "9983",
+ "8880",
+ "2737",
+ "2739",
+ "7408",
+ "3320",
+ "2666",
+ "3323",
+ "3324",
+ "3294",
+ "22723",
+ "23219",
+ "23220",
+ "23221",
+ "23228",
+ "23338",
+ "10788",
+ "10790",
+ "5611",
+ "5016",
+ "5609",
+ "2060",
+ "10963",
+ "10964",
+ "10965",
+ "22593",
+ "22594",
+ "596",
+ "996",
+ "499",
+ "768",
+ "17002",
+ "1448",
+ "1082",
+ "16979",
+ "1079",
+ "5215",
+ "20484",
+ "5221",
+ "15590",
+ "17007",
+ "6795",
+ "6807",
+ "5487",
+ "1446",
+ "1066",
+ "5421",
+ "3139",
+ "779",
+ "6811",
+ "6808",
+ "1445",
+ "5216",
+ "1737",
+ "5222",
+ "5217",
+ "1432",
+ "6812",
+ "9492",
+ "5210",
+ "3030",
+ "1441",
+ "783",
+ "6801",
+ "20739",
+ "8944",
+ "9491",
+ "22569",
+ "5226",
+ "6786",
+ "1433",
+ "8973",
+ "1828",
+ "9495",
+ "9006",
+ "6794",
+ "8993",
+ "5203",
+ "16914",
+ "6784",
+ "9635",
+ "22830",
+ "20722",
+ "9748",
+ "6790",
+ "9753",
+ "9493",
+ "9752",
+ "9831",
+ "9825",
+ "9822",
+ "5204",
+ "5401",
+ "22831",
+ "6793",
+ "9845",
+ "17401",
+ "9882",
+ "9868",
+ "20749",
+ "9893",
+ "9899",
+ "9895",
+ "9832",
+ "9902",
+ "9909",
+ "22832",
+ "9828",
+ "9851",
+ "9883",
+ "9869",
+ "17406",
+ "17402",
+ "9914",
+ "20750",
+ "9897",
+ "9848",
+ "3127",
+ "107",
+ "204",
+ "9116",
+ "2457",
+ "78",
+ "18848",
+ "331",
+ "403",
+ "2098",
+ "1752",
+ "11278",
+ "11288",
+ "11284",
+ "6461",
+ "2344",
+ "2345",
+ "6463",
+ "2346",
+ "2352",
+ "775",
+ "1434",
+ "1612",
+ "71",
+ "2468",
+ "2458",
+ "2467",
+ "7164",
+ "7178",
+ "7367",
+ "7376",
+ "7381",
+ "21156",
+ "5209",
+ "3029",
+ "5201",
+ "9849",
+ "9850",
+ "20719",
+ "22568",
+ "22827",
+ "22828",
+ "22829",
+ "6809",
+ "8972",
+ "9005",
+ "9823",
+ "9827",
+ "6783",
+ "9913",
+ "6785",
+ "6787",
+ "9866",
+ "9867",
+ "9894",
+ "9896",
+ "6800",
+ "8992",
+ "9829",
+ "9830",
+ "780",
+ "769",
+ "6749",
+ "6750",
+ "9755",
+ "9754",
+ "9908",
+ "20745",
+ "20742",
+ "20747",
+ "20748",
+ "9746",
+ "9745",
+ "9880",
+ "9881",
+ "5391",
+ "842",
+ "3025",
+ "3031",
+ "3287",
+ "3329",
+ "1945",
+ "3559",
+ "4933",
+ "4934",
+ "4935",
+ "4936",
+ "5142",
+ "5390",
+ "5392",
+ "5404",
+ "5420",
+ "6405",
+ "7293",
+ "7965",
+ "8041",
+ "8153",
+ "9033",
+ "9034",
+ //"9036", problems with ghost state
+ "16421",
+ "21653",
+ "22660",
+ "5225",
+ "9846",
+ "2426",
+ "5916",
+ "6634",
+ //"6718", phasing stealth, annoying for learn all case.
+ "6719",
+ "8822",
+ "9591",
+ "9590",
+ "10032",
+ "17746",
+ "17747",
+ "8203",
+ "11392",
+ "12495",
+ "16380",
+ "23452",
+ "4079",
+ "4996",
+ "4997",
+ "4998",
+ "4999",
+ "5000",
+ "6348",
+ "6349",
+ "6481",
+ "6482",
+ "6483",
+ "6484",
+ "11362",
+ "11410",
+ "11409",
+ "12510",
+ "12509",
+ "12885",
+ "13142",
+ "21463",
+ "23460",
+ "11421",
+ "11416",
+ "11418",
+ "1851",
+ "10059",
+ "11423",
+ "11417",
+ "11422",
+ "11419",
+ "11424",
+ "11420",
+ "27",
+ "31",
+ "33",
+ "34",
+ "35",
+ "15125",
+ "21127",
+ "22950",
+ "1180",
+ "201",
+ "12593",
+ "16770",
+ "6057",
+ "12051",
+ "18468",
+ "12606",
+ "12605",
+ "18466",
+ "12502",
+ "12043",
+ "15060",
+ "12042",
+ "12341",
+ "12848",
+ "12344",
+ "12353",
+ "18460",
+ "11366",
+ "12350",
+ "12352",
+ "13043",
+ "11368",
+ "11113",
+ "12400",
+ "11129",
+ "16766",
+ "12573",
+ "12580",
+ "12472",
+ "12953",
+ "12488",
+ "11189",
+ "12985",
+ "12519",
+ "16758",
+ "11958",
+ "12490",
+ "11426",
+ "3565",
+ "3562",
+ "18960",
+ "3567",
+ "3561",
+ "3566",
+ "3563",
+ "1953",
+ "2139",
+ "12505",
+ "13018",
+ "12522",
+ "12523",
+ "5146",
+ "5144",
+ "5148",
+ "8419",
+ "8418",
+ "10213",
+ "10212",
+ "10157",
+ "12524",
+ "13019",
+ "12525",
+ "13020",
+ "12526",
+ "13021",
+ "18809",
+ "13031",
+ "13032",
+ "13033",
+ "4036",
+ "3920",
+ "3919",
+ "3918",
+ "7430",
+ "3922",
+ "3923",
+ "7411",
+ "7418",
+ "7421",
+ "13262",
+ "7412",
+ "7415",
+ "7413",
+ "7416",
+ "13920",
+ "13921",
+ "7745",
+ "7779",
+ "7428",
+ "7457",
+ "7857",
+ "7748",
+ "7426",
+ "13421",
+ "7454",
+ "13378",
+ "7788",
+ "14807",
+ "14293",
+ "7795",
+ "6296",
+ "20608",
+ "755",
+ "444",
+ "427",
+ "428",
+ "442",
+ "447",
+ "3578",
+ "3581",
+ "19027",
+ "3580",
+ "665",
+ "3579",
+ "3577",
+ "6755",
+ "3576",
+ "2575",
+ "2577",
+ "2578",
+ "2579",
+ "2580",
+ "2656",
+ "2657",
+ "2576",
+ "3564",
+ "10248",
+ "8388",
+ "2659",
+ "14891",
+ "3308",
+ "3307",
+ "10097",
+ "2658",
+ "3569",
+ "16153",
+ "3304",
+ "10098",
+ "4037",
+ "3929",
+ "3931",
+ "3926",
+ "3924",
+ "3930",
+ "3977",
+ "3925",
+ "136",
+ "228",
+ "5487",
+ "43",
+ "202",
+ "0"
+ };
+
+ int loop = 0;
+ while (strcmp(allSpellList[loop], "0"))
+ {
+ uint32 spell = atol((char*)allSpellList[loop++]);
+
+ if (m_session->GetPlayer()->HasSpell(spell))
+ continue;
+
+ SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
+ if (!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
+ {
+ PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
+ continue;
+ }
+
+ m_session->GetPlayer()->learnSpell(spell, false);
+ }
+
+ SendSysMessage(LANG_COMMAND_LEARN_MANY_SPELLS);
+
+ return true;
+}
+
+bool ChatHandler::HandleLearnAllGMCommand(const char* /*args*/)
+{
+ static const char *gmSpellList[] =
+ {
+ "24347", // Become A Fish, No Breath Bar
+ "35132", // Visual Boom
+ "38488", // Attack 4000-8000 AOE
+ "38795", // Attack 2000 AOE + Slow Down 90%
+ "15712", // Attack 200
+ "1852", // GM Spell Silence
+ "31899", // Kill
+ "31924", // Kill
+ "29878", // Kill My Self
+ "26644", // More Kill
+
+ "28550", //Invisible 24
+ "23452", //Invisible + Target
+ "0"
+ };
+
+ uint16 gmSpellIter = 0;
+ while (strcmp(gmSpellList[gmSpellIter], "0"))
+ {
+ uint32 spell = atol((char*)gmSpellList[gmSpellIter++]);
+
+ SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
+ if (!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
+ {
+ PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
+ continue;
+ }
+
+ m_session->GetPlayer()->learnSpell(spell, false);
+ }
+
+ SendSysMessage(LANG_LEARNING_GM_SKILLS);
+ return true;
+}
+
+bool ChatHandler::HandleLearnAllMyClassCommand(const char* /*args*/)
+{
+ HandleLearnAllMySpellsCommand("");
+ HandleLearnAllMyTalentsCommand("");
+ return true;
+}
+
+bool ChatHandler::HandleLearnAllMySpellsCommand(const char* /*args*/)
+{
+ ChrClassesEntry const* clsEntry = sChrClassesStore.LookupEntry(m_session->GetPlayer()->getClass());
+ if (!clsEntry)
+ return true;
+ uint32 family = clsEntry->spellfamily;
+
+ for (uint32 i = 0; i < sSpellStore.GetNumRows(); ++i)
+ {
+ SpellEntry const *spellInfo = sSpellStore.LookupEntry(i);
+ if (!spellInfo)
+ continue;
+
+ // skip server-side/triggered spells
+ if (spellInfo->spellLevel == 0)
+ continue;
+
+ // skip wrong class/race skills
+ if (!m_session->GetPlayer()->IsSpellFitByClassAndRace(spellInfo->Id))
+ continue;
+
+ // skip other spell families
+ if (spellInfo->SpellFamilyName != family)
+ continue;
+
+ // skip spells with first rank learned as talent (and all talents then also)
+ uint32 first_rank = spellmgr.GetFirstSpellInChain(spellInfo->Id);
+ if (GetTalentSpellCost(first_rank) > 0)
+ continue;
+
+ // skip broken spells
+ if (!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
+ continue;
+
+ m_session->GetPlayer()->learnSpell(i, false);
+ }
+
+ SendSysMessage(LANG_COMMAND_LEARN_CLASS_SPELLS);
+ return true;
+}
+
+bool ChatHandler::HandleLearnAllMyTalentsCommand(const char* /*args*/)
+{
+ Player* player = m_session->GetPlayer();
+ uint32 classMask = player->getClassMask();
+
+ for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
+ {
+ TalentEntry const *talentInfo = sTalentStore.LookupEntry(i);
+ if (!talentInfo)
+ continue;
+
+ TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry(talentInfo->TalentTab);
+ if (!talentTabInfo)
+ continue;
+
+ if ((classMask & talentTabInfo->ClassMask) == 0)
+ continue;
+
+ // search highest talent rank
+ uint32 spellId = 0;
+ for (int8 rank = MAX_TALENT_RANK-1; rank >= 0; --rank)
+ {
+ if (talentInfo->RankID[rank] != 0)
+ {
+ spellId = talentInfo->RankID[rank];
+ break;
+ }
+ }
+
+ if (!spellId) // ??? none spells in talent
+ continue;
+
+ SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellId);
+ if (!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
+ continue;
+
+ // learn highest rank of talent and learn all non-talent spell ranks (recursive by tree)
+ player->learnSpellHighRank(spellId);
+ player->AddTalent(spellId, player->GetActiveSpec(), true);
+ }
+
+ player->SetFreeTalentPoints(0);
+
+ SendSysMessage(LANG_COMMAND_LEARN_CLASS_TALENTS);
+ return true;
+}
+
+bool ChatHandler::HandleLearnAllMyPetTalentsCommand(const char* /*args*/)
+{
+ Player* player = m_session->GetPlayer();
+
+ Pet* pet = player->GetPet();
+ if (!pet)
+ {
+ SendSysMessage(LANG_NO_PET_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ CreatureInfo const *ci = pet->GetCreatureInfo();
+ if (!ci)
+ {
+ SendSysMessage(LANG_WRONG_PET_TYPE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ CreatureFamilyEntry const *pet_family = sCreatureFamilyStore.LookupEntry(ci->family);
+ if (!pet_family)
+ {
+ SendSysMessage(LANG_WRONG_PET_TYPE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (pet_family->petTalentType < 0) // not hunter pet
+ {
+ SendSysMessage(LANG_WRONG_PET_TYPE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
+ {
+ TalentEntry const *talentInfo = sTalentStore.LookupEntry(i);
+ if (!talentInfo)
+ continue;
+
+ TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry(talentInfo->TalentTab);
+ if (!talentTabInfo)
+ continue;
+
+ // prevent learn talent for different family (cheating)
+ if (((1 << pet_family->petTalentType) & talentTabInfo->petTalentMask) == 0)
+ continue;
+
+ // search highest talent rank
+ uint32 spellid = 0;
+
+ for (int8 rank = MAX_TALENT_RANK-1; rank >= 0; --rank)
+ {
+ if (talentInfo->RankID[rank] != 0)
+ {
+ spellid = talentInfo->RankID[rank];
+ break;
+ }
+ }
+
+ if (!spellid) // ??? none spells in talent
+ continue;
+
+ SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid);
+ if (!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
+ continue;
+
+ // learn highest rank of talent and learn all non-talent spell ranks (recursive by tree)
+ pet->learnSpellHighRank(spellid);
+ }
+
+ pet->SetFreeTalentPoints(0);
+
+ SendSysMessage(LANG_COMMAND_LEARN_PET_TALENTS);
+ return true;
+}
+
+bool ChatHandler::HandleLearnAllLangCommand(const char* /*args*/)
+{
+ // skipping UNIVERSAL language (0)
+ for (uint8 i = 1; i < LANGUAGES_COUNT; ++i)
+ m_session->GetPlayer()->learnSpell(lang_description[i].spell_id, false);
+
+ SendSysMessage(LANG_COMMAND_LEARN_ALL_LANG);
+ return true;
+}
+
+bool ChatHandler::HandleLearnAllDefaultCommand(const char *args)
+{
+ Player* target;
+ if (!extractPlayerTarget((char*)args,&target))
+ return false;
+
+ target->learnDefaultSpells();
+ target->learnQuestRewardedSpells();
+
+ PSendSysMessage(LANG_COMMAND_LEARN_ALL_DEFAULT_AND_QUEST,GetNameLink(target).c_str());
+ return true;
+}
+
+bool ChatHandler::HandleLearnCommand(const char *args)
+{
+ Player* targetPlayer = getSelectedPlayer();
+
+ if (!targetPlayer)
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
+ uint32 spell = extractSpellIdFromLink((char*)args);
+ if (!spell || !sSpellStore.LookupEntry(spell))
+ return false;
+
+ char const* allStr = strtok(NULL," ");
+ bool allRanks = allStr ? (strncmp(allStr, "all", strlen(allStr)) == 0) : false;
+
+ SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
+ if (!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
+ {
+ PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (!allRanks && targetPlayer->HasSpell(spell))
+ {
+ if (targetPlayer == m_session->GetPlayer())
+ SendSysMessage(LANG_YOU_KNOWN_SPELL);
+ else
+ PSendSysMessage(LANG_TARGET_KNOWN_SPELL,GetNameLink(targetPlayer).c_str());
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (allRanks)
+ targetPlayer->learnSpellHighRank(spell);
+ else
+ targetPlayer->learnSpell(spell, false);
+
+ uint32 first_spell = spellmgr.GetFirstSpellInChain(spell);
+ if (GetTalentSpellCost(first_spell))
+ targetPlayer->SendTalentsInfoData(false);
+
+ return true;
+}
+
+bool ChatHandler::HandleAddItemCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ uint32 itemId = 0;
+
+ if (args[0] == '[') // [name] manual form
+ {
+ char* citemName = strtok((char*)args, "]");
+
+ if (citemName && citemName[0])
+ {
+ std::string itemName = citemName+1;
+ WorldDatabase.escape_string(itemName);
+ QueryResult_AutoPtr result = WorldDatabase.PQuery("SELECT entry FROM item_template WHERE name = '%s'", itemName.c_str());
+ if (!result)
+ {
+ PSendSysMessage(LANG_COMMAND_COULDNOTFIND, citemName+1);
+ SetSentErrorMessage(true);
+ return false;
+ }
+ itemId = result->Fetch()->GetUInt16();
+ }
+ else
+ return false;
+ }
+ else // item_id or [name] Shift-click form |color|Hitem:item_id:0:0:0|h[name]|h|r
+ {
+ char* cId = extractKeyFromLink((char*)args,"Hitem");
+ if (!cId)
+ return false;
+ itemId = atol(cId);
+ }
+
+ char* ccount = strtok(NULL, " ");
+
+ int32 count = 1;
+
+ if (ccount)
+ count = strtol(ccount, NULL, 10);
+
+ if (count == 0)
+ count = 1;
+
+ Player* pl = m_session->GetPlayer();
+ Player* plTarget = getSelectedPlayer();
+ if (!plTarget)
+ plTarget = pl;
+
+ sLog.outDetail(GetTrinityString(LANG_ADDITEM), itemId, count);
+
+ ItemPrototype const *pProto = objmgr.GetItemPrototype(itemId);
+ if (!pProto)
+ {
+ PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ //Subtract
+ if (count < 0)
+ {
+ plTarget->DestroyItemCount(itemId, -count, true, false);
+ PSendSysMessage(LANG_REMOVEITEM, itemId, -count, GetNameLink(plTarget).c_str());
+ return true;
+ }
+
+ //Adding items
+ uint32 noSpaceForCount = 0;
+
+ // check space and find places
+ ItemPosCountVec dest;
+ uint8 msg = plTarget->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemId, count, &noSpaceForCount);
+ if (msg != EQUIP_ERR_OK) // convert to possible store amount
+ count -= noSpaceForCount;
+
+ if (count == 0 || dest.empty()) // can't add any
+ {
+ PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Item* item = plTarget->StoreNewItem(dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId));
+
+ // remove binding (let GM give it to another player later)
+ if (pl == plTarget)
+ for (ItemPosCountVec::const_iterator itr = dest.begin(); itr != dest.end(); ++itr)
+ if (Item* item1 = pl->GetItemByPos(itr->pos))
+ item1->SetBinding(false);
+
+ if (count > 0 && item)
+ {
+ pl->SendNewItem(item,count,false,true);
+ if (pl != plTarget)
+ plTarget->SendNewItem(item,count,true,false);
+ }
+
+ if (noSpaceForCount > 0)
+ PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount);
+
+ return true;
+}
+
+bool ChatHandler::HandleAddItemSetCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ char* cId = extractKeyFromLink((char*)args,"Hitemset"); // number or [name] Shift-click form |color|Hitemset:itemset_id|h[name]|h|r
+ if (!cId)
+ return false;
+
+ uint32 itemsetId = atol(cId);
+
+ // prevent generation all items with itemset field value '0'
+ if (itemsetId == 0)
+ {
+ PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND,itemsetId);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Player* pl = m_session->GetPlayer();
+ Player* plTarget = getSelectedPlayer();
+ if (!plTarget)
+ plTarget = pl;
+
+ sLog.outDetail(GetTrinityString(LANG_ADDITEMSET), itemsetId);
+
+ bool found = false;
+ for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
+ {
+ ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype>(id);
+ if (!pProto)
+ continue;
+
+ if (pProto->ItemSet == itemsetId)
+ {
+ found = true;
+ ItemPosCountVec dest;
+ uint8 msg = plTarget->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, pProto->ItemId, 1);
+ if (msg == EQUIP_ERR_OK)
+ {
+ Item* item = plTarget->StoreNewItem(dest, pProto->ItemId, true);
+
+ // remove binding (let GM give it to another player later)
+ if (pl == plTarget)
+ item->SetBinding(false);
+
+ pl->SendNewItem(item,1,false,true);
+ if (pl != plTarget)
+ plTarget->SendNewItem(item,1,true,false);
+ }
+ else
+ {
+ pl->SendEquipError(msg, NULL, NULL);
+ PSendSysMessage(LANG_ITEM_CANNOT_CREATE, pProto->ItemId, 1);
+ }
+ }
+ }
+
+ if (!found)
+ {
+ PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND,itemsetId);
+
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ return true;
+}
+
+bool ChatHandler::HandleListItemCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ char* cId = extractKeyFromLink((char*)args,"Hitem");
+ if (!cId)
+ return false;
+
+ uint32 item_id = atol(cId);
+ if (!item_id)
+ {
+ PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ ItemPrototype const* itemProto = objmgr.GetItemPrototype(item_id);
+ if (!itemProto)
+ {
+ PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ char* c_count = strtok(NULL, " ");
+ int count = c_count ? atol(c_count) : 10;
+
+ if (count < 0)
+ return false;
+
+ QueryResult_AutoPtr result;
+
+ // inventory case
+ uint32 inv_count = 0;
+ result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM character_inventory WHERE item_template='%u'",item_id);
+ if (result)
+ inv_count = (*result)[0].GetUInt32();
+
+ result=CharacterDatabase.PQuery(
+ // 0 1 2 3 4 5
+ "SELECT ci.item, cibag.slot AS bag, ci.slot, ci.guid, characters.account,characters.name "
+ "FROM character_inventory AS ci LEFT JOIN character_inventory AS cibag ON (cibag.item=ci.bag),characters "
+ "WHERE ci.item_template='%u' AND ci.guid = characters.guid LIMIT %u ",
+ item_id,uint32(count));
+
+ if (result)
+ {
+ do
+ {
+ Field *fields = result->Fetch();
+ uint32 item_guid = fields[0].GetUInt32();
+ uint32 item_bag = fields[1].GetUInt32();
+ uint32 item_slot = fields[2].GetUInt32();
+ uint32 owner_guid = fields[3].GetUInt32();
+ uint32 owner_acc = fields[4].GetUInt32();
+ std::string owner_name = fields[5].GetCppString();
+
+ char const* item_pos = 0;
+ if (Player::IsEquipmentPos(item_bag,item_slot))
+ item_pos = "[equipped]";
+ else if (Player::IsInventoryPos(item_bag,item_slot))
+ item_pos = "[in inventory]";
+ else if (Player::IsBankPos(item_bag,item_slot))
+ item_pos = "[in bank]";
+ else
+ item_pos = "";
+
+ PSendSysMessage(LANG_ITEMLIST_SLOT,
+ item_guid,owner_name.c_str(),owner_guid,owner_acc,item_pos);
+ } while (result->NextRow());
+
+ int64 res_count = result->GetRowCount();
+
+ if (count > res_count)
+ count-=res_count;
+ else if (count)
+ count = 0;
+ }
+
+ // mail case
+ uint32 mail_count = 0;
+ result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM mail_items WHERE item_template='%u'", item_id);
+ if (result)
+ mail_count = (*result)[0].GetUInt32();
+
+ if (count > 0)
+ {
+ result=CharacterDatabase.PQuery(
+ // 0 1 2 3 4 5 6
+ "SELECT mail_items.item_guid, mail.sender, mail.receiver, char_s.account, char_s.name, char_r.account, char_r.name "
+ "FROM mail,mail_items,characters as char_s,characters as char_r "
+ "WHERE mail_items.item_template='%u' AND char_s.guid = mail.sender AND char_r.guid = mail.receiver AND mail.id=mail_items.mail_id LIMIT %u",
+ item_id,uint32(count));
+ }
+ else
+ result = QueryResult_AutoPtr(NULL);
+
+ if (result)
+ {
+ do
+ {
+ Field *fields = result->Fetch();
+ uint32 item_guid = fields[0].GetUInt32();
+ uint32 item_s = fields[1].GetUInt32();
+ uint32 item_r = fields[2].GetUInt32();
+ uint32 item_s_acc = fields[3].GetUInt32();
+ std::string item_s_name = fields[4].GetCppString();
+ uint32 item_r_acc = fields[5].GetUInt32();
+ std::string item_r_name = fields[6].GetCppString();
+
+ char const* item_pos = "[in mail]";
+
+ PSendSysMessage(LANG_ITEMLIST_MAIL,
+ item_guid,item_s_name.c_str(),item_s,item_s_acc,item_r_name.c_str(),item_r,item_r_acc,item_pos);
+ } while (result->NextRow());
+
+ int64 res_count = result->GetRowCount();
+
+ if (count > res_count)
+ count-=res_count;
+ else if (count)
+ count = 0;
+ }
+
+ // auction case
+ uint32 auc_count = 0;
+ result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM auctionhouse WHERE item_template='%u'",item_id);
+ if (result)
+ auc_count = (*result)[0].GetUInt32();
+
+ if (count > 0)
+ {
+ result=CharacterDatabase.PQuery(
+ // 0 1 2 3
+ "SELECT auctionhouse.itemguid, auctionhouse.itemowner, characters.account, characters.name "
+ "FROM auctionhouse,characters WHERE auctionhouse.item_template='%u' AND characters.guid = auctionhouse.itemowner LIMIT %u",
+ item_id,uint32(count));
+ }
+ else
+ result = QueryResult_AutoPtr(NULL);
+
+ if (result)
+ {
+ do
+ {
+ Field *fields = result->Fetch();
+ uint32 item_guid = fields[0].GetUInt32();
+ uint32 owner = fields[1].GetUInt32();
+ uint32 owner_acc = fields[2].GetUInt32();
+ std::string owner_name = fields[3].GetCppString();
+
+ char const* item_pos = "[in auction]";
+
+ PSendSysMessage(LANG_ITEMLIST_AUCTION, item_guid, owner_name.c_str(), owner, owner_acc,item_pos);
+ } while (result->NextRow());
+ }
+
+ // guild bank case
+ uint32 guild_count = 0;
+ result=CharacterDatabase.PQuery("SELECT COUNT(item_entry) FROM guild_bank_item WHERE item_entry='%u'",item_id);
+ if (result)
+ guild_count = (*result)[0].GetUInt32();
+
+ result=CharacterDatabase.PQuery(
+ // 0 1 2
+ "SELECT gi.item_guid, gi.guildid, guild.name "
+ "FROM guild_bank_item AS gi, guild WHERE gi.item_entry='%u' AND gi.guildid = guild.guildid LIMIT %u ",
+ item_id,uint32(count));
+
+ if (result)
+ {
+ do
+ {
+ Field *fields = result->Fetch();
+ uint32 item_guid = fields[0].GetUInt32();
+ uint32 guild_guid = fields[1].GetUInt32();
+ std::string guild_name = fields[2].GetCppString();
+
+ char const* item_pos = "[in guild bank]";
+
+ PSendSysMessage(LANG_ITEMLIST_GUILD,item_guid,guild_name.c_str(),guild_guid,item_pos);
+ } while (result->NextRow());
+
+ int64 res_count = result->GetRowCount();
+
+ if (count > res_count)
+ count-=res_count;
+ else if (count)
+ count = 0;
+ }
+
+ if (inv_count+mail_count+auc_count+guild_count == 0)
+ {
+ SendSysMessage(LANG_COMMAND_NOITEMFOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ PSendSysMessage(LANG_COMMAND_LISTITEMMESSAGE,item_id,inv_count+mail_count+auc_count+guild_count,inv_count,mail_count,auc_count,guild_count);
+
+ return true;
+}
+
+bool ChatHandler::HandleListObjectCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r
+ char* cId = extractKeyFromLink((char*)args,"Hgameobject_entry");
+ if (!cId)
+ return false;
+
+ uint32 go_id = atol(cId);
+ if (!go_id)
+ {
+ PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ GameObjectInfo const * gInfo = objmgr.GetGameObjectInfo(go_id);
+ if (!gInfo)
+ {
+ PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ char* c_count = strtok(NULL, " ");
+ int count = c_count ? atol(c_count) : 10;
+
+ if (count < 0)
+ return false;
+
+ QueryResult_AutoPtr result;
+
+ uint32 obj_count = 0;
+ result=WorldDatabase.PQuery("SELECT COUNT(guid) FROM gameobject WHERE id='%u'",go_id);
+ if (result)
+ obj_count = (*result)[0].GetUInt32();
+
+ if (m_session)
+ {
+ Player* pl = m_session->GetPlayer();
+ result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map, (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ FROM gameobject WHERE id = '%u' ORDER BY order_ ASC LIMIT %u",
+ pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),go_id,uint32(count));
+ }
+ else
+ result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map FROM gameobject WHERE id = '%u' LIMIT %u",
+ go_id,uint32(count));
+
+ if (result)
+ {
+ do
+ {
+ Field *fields = result->Fetch();
+ uint32 guid = fields[0].GetUInt32();
+ float x = fields[1].GetFloat();
+ float y = fields[2].GetFloat();
+ float z = fields[3].GetFloat();
+ int mapid = fields[4].GetUInt16();
+
+ if (m_session)
+ PSendSysMessage(LANG_GO_LIST_CHAT, guid, guid, gInfo->name, x, y, z, mapid);
+ else
+ PSendSysMessage(LANG_GO_LIST_CONSOLE, guid, gInfo->name, x, y, z, mapid);
+ } while (result->NextRow());
+ }
+
+ PSendSysMessage(LANG_COMMAND_LISTOBJMESSAGE,go_id,obj_count);
+ return true;
+}
+
+bool ChatHandler::HandleGameObjectStateCommand(const char *args)
+{
+ // number or [name] Shift-click form |color|Hgameobject:go_id|h[name]|h|r
+ char* cId = extractKeyFromLink((char*)args, "Hgameobject");
+ if (!cId)
+ return false;
+
+ uint32 lowguid = atoi(cId);
+ if (!lowguid)
+ return false;
+
+ GameObject* gobj = NULL;
+
+ if (GameObjectData const* goData = objmgr.GetGOData(lowguid))
+ gobj = GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid, goData->id);
+
+ if (!gobj)
+ {
+ PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ char* ctype = strtok(NULL, " ");
+ if (!ctype)
+ return false;
+
+ int32 type = atoi(ctype);
+ if (type < 0)
+ {
+ if (type == -1)
+ gobj->SendObjectDeSpawnAnim(gobj->GetGUID());
+ else if (type == -2)
+ {
+ return false;
+ }
+ return true;
+ }
+
+ char* cstate = strtok(NULL, " ");
+ if (!cstate)
+ return false;
+
+ int32 state = atoi(cstate);
+
+ if (type < 4)
+ gobj->SetByteValue(GAMEOBJECT_BYTES_1, type, state);
+ else if (type == 4)
+ {
+ WorldPacket data(SMSG_GAMEOBJECT_CUSTOM_ANIM,8+4);
+ data << gobj->GetGUID();
+ data << (uint32)(state);
+ gobj->SendMessageToSet(&data, true);
+ }
+ PSendSysMessage("Set gobject type %d state %d", type, state);
+
+ return true;
+}
+
+bool ChatHandler::HandleListCreatureCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
+ char* cId = extractKeyFromLink((char*)args,"Hcreature_entry");
+ if (!cId)
+ return false;
+
+ uint32 cr_id = atol(cId);
+ if (!cr_id)
+ {
+ PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ CreatureInfo const* cInfo = objmgr.GetCreatureTemplate(cr_id);
+ if (!cInfo)
+ {
+ PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ char* c_count = strtok(NULL, " ");
+ int count = c_count ? atol(c_count) : 10;
+
+ if (count < 0)
+ return false;
+
+ QueryResult_AutoPtr result;
+
+ uint32 cr_count = 0;
+ result=WorldDatabase.PQuery("SELECT COUNT(guid) FROM creature WHERE id='%u'",cr_id);
+ if (result)
+ cr_count = (*result)[0].GetUInt32();
+
+ if (m_session)
+ {
+ Player* pl = m_session->GetPlayer();
+ result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map, (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ FROM creature WHERE id = '%u' ORDER BY order_ ASC LIMIT %u",
+ pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), cr_id,uint32(count));
+ }
+ else
+ result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map FROM creature WHERE id = '%u' LIMIT %u",
+ cr_id,uint32(count));
+
+ if (result)
+ {
+ do
+ {
+ Field *fields = result->Fetch();
+ uint32 guid = fields[0].GetUInt32();
+ float x = fields[1].GetFloat();
+ float y = fields[2].GetFloat();
+ float z = fields[3].GetFloat();
+ int mapid = fields[4].GetUInt16();
+
+ if (m_session)
+ PSendSysMessage(LANG_CREATURE_LIST_CHAT, guid, guid, cInfo->Name, x, y, z, mapid);
+ else
+ PSendSysMessage(LANG_CREATURE_LIST_CONSOLE, guid, cInfo->Name, x, y, z, mapid);
+ } while (result->NextRow());
+ }
+
+ PSendSysMessage(LANG_COMMAND_LISTCREATUREMESSAGE,cr_id,cr_count);
+ return true;
+}
+
+bool ChatHandler::HandleLookupItemCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ std::string namepart = args;
+ std::wstring wnamepart;
+
+ // converting string that we try to find to lower case
+ if (!Utf8toWStr(namepart,wnamepart))
+ return false;
+
+ wstrToLower(wnamepart);
+
+ bool found = false;
+
+ // Search in `item_template`
+ for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
+ {
+ ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype >(id);
+ if (!pProto)
+ continue;
+
+ int loc_idx = GetSessionDbLocaleIndex();
+ if (loc_idx >= 0)
+ {
+ ItemLocale const *il = objmgr.GetItemLocale(pProto->ItemId);
+ if (il)
+ {
+ if (il->Name.size() > loc_idx && !il->Name[loc_idx].empty())
+ {
+ std::string name = il->Name[loc_idx];
+
+ if (Utf8FitTo(name, wnamepart))
+ {
+ if (m_session)
+ PSendSysMessage(LANG_ITEM_LIST_CHAT, id, id, name.c_str());
+ else
+ PSendSysMessage(LANG_ITEM_LIST_CONSOLE, id, name.c_str());
+
+ if (!found)
+ found = true;
+
+ continue;
+ }
+ }
+ }
+ }
+
+ std::string name = pProto->Name1;
+ if (name.empty())
+ continue;
+
+ if (Utf8FitTo(name, wnamepart))
+ {
+ if (m_session)
+ PSendSysMessage(LANG_ITEM_LIST_CHAT, id, id, name.c_str());
+ else
+ PSendSysMessage(LANG_ITEM_LIST_CONSOLE, id, name.c_str());
+
+ if (!found)
+ found = true;
+ }
+ }
+
+ if (!found)
+ SendSysMessage(LANG_COMMAND_NOITEMFOUND);
+
+ return true;
+}
+
+bool ChatHandler::HandleLookupItemSetCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ std::string namepart = args;
+ std::wstring wnamepart;
+
+ if (!Utf8toWStr(namepart,wnamepart))
+ return false;
+
+ // converting string that we try to find to lower case
+ wstrToLower(wnamepart);
+
+ bool found = false;
+
+ // Search in ItemSet.dbc
+ for (uint32 id = 0; id < sItemSetStore.GetNumRows(); id++)
+ {
+ ItemSetEntry const *set = sItemSetStore.LookupEntry(id);
+ if (set)
+ {
+ int loc = GetSessionDbcLocale();
+ std::string name = set->name[loc];
+ if (name.empty())
+ continue;
+
+ if (!Utf8FitTo(name, wnamepart))
+ {
+ loc = 0;
+ for (; loc < MAX_LOCALE; ++loc)
+ {
+ if (loc == GetSessionDbcLocale())
+ continue;
+
+ name = set->name[loc];
+ if (name.empty())
+ continue;
+
+ if (Utf8FitTo(name, wnamepart))
+ break;
+ }
+ }
+
+ if (loc < MAX_LOCALE)
+ {
+ // send item set in "id - [namedlink locale]" format
+ if (m_session)
+ PSendSysMessage(LANG_ITEMSET_LIST_CHAT,id,id,name.c_str(),localeNames[loc]);
+ else
+ PSendSysMessage(LANG_ITEMSET_LIST_CONSOLE,id,name.c_str(),localeNames[loc]);
+
+ if (!found)
+ found = true;
+ }
+ }
+ }
+ if (!found)
+ SendSysMessage(LANG_COMMAND_NOITEMSETFOUND);
+ return true;
+}
+
+bool ChatHandler::HandleLookupSkillCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ // can be NULL in console call
+ Player* target = getSelectedPlayer();
+
+ std::string namepart = args;
+ std::wstring wnamepart;
+
+ if (!Utf8toWStr(namepart,wnamepart))
+ return false;
+
+ // converting string that we try to find to lower case
+ wstrToLower(wnamepart);
+
+ bool found = false;
+
+ // Search in SkillLine.dbc
+ for (uint32 id = 0; id < sSkillLineStore.GetNumRows(); id++)
+ {
+ SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(id);
+ if (skillInfo)
+ {
+ int loc = GetSessionDbcLocale();
+ std::string name = skillInfo->name[loc];
+ if (name.empty())
+ continue;
+
+ if (!Utf8FitTo(name, wnamepart))
+ {
+ loc = 0;
+ for (; loc < MAX_LOCALE; ++loc)
+ {
+ if (loc == GetSessionDbcLocale())
+ continue;
+
+ name = skillInfo->name[loc];
+ if (name.empty())
+ continue;
+
+ if (Utf8FitTo(name, wnamepart))
+ break;
+ }
+ }
+
+ if (loc < MAX_LOCALE)
+ {
+ char valStr[50] = "";
+ char const* knownStr = "";
+ if (target && target->HasSkill(id))
+ {
+ knownStr = GetTrinityString(LANG_KNOWN);
+ uint32 curValue = target->GetPureSkillValue(id);
+ uint32 maxValue = target->GetPureMaxSkillValue(id);
+ uint32 permValue = target->GetSkillPermBonusValue(id);
+ uint32 tempValue = target->GetSkillTempBonusValue(id);
+
+ char const* valFormat = GetTrinityString(LANG_SKILL_VALUES);
+ snprintf(valStr,50,valFormat,curValue,maxValue,permValue,tempValue);
+ }
+
+ // send skill in "id - [namedlink locale]" format
+ if (m_session)
+ PSendSysMessage(LANG_SKILL_LIST_CHAT,id,id,name.c_str(),localeNames[loc],knownStr,valStr);
+ else
+ PSendSysMessage(LANG_SKILL_LIST_CONSOLE,id,name.c_str(),localeNames[loc],knownStr,valStr);
+
+ if (!found)
+ found = true;
+ }
+ }
+ }
+ if (!found)
+ SendSysMessage(LANG_COMMAND_NOSKILLFOUND);
+ return true;
+}
+
+bool ChatHandler::HandleLookupSpellCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ // can be NULL at console call
+ Player* target = getSelectedPlayer();
+
+ std::string namepart = args;
+ std::wstring wnamepart;
+
+ if (!Utf8toWStr(namepart,wnamepart))
+ return false;
+
+ // converting string that we try to find to lower case
+ wstrToLower(wnamepart);
+
+ bool found = false;
+
+ // Search in Spell.dbc
+ for (uint32 id = 0; id < sSpellStore.GetNumRows(); id++)
+ {
+ SpellEntry const *spellInfo = sSpellStore.LookupEntry(id);
+ if (spellInfo)
+ {
+ int loc = GetSessionDbcLocale();
+ std::string name = spellInfo->SpellName[loc];
+ if (name.empty())
+ continue;
+
+ if (!Utf8FitTo(name, wnamepart))
+ {
+ loc = 0;
+ for (; loc < MAX_LOCALE; ++loc)
+ {
+ if (loc == GetSessionDbcLocale())
+ continue;
+
+ name = spellInfo->SpellName[loc];
+ if (name.empty())
+ continue;
+
+ if (Utf8FitTo(name, wnamepart))
+ break;
+ }
+ }
+
+ if (loc < MAX_LOCALE)
+ {
+ bool known = target && target->HasSpell(id);
+ bool learn = (spellInfo->Effect[0] == SPELL_EFFECT_LEARN_SPELL);
+
+ uint32 talentCost = GetTalentSpellCost(id);
+
+ bool talent = (talentCost > 0);
+ bool passive = IsPassiveSpell(id);
+ bool active = target && target->HasAura(id);
+
+ // unit32 used to prevent interpreting uint8 as char at output
+ // find rank of learned spell for learning spell, or talent rank
+ uint32 rank = talentCost ? talentCost : spellmgr.GetSpellRank(learn ? spellInfo->EffectTriggerSpell[0] : id);
+
+ // send spell in "id - [name, rank N] [talent] [passive] [learn] [known]" format
+ std::ostringstream ss;
+ if (m_session)
+ ss << id << " - |cffffffff|Hspell:" << id << "|h[" << name;
+ else
+ ss << id << " - " << name;
+
+ // include rank in link name
+ if (rank)
+ ss << GetTrinityString(LANG_SPELL_RANK) << rank;
+
+ if (m_session)
+ ss << " " << localeNames[loc] << "]|h|r";
+ else
+ ss << " " << localeNames[loc];
+
+ if (talent)
+ ss << GetTrinityString(LANG_TALENT);
+ if (passive)
+ ss << GetTrinityString(LANG_PASSIVE);
+ if (learn)
+ ss << GetTrinityString(LANG_LEARN);
+ if (known)
+ ss << GetTrinityString(LANG_KNOWN);
+ if (active)
+ ss << GetTrinityString(LANG_ACTIVE);
+
+ SendSysMessage(ss.str().c_str());
+
+ if (!found)
+ found = true;
+ }
+ }
+ }
+ if (!found)
+ SendSysMessage(LANG_COMMAND_NOSPELLFOUND);
+ return true;
+}
+
+bool ChatHandler::HandleLookupQuestCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ // can be NULL at console call
+ Player* target = getSelectedPlayer();
+
+ std::string namepart = args;
+ std::wstring wnamepart;
+
+ // converting string that we try to find to lower case
+ if (!Utf8toWStr(namepart,wnamepart))
+ return false;
+
+ wstrToLower(wnamepart);
+
+ bool found = false;
+
+ ObjectMgr::QuestMap const& qTemplates = objmgr.GetQuestTemplates();
+ for (ObjectMgr::QuestMap::const_iterator iter = qTemplates.begin(); iter != qTemplates.end(); ++iter)
+ {
+ Quest * qinfo = iter->second;
+
+ int loc_idx = GetSessionDbLocaleIndex();
+ if (loc_idx >= 0)
+ {
+ QuestLocale const *il = objmgr.GetQuestLocale(qinfo->GetQuestId());
+ if (il)
+ {
+ if (il->Title.size() > loc_idx && !il->Title[loc_idx].empty())
+ {
+ std::string title = il->Title[loc_idx];
+
+ if (Utf8FitTo(title, wnamepart))
+ {
+ char const* statusStr = "";
+
+ if (target)
+ {
+ QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId());
+
+ if (status == QUEST_STATUS_COMPLETE)
+ {
+ if (target->GetQuestRewardStatus(qinfo->GetQuestId()))
+ statusStr = GetTrinityString(LANG_COMMAND_QUEST_REWARDED);
+ else
+ statusStr = GetTrinityString(LANG_COMMAND_QUEST_COMPLETE);
+ }
+ else if (status == QUEST_STATUS_INCOMPLETE)
+ statusStr = GetTrinityString(LANG_COMMAND_QUEST_ACTIVE);
+ }
+
+ if (m_session)
+ PSendSysMessage(LANG_QUEST_LIST_CHAT,qinfo->GetQuestId(),qinfo->GetQuestId(),qinfo->GetQuestLevel(),title.c_str(),statusStr);
+ else
+ PSendSysMessage(LANG_QUEST_LIST_CONSOLE,qinfo->GetQuestId(),title.c_str(),statusStr);
+
+ if (!found)
+ found = true;
+
+ continue;
+ }
+ }
+ }
+ }
+
+ std::string title = qinfo->GetTitle();
+ if (title.empty())
+ continue;
+
+ if (Utf8FitTo(title, wnamepart))
+ {
+ char const* statusStr = "";
+
+ if (target)
+ {
+ QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId());
+
+ if (status == QUEST_STATUS_COMPLETE)
+ {
+ if (target->GetQuestRewardStatus(qinfo->GetQuestId()))
+ statusStr = GetTrinityString(LANG_COMMAND_QUEST_REWARDED);
+ else
+ statusStr = GetTrinityString(LANG_COMMAND_QUEST_COMPLETE);
+ }
+ else if (status == QUEST_STATUS_INCOMPLETE)
+ statusStr = GetTrinityString(LANG_COMMAND_QUEST_ACTIVE);
+ }
+
+ if (m_session)
+ PSendSysMessage(LANG_QUEST_LIST_CHAT,qinfo->GetQuestId(),qinfo->GetQuestId(),qinfo->GetQuestLevel(),title.c_str(),statusStr);
+ else
+ PSendSysMessage(LANG_QUEST_LIST_CONSOLE,qinfo->GetQuestId(),title.c_str(),statusStr);
+
+ if (!found)
+ found = true;
+ }
+ }
+
+ if (!found)
+ SendSysMessage(LANG_COMMAND_NOQUESTFOUND);
+
+ return true;
+}
+
+bool ChatHandler::HandleLookupCreatureCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ std::string namepart = args;
+ std::wstring wnamepart;
+
+ // converting string that we try to find to lower case
+ if (!Utf8toWStr (namepart,wnamepart))
+ return false;
+
+ wstrToLower (wnamepart);
+
+ bool found = false;
+
+ for (uint32 id = 0; id< sCreatureStorage.MaxEntry; ++id)
+ {
+ CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo> (id);
+ if (!cInfo)
+ continue;
+
+ int loc_idx = GetSessionDbLocaleIndex();
+ if (loc_idx >= 0)
+ {
+ CreatureLocale const *cl = objmgr.GetCreatureLocale (id);
+ if (cl)
+ {
+ if (cl->Name.size() > loc_idx && !cl->Name[loc_idx].empty ())
+ {
+ std::string name = cl->Name[loc_idx];
+
+ if (Utf8FitTo (name, wnamepart))
+ {
+ if (m_session)
+ PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CHAT, id, id, name.c_str ());
+ else
+ PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CONSOLE, id, name.c_str ());
+
+ if (!found)
+ found = true;
+
+ continue;
+ }
+ }
+ }
+ }
+
+ std::string name = cInfo->Name;
+ if (name.empty ())
+ continue;
+
+ if (Utf8FitTo(name, wnamepart))
+ {
+ if (m_session)
+ PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CHAT, id, id, name.c_str ());
+ else
+ PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CONSOLE, id, name.c_str ());
+
+ if (!found)
+ found = true;
+ }
+ }
+
+ if (!found)
+ SendSysMessage (LANG_COMMAND_NOCREATUREFOUND);
+
+ return true;
+}
+
+bool ChatHandler::HandleLookupObjectCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ std::string namepart = args;
+ std::wstring wnamepart;
+
+ // converting string that we try to find to lower case
+ if (!Utf8toWStr(namepart,wnamepart))
+ return false;
+
+ wstrToLower(wnamepart);
+
+ bool found = false;
+
+ for (uint32 id = 0; id< sGOStorage.MaxEntry; id++)
+ {
+ GameObjectInfo const* gInfo = sGOStorage.LookupEntry<GameObjectInfo>(id);
+ if (!gInfo)
+ continue;
+
+ int loc_idx = GetSessionDbLocaleIndex();
+ if (loc_idx >= 0)
+ {
+ GameObjectLocale const *gl = objmgr.GetGameObjectLocale(id);
+ if (gl)
+ {
+ if (gl->Name.size() > loc_idx && !gl->Name[loc_idx].empty())
+ {
+ std::string name = gl->Name[loc_idx];
+
+ if (Utf8FitTo(name, wnamepart))
+ {
+ if (m_session)
+ PSendSysMessage(LANG_GO_ENTRY_LIST_CHAT, id, id, name.c_str());
+ else
+ PSendSysMessage(LANG_GO_ENTRY_LIST_CONSOLE, id, name.c_str());
+
+ if (!found)
+ found = true;
+
+ continue;
+ }
+ }
+ }
+ }
+
+ std::string name = gInfo->name;
+ if (name.empty())
+ continue;
+
+ if (Utf8FitTo(name, wnamepart))
+ {
+ if (m_session)
+ PSendSysMessage(LANG_GO_ENTRY_LIST_CHAT, id, id, name.c_str());
+ else
+ PSendSysMessage(LANG_GO_ENTRY_LIST_CONSOLE, id, name.c_str());
+
+ if (!found)
+ found = true;
+ }
+ }
+
+ if (!found)
+ SendSysMessage(LANG_COMMAND_NOGAMEOBJECTFOUND);
+
+ return true;
+}
+
+bool ChatHandler::HandleLookupFactionCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ // Can be NULL at console call
+ Player *target = getSelectedPlayer ();
+
+ std::string namepart = args;
+ std::wstring wnamepart;
+
+ if (!Utf8toWStr (namepart,wnamepart))
+ return false;
+
+ // converting string that we try to find to lower case
+ wstrToLower (wnamepart);
+
+ bool found = false;
+
+ for (uint32 id = 0; id < sFactionStore.GetNumRows(); ++id)
+ {
+ FactionEntry const *factionEntry = sFactionStore.LookupEntry (id);
+ if (factionEntry)
+ {
+ FactionState const* repState = target ? target->GetReputationMgr().GetState(factionEntry) : NULL;
+
+ int loc = GetSessionDbcLocale();
+ std::string name = factionEntry->name[loc];
+ if (name.empty())
+ continue;
+
+ if (!Utf8FitTo(name, wnamepart))
+ {
+ loc = 0;
+ for (; loc < MAX_LOCALE; ++loc)
+ {
+ if (loc == GetSessionDbcLocale())
+ continue;
+
+ name = factionEntry->name[loc];
+ if (name.empty())
+ continue;
+
+ if (Utf8FitTo(name, wnamepart))
+ break;
+ }
+ }
+
+ if (loc < MAX_LOCALE)
+ {
+ // send faction in "id - [faction] rank reputation [visible] [at war] [own team] [unknown] [invisible] [inactive]" format
+ // or "id - [faction] [no reputation]" format
+ std::ostringstream ss;
+ if (m_session)
+ ss << id << " - |cffffffff|Hfaction:" << id << "|h[" << name << " " << localeNames[loc] << "]|h|r";
+ else
+ ss << id << " - " << name << " " << localeNames[loc];
+
+ if (repState) // and then target != NULL also
+ {
+ ReputationRank rank = target->GetReputationMgr().GetRank(factionEntry);
+ std::string rankName = GetTrinityString(ReputationRankStrIndex[rank]);
+
+ ss << " " << rankName << "|h|r (" << target->GetReputationMgr().GetReputation(factionEntry) << ")";
+
+ if (repState->Flags & FACTION_FLAG_VISIBLE)
+ ss << GetTrinityString(LANG_FACTION_VISIBLE);
+ if (repState->Flags & FACTION_FLAG_AT_WAR)
+ ss << GetTrinityString(LANG_FACTION_ATWAR);
+ if (repState->Flags & FACTION_FLAG_PEACE_FORCED)
+ ss << GetTrinityString(LANG_FACTION_PEACE_FORCED);
+ if (repState->Flags & FACTION_FLAG_HIDDEN)
+ ss << GetTrinityString(LANG_FACTION_HIDDEN);
+ if (repState->Flags & FACTION_FLAG_INVISIBLE_FORCED)
+ ss << GetTrinityString(LANG_FACTION_INVISIBLE_FORCED);
+ if (repState->Flags & FACTION_FLAG_INACTIVE)
+ ss << GetTrinityString(LANG_FACTION_INACTIVE);
+ }
+ else
+ ss << GetTrinityString(LANG_FACTION_NOREPUTATION);
+
+ SendSysMessage(ss.str().c_str());
+
+ if (!found)
+ found = true;
+ }
+ }
+ }
+
+ if (!found)
+ SendSysMessage(LANG_COMMAND_FACTION_NOTFOUND);
+ return true;
+}
+
+bool ChatHandler::HandleLookupTaxiNodeCommand(const char * args)
+{
+ if (!*args)
+ return false;
+
+ std::string namepart = args;
+ std::wstring wnamepart;
+
+ if (!Utf8toWStr(namepart,wnamepart))
+ return false;
+
+ // converting string that we try to find to lower case
+ wstrToLower(wnamepart);
+
+ bool found = false;
+
+ // Search in TaxiNodes.dbc
+ for (uint32 id = 0; id < sTaxiNodesStore.GetNumRows(); id++)
+ {
+ TaxiNodesEntry const *nodeEntry = sTaxiNodesStore.LookupEntry(id);
+ if (nodeEntry)
+ {
+ int loc = GetSessionDbcLocale();
+ std::string name = nodeEntry->name[loc];
+ if (name.empty())
+ continue;
+
+ if (!Utf8FitTo(name, wnamepart))
+ {
+ loc = 0;
+ for (; loc < MAX_LOCALE; ++loc)
+ {
+ if (loc == GetSessionDbcLocale())
+ continue;
+
+ name = nodeEntry->name[loc];
+ if (name.empty())
+ continue;
+
+ if (Utf8FitTo(name, wnamepart))
+ break;
+ }
+ }
+
+ if (loc < MAX_LOCALE)
+ {
+ // send taxinode in "id - [name] (Map:m X:x Y:y Z:z)" format
+ if (m_session)
+ PSendSysMessage (LANG_TAXINODE_ENTRY_LIST_CHAT, id, id, name.c_str(),localeNames[loc],
+ nodeEntry->map_id,nodeEntry->x,nodeEntry->y,nodeEntry->z);
+ else
+ PSendSysMessage (LANG_TAXINODE_ENTRY_LIST_CONSOLE, id, name.c_str(), localeNames[loc],
+ nodeEntry->map_id,nodeEntry->x,nodeEntry->y,nodeEntry->z);
+
+ if (!found)
+ found = true;
+ }
+ }
+ }
+ if (!found)
+ SendSysMessage(LANG_COMMAND_NOTAXINODEFOUND);
+ return true;
+}
+
+bool ChatHandler::HandleLookupMapCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ /*std::string namepart = args;
+ std::wstring wnamepart;
+
+ // converting string that we try to find to lower case
+ if (!Utf8toWStr(namepart, wnamepart))
+ return false;
+
+ wstrToLower(wnamepart);
+
+ bool found = false;
+
+ // search in Map.dbc
+ for (uint32 id = 0; id < sMapStore.GetNumRows(); id++)
+ {
+ MapEntry const* MapInfo = sMapStore.LookupEntry(id);
+ if (MapInfo)
+ {
+ uint8 loc = m_session ? m_session->GetSessionDbcLocale() : sWorld.GetDefaultDbcLocale();
+
+ std::string name = MapInfo->name[loc];
+ if (name.empty())
+ continue;
+
+ if (!Utf8FitTo(name, wnamepart))
+ {
+ loc = LOCALE_enUS;
+ for (; loc < MAX_LOCALE; loc++)
+ {
+ if (m_session && loc == m_session->GetSessionDbcLocale())
+ continue;
+
+ name = MapInfo->name[loc];
+ if (name.empty())
+ continue;
+
+ if (Utf8FitTo(name, wnamepart))
+ break;
+ }
+ }
+
+ if (loc < MAX_LOCALE)
+ {
+ // send map in "id - [name][Continent][Instance/Battleground/Arena][Raid reset time:][Heroic reset time:][Mountable]" format
+ std::ostringstream ss;
+
+ if (m_session)
+ ss << id << " - |cffffffff|Hmap:" << id << "|h[" << name << "]";
+ else // console
+ ss << id << " - [" << name << "]";
+
+ if (MapInfo->IsContinent())
+ ss << GetTrinityString(LANG_CONTINENT);
+
+ switch(MapInfo->map_type)
+ {
+ case MAP_INSTANCE: ss << GetTrinityString(LANG_INSTANCE); break;
+ case MAP_BATTLEGROUND: ss << GetTrinityString(LANG_BATTLEGROUND); break;
+ case MAP_ARENA: ss << GetTrinityString(LANG_ARENA); break;
+ }
+
+ if (MapInfo->IsRaid())
+ ss << GetTrinityString(LANG_RAID);
+
+ if (MapInfo->SupportsHeroicMode())
+ ss << GetTrinityString(LANG_HEROIC);
+
+ uint32 ResetTimeRaid = MapInfo->resetTimeRaid;
+
+ std::string ResetTimeRaidStr;
+ if (ResetTimeRaid)
+ ResetTimeRaidStr = secsToTimeString(ResetTimeRaid, true, false);
+
+ uint32 ResetTimeHeroic = MapInfo->resetTimeHeroic;
+ std::string ResetTimeHeroicStr;
+ if (ResetTimeHeroic)
+ ResetTimeHeroicStr = secsToTimeString(ResetTimeHeroic, true, false);
+
+ if (MapInfo->IsMountAllowed())
+ ss << GetTrinityString(LANG_MOUNTABLE);
+
+ if (ResetTimeRaid && !ResetTimeHeroic)
+ PSendSysMessage(ss.str().c_str(), ResetTimeRaidStr.c_str());
+ else if (!ResetTimeRaid && ResetTimeHeroic)
+ PSendSysMessage(ss.str().c_str(), ResetTimeHeroicStr.c_str());
+ else if (ResetTimeRaid && ResetTimeHeroic)
+ PSendSysMessage(ss.str().c_str(), ResetTimeRaidStr.c_str(), ResetTimeHeroicStr.c_str());
+ else
+ SendSysMessage(ss.str().c_str());
+
+ if (!found)
+ found = true;
+ }
+ }
+ }
+
+ if (!found)
+ SendSysMessage(LANG_COMMAND_NOMAPFOUND);
+ */
+ return true;
+}
+
+/** \brief GM command level 3 - Create a guild.
+ *
+ * This command allows a GM (level 3) to create a guild.
+ *
+ * The "args" parameter contains the name of the guild leader
+ * and then the name of the guild.
+ *
+ */
+bool ChatHandler::HandleGuildCreateCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ // if not guild name only (in "") then player name
+ Player* target;
+ if (!extractPlayerTarget(*args != '"' ? (char*)args : NULL, &target))
+ return false;
+
+ char* tailStr = *args != '"' ? strtok(NULL, "") : (char*)args;
+ if (!tailStr)
+ return false;
+
+ char* guildStr = extractQuotedArg(tailStr);
+ if (!guildStr)
+ return false;
+
+ std::string guildname = guildStr;
+
+ if (target->GetGuildId())
+ {
+ SendSysMessage (LANG_PLAYER_IN_GUILD);
+ return true;
+ }
+
+ Guild *guild = new Guild;
+ if (!guild->Create (target,guildname))
+ {
+ delete guild;
+ SendSysMessage (LANG_GUILD_NOT_CREATED);
+ SetSentErrorMessage (true);
+ return false;
+ }
+
+ objmgr.AddGuild (guild);
+ return true;
+}
+
+bool ChatHandler::HandleGuildInviteCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ // if not guild name only (in "") then player name
+ uint64 target_guid;
+ if (!extractPlayerTarget(*args != '"' ? (char*)args : NULL, NULL, &target_guid))
+ return false;
+
+ char* tailStr = *args != '"' ? strtok(NULL, "") : (char*)args;
+ if (!tailStr)
+ return false;
+
+ char* guildStr = extractQuotedArg(tailStr);
+ if (!guildStr)
+ return false;
+
+ std::string glName = guildStr;
+ Guild* targetGuild = objmgr.GetGuildByName (glName);
+ if (!targetGuild)
+ return false;
+
+ // player's guild membership checked in AddMember before add
+ if (!targetGuild->AddMember (target_guid,targetGuild->GetLowestRank ()))
+ return false;
+
+ return true;
+}
+
+bool ChatHandler::HandleGuildUninviteCommand(const char *args)
+{
+ Player* target;
+ uint64 target_guid;
+ if (!extractPlayerTarget((char*)args,&target,&target_guid))
+ return false;
+
+ uint32 glId = target ? target->GetGuildId () : Player::GetGuildIdFromDB (target_guid);
+ if (!glId)
+ return false;
+
+ Guild* targetGuild = objmgr.GetGuildById (glId);
+ if (!targetGuild)
+ return false;
+
+ targetGuild->DelMember (target_guid);
+ return true;
+}
+
+bool ChatHandler::HandleGuildRankCommand(const char *args)
+{
+ char* nameStr;
+ char* rankStr;
+ extractOptFirstArg((char*)args,&nameStr,&rankStr);
+ if (!rankStr)
+ return false;
+
+ Player* target;
+ uint64 target_guid;
+ std::string target_name;
+ if (!extractPlayerTarget(nameStr,&target,&target_guid,&target_name))
+ return false;
+
+ uint32 glId = target ? target->GetGuildId () : Player::GetGuildIdFromDB (target_guid);
+ if (!glId)
+ return false;
+
+ Guild* targetGuild = objmgr.GetGuildById (glId);
+ if (!targetGuild)
+ return false;
+
+ uint32 newrank = uint32 (atoi (rankStr));
+ if (newrank > targetGuild->GetLowestRank ())
+ return false;
+
+ targetGuild->ChangeRank (target_guid,newrank);
+ return true;
+}
+
+bool ChatHandler::HandleGuildDeleteCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ char* guildStr = extractQuotedArg((char*)args);
+ if (!guildStr)
+ return false;
+
+ std::string gld = guildStr;
+
+ Guild* targetGuild = objmgr.GetGuildByName (gld);
+ if (!targetGuild)
+ return false;
+
+ targetGuild->Disband ();
+
+ return true;
+}
+
+bool ChatHandler::HandleGetDistanceCommand(const char *args)
+{
+ WorldObject* obj = NULL;
+
+ if (*args)
+ {
+ uint64 guid = extractGuidFromLink((char*)args);
+ if (guid)
+ obj = (WorldObject*)ObjectAccessor::GetObjectByTypeMask(*m_session->GetPlayer(),guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
+
+ if (!obj)
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+ }
+ else
+ {
+ obj = getSelectedUnit();
+
+ if (!obj)
+ {
+ SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+ }
+
+ PSendSysMessage(LANG_DISTANCE, m_session->GetPlayer()->GetDistance(obj), m_session->GetPlayer()->GetDistance2d(obj), m_session->GetPlayer()->GetExactDist(obj), m_session->GetPlayer()->GetExactDist2d(obj));
+ return true;
+}
+
+bool ChatHandler::HandleDieCommand(const char* /*args*/)
+{
+ Unit* target = getSelectedUnit();
+
+ if (!target || !m_session->GetPlayer()->GetSelection())
+ {
+ SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (target->GetTypeId() == TYPEID_PLAYER)
+ {
+ if (HasLowerSecurity((Player*)target,0,false))
+ return false;
+ }
+
+ if (target->isAlive())
+ {
+ if (sWorld.getConfig(CONFIG_DIE_COMMAND_MODE))
+ m_session->GetPlayer()->Kill(target);
+ else
+ m_session->GetPlayer()->DealDamage(target, target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ }
+
+ return true;
+}
+
+bool ChatHandler::HandleDamageCommand(const char * args)
+{
+ if (!*args)
+ return false;
+
+ Unit* target = getSelectedUnit();
+
+ if (!target || !m_session->GetPlayer()->GetSelection())
+ {
+ SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (!target->isAlive())
+ return true;
+
+ char* damageStr = strtok((char*)args, " ");
+ if (!damageStr)
+ return false;
+
+ int32 damage_int = atoi((char*)damageStr);
+ if (damage_int <= 0)
+ return true;
+
+ uint32 damage = damage_int;
+
+ char* schoolStr = strtok((char*)NULL, " ");
+
+ // flat melee damage without resistence/etc reduction
+ if (!schoolStr)
+ {
+ m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ if (target != m_session->GetPlayer())
+ m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, SPELL_SCHOOL_MASK_NORMAL, damage, 0, 0, VICTIMSTATE_NORMAL, 0);
+ return true;
+ }
+
+ uint32 school = schoolStr ? atoi((char*)schoolStr) : SPELL_SCHOOL_NORMAL;
+ if (school >= MAX_SPELL_SCHOOL)
+ return false;
+
+ SpellSchoolMask schoolmask = SpellSchoolMask(1 << school);
+
+ if (schoolmask & SPELL_SCHOOL_MASK_NORMAL)
+ damage = m_session->GetPlayer()->CalcArmorReducedDamage(target, damage, NULL, BASE_ATTACK);
+
+ char* spellStr = strtok((char*)NULL, " ");
+
+ // melee damage by specific school
+ if (!spellStr)
+ {
+ uint32 absorb = 0;
+ uint32 resist = 0;
+
+ m_session->GetPlayer()->CalcAbsorbResist(target,schoolmask, SPELL_DIRECT_DAMAGE, damage, &absorb, &resist);
+
+ if (damage <= absorb + resist)
+ return true;
+
+ damage -= absorb + resist;
+
+ m_session->GetPlayer()->DealDamageMods(target,damage,&absorb);
+ m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, schoolmask, NULL, false);
+ m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, schoolmask, damage, absorb, resist, VICTIMSTATE_NORMAL, 0);
+ return true;
+ }
+
+ // non-melee damage
+
+ // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
+ uint32 spellid = extractSpellIdFromLink((char*)args);
+ if (!spellid || !sSpellStore.LookupEntry(spellid))
+ return false;
+
+ m_session->GetPlayer()->SpellNonMeleeDamageLog(target, spellid, damage);
+ return true;
+}
+
+bool ChatHandler::HandleModifyArenaCommand(const char * args)
+{
+ if (!*args)
+ return false;
+
+ Player *target = getSelectedPlayer();
+ if (!target)
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ int32 amount = (uint32)atoi(args);
+
+ target->ModifyArenaPoints(amount);
+
+ PSendSysMessage(LANG_COMMAND_MODIFY_ARENA, GetNameLink(target).c_str(), target->GetArenaPoints());
+
+ return true;
+}
+
+bool ChatHandler::HandleReviveCommand(const char *args)
+{
+ Player* target;
+ uint64 target_guid;
+ if (!extractPlayerTarget((char*)args,&target,&target_guid))
+ return false;
+
+ if (target)
+ {
+ target->ResurrectPlayer(target->GetSession()->GetSecurity() > SEC_PLAYER ? 1.0f : 0.5f);
+ target->SpawnCorpseBones();
+ target->SaveToDB();
+ }
+ else
+ // will resurrected at login without corpse
+ ObjectAccessor::Instance().ConvertCorpseForPlayer(target_guid);
+
+ return true;
+}
+
+bool ChatHandler::HandleAuraCommand(const char *args)
+{
+ Unit *target = getSelectedUnit();
+ if (!target)
+ {
+ SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
+ uint32 spellID = extractSpellIdFromLink((char*)args);
+
+ if (SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellID))
+ Aura::TryCreate(spellInfo, target, target);
+
+ return true;
+}
+
+bool ChatHandler::HandleUnAuraCommand(const char *args)
+{
+ Unit *target = getSelectedUnit();
+ if (!target)
+ {
+ SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ std::string argstr = args;
+ if (argstr == "all")
+ {
+ target->RemoveAllAuras();
+ return true;
+ }
+
+ // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
+ uint32 spellID = extractSpellIdFromLink((char*)args);
+ if (!spellID)
+ return false;
+
+ target->RemoveAurasDueToSpell(spellID);
+
+ return true;
+}
+
+bool ChatHandler::HandleLinkGraveCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ char* px = strtok((char*)args, " ");
+ if (!px)
+ return false;
+
+ uint32 g_id = (uint32)atoi(px);
+
+ uint32 g_team;
+
+ char* px2 = strtok(NULL, " ");
+
+ if (!px2)
+ g_team = 0;
+ else if (strncmp(px2,"horde",6) == 0)
+ g_team = HORDE;
+ else if (strncmp(px2,"alliance",9) == 0)
+ g_team = ALLIANCE;
+ else
+ return false;
+
+ WorldSafeLocsEntry const* graveyard = sWorldSafeLocsStore.LookupEntry(g_id);
+
+ if (!graveyard)
+ {
+ PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST, g_id);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Player* player = m_session->GetPlayer();
+
+ uint32 zoneId = player->GetZoneId();
+
+ AreaTableEntry const *areaEntry = GetAreaEntryByAreaID(zoneId);
+ if (!areaEntry || areaEntry->zone !=0)
+ {
+ PSendSysMessage(LANG_COMMAND_GRAVEYARDWRONGZONE, g_id,zoneId);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (objmgr.AddGraveYardLink(g_id,zoneId,g_team))
+ PSendSysMessage(LANG_COMMAND_GRAVEYARDLINKED, g_id,zoneId);
+ else
+ PSendSysMessage(LANG_COMMAND_GRAVEYARDALRLINKED, g_id,zoneId);
+
+ return true;
+}
+
+bool ChatHandler::HandleNearGraveCommand(const char *args)
+{
+ uint32 g_team;
+
+ size_t argslen = strlen(args);
+
+ if (!*args)
+ g_team = 0;
+ else if (strncmp((char*)args,"horde",argslen) == 0)
+ g_team = HORDE;
+ else if (strncmp((char*)args,"alliance",argslen) == 0)
+ g_team = ALLIANCE;
+ else
+ return false;
+
+ Player* player = m_session->GetPlayer();
+ uint32 zone_id = player->GetZoneId();
+
+ WorldSafeLocsEntry const* graveyard = objmgr.GetClosestGraveYard(
+ player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(),player->GetMapId(),g_team);
+
+ if (graveyard)
+ {
+ uint32 g_id = graveyard->ID;
+
+ GraveYardData const* data = objmgr.FindGraveYardData(g_id,zone_id);
+ if (!data)
+ {
+ PSendSysMessage(LANG_COMMAND_GRAVEYARDERROR,g_id);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ g_team = data->team;
+
+ std::string team_name = GetTrinityString(LANG_COMMAND_GRAVEYARD_NOTEAM);
+
+ if (g_team == 0)
+ team_name = GetTrinityString(LANG_COMMAND_GRAVEYARD_ANY);
+ else if (g_team == HORDE)
+ team_name = GetTrinityString(LANG_COMMAND_GRAVEYARD_HORDE);
+ else if (g_team == ALLIANCE)
+ team_name = GetTrinityString(LANG_COMMAND_GRAVEYARD_ALLIANCE);
+
+ PSendSysMessage(LANG_COMMAND_GRAVEYARDNEAREST, g_id,team_name.c_str(),zone_id);
+ }
+ else
+ {
+ std::string team_name;
+
+ if (g_team == 0)
+ team_name = GetTrinityString(LANG_COMMAND_GRAVEYARD_ANY);
+ else if (g_team == HORDE)
+ team_name = GetTrinityString(LANG_COMMAND_GRAVEYARD_HORDE);
+ else if (g_team == ALLIANCE)
+ team_name = GetTrinityString(LANG_COMMAND_GRAVEYARD_ALLIANCE);
+
+ if (g_team == ~uint32(0))
+ PSendSysMessage(LANG_COMMAND_ZONENOGRAVEYARDS, zone_id);
+ else
+ PSendSysMessage(LANG_COMMAND_ZONENOGRAFACTION, zone_id,team_name.c_str());
+ }
+
+ return true;
+}
+
+//-----------------------Npc Commands-----------------------
+bool ChatHandler::HandleNpcAllowMovementCommand(const char* /*args*/)
+{
+ if (sWorld.getAllowMovement())
+ {
+ sWorld.SetAllowMovement(false);
+ SendSysMessage(LANG_CREATURE_MOVE_DISABLED);
+ }
+ else
+ {
+ sWorld.SetAllowMovement(true);
+ SendSysMessage(LANG_CREATURE_MOVE_ENABLED);
+ }
+ return true;
+}
+
+bool ChatHandler::HandleNpcChangeEntryCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ uint32 newEntryNum = atoi(args);
+ if (!newEntryNum)
+ return false;
+
+ Unit* unit = getSelectedUnit();
+ if (!unit || unit->GetTypeId() != TYPEID_UNIT)
+ {
+ SendSysMessage(LANG_SELECT_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+ Creature* creature = unit->ToCreature();
+ if (creature->UpdateEntry(newEntryNum))
+ SendSysMessage(LANG_DONE);
+ else
+ SendSysMessage(LANG_ERROR);
+ return true;
+}
+
+bool ChatHandler::HandleNpcInfoCommand(const char* /*args*/)
+{
+ Creature* target = getSelectedCreature();
+
+ if (!target)
+ {
+ SendSysMessage(LANG_SELECT_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ uint32 faction = target->getFaction();
+ uint32 npcflags = target->GetUInt32Value(UNIT_NPC_FLAGS);
+ uint32 displayid = target->GetDisplayId();
+ uint32 nativeid = target->GetNativeDisplayId();
+ uint32 Entry = target->GetEntry();
+ CreatureInfo const* cInfo = target->GetCreatureInfo();
+
+ int32 curRespawnDelay = target->GetRespawnTimeEx()-time(NULL);
+ if (curRespawnDelay < 0)
+ curRespawnDelay = 0;
+ std::string curRespawnDelayStr = secsToTimeString(curRespawnDelay,true);
+ std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(),true);
+
+ PSendSysMessage(LANG_NPCINFO_CHAR, target->GetDBTableGUIDLow(), faction, npcflags, Entry, displayid, nativeid);
+ PSendSysMessage(LANG_NPCINFO_LEVEL, target->getLevel());
+ PSendSysMessage(LANG_NPCINFO_HEALTH,target->GetCreateHealth(), target->GetMaxHealth(), target->GetHealth());
+ PSendSysMessage(LANG_NPCINFO_FLAGS, target->GetUInt32Value(UNIT_FIELD_FLAGS), target->GetUInt32Value(UNIT_DYNAMIC_FLAGS), target->getFaction());
+ PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES, defRespawnDelayStr.c_str(),curRespawnDelayStr.c_str());
+ PSendSysMessage(LANG_NPCINFO_LOOT, cInfo->lootid,cInfo->pickpocketLootId,cInfo->SkinLootId);
+ PSendSysMessage(LANG_NPCINFO_DUNGEON_ID, target->GetInstanceId());
+ PSendSysMessage(LANG_NPCINFO_PHASEMASK, target->GetPhaseMask());
+ PSendSysMessage(LANG_NPCINFO_ARMOR, target->GetArmor());
+ PSendSysMessage(LANG_NPCINFO_POSITION,float(target->GetPositionX()), float(target->GetPositionY()), float(target->GetPositionZ()));
+ if (const CreatureData* const linked = target->GetLinkedRespawnCreatureData())
+ if (CreatureInfo const *master = GetCreatureInfo(linked->id))
+ PSendSysMessage(LANG_NPCINFO_LINKGUID, objmgr.GetLinkedRespawnGuid(target->GetDBTableGUIDLow()), linked->id, master->Name);
+
+ if ((npcflags & UNIT_NPC_FLAG_VENDOR))
+ {
+ SendSysMessage(LANG_NPCINFO_VENDOR);
+ }
+ if ((npcflags & UNIT_NPC_FLAG_TRAINER))
+ {
+ SendSysMessage(LANG_NPCINFO_TRAINER);
+ }
+
+ return true;
+}
+
+//play npc emote
+bool ChatHandler::HandleNpcPlayEmoteCommand(const char *args)
+{
+ uint32 emote = atoi((char*)args);
+
+ Creature* target = getSelectedCreature();
+ if (!target)
+ {
+ SendSysMessage(LANG_SELECT_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ target->SetUInt32Value(UNIT_NPC_EMOTESTATE,emote);
+
+ return true;
+}
+
+//TODO: NpcCommands that needs to be fixed :
+
+bool ChatHandler::HandleNpcAddWeaponCommand(const char* /*args*/)
+{
+ /*if (!*args)
+ return false;
+
+ uint64 guid = m_session->GetPlayer()->GetSelection();
+ if (guid == 0)
+ {
+ SendSysMessage(LANG_NO_SELECTION);
+ return true;
+ }
+
+ Creature *pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
+
+ if (!pCreature)
+ {
+ SendSysMessage(LANG_SELECT_CREATURE);
+ return true;
+ }
+
+ char* pSlotID = strtok((char*)args, " ");
+ if (!pSlotID)
+ return false;
+
+ char* pItemID = strtok(NULL, " ");
+ if (!pItemID)
+ return false;
+
+ uint32 ItemID = atoi(pItemID);
+ uint32 SlotID = atoi(pSlotID);
+
+ ItemPrototype* tmpItem = objmgr.GetItemPrototype(ItemID);
+
+ bool added = false;
+ if (tmpItem)
+ {
+ switch(SlotID)
+ {
+ case 1:
+ pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, ItemID);
+ added = true;
+ break;
+ case 2:
+ pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_01, ItemID);
+ added = true;
+ break;
+ case 3:
+ pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_02, ItemID);
+ added = true;
+ break;
+ default:
+ PSendSysMessage(LANG_ITEM_SLOT_NOT_EXIST,SlotID);
+ added = false;
+ break;
+ }
+
+ if (added)
+ PSendSysMessage(LANG_ITEM_ADDED_TO_SLOT,ItemID,tmpItem->Name1,SlotID);
+ }
+ else
+ {
+ PSendSysMessage(LANG_ITEM_NOT_FOUND,ItemID);
+ return true;
+ }
+ */
+ return true;
+}
+//----------------------------------------------------------
+
+bool ChatHandler::HandleExploreCheatCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ int flag = atoi((char*)args);
+
+ Player *chr = getSelectedPlayer();
+ if (chr == NULL)
+ {
+ SendSysMessage(LANG_NO_CHAR_SELECTED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (flag != 0)
+ {
+ PSendSysMessage(LANG_YOU_SET_EXPLORE_ALL, GetNameLink(chr).c_str());
+ if (needReportToTarget(chr))
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_ALL,GetNameLink().c_str());
+ }
+ else
+ {
+ PSendSysMessage(LANG_YOU_SET_EXPLORE_NOTHING, GetNameLink(chr).c_str());
+ if (needReportToTarget(chr))
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_NOTHING,GetNameLink().c_str());
+ }
+
+ for (uint8 i=0; i<PLAYER_EXPLORED_ZONES_SIZE; ++i)
+ {
+ if (flag != 0)
+ {
+ m_session->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i,0xFFFFFFFF);
+ }
+ else
+ {
+ m_session->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i,0);
+ }
+ }
+
+ return true;
+}
+
+bool ChatHandler::HandleHoverCommand(const char *args)
+{
+ char* px = strtok((char*)args, " ");
+ uint32 flag;
+ if (!px)
+ flag = 1;
+ else
+ flag = atoi(px);
+
+ m_session->GetPlayer()->SetHover(flag);
+
+ if (flag)
+ SendSysMessage(LANG_HOVER_ENABLED);
+ else
+ SendSysMessage(LANG_HOVER_DISABLED);
+
+ return true;
+}
+
+void ChatHandler::HandleCharacterLevel(Player* player, uint64 player_guid, uint32 oldlevel, uint32 newlevel)
+{
+ if (player)
+ {
+ player->GiveLevel(newlevel);
+ player->InitTalentForLevel();
+ player->SetUInt32Value(PLAYER_XP,0);
+
+ if (needReportToTarget(player))
+ {
+ if (oldlevel == newlevel)
+ ChatHandler(player).PSendSysMessage(LANG_YOURS_LEVEL_PROGRESS_RESET,GetNameLink().c_str());
+ else if (oldlevel < newlevel)
+ ChatHandler(player).PSendSysMessage(LANG_YOURS_LEVEL_UP,GetNameLink().c_str(),newlevel);
+ else // if (oldlevel > newlevel)
+ ChatHandler(player).PSendSysMessage(LANG_YOURS_LEVEL_DOWN,GetNameLink().c_str(),newlevel);
+ }
+ }
+ else
+ {
+ // update level and XP at level, all other will be updated at loading
+ CharacterDatabase.PExecute("UPDATE characters SET level = '%u', xp = 0 WHERE guid = '%u'", newlevel, GUID_LOPART(player_guid));
+ }
+}
+
+bool ChatHandler::HandleCharacterLevelCommand(const char *args)
+{
+ char* nameStr;
+ char* levelStr;
+ extractOptFirstArg((char*)args,&nameStr,&levelStr);
+ if (!levelStr)
+ return false;
+
+ // exception opt second arg: .character level $name
+ if (isalpha(levelStr[0]))
+ {
+ nameStr = levelStr;
+ levelStr = NULL; // current level will used
+ }
+
+ Player* target;
+ uint64 target_guid;
+ std::string target_name;
+ if (!extractPlayerTarget(nameStr,&target,&target_guid,&target_name))
+ return false;
+
+ int32 oldlevel = target ? target->getLevel() : Player::GetLevelFromDB(target_guid);
+ int32 newlevel = levelStr ? atoi(levelStr) : oldlevel;
+
+ if (newlevel < 1)
+ return false; // invalid level
+
+ if (newlevel > STRONG_MAX_LEVEL) // hardcoded maximum level
+ newlevel = STRONG_MAX_LEVEL;
+
+ HandleCharacterLevel(target,target_guid,oldlevel,newlevel);
+
+ if (!m_session || m_session->GetPlayer() != target) // including player == NULL
+ {
+ std::string nameLink = playerLink(target_name);
+ PSendSysMessage(LANG_YOU_CHANGE_LVL,nameLink.c_str(),newlevel);
+ }
+
+ return true;
+}
+
+bool ChatHandler::HandleLevelUpCommand(const char *args)
+{
+ char* nameStr;
+ char* levelStr;
+ extractOptFirstArg((char*)args,&nameStr,&levelStr);
+
+ // exception opt second arg: .character level $name
+ if (levelStr && isalpha(levelStr[0]))
+ {
+ nameStr = levelStr;
+ levelStr = NULL; // current level will used
+ }
+
+ Player* target;
+ uint64 target_guid;
+ std::string target_name;
+ if (!extractPlayerTarget(nameStr,&target,&target_guid,&target_name))
+ return false;
+
+ int32 oldlevel = target ? target->getLevel() : Player::GetLevelFromDB(target_guid);
+ int32 addlevel = levelStr ? atoi(levelStr) : 1;
+ int32 newlevel = oldlevel + addlevel;
+
+ if (newlevel < 1)
+ newlevel = 1;
+
+ if (newlevel > STRONG_MAX_LEVEL) // hardcoded maximum level
+ newlevel = STRONG_MAX_LEVEL;
+
+ HandleCharacterLevel(target,target_guid,oldlevel,newlevel);
+
+ if (!m_session || m_session->GetPlayer() != target) // including chr == NULL
+ {
+ std::string nameLink = playerLink(target_name);
+ PSendSysMessage(LANG_YOU_CHANGE_LVL,nameLink.c_str(),newlevel);
+ }
+
+ return true;
+}
+
+bool ChatHandler::HandleShowAreaCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ Player *chr = getSelectedPlayer();
+ if (chr == NULL)
+ {
+ SendSysMessage(LANG_NO_CHAR_SELECTED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ int area = GetAreaFlagByAreaID(atoi((char*)args));
+ int offset = area / 32;
+ uint32 val = (uint32)(1 << (area % 32));
+
+ if (area<0 || offset >= PLAYER_EXPLORED_ZONES_SIZE)
+ {
+ SendSysMessage(LANG_BAD_VALUE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ uint32 currFields = chr->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset);
+ chr->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields | val));
+
+ SendSysMessage(LANG_EXPLORE_AREA);
+ return true;
+}
+
+bool ChatHandler::HandleHideAreaCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ Player *chr = getSelectedPlayer();
+ if (chr == NULL)
+ {
+ SendSysMessage(LANG_NO_CHAR_SELECTED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ int area = GetAreaFlagByAreaID(atoi((char*)args));
+ int offset = area / 32;
+ uint32 val = (uint32)(1 << (area % 32));
+
+ if (area<0 || offset >= PLAYER_EXPLORED_ZONES_SIZE)
+ {
+ SendSysMessage(LANG_BAD_VALUE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ uint32 currFields = chr->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset);
+ chr->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields ^ val));
+
+ SendSysMessage(LANG_UNEXPLORE_AREA);
+ return true;
+}
+
+bool ChatHandler::HandleBankCommand(const char* /*args*/)
+{
+ m_session->SendShowBank(m_session->GetPlayer()->GetGUID());
+
+ return true;
+}
+
+bool ChatHandler::HandleChangeWeather(const char *args)
+{
+ if (!*args)
+ return false;
+
+ //Weather is OFF
+ if (!sWorld.getConfig(CONFIG_WEATHER))
+ {
+ SendSysMessage(LANG_WEATHER_DISABLED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ //*Change the weather of a cell
+ char* px = strtok((char*)args, " ");
+ char* py = strtok(NULL, " ");
+
+ if (!px || !py)
+ return false;
+
+ uint32 type = (uint32)atoi(px); //0 to 3, 0: fine, 1: rain, 2: snow, 3: sand
+ float grade = (float)atof(py); //0 to 1, sending -1 is instand good weather
+
+ Player *player = m_session->GetPlayer();
+ uint32 zoneid = player->GetZoneId();
+
+ Weather* wth = sWorld.FindWeather(zoneid);
+
+ if (!wth)
+ wth = sWorld.AddWeather(zoneid);
+ if (!wth)
+ {
+ SendSysMessage(LANG_NO_WEATHER);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ wth->SetWeather(WeatherType(type), grade);
+
+ return true;
+}
+
+bool ChatHandler::HandleDebugSet32Bit(const char *args)
+{
+ if (!*args)
+ return false;
+
+ WorldObject* target = getSelectedObject();
+ if (!target)
+ {
+ SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ char* px = strtok((char*)args, " ");
+ char* py = strtok(NULL, " ");
+
+ if (!px || !py)
+ return false;
+
+ uint32 Opcode = (uint32)atoi(px);
+ uint32 Value = (uint32)atoi(py);
+ if (Value > 32) //uint32 = 32 bits
+ return false;
+
+ sLog.outDebug(GetTrinityString(LANG_SET_32BIT), Opcode, Value);
+
+ uint32 iValue = Value ? 1 << (Value - 1) : 0;
+ target->SetUInt32Value(Opcode , iValue);
+
+ PSendSysMessage(LANG_SET_32BIT_FIELD, Opcode, iValue);
+ return true;
+}
+
+bool ChatHandler::HandleTeleAddCommand(const char * args)
+{
+ if (!*args)
+ return false;
+
+ Player *player=m_session->GetPlayer();
+ if (!player)
+ return false;
+
+ std::string name = args;
+
+ if (objmgr.GetGameTele(name))
+ {
+ SendSysMessage(LANG_COMMAND_TP_ALREADYEXIST);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ GameTele tele;
+ tele.position_x = player->GetPositionX();
+ tele.position_y = player->GetPositionY();
+ tele.position_z = player->GetPositionZ();
+ tele.orientation = player->GetOrientation();
+ tele.mapId = player->GetMapId();
+ tele.name = name;
+
+ if (objmgr.AddGameTele(tele))
+ {
+ SendSysMessage(LANG_COMMAND_TP_ADDED);
+ }
+ else
+ {
+ SendSysMessage(LANG_COMMAND_TP_ADDEDERR);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ return true;
+}
+
+bool ChatHandler::HandleTeleDelCommand(const char * args)
+{
+ if (!*args)
+ return false;
+
+ std::string name = args;
+
+ if (!objmgr.DeleteGameTele(name))
+ {
+ SendSysMessage(LANG_COMMAND_TELE_NOTFOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ SendSysMessage(LANG_COMMAND_TP_DELETED);
+ return true;
+}
+
+bool ChatHandler::HandleListAurasCommand (const char * /*args*/)
+{
+ Unit *unit = getSelectedUnit();
+ if (!unit)
+ {
+ SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ char const* talentStr = GetTrinityString(LANG_TALENT);
+ char const* passiveStr = GetTrinityString(LANG_PASSIVE);
+
+ Unit::AuraApplicationMap const& uAuras = unit->GetAppliedAuras();
+ PSendSysMessage(LANG_COMMAND_TARGET_LISTAURAS, uAuras.size());
+ for (Unit::AuraApplicationMap::const_iterator itr = uAuras.begin(); itr != uAuras.end(); ++itr)
+ {
+ bool talent = GetTalentSpellCost(itr->second->GetBase()->GetId()) > 0;
+
+ AuraApplication const * aurApp = itr->second;
+ Aura const * aura = aurApp->GetBase();
+ char const* name = aura->GetSpellProto()->SpellName[GetSessionDbcLocale()];
+
+ if (m_session)
+ {
+ std::ostringstream ss_name;
+ ss_name << "|cffffffff|Hspell:" << aura->GetId() << "|h[" << name << "]|h|r";
+
+ PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, aura->GetId(), aurApp->GetEffectMask(),
+ aura->GetCharges(), aura->GetStackAmount(), aurApp->GetSlot(),
+ aura->GetDuration(), aura->GetMaxDuration(),
+ ss_name.str().c_str(),
+ (aura->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
+ IS_PLAYER_GUID(aura->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(aura->GetCasterGUID()));
+ }
+ else
+ {
+ PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, aura->GetId(), aurApp->GetEffectMask(),
+ aura->GetCharges(), aura->GetStackAmount(), aurApp->GetSlot(),
+ aura->GetDuration(), aura->GetMaxDuration(),
+ name,
+ (aura->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
+ IS_PLAYER_GUID(aura->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(aura->GetCasterGUID()));
+ }
+ }
+ for (uint16 i = 0; i < TOTAL_AURAS; ++i)
+ {
+ Unit::AuraEffectList const& uAuraList = unit->GetAuraEffectsByType(AuraType(i));
+ if (uAuraList.empty()) continue;
+ PSendSysMessage(LANG_COMMAND_TARGET_LISTAURATYPE, uAuraList.size(), i);
+ for (Unit::AuraEffectList::const_iterator itr = uAuraList.begin(); itr != uAuraList.end(); ++itr)
+ {
+ //bool talent = GetTalentSpellCost((*itr)->GetId()) > 0;
+
+ char const* name = (*itr)->GetSpellProto()->SpellName[GetSessionDbcLocale()];
+
+ std::ostringstream ss_name;
+ ss_name << "|cffffffff|Hspell:" << (*itr)->GetId() << "|h[" << name << "]|h|r";
+
+ PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(),
+ (*itr)->GetAmount());
+ }
+ }
+ return true;
+}
+
+bool ChatHandler::HandleResetAchievementsCommand (const char * args)
+{
+ Player* target;
+ uint64 target_guid;
+ if (!extractPlayerTarget((char*)args,&target,&target_guid))
+ return false;
+
+ if (target)
+ target->GetAchievementMgr().Reset();
+ else
+ AchievementMgr::DeleteFromDB(GUID_LOPART(target_guid));
+
+ return true;
+}
+
+bool ChatHandler::HandleResetHonorCommand (const char * args)
+{
+ Player* target;
+ if (!extractPlayerTarget((char*)args,&target))
+ return false;
+
+ target->SetUInt32Value(PLAYER_FIELD_KILLS, 0);
+ target->SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS, 0);
+ target->SetUInt32Value(PLAYER_FIELD_HONOR_CURRENCY, 0);
+ target->SetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, 0);
+ target->SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, 0);
+ target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL);
+
+ return true;
+}
+
+static bool HandleResetStatsOrLevelHelper(Player* player)
+{
+ ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(player->getClass());
+ if (!cEntry)
+ {
+ sLog.outError("Class %u not found in DBC (Wrong DBC files?)",player->getClass());
+ return false;
+ }
+
+ uint8 powertype = cEntry->powerType;
+
+ // reset m_form if no aura
+ if (!player->HasAuraType(SPELL_AURA_MOD_SHAPESHIFT))
+ player->m_form = FORM_NONE;
+
+ player->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE);
+ player->SetFloatValue(UNIT_FIELD_COMBATREACH, DEFAULT_COMBAT_REACH);
+
+ player->setFactionForRace(player->getRace());
+
+ player->SetUInt32Value(UNIT_FIELD_BYTES_0, ((player->getRace()) | (player->getClass() << 8) | (player->getGender() << 16) | (powertype << 24)));
+
+ // reset only if player not in some form;
+ if (player->m_form == FORM_NONE)
+ player->InitDisplayIds();
+
+ player->SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP);
+ player->SetByteValue(UNIT_FIELD_BYTES_2, 3, player->m_form);
+
+ player->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
+
+ //-1 is default value
+ player->SetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, uint32(-1));
+
+ //player->SetUInt32Value(PLAYER_FIELD_BYTES, 0xEEE00000);
+ return true;
+}
+
+bool ChatHandler::HandleResetLevelCommand(const char * args)
+{
+ Player* target;
+ if (!extractPlayerTarget((char*)args,&target))
+ return false;
+
+ if (!HandleResetStatsOrLevelHelper(target))
+ return false;
+
+ // set starting level
+ uint32 start_level = target->getClass() != CLASS_DEATH_KNIGHT
+ ? sWorld.getConfig(CONFIG_START_PLAYER_LEVEL)
+ : sWorld.getConfig(CONFIG_START_HEROIC_PLAYER_LEVEL);
+
+ target->_ApplyAllLevelScaleItemMods(false);
+
+ target->SetLevel(start_level);
+ target->InitRunes();
+ target->InitStatsForLevel(true);
+ target->InitTaxiNodesForLevel();
+ target->InitGlyphsForLevel();
+ target->InitTalentForLevel();
+ target->SetUInt32Value(PLAYER_XP,0);
+
+ target->_ApplyAllLevelScaleItemMods(true);
+
+ // reset level for pet
+ if (Pet* pet = target->GetPet())
+ pet->SynchronizeLevelWithOwner();
+
+ return true;
+}
+
+bool ChatHandler::HandleResetStatsCommand(const char * args)
+{
+ Player* target;
+ if (!extractPlayerTarget((char*)args,&target))
+ return false;
+
+ if (!HandleResetStatsOrLevelHelper(target))
+ return false;
+
+ target->InitRunes();
+ target->InitStatsForLevel(true);
+ target->InitTaxiNodesForLevel();
+ target->InitGlyphsForLevel();
+ target->InitTalentForLevel();
+
+ return true;
+}
+
+bool ChatHandler::HandleResetSpellsCommand(const char * args)
+{
+ Player* target;
+ uint64 target_guid;
+ std::string target_name;
+ if (!extractPlayerTarget((char*)args,&target,&target_guid,&target_name))
+ return false;
+
+ if (target)
+ {
+ target->resetSpells(/* bool myClassOnly */);
+
+ ChatHandler(target).SendSysMessage(LANG_RESET_SPELLS);
+ if (!m_session || m_session->GetPlayer() != target)
+ PSendSysMessage(LANG_RESET_SPELLS_ONLINE,GetNameLink(target).c_str());
+ }
+ else
+ {
+ CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",uint32(AT_LOGIN_RESET_SPELLS), GUID_LOPART(target_guid));
+ PSendSysMessage(LANG_RESET_SPELLS_OFFLINE,target_name.c_str());
+ }
+
+ return true;
+}
+
+bool ChatHandler::HandleResetTalentsCommand(const char * args)
+{
+ Player* target;
+ uint64 target_guid;
+ std::string target_name;
+ if (!extractPlayerTarget((char*)args,&target,&target_guid,&target_name))
+ {
+ // Try reset talents as Hunter Pet
+ Creature* creature = getSelectedCreature();
+ if (!*args && creature && creature->isPet())
+ {
+ Unit *owner = creature->GetOwner();
+ if (owner && owner->GetTypeId() == TYPEID_PLAYER && ((Pet *)creature)->IsPermanentPetFor(owner->ToPlayer()))
+ {
+ ((Pet *)creature)->resetTalents(true);
+ owner->ToPlayer()->SendTalentsInfoData(true);
+
+ ChatHandler(owner->ToPlayer()).SendSysMessage(LANG_RESET_PET_TALENTS);
+ if (!m_session || m_session->GetPlayer() != owner->ToPlayer())
+ PSendSysMessage(LANG_RESET_PET_TALENTS_ONLINE,GetNameLink(owner->ToPlayer()).c_str());
+ }
+ return true;
+ }
+
+ SendSysMessage(LANG_NO_CHAR_SELECTED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (target)
+ {
+ target->resetTalents(true);
+ target->SendTalentsInfoData(false);
+ ChatHandler(target).SendSysMessage(LANG_RESET_TALENTS);
+ if (!m_session || m_session->GetPlayer() != target)
+ PSendSysMessage(LANG_RESET_TALENTS_ONLINE,GetNameLink(target).c_str());
+
+ Pet* pet = target->GetPet();
+ Pet::resetTalentsForAllPetsOf(target,pet);
+ if (pet)
+ target->SendTalentsInfoData(true);
+ return true;
+ }
+ else if (target_guid)
+ {
+ uint32 at_flags = AT_LOGIN_NONE | AT_LOGIN_RESET_PET_TALENTS;
+ CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",at_flags, GUID_LOPART(target_guid));
+ std::string nameLink = playerLink(target_name);
+ PSendSysMessage(LANG_RESET_TALENTS_OFFLINE,nameLink.c_str());
+ return true;
+ }
+
+ SendSysMessage(LANG_NO_CHAR_SELECTED);
+ SetSentErrorMessage(true);
+ return false;
+}
+
+bool ChatHandler::HandleResetAllCommand(const char * args)
+{
+ if (!*args)
+ return false;
+
+ std::string casename = args;
+
+ AtLoginFlags atLogin;
+
+ // Command specially created as single command to prevent using short case names
+ if (casename == "spells")
+ {
+ atLogin = AT_LOGIN_RESET_SPELLS;
+ sWorld.SendWorldText(LANG_RESETALL_SPELLS);
+ if (!m_session)
+ SendSysMessage(LANG_RESETALL_SPELLS);
+ }
+ else if (casename == "talents")
+ {
+ atLogin = AtLoginFlags(AT_LOGIN_RESET_TALENTS | AT_LOGIN_RESET_PET_TALENTS);
+ sWorld.SendWorldText(LANG_RESETALL_TALENTS);
+ if (!m_session)
+ SendSysMessage(LANG_RESETALL_TALENTS);
+ }
+ else
+ {
+ PSendSysMessage(LANG_RESETALL_UNKNOWN_CASE,args);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE (at_login & '%u') = '0'",atLogin,atLogin);
+
+ ObjectAccessor::Guard guard(*HashMapHolder<Player>::GetLock());
+ HashMapHolder<Player>::MapType const& plist = ObjectAccessor::Instance().GetPlayers();
+ for (HashMapHolder<Player>::MapType::const_iterator itr = plist.begin(); itr != plist.end(); ++itr)
+ itr->second->SetAtLoginFlag(atLogin);
+
+ return true;
+}
+
+bool ChatHandler::HandleServerShutDownCancelCommand(const char* /*args*/)
+{
+ sWorld.ShutdownCancel();
+ return true;
+}
+
+bool ChatHandler::HandleServerShutDownCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ char* time_str = strtok ((char*) args, " ");
+ char* exitcode_str = strtok (NULL, "");
+
+ int32 time = atoi (time_str);
+
+ ///- Prevent interpret wrong arg value as 0 secs shutdown time
+ if ((time == 0 && (time_str[0] != '0' || time_str[1] != '\0')) || time < 0)
+ return false;
+
+ if (exitcode_str)
+ {
+ int32 exitcode = atoi (exitcode_str);
+
+ // Handle atoi() errors
+ if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
+ return false;
+
+ // Exit code should be in range of 0-125, 126-255 is used
+ // in many shells for their own return codes and code > 255
+ // is not supported in many others
+ if (exitcode < 0 || exitcode > 125)
+ return false;
+
+ sWorld.ShutdownServ (time, 0, exitcode);
+ }
+ else
+ sWorld.ShutdownServ(time,0,SHUTDOWN_EXIT_CODE);
+ return true;
+}
+
+bool ChatHandler::HandleServerRestartCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ char* time_str = strtok ((char*) args, " ");
+ char* exitcode_str = strtok (NULL, "");
+
+ int32 time = atoi (time_str);
+
+ ///- Prevent interpret wrong arg value as 0 secs shutdown time
+ if ((time == 0 && (time_str[0] != '0' || time_str[1] != '\0') || time < 0))
+ return false;
+
+ if (exitcode_str)
+ {
+ int32 exitcode = atoi (exitcode_str);
+
+ // Handle atoi() errors
+ if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
+ return false;
+
+ // Exit code should be in range of 0-125, 126-255 is used
+ // in many shells for their own return codes and code > 255
+ // is not supported in many others
+ if (exitcode < 0 || exitcode > 125)
+ return false;
+
+ sWorld.ShutdownServ (time, SHUTDOWN_MASK_RESTART, exitcode);
+ }
+ else
+ sWorld.ShutdownServ(time, SHUTDOWN_MASK_RESTART, RESTART_EXIT_CODE);
+ return true;
+}
+
+bool ChatHandler::HandleServerIdleRestartCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ char* time_str = strtok ((char*) args, " ");
+ char* exitcode_str = strtok (NULL, "");
+
+ int32 time = atoi (time_str);
+
+ ///- Prevent interpret wrong arg value as 0 secs shutdown time
+ if ((time == 0 && (time_str[0] != '0' || time_str[1] != '\0') || time < 0))
+ return false;
+
+ if (exitcode_str)
+ {
+ int32 exitcode = atoi (exitcode_str);
+
+ // Handle atoi() errors
+ if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
+ return false;
+
+ // Exit code should be in range of 0-125, 126-255 is used
+ // in many shells for their own return codes and code > 255
+ // is not supported in many others
+ if (exitcode < 0 || exitcode > 125)
+ return false;
+
+ sWorld.ShutdownServ (time, SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE, exitcode);
+ }
+ else
+ sWorld.ShutdownServ(time,SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE,RESTART_EXIT_CODE);
+ return true;
+}
+
+bool ChatHandler::HandleServerIdleShutDownCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ char* time_str = strtok ((char*) args, " ");
+ char* exitcode_str = strtok (NULL, "");
+
+ int32 time = atoi (time_str);
+
+ ///- Prevent interpret wrong arg value as 0 secs shutdown time
+ if (time == 0 && (time_str[0] != '0' || time_str[1] != '\0') || time < 0)
+ return false;
+
+ if (exitcode_str)
+ {
+ int32 exitcode = atoi (exitcode_str);
+
+ // Handle atoi() errors
+ if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
+ return false;
+
+ // Exit code should be in range of 0-125, 126-255 is used
+ // in many shells for their own return codes and code > 255
+ // is not supported in many others
+ if (exitcode < 0 || exitcode > 125)
+ return false;
+
+ sWorld.ShutdownServ (time, SHUTDOWN_MASK_IDLE, exitcode);
+ }
+ else
+ sWorld.ShutdownServ(time,SHUTDOWN_MASK_IDLE,SHUTDOWN_EXIT_CODE);
+ return true;
+}
+
+bool ChatHandler::HandleQuestAdd(const char *args)
+{
+ Player* player = getSelectedPlayer();
+ if (!player)
+ {
+ SendSysMessage(LANG_NO_CHAR_SELECTED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // .addquest #entry'
+ // number or [name] Shift-click form |color|Hquest:quest_id:quest_level|h[name]|h|r
+ char* cId = extractKeyFromLink((char*)args,"Hquest");
+ if (!cId)
+ return false;
+
+ uint32 entry = atol(cId);
+
+ Quest const* pQuest = objmgr.GetQuestTemplate(entry);
+
+ if (!pQuest)
+ {
+ PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND,entry);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // check item starting quest (it can work incorrectly if added without item in inventory)
+ for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
+ {
+ ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype>(id);
+ if (!pProto)
+ continue;
+
+ if (pProto->StartQuest == entry)
+ {
+ PSendSysMessage(LANG_COMMAND_QUEST_STARTFROMITEM, entry, pProto->ItemId);
+ SetSentErrorMessage(true);
+ return false;
+ }
+ }
+
+ // ok, normal (creature/GO starting) quest
+ if (player->CanAddQuest(pQuest, true))
+ {
+ player->AddQuest(pQuest, NULL);
+
+ if (player->CanCompleteQuest(entry))
+ player->CompleteQuest(entry);
+ }
+
+ return true;
+}
+
+bool ChatHandler::HandleQuestRemove(const char *args)
+{
+ Player* player = getSelectedPlayer();
+ if (!player)
+ {
+ SendSysMessage(LANG_NO_CHAR_SELECTED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // .removequest #entry'
+ // number or [name] Shift-click form |color|Hquest:quest_id:quest_level|h[name]|h|r
+ char* cId = extractKeyFromLink((char*)args,"Hquest");
+ if (!cId)
+ return false;
+
+ uint32 entry = atol(cId);
+
+ Quest const* pQuest = objmgr.GetQuestTemplate(entry);
+
+ if (!pQuest)
+ {
+ PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // remove all quest entries for 'entry' from quest log
+ for (uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot)
+ {
+ uint32 quest = player->GetQuestSlotQuestId(slot);
+ if (quest == entry)
+ {
+ player->SetQuestSlot(slot,0);
+
+ // we ignore unequippable quest items in this case, its' still be equipped
+ player->TakeQuestSourceItem(quest, false);
+ }
+ }
+
+ // set quest status to not started (will updated in DB at next save)
+ player->SetQuestStatus(entry, QUEST_STATUS_NONE);
+
+ // reset rewarded for restart repeatable quest
+ player->getQuestStatusMap()[entry].m_rewarded = false;
+
+ SendSysMessage(LANG_COMMAND_QUEST_REMOVED);
+ return true;
+}
+
+bool ChatHandler::HandleQuestComplete(const char *args)
+{
+ Player* player = getSelectedPlayer();
+ if (!player)
+ {
+ SendSysMessage(LANG_NO_CHAR_SELECTED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // .quest complete #entry
+ // number or [name] Shift-click form |color|Hquest:quest_id:quest_level|h[name]|h|r
+ char* cId = extractKeyFromLink((char*)args,"Hquest");
+ if (!cId)
+ return false;
+
+ uint32 entry = atol(cId);
+
+ Quest const* pQuest = objmgr.GetQuestTemplate(entry);
+
+ // If player doesn't have the quest
+ if (!pQuest || player->GetQuestStatus(entry) == QUEST_STATUS_NONE)
+ {
+ PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // Add quest items for quests that require items
+ for (uint8 x = 0; x < QUEST_ITEM_OBJECTIVES_COUNT; ++x)
+ {
+ uint32 id = pQuest->ReqItemId[x];
+ uint32 count = pQuest->ReqItemCount[x];
+ if (!id || !count)
+ continue;
+
+ uint32 curItemCount = player->GetItemCount(id,true);
+
+ ItemPosCountVec dest;
+ uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, id, count-curItemCount);
+ if (msg == EQUIP_ERR_OK)
+ {
+ Item* item = player->StoreNewItem(dest, id, true);
+ player->SendNewItem(item,count-curItemCount,true,false);
+ }
+ }
+
+ // All creature/GO slain/casted (not required, but otherwise it will display "Creature slain 0/10")
+ for (uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
+ {
+ uint32 creature = pQuest->ReqCreatureOrGOId[i];
+ uint32 creaturecount = pQuest->ReqCreatureOrGOCount[i];
+
+ if (uint32 spell_id = pQuest->ReqSpell[i])
+ {
+ for (uint16 z = 0; z < creaturecount; ++z)
+ player->CastedCreatureOrGO(creature,0,spell_id);
+ }
+ else if (creature > 0)
+ {
+ if (CreatureInfo const* cInfo = objmgr.GetCreatureTemplate(creature))
+ for (uint16 z = 0; z < creaturecount; ++z)
+ player->KilledMonster(cInfo,0);
+ }
+ else if (creature < 0)
+ {
+ for (uint16 z = 0; z < creaturecount; ++z)
+ player->CastedCreatureOrGO(creature,0,0);
+ }
+ }
+
+ // If the quest requires reputation to complete
+ if (uint32 repFaction = pQuest->GetRepObjectiveFaction())
+ {
+ uint32 repValue = pQuest->GetRepObjectiveValue();
+ uint32 curRep = player->GetReputationMgr().GetReputation(repFaction);
+ if (curRep < repValue)
+ if (FactionEntry const *factionEntry = sFactionStore.LookupEntry(repFaction))
+ player->GetReputationMgr().SetReputation(factionEntry,repValue);
+ }
+
+ // If the quest requires a SECOND reputation to complete
+ if (uint32 repFaction = pQuest->GetRepObjectiveFaction2())
+ {
+ uint32 repValue2 = pQuest->GetRepObjectiveValue2();
+ uint32 curRep = player->GetReputationMgr().GetReputation(repFaction);
+ if (curRep < repValue2)
+ if (FactionEntry const *factionEntry = sFactionStore.LookupEntry(repFaction))
+ player->GetReputationMgr().SetReputation(factionEntry,repValue2);
+ }
+
+ // If the quest requires money
+ int32 ReqOrRewMoney = pQuest->GetRewOrReqMoney();
+ if (ReqOrRewMoney < 0)
+ player->ModifyMoney(-ReqOrRewMoney);
+
+ player->CompleteQuest(entry);
+ return true;
+}
+
+bool ChatHandler::HandleBanAccountCommand(const char *args)
+{
+ return HandleBanHelper(BAN_ACCOUNT,args);
+}
+
+bool ChatHandler::HandleBanCharacterCommand(const char *args)
+{
+ return HandleBanHelper(BAN_CHARACTER,args);
+}
+
+bool ChatHandler::HandleBanIPCommand(const char *args)
+{
+ return HandleBanHelper(BAN_IP,args);
+}
+
+bool ChatHandler::HandleBanHelper(BanMode mode, const char *args)
+{
+ if (!*args)
+ return false;
+
+ char* cnameOrIP = strtok ((char*)args, " ");
+ if (!cnameOrIP)
+ return false;
+
+ std::string nameOrIP = cnameOrIP;
+
+ char* duration = strtok (NULL," ");
+ if (!duration || !atoi(duration))
+ return false;
+
+ char* reason = strtok (NULL,"");
+ if (!reason)
+ return false;
+
+ switch(mode)
+ {
+ case BAN_ACCOUNT:
+ if (!AccountMgr::normalizeString(nameOrIP))
+ {
+ PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,nameOrIP.c_str());
+ SetSentErrorMessage(true);
+ return false;
+ }
+ break;
+ case BAN_CHARACTER:
+ if (!normalizePlayerName(nameOrIP))
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+ break;
+ case BAN_IP:
+ if (!IsIPAddress(nameOrIP.c_str()))
+ return false;
+ break;
+ }
+
+ switch(sWorld.BanAccount(mode, nameOrIP, duration, reason,m_session ? m_session->GetPlayerName() : ""))
+ {
+ case BAN_SUCCESS:
+ if (atoi(duration)>0)
+ PSendSysMessage(LANG_BAN_YOUBANNED,nameOrIP.c_str(),secsToTimeString(TimeStringToSecs(duration),true).c_str(),reason);
+ else
+ PSendSysMessage(LANG_BAN_YOUPERMBANNED,nameOrIP.c_str(),reason);
+ break;
+ case BAN_SYNTAX_ERROR:
+ return false;
+ case BAN_NOTFOUND:
+ switch(mode)
+ {
+ default:
+ PSendSysMessage(LANG_BAN_NOTFOUND,"account",nameOrIP.c_str());
+ break;
+ case BAN_CHARACTER:
+ PSendSysMessage(LANG_BAN_NOTFOUND,"character",nameOrIP.c_str());
+ break;
+ case BAN_IP:
+ PSendSysMessage(LANG_BAN_NOTFOUND,"ip",nameOrIP.c_str());
+ break;
+ }
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ return true;
+}
+
+bool ChatHandler::HandleUnBanAccountCommand(const char *args)
+{
+ return HandleUnBanHelper(BAN_ACCOUNT,args);
+}
+
+bool ChatHandler::HandleUnBanCharacterCommand(const char *args)
+{
+ return HandleUnBanHelper(BAN_CHARACTER,args);
+}
+
+bool ChatHandler::HandleUnBanIPCommand(const char *args)
+{
+ return HandleUnBanHelper(BAN_IP,args);
+}
+
+bool ChatHandler::HandleUnBanHelper(BanMode mode, const char *args)
+{
+ if (!*args)
+ return false;
+
+ char* cnameOrIP = strtok ((char*)args, " ");
+ if (!cnameOrIP)
+ return false;
+
+ std::string nameOrIP = cnameOrIP;
+
+ switch(mode)
+ {
+ case BAN_ACCOUNT:
+ if (!AccountMgr::normalizeString(nameOrIP))
+ {
+ PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,nameOrIP.c_str());
+ SetSentErrorMessage(true);
+ return false;
+ }
+ break;
+ case BAN_CHARACTER:
+ if (!normalizePlayerName(nameOrIP))
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+ break;
+ case BAN_IP:
+ if (!IsIPAddress(nameOrIP.c_str()))
+ return false;
+ break;
+ }
+
+ if (sWorld.RemoveBanAccount(mode,nameOrIP))
+ PSendSysMessage(LANG_UNBAN_UNBANNED,nameOrIP.c_str());
+ else
+ PSendSysMessage(LANG_UNBAN_ERROR,nameOrIP.c_str());
+
+ return true;
+}
+
+bool ChatHandler::HandleBanInfoAccountCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ char* cname = strtok((char*)args, "");
+ if (!cname)
+ return false;
+
+ std::string account_name = cname;
+ if (!AccountMgr::normalizeString(account_name))
+ {
+ PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ uint32 accountid = accmgr.GetId(account_name);
+ if (!accountid)
+ {
+ PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
+ return true;
+ }
+
+ return HandleBanInfoHelper(accountid,account_name.c_str());
+}
+
+bool ChatHandler::HandleBanInfoCharacterCommand(const char *args)
+{
+ Player* target;
+ uint64 target_guid;
+ if (!extractPlayerTarget((char*)args,&target,&target_guid))
+ return false;
+
+ uint32 accountid = target ? target->GetSession()->GetAccountId() : objmgr.GetPlayerAccountIdByGUID(target_guid);
+
+ std::string accountname;
+ if (!accmgr.GetName(accountid,accountname))
+ {
+ PSendSysMessage(LANG_BANINFO_NOCHARACTER);
+ return true;
+ }
+
+ return HandleBanInfoHelper(accountid,accountname.c_str());
+}
+
+bool ChatHandler::HandleBanInfoHelper(uint32 accountid, char const* accountname)
+{
+ QueryResult_AutoPtr result = LoginDatabase.PQuery("SELECT FROM_UNIXTIME(bandate), unbandate-bandate, active, unbandate,banreason,bannedby FROM account_banned WHERE id = '%u' ORDER BY bandate ASC",accountid);
+ if (!result)
+ {
+ PSendSysMessage(LANG_BANINFO_NOACCOUNTBAN, accountname);
+ return true;
+ }
+
+ PSendSysMessage(LANG_BANINFO_BANHISTORY,accountname);
+ do
+ {
+ Field* fields = result->Fetch();
+
+ time_t unbandate = time_t(fields[3].GetUInt64());
+ bool active = false;
+ if (fields[2].GetBool() && (fields[1].GetUInt64() == (uint64)0 ||unbandate >= time(NULL)))
+ active = true;
+ bool permanent = (fields[1].GetUInt64() == (uint64)0);
+ std::string bantime = permanent?GetTrinityString(LANG_BANINFO_INFINITE):secsToTimeString(fields[1].GetUInt64(), true);
+ PSendSysMessage(LANG_BANINFO_HISTORYENTRY,
+ fields[0].GetString(), bantime.c_str(), active ? GetTrinityString(LANG_BANINFO_YES):GetTrinityString(LANG_BANINFO_NO), fields[4].GetString(), fields[5].GetString());
+ }while (result->NextRow());
+
+ return true;
+}
+
+bool ChatHandler::HandleBanInfoIPCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ char* cIP = strtok ((char*)args, "");
+ if (!cIP)
+ return false;
+
+ if (!IsIPAddress(cIP))
+ return false;
+
+ std::string IP = cIP;
+
+ LoginDatabase.escape_string(IP);
+ QueryResult_AutoPtr result = LoginDatabase.PQuery("SELECT ip, FROM_UNIXTIME(bandate), FROM_UNIXTIME(unbandate), unbandate-UNIX_TIMESTAMP(), banreason,bannedby,unbandate-bandate FROM ip_banned WHERE ip = '%s'",IP.c_str());
+ if (!result)
+ {
+ PSendSysMessage(LANG_BANINFO_NOIP);
+ return true;
+ }
+
+ Field *fields = result->Fetch();
+ bool permanent = !fields[6].GetUInt64();
+ PSendSysMessage(LANG_BANINFO_IPENTRY,
+ fields[0].GetString(), fields[1].GetString(), permanent ? GetTrinityString(LANG_BANINFO_NEVER):fields[2].GetString(),
+ permanent ? GetTrinityString(LANG_BANINFO_INFINITE):secsToTimeString(fields[3].GetUInt64(), true).c_str(), fields[4].GetString(), fields[5].GetString());
+
+ return true;
+}
+
+bool ChatHandler::HandleBanListCharacterCommand(const char *args)
+{
+ LoginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate <= UNIX_TIMESTAMP() AND unbandate<>bandate");
+
+ char* cFilter = strtok ((char*)args, " ");
+ if (!cFilter)
+ return false;
+
+ std::string filter = cFilter;
+ LoginDatabase.escape_string(filter);
+ QueryResult_AutoPtr result = CharacterDatabase.PQuery("SELECT account FROM characters WHERE name "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'"),filter.c_str());
+ if (!result)
+ {
+ PSendSysMessage(LANG_BANLIST_NOCHARACTER);
+ return true;
+ }
+
+ return HandleBanListHelper(result);
+}
+
+bool ChatHandler::HandleBanListAccountCommand(const char *args)
+{
+ LoginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate <= UNIX_TIMESTAMP() AND unbandate<>bandate");
+
+ char* cFilter = strtok((char*)args, " ");
+ std::string filter = cFilter ? cFilter : "";
+ LoginDatabase.escape_string(filter);
+
+ QueryResult_AutoPtr result;
+
+ if (filter.empty())
+ {
+ result = LoginDatabase.Query("SELECT account.id, username FROM account, account_banned"
+ " WHERE account.id = account_banned.id AND active = 1 GROUP BY account.id");
+ }
+ else
+ {
+ result = LoginDatabase.PQuery("SELECT account.id, username FROM account, account_banned"
+ " WHERE account.id = account_banned.id AND active = 1 AND username "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")" GROUP BY account.id",
+ filter.c_str());
+ }
+
+ if (!result)
+ {
+ PSendSysMessage(LANG_BANLIST_NOACCOUNT);
+ return true;
+ }
+
+ return HandleBanListHelper(result);
+}
+
+bool ChatHandler::HandleBanListHelper(QueryResult_AutoPtr result)
+{
+ PSendSysMessage(LANG_BANLIST_MATCHINGACCOUNT);
+
+ // Chat short output
+ if (m_session)
+ {
+ do
+ {
+ Field* fields = result->Fetch();
+ uint32 accountid = fields[0].GetUInt32();
+
+ QueryResult_AutoPtr banresult = LoginDatabase.PQuery("SELECT account.username FROM account,account_banned WHERE account_banned.id='%u' AND account_banned.id=account.id",accountid);
+ if (banresult)
+ {
+ Field* fields2 = banresult->Fetch();
+ PSendSysMessage("%s",fields2[0].GetString());
+ }
+ } while (result->NextRow());
+ }
+ // Console wide output
+ else
+ {
+ SendSysMessage(LANG_BANLIST_ACCOUNTS);
+ SendSysMessage(" ===============================================================================");
+ SendSysMessage(LANG_BANLIST_ACCOUNTS_HEADER);
+ do
+ {
+ SendSysMessage("-------------------------------------------------------------------------------");
+ Field *fields = result->Fetch();
+ uint32 account_id = fields[0].GetUInt32 ();
+
+ std::string account_name;
+
+ // "account" case, name can be get in same query
+ if (result->GetFieldCount() > 1)
+ account_name = fields[1].GetCppString();
+ // "character" case, name need extract from another DB
+ else
+ accmgr.GetName (account_id,account_name);
+
+ // No SQL injection. id is uint32.
+ QueryResult_AutoPtr banInfo = LoginDatabase.PQuery("SELECT bandate,unbandate,bannedby,banreason FROM account_banned WHERE id = %u ORDER BY unbandate", account_id);
+ if (banInfo)
+ {
+ Field *fields2 = banInfo->Fetch();
+ do
+ {
+ time_t t_ban = fields2[0].GetUInt64();
+ tm* aTm_ban = localtime(&t_ban);
+
+ if (fields2[0].GetUInt64() == fields2[1].GetUInt64())
+ {
+ PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|",
+ account_name.c_str(),aTm_ban->tm_year%100, aTm_ban->tm_mon+1, aTm_ban->tm_mday, aTm_ban->tm_hour, aTm_ban->tm_min,
+ fields2[2].GetString(),fields2[3].GetString());
+ }
+ else
+ {
+ time_t t_unban = fields2[1].GetUInt64();
+ tm* aTm_unban = localtime(&t_unban);
+ PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|",
+ account_name.c_str(),aTm_ban->tm_year%100, aTm_ban->tm_mon+1, aTm_ban->tm_mday, aTm_ban->tm_hour, aTm_ban->tm_min,
+ aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min,
+ fields2[2].GetString(),fields2[3].GetString());
+ }
+ }while (banInfo->NextRow());
+ }
+ }while (result->NextRow());
+ SendSysMessage(" ===============================================================================");
+ }
+ return true;
+}
+
+bool ChatHandler::HandleBanListIPCommand(const char *args)
+{
+ LoginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate <= UNIX_TIMESTAMP() AND unbandate<>bandate");
+
+ char* cFilter = strtok((char*)args, " ");
+ std::string filter = cFilter ? cFilter : "";
+ LoginDatabase.escape_string(filter);
+
+ QueryResult_AutoPtr result;
+
+ if (filter.empty())
+ {
+ result = LoginDatabase.Query ("SELECT ip,bandate,unbandate,bannedby,banreason FROM ip_banned"
+ " WHERE (bandate=unbandate OR unbandate>UNIX_TIMESTAMP())"
+ " ORDER BY unbandate");
+ }
+ else
+ {
+ result = LoginDatabase.PQuery("SELECT ip,bandate,unbandate,bannedby,banreason FROM ip_banned"
+ " WHERE (bandate=unbandate OR unbandate>UNIX_TIMESTAMP()) AND ip "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")
+ " ORDER BY unbandate",filter.c_str());
+ }
+
+ if (!result)
+ {
+ PSendSysMessage(LANG_BANLIST_NOIP);
+ return true;
+ }
+
+ PSendSysMessage(LANG_BANLIST_MATCHINGIP);
+ // Chat short output
+ if (m_session)
+ {
+ do
+ {
+ Field* fields = result->Fetch();
+ PSendSysMessage("%s",fields[0].GetString());
+ } while (result->NextRow());
+ }
+ // Console wide output
+ else
+ {
+ SendSysMessage(LANG_BANLIST_IPS);
+ SendSysMessage(" ===============================================================================");
+ SendSysMessage(LANG_BANLIST_IPS_HEADER);
+ do
+ {
+ SendSysMessage("-------------------------------------------------------------------------------");
+ Field *fields = result->Fetch();
+ time_t t_ban = fields[1].GetUInt64();
+ tm* aTm_ban = localtime(&t_ban);
+ if (fields[1].GetUInt64() == fields[2].GetUInt64())
+ {
+ PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|",
+ fields[0].GetString(), aTm_ban->tm_year%100, aTm_ban->tm_mon+1, aTm_ban->tm_mday, aTm_ban->tm_hour, aTm_ban->tm_min,
+ fields[3].GetString(), fields[4].GetString());
+ }
+ else
+ {
+ time_t t_unban = fields[2].GetUInt64();
+ tm* aTm_unban = localtime(&t_unban);
+ PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|",
+ fields[0].GetString(), aTm_ban->tm_year%100, aTm_ban->tm_mon+1, aTm_ban->tm_mday, aTm_ban->tm_hour, aTm_ban->tm_min,
+ aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min,
+ fields[3].GetString(), fields[4].GetString());
+ }
+ }while (result->NextRow());
+ SendSysMessage(" ===============================================================================");
+ }
+
+ return true;
+}
+
+bool ChatHandler::HandleRespawnCommand(const char* /*args*/)
+{
+ Player* pl = m_session->GetPlayer();
+
+ // accept only explicitly selected target (not implicitly self targeting case)
+ Unit* target = getSelectedUnit();
+ if (pl->GetSelection() && target)
+ {
+ if (target->GetTypeId() != TYPEID_UNIT || target->isPet())
+ {
+ SendSysMessage(LANG_SELECT_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (target->isDead())
+ target->ToCreature()->Respawn();
+ return true;
+ }
+
+ CellPair p(Trinity::ComputeCellPair(pl->GetPositionX(), pl->GetPositionY()));
+ Cell cell(p);
+ cell.data.Part.reserved = ALL_DISTRICT;
+ cell.SetNoCreate();
+
+ Trinity::RespawnDo u_do;
+ Trinity::WorldObjectWorker<Trinity::RespawnDo> worker(pl,u_do);
+
+ TypeContainerVisitor<Trinity::WorldObjectWorker<Trinity::RespawnDo>, GridTypeMapContainer > obj_worker(worker);
+ cell.Visit(p, obj_worker, *pl->GetMap());
+
+ return true;
+}
+
+bool ChatHandler::HandleGMFlyCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ Player *target = getSelectedPlayer();
+ if (!target)
+ target = m_session->GetPlayer();
+
+ WorldPacket data(12);
+ if (strncmp(args, "on", 3) == 0)
+ data.SetOpcode(SMSG_MOVE_SET_CAN_FLY);
+ else if (strncmp(args, "off", 4) == 0)
+ data.SetOpcode(SMSG_MOVE_UNSET_CAN_FLY);
+ else
+ {
+ SendSysMessage(LANG_USE_BOL);
+ return false;
+ }
+ data.append(target->GetPackGUID());
+ data << uint32(0); // unknown
+ target->SendMessageToSet(&data, true);
+ PSendSysMessage(LANG_COMMAND_FLYMODE_STATUS, GetNameLink(target).c_str(), args);
+ return true;
+}
+
+bool ChatHandler::HandlePDumpLoadCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ char * file = strtok((char*)args, " ");
+ if (!file)
+ return false;
+
+ char * account = strtok(NULL, " ");
+ if (!account)
+ return false;
+
+ std::string account_name = account;
+ if (!AccountMgr::normalizeString(account_name))
+ {
+ PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ uint32 account_id = accmgr.GetId(account_name);
+ if (!account_id)
+ {
+ account_id = atoi(account); // use original string
+ if (!account_id)
+ {
+ PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
+ SetSentErrorMessage(true);
+ return false;
+ }
+ }
+
+ if (!accmgr.GetName(account_id,account_name))
+ {
+ PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ char* guid_str = NULL;
+ char* name_str = strtok(NULL, " ");
+
+ std::string name;
+ if (name_str)
+ {
+ name = name_str;
+ // normalize the name if specified and check if it exists
+ if (!normalizePlayerName(name))
+ {
+ PSendSysMessage(LANG_INVALID_CHARACTER_NAME);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (ObjectMgr::CheckPlayerName(name,true) != CHAR_NAME_SUCCESS)
+ {
+ PSendSysMessage(LANG_INVALID_CHARACTER_NAME);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ guid_str = strtok(NULL, " ");
+ }
+
+ uint32 guid = 0;
+
+ if (guid_str)
+ {
+ guid = atoi(guid_str);
+ if (!guid)
+ {
+ PSendSysMessage(LANG_INVALID_CHARACTER_GUID);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (objmgr.GetPlayerAccountIdByGUID(guid))
+ {
+ PSendSysMessage(LANG_CHARACTER_GUID_IN_USE,guid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+ }
+
+ switch(PlayerDumpReader().LoadDump(file, account_id, name, guid))
+ {
+ case DUMP_SUCCESS:
+ PSendSysMessage(LANG_COMMAND_IMPORT_SUCCESS);
+ break;
+ case DUMP_FILE_OPEN_ERROR:
+ PSendSysMessage(LANG_FILE_OPEN_FAIL,file);
+ SetSentErrorMessage(true);
+ return false;
+ case DUMP_FILE_BROKEN:
+ PSendSysMessage(LANG_DUMP_BROKEN,file);
+ SetSentErrorMessage(true);
+ return false;
+ case DUMP_TOO_MANY_CHARS:
+ PSendSysMessage(LANG_ACCOUNT_CHARACTER_LIST_FULL,account_name.c_str(),account_id);
+ SetSentErrorMessage(true);
+ return false;
+ default:
+ PSendSysMessage(LANG_COMMAND_IMPORT_FAILED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ return true;
+}
+
+bool ChatHandler::HandlePDumpWriteCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ char* file = strtok((char*)args, " ");
+ char* p2 = strtok(NULL, " ");
+
+ if (!file || !p2)
+ return false;
+
+ uint32 guid;
+ // character name can't start from number
+ if (isNumeric(p2[0]))
+ guid = atoi(p2);
+ else
+ {
+ std::string name = extractPlayerNameFromLink(p2);
+ if (name.empty())
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ guid = objmgr.GetPlayerGUIDByName(name);
+ }
+
+ if (!objmgr.GetPlayerAccountIdByGUID(guid))
+ {
+ PSendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ switch(PlayerDumpWriter().WriteDump(file, guid))
+ {
+ case DUMP_SUCCESS:
+ PSendSysMessage(LANG_COMMAND_EXPORT_SUCCESS);
+ break;
+ case DUMP_FILE_OPEN_ERROR:
+ PSendSysMessage(LANG_FILE_OPEN_FAIL,file);
+ SetSentErrorMessage(true);
+ return false;
+ default:
+ PSendSysMessage(LANG_COMMAND_EXPORT_FAILED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ return true;
+}
+
+bool ChatHandler::HandleMovegensCommand(const char* /*args*/)
+{
+ Unit* unit = getSelectedUnit();
+ if (!unit)
+ {
+ SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ PSendSysMessage(LANG_MOVEGENS_LIST,(unit->GetTypeId() == TYPEID_PLAYER ? "Player" : "Creature"),unit->GetGUIDLow());
+
+ MotionMaster* mm = unit->GetMotionMaster();
+ for (uint8 i = 0; i < MAX_MOTION_SLOT; ++i)
+ {
+ MovementGenerator* mg = mm->GetMotionSlot(i);
+ if (!mg)
+ {
+ SendSysMessage("Empty");
+ continue;
+ }
+ switch(mg->GetMovementGeneratorType())
+ {
+ case IDLE_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_IDLE); break;
+ case RANDOM_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_RANDOM); break;
+ case WAYPOINT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_WAYPOINT); break;
+ case ANIMAL_RANDOM_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_ANIMAL_RANDOM); break;
+ case CONFUSED_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_CONFUSED); break;
+ case TARGETED_MOTION_TYPE:
+ {
+ if (unit->GetTypeId() == TYPEID_PLAYER)
+ {
+ TargetedMovementGenerator<Player> const* mgen = static_cast<TargetedMovementGenerator<Player> const*>(mg);
+ Unit* target = mgen->GetTarget();
+ if (target)
+ PSendSysMessage(LANG_MOVEGENS_TARGETED_PLAYER,target->GetName(),target->GetGUIDLow());
+ else
+ SendSysMessage(LANG_MOVEGENS_TARGETED_NULL);
+ }
+ else
+ {
+ TargetedMovementGenerator<Creature> const* mgen = static_cast<TargetedMovementGenerator<Creature> const*>(mg);
+ Unit* target = mgen->GetTarget();
+ if (target)
+ PSendSysMessage(LANG_MOVEGENS_TARGETED_CREATURE,target->GetName(),target->GetGUIDLow());
+ else
+ SendSysMessage(LANG_MOVEGENS_TARGETED_NULL);
+ }
+ break;
+ }
+ case HOME_MOTION_TYPE:
+ if (unit->GetTypeId() == TYPEID_UNIT)
+ {
+ float x,y,z;
+ mg->GetDestination(x,y,z);
+ PSendSysMessage(LANG_MOVEGENS_HOME_CREATURE,x,y,z);
+ }
+ else
+ SendSysMessage(LANG_MOVEGENS_HOME_PLAYER);
+ break;
+ case FLIGHT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_FLIGHT); break;
+ case POINT_MOTION_TYPE:
+ {
+ float x,y,z;
+ mg->GetDestination(x,y,z);
+ PSendSysMessage(LANG_MOVEGENS_POINT,x,y,z);
+ break;
+ }
+ case FLEEING_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_FEAR); break;
+ case DISTRACT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_DISTRACT); break;
+ default:
+ PSendSysMessage(LANG_MOVEGENS_UNKNOWN,mg->GetMovementGeneratorType());
+ break;
+ }
+ }
+ return true;
+}
+
+bool ChatHandler::HandleServerPLimitCommand(const char *args)
+{
+ if (*args)
+ {
+ char* param = strtok((char*)args, " ");
+ if (!param)
+ return false;
+
+ int l = strlen(param);
+
+ if (strncmp(param,"player",l) == 0)
+ sWorld.SetPlayerSecurityLimit(SEC_PLAYER);
+ else if (strncmp(param,"moderator",l) == 0)
+ sWorld.SetPlayerSecurityLimit(SEC_MODERATOR);
+ else if (strncmp(param,"gamemaster",l) == 0)
+ sWorld.SetPlayerSecurityLimit(SEC_GAMEMASTER);
+ else if (strncmp(param,"administrator",l) == 0)
+ sWorld.SetPlayerSecurityLimit(SEC_ADMINISTRATOR);
+ else if (strncmp(param,"reset",l) == 0)
+ sWorld.SetPlayerLimit(sConfig.GetIntDefault("PlayerLimit", DEFAULT_PLAYER_LIMIT));
+ else
+ {
+ int val = atoi(param);
+ if (val < 0)
+ sWorld.SetPlayerSecurityLimit(AccountTypes(uint32(-val)));
+ else
+ sWorld.SetPlayerLimit(val);
+ }
+
+ // kick all low security level players
+ if (sWorld.GetPlayerSecurityLimit() > SEC_PLAYER)
+ sWorld.KickAllLess(sWorld.GetPlayerSecurityLimit());
+ }
+
+ uint32 pLimit = sWorld.GetPlayerAmountLimit();
+ AccountTypes allowedAccountType = sWorld.GetPlayerSecurityLimit();
+ char const* secName = "";
+ switch(allowedAccountType)
+ {
+ case SEC_PLAYER: secName = "Player"; break;
+ case SEC_MODERATOR: secName = "Moderator"; break;
+ case SEC_GAMEMASTER: secName = "Gamemaster"; break;
+ case SEC_ADMINISTRATOR: secName = "Administrator"; break;
+ default: secName = "<unknown>"; break;
+ }
+
+ PSendSysMessage("Player limits: amount %u, min. security level %s.",pLimit,secName);
+
+ return true;
+}
+
+bool ChatHandler::HandleCastCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ Unit* target = getSelectedUnit();
+
+ if (!target)
+ {
+ SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
+ uint32 spell = extractSpellIdFromLink((char*)args);
+ if (!spell)
+ return false;
+
+ SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
+ if (!spellInfo)
+ {
+ PSendSysMessage(LANG_COMMAND_NOSPELLFOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
+ {
+ PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ char* trig_str = strtok(NULL, " ");
+ if (trig_str)
+ {
+ int l = strlen(trig_str);
+ if (strncmp(trig_str,"triggered",l) != 0)
+ return false;
+ }
+
+ bool triggered = (trig_str != NULL);
+
+ m_session->GetPlayer()->CastSpell(target,spell,triggered);
+
+ return true;
+}
+
+bool ChatHandler::HandleCastBackCommand(const char *args)
+{
+ Creature* caster = getSelectedCreature();
+
+ if (!caster)
+ {
+ SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
+ // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
+ uint32 spell = extractSpellIdFromLink((char*)args);
+ if (!spell || !sSpellStore.LookupEntry(spell))
+ {
+ PSendSysMessage(LANG_COMMAND_NOSPELLFOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ char* trig_str = strtok(NULL, " ");
+ if (trig_str)
+ {
+ int l = strlen(trig_str);
+ if (strncmp(trig_str,"triggered",l) != 0)
+ return false;
+ }
+
+ bool triggered = (trig_str != NULL);
+
+ caster->SetFacingToObject(m_session->GetPlayer());
+
+ caster->CastSpell(m_session->GetPlayer(),spell,triggered);
+
+ return true;
+}
+
+bool ChatHandler::HandleCastDistCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
+ uint32 spell = extractSpellIdFromLink((char*)args);
+ if (!spell)
+ return false;
+
+ SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
+ if (!spellInfo)
+ {
+ PSendSysMessage(LANG_COMMAND_NOSPELLFOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
+ {
+ PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ char *distStr = strtok(NULL, " ");
+
+ float dist = 0;
+
+ if (distStr)
+ sscanf(distStr, "%f", &dist);
+
+ char* trig_str = strtok(NULL, " ");
+ if (trig_str)
+ {
+ int l = strlen(trig_str);
+ if (strncmp(trig_str,"triggered",l) != 0)
+ return false;
+ }
+
+ bool triggered = (trig_str != NULL);
+
+ float x,y,z;
+ m_session->GetPlayer()->GetClosePoint(x,y,z,dist);
+
+ m_session->GetPlayer()->CastSpell(x,y,z,spell,triggered);
+ return true;
+}
+
+bool ChatHandler::HandleCastTargetCommand(const char *args)
+{
+ Creature* caster = getSelectedCreature();
+
+ if (!caster)
+ {
+ SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (!caster->getVictim())
+ {
+ SendSysMessage(LANG_SELECTED_TARGET_NOT_HAVE_VICTIM);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
+ uint32 spell = extractSpellIdFromLink((char*)args);
+ if (!spell || !sSpellStore.LookupEntry(spell))
+ {
+ PSendSysMessage(LANG_COMMAND_NOSPELLFOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ char* trig_str = strtok(NULL, " ");
+ if (trig_str)
+ {
+ int l = strlen(trig_str);
+ if (strncmp(trig_str,"triggered",l) != 0)
+ return false;
+ }
+
+ bool triggered = (trig_str != NULL);
+
+ caster->SetFacingToObject(m_session->GetPlayer());
+
+ caster->CastSpell(caster->getVictim(),spell,triggered);
+
+ return true;
+}
+
+/*
+ComeToMe command REQUIRED for 3rd party scripting library to have access to PointMovementGenerator
+Without this function 3rd party scripting library will get linking errors (unresolved external)
+when attempting to use the PointMovementGenerator
+*/
+bool ChatHandler::HandleComeToMeCommand(const char *args)
+{
+ char* newFlagStr = strtok((char*)args, " ");
+
+ if (!newFlagStr)
+ return false;
+
+ uint32 newFlags = (uint32)strtoul(newFlagStr, NULL, 0);
+
+ Creature* caster = getSelectedCreature();
+ if (!caster)
+ {
+ m_session->GetPlayer()->SetUnitMovementFlags(newFlags);
+ SendSysMessage(LANG_SELECT_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ caster->SetUnitMovementFlags(newFlags);
+
+ Player* pl = m_session->GetPlayer();
+
+ caster->GetMotionMaster()->MovePoint(0, pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ());
+ return true;
+}
+
+bool ChatHandler::HandleCastSelfCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ Unit* target = getSelectedUnit();
+
+ if (!target)
+ {
+ SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
+ uint32 spell = extractSpellIdFromLink((char*)args);
+ if (!spell)
+ return false;
+
+ SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
+ if (!spellInfo)
+ return false;
+
+ if (!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
+ {
+ PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ target->CastSpell(target,spell,false);
+
+ return true;
+}
+
+std::string GetTimeString(uint32 time)
+{
+ uint16 days = time / DAY, hours = (time % DAY) / HOUR, minute = (time % HOUR) / MINUTE;
+ std::ostringstream ss;
+ if (days) ss << days << "d ";
+ if (hours) ss << hours << "h ";
+ ss << minute << "m";
+ return ss.str();
+}
+
+bool ChatHandler::HandleInstanceListBindsCommand(const char* /*args*/)
+{
+ Player* player = getSelectedPlayer();
+ if (!player) player = m_session->GetPlayer();
+ uint32 counter = 0;
+ for (uint8 i = 0; i < MAX_DIFFICULTY; ++i)
+ {
+ Player::BoundInstancesMap &binds = player->GetBoundInstances(Difficulty(i));
+ for (Player::BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end(); ++itr)
+ {
+ InstanceSave *save = itr->second.save;
+ std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
+ PSendSysMessage("map: %d inst: %d perm: %s diff: %d canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str());
+ counter++;
+ }
+ }
+ PSendSysMessage("player binds: %d", counter);
+ counter = 0;
+ Group *group = player->GetGroup();
+ if (group)
+ {
+ for (uint8 i = 0; i < MAX_DIFFICULTY; ++i)
+ {
+ Group::BoundInstancesMap &binds = group->GetBoundInstances(Difficulty(i));
+ for (Group::BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end(); ++itr)
+ {
+ InstanceSave *save = itr->second.save;
+ std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
+ PSendSysMessage("map: %d inst: %d perm: %s diff: %d canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str()); counter++;
+ }
+ }
+ }
+ PSendSysMessage("group binds: %d", counter);
+
+ return true;
+}
+
+bool ChatHandler::HandleInstanceUnbindCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ std::string cmd = args;
+ if (cmd == "all")
+ {
+ Player* player = getSelectedPlayer();
+ if (!player) player = m_session->GetPlayer();
+ uint32 counter = 0;
+ for (uint8 i = 0; i < MAX_DIFFICULTY; ++i)
+ {
+ Player::BoundInstancesMap &binds = player->GetBoundInstances(Difficulty(i));
+ for (Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end();)
+ {
+ if (itr->first != player->GetMapId())
+ {
+ InstanceSave *save = itr->second.save;
+ std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
+ PSendSysMessage("unbinding map: %d inst: %d perm: %s diff: %d canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str());
+ player->UnbindInstance(itr, Difficulty(i));
+ counter++;
+ }
+ else
+ ++itr;
+ }
+ }
+ PSendSysMessage("instances unbound: %d", counter);
+ }
+ return true;
+}
+
+bool ChatHandler::HandleInstanceStatsCommand(const char* /*args*/)
+{
+ PSendSysMessage("instances loaded: %d", MapManager::Instance().GetNumInstances());
+ PSendSysMessage("players in instances: %d", MapManager::Instance().GetNumPlayersInInstances());
+ PSendSysMessage("instance saves: %d", sInstanceSaveManager.GetNumInstanceSaves());
+ PSendSysMessage("players bound: %d", sInstanceSaveManager.GetNumBoundPlayersTotal());
+ PSendSysMessage("groups bound: %d", sInstanceSaveManager.GetNumBoundGroupsTotal());
+ return true;
+}
+
+bool ChatHandler::HandleInstanceSaveDataCommand(const char * /*args*/)
+{
+ Player* pl = m_session->GetPlayer();
+
+ Map* map = pl->GetMap();
+ if (!map->IsDungeon())
+ {
+ PSendSysMessage("Map is not a dungeon.");
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (!((InstanceMap*)map)->GetInstanceData())
+ {
+ PSendSysMessage("Map has no instance data.");
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ ((InstanceMap*)map)->GetInstanceData()->SaveToDB();
+ return true;
+}
+
+bool ChatHandler::HandleInstanceOpenCommand(const char *args)
+{
+ return HandleInstanceOpenCloseCommand(args,true);
+}
+
+bool ChatHandler::HandleInstanceCloseCommand(const char *args)
+{
+ return HandleInstanceOpenCloseCommand(args,false);
+}
+
+bool ChatHandler::HandleInstanceOpenCloseCommand(const char *args,bool open)
+{
+ char *mapIdStr;
+ char *instanceModeStr;
+ extractOptFirstArg((char*)args,&mapIdStr,&instanceModeStr);
+ if (!mapIdStr || !instanceModeStr)
+ return false;
+
+ uint32 mapid = atoi(mapIdStr);
+
+ InstanceTemplate const* instance = objmgr.GetInstanceTemplate(mapid);
+ if (!instance)
+ {
+ PSendSysMessage("Invalid map id");
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ uint8 status = objmgr.GetAccessRequirement(instance->access_id)->status;
+ uint8 flag = 0;
+
+ if (strcmp(instanceModeStr,"normal") || strcmp(instanceModeStr,"10normal"))
+ flag = DUNGEON_STATUSFLAG_NORMAL;
+ else if (strcmp(instanceModeStr,"heroic") || strcmp(instanceModeStr,"25normal"))
+ flag = DUNGEON_STATUSFLAG_HEROIC;
+ else if (strcmp(instanceModeStr,"10heroic"))
+ flag = RAID_STATUSFLAG_10MAN_HEROIC;
+ else if (strcmp(instanceModeStr,"25heroic"))
+ flag = RAID_STATUSFLAG_25MAN_HEROIC;
+ else
+ {
+ PSendSysMessage("Unrecognized difficulty string");
+ SetSentErrorMessage(true);
+ return false;
+ }
+ if (open)
+ status |= flag;
+ else
+ status &= ~flag;
+
+ WorldDatabase.PExecute("UPDATE access_requirement SET status = '%u' WHERE id = '%u'", status, instance->access_id);
+ PSendSysMessage("Instance status changed. Don't forget to reload access_requirement table");
+ return true;
+}
+
+/// Display the list of GMs
+bool ChatHandler::HandleGMListFullCommand(const char* /*args*/)
+{
+ ///- Get the accounts with GM Level >0
+ QueryResult_AutoPtr result = LoginDatabase.Query("SELECT a.username,aa.gmlevel FROM account a, account_access aa WHERE a.id=aa.id AND aa.gmlevel > 0");
+ if (result)
+ {
+ SendSysMessage(LANG_GMLIST);
+ SendSysMessage(" ======================== ");
+ SendSysMessage(LANG_GMLIST_HEADER);
+ SendSysMessage(" ======================== ");
+
+ ///- Circle through them. Display username and GM level
+ do
+ {
+ Field *fields = result->Fetch();
+ PSendSysMessage("|%15s|%6s|", fields[0].GetString(),fields[1].GetString());
+ }while (result->NextRow());
+
+ PSendSysMessage(" ======================== ");
+ }
+ else
+ PSendSysMessage(LANG_GMLIST_EMPTY);
+ return true;
+}
+
+/// Define the 'Message of the day' for the realm
+bool ChatHandler::HandleServerSetMotdCommand(const char *args)
+{
+ sWorld.SetMotd(args);
+ PSendSysMessage(LANG_MOTD_NEW, args);
+ return true;
+}
+
+/// Set whether we accept new clients
+bool ChatHandler::HandleServerSetClosedCommand(const char *args)
+{
+ std::string arg = args;
+
+ if (strncmp(args, "on", 3) == 0)
+ {
+ SendSysMessage(LANG_WORLD_CLOSED);
+ sWorld.SetClosed(true);
+ return true;
+ }
+ else if (strncmp(args, "off", 4) == 0)
+ {
+ SendSysMessage(LANG_WORLD_OPENED);
+ sWorld.SetClosed(false);
+ return true;
+ }
+
+ SendSysMessage(LANG_USE_BOL);
+ SetSentErrorMessage(true);
+ return false;
+}
+
+/// Set/Unset the expansion level for an account
+bool ChatHandler::HandleAccountSetAddonCommand(const char *args)
+{
+ ///- Get the command line arguments
+ char *szAcc = strtok((char*)args," ");
+ char *szExp = strtok(NULL," ");
+
+ if (!szAcc)
+ return false;
+
+ std::string account_name;
+ uint32 account_id;
+
+ if (!szExp)
+ {
+ Player* player = getSelectedPlayer();
+ if (!player)
+ return false;
+
+ account_id = player->GetSession()->GetAccountId();
+ accmgr.GetName(account_id,account_name);
+ szExp = szAcc;
+ }
+ else
+ {
+ ///- Convert Account name to Upper Format
+ account_name = szAcc;
+ if (!AccountMgr::normalizeString(account_name))
+ {
+ PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ account_id = accmgr.GetId(account_name);
+ if (!account_id)
+ {
+ PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ }
+
+ // Let set addon state only for lesser (strong) security level
+ // or to self account
+ if (m_session && m_session->GetAccountId () != account_id &&
+ HasLowerSecurityAccount (NULL,account_id,true))
+ return false;
+
+ int expansion = atoi(szExp); //get int anyway (0 if error)
+ if (expansion < 0 || expansion > sWorld.getConfig(CONFIG_EXPANSION))
+ return false;
+
+ // No SQL injection
+ LoginDatabase.PExecute("UPDATE account SET expansion = '%d' WHERE id = '%u'",expansion,account_id);
+ PSendSysMessage(LANG_ACCOUNT_SETADDON,account_name.c_str(),account_id,expansion);
+ return true;
+}
+
+//Send items by mail
+bool ChatHandler::HandleSendItemsCommand(const char *args)
+{
+ // format: name "subject text" "mail text" item1[:count1] item2[:count2] ... item12[:count12]
+ Player* receiver;
+ uint64 receiver_guid;
+ std::string receiver_name;
+ if (!extractPlayerTarget((char*)args,&receiver,&receiver_guid,&receiver_name))
+ return false;
+
+ char* tail1 = strtok(NULL, "");
+ if (!tail1)
+ return false;
+
+ char* msgSubject = extractQuotedArg(tail1);
+ if (!msgSubject)
+ return false;
+
+ char* tail2 = strtok(NULL, "");
+ if (!tail2)
+ return false;
+
+ char* msgText = extractQuotedArg(tail2);
+ if (!msgText)
+ return false;
+
+ // msgSubject, msgText isn't NUL after prev. check
+ std::string subject = msgSubject;
+ std::string text = msgText;
+
+ // extract items
+ typedef std::pair<uint32,uint32> ItemPair;
+ typedef std::list< ItemPair > ItemPairs;
+ ItemPairs items;
+
+ // get all tail string
+ char* tail = strtok(NULL, "");
+
+ // get from tail next item str
+ while (char* itemStr = strtok(tail, " "))
+ {
+ // and get new tail
+ tail = strtok(NULL, "");
+
+ // parse item str
+ char* itemIdStr = strtok(itemStr, ":");
+ char* itemCountStr = strtok(NULL, " ");
+
+ uint32 item_id = atoi(itemIdStr);
+ if (!item_id)
+ return false;
+
+ ItemPrototype const* item_proto = objmgr.GetItemPrototype(item_id);
+ if (!item_proto)
+ {
+ PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ uint32 item_count = itemCountStr ? atoi(itemCountStr) : 1;
+ if (item_count < 1 || (item_proto->MaxCount > 0 && item_count > uint32(item_proto->MaxCount)))
+ {
+ PSendSysMessage(LANG_COMMAND_INVALID_ITEM_COUNT, item_count,item_id);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ while (item_count > item_proto->GetMaxStackSize())
+ {
+ items.push_back(ItemPair(item_id,item_proto->GetMaxStackSize()));
+ item_count -= item_proto->GetMaxStackSize();
+ }
+
+ items.push_back(ItemPair(item_id,item_count));
+
+ if (items.size() > MAX_MAIL_ITEMS)
+ {
+ PSendSysMessage(LANG_COMMAND_MAIL_ITEMS_LIMIT, MAX_MAIL_ITEMS);
+ SetSentErrorMessage(true);
+ return false;
+ }
+ }
+
+ // from console show not existed sender
+ MailSender sender(MAIL_NORMAL,m_session ? m_session->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM);
+
+ // fill mail
+ MailDraft draft(subject, text);
+
+ for (ItemPairs::const_iterator itr = items.begin(); itr != items.end(); ++itr)
+ {
+ if (Item* item = Item::CreateItem(itr->first,itr->second,m_session ? m_session->GetPlayer() : 0))
+ {
+ item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted
+ draft.AddItem(item);
+ }
+ }
+
+ draft.SendMailTo(MailReceiver(receiver,GUID_LOPART(receiver_guid)), sender);
+
+ std::string nameLink = playerLink(receiver_name);
+ PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
+ return true;
+}
+
+///Send money by mail
+bool ChatHandler::HandleSendMoneyCommand(const char *args)
+{
+ /// format: name "subject text" "mail text" money
+
+ Player* receiver;
+ uint64 receiver_guid;
+ std::string receiver_name;
+ if (!extractPlayerTarget((char*)args,&receiver,&receiver_guid,&receiver_name))
+ return false;
+
+ char* tail1 = strtok(NULL, "");
+ if (!tail1)
+ return false;
+
+ char* msgSubject = extractQuotedArg(tail1);
+ if (!msgSubject)
+ return false;
+
+ char* tail2 = strtok(NULL, "");
+ if (!tail2)
+ return false;
+
+ char* msgText = extractQuotedArg(tail2);
+ if (!msgText)
+ return false;
+
+ char* money_str = strtok(NULL, "");
+ int32 money = money_str ? atoi(money_str) : 0;
+ if (money <= 0)
+ return false;
+
+ // msgSubject, msgText isn't NUL after prev. check
+ std::string subject = msgSubject;
+ std::string text = msgText;
+
+ // from console show not existed sender
+ MailSender sender(MAIL_NORMAL,m_session ? m_session->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM);
+
+ MailDraft(subject, text)
+ .AddMoney(money)
+ .SendMailTo(MailReceiver(receiver,GUID_LOPART(receiver_guid)),sender);
+
+ std::string nameLink = playerLink(receiver_name);
+ PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
+ return true;
+}
+
+/// Send a message to a player in game
+bool ChatHandler::HandleSendMessageCommand(const char *args)
+{
+ ///- Find the player
+ Player *rPlayer;
+ if (!extractPlayerTarget((char*)args, &rPlayer))
+ return false;
+
+ char* msg_str = strtok(NULL, "");
+ if (!msg_str)
+ return false;
+
+ ///- Check that he is not logging out.
+ if (rPlayer->GetSession()->isLogingOut())
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ ///- Send the message
+ //Use SendAreaTriggerMessage for fastest delivery.
+ rPlayer->GetSession()->SendAreaTriggerMessage("%s", msg_str);
+ rPlayer->GetSession()->SendAreaTriggerMessage("|cffff0000[Message from administrator]:|r");
+
+ //Confirmation message
+ std::string nameLink = GetNameLink(rPlayer);
+ PSendSysMessage(LANG_SENDMESSAGE,nameLink.c_str(),msg_str);
+ return true;
+}
+
+bool ChatHandler::HandleFlushArenaPointsCommand(const char * /*args*/)
+{
+ sBattleGroundMgr.DistributeArenaPoints();
+ return true;
+}
+
+bool ChatHandler::HandleModifyGenderCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ Player *player = getSelectedPlayer();
+
+ if (!player)
+ {
+ PSendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ PlayerInfo const* info = objmgr.GetPlayerInfo(player->getRace(), player->getClass());
+ if (!info)
+ return false;
+
+ char const* gender_str = (char*)args;
+ int gender_len = strlen(gender_str);
+
+ Gender gender;
+
+ if (!strncmp(gender_str, "male", gender_len)) // MALE
+ {
+ if (player->getGender() == GENDER_MALE)
+ return true;
+
+ gender = GENDER_MALE;
+ }
+ else if (!strncmp(gender_str, "female", gender_len)) // FEMALE
+ {
+ if (player->getGender() == GENDER_FEMALE)
+ return true;
+
+ gender = GENDER_FEMALE;
+ }
+ else
+ {
+ SendSysMessage(LANG_MUST_MALE_OR_FEMALE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // Set gender
+ player->SetByteValue(UNIT_FIELD_BYTES_0, 2, gender);
+ player->SetByteValue(PLAYER_BYTES_3, 0, gender);
+
+ // Change display ID
+ player->InitDisplayIds();
+
+ char const* gender_full = gender ? "female" : "male";
+
+ PSendSysMessage(LANG_YOU_CHANGE_GENDER, GetNameLink(player).c_str(), gender_full);
+
+ if (needReportToTarget(player))
+ ChatHandler(player).PSendSysMessage(LANG_YOUR_GENDER_CHANGED, gender_full, GetNameLink().c_str());
+
+ return true;
+}
+
+bool ChatHandler::HandleChannelSetPublic(const char *args)
+{
+ if (!*args)
+ return false;
+ std::string channel = strtok((char*)args, " ");
+ uint32 val = atoi((char*)args);
+
+ if (val)
+ {
+ CharacterDatabase.PExecute("UPDATE channels SET m_public = 1 WHERE m_name LIKE '%s'", channel.c_str());
+ val = 1;
+ }
+ else
+ {
+ CharacterDatabase.PExecute("UPDATE channels SET m_public = 0 WHERE m_name LIKE '%s'", channel.c_str());
+ val = 0;
+ }
+
+ PSendSysMessage(LANG_CHANNEL_PUBLIC_CHANGED, channel.c_str(), val);
+
+ return true;
+}
+
+
+/*------------------------------------------
+ *-------------TRINITY----------------------
+ *-------------------------------------*/
+
+bool ChatHandler::HandlePlayAllCommand(const char *args)
+{
+ if (!*args)
+ return false;
+
+ uint32 soundId = atoi((char*)args);
+
+ if (!sSoundEntriesStore.LookupEntry(soundId))
+ {
+ PSendSysMessage(LANG_SOUND_NOT_EXIST, soundId);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ WorldPacket data(SMSG_PLAY_SOUND, 4);
+ data << uint32(soundId) << m_session->GetPlayer()->GetGUID();
+ sWorld.SendGlobalMessage(&data);
+
+ PSendSysMessage(LANG_COMMAND_PLAYED_TO_ALL, soundId);
+ return true;
+}
+
+bool ChatHandler::HandleFreezeCommand(const char *args)
+{
+ std::string name;
+ Player *player;
+ char *TargetName = strtok((char*)args, " "); //get entered name
+ if (!TargetName) //if no name entered use target
+ {
+ player = getSelectedPlayer();
+ if (player) //prevent crash with creature as target
+ {
+ name = player->GetName();
+ normalizePlayerName(name);
+ }
+ }
+ else // if name entered
+ {
+ name = TargetName;
+ normalizePlayerName(name);
+ player = objmgr.GetPlayer(name.c_str()); //get player by name
+ }
+
+ if (!player)
+ {
+ SendSysMessage(LANG_COMMAND_FREEZE_WRONG);
+ return true;
+ }
+
+ if (player == m_session->GetPlayer())
+ {
+ SendSysMessage(LANG_COMMAND_FREEZE_ERROR);
+ return true;
+ }
+
+ //effect
+ if (player && player != m_session->GetPlayer())
+ {
+ PSendSysMessage(LANG_COMMAND_FREEZE,name.c_str());
+
+ //stop combat + make player unattackable + duel stop + stop some spells
+ player->setFaction(35);
+ player->CombatStop();
+ if (player->IsNonMeleeSpellCasted(true))
+ player->InterruptNonMeleeSpells(true);
+ player->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ player->SetUInt32Value(PLAYER_DUEL_TEAM, 1);
+
+ //if player class = hunter || warlock remove pet if alive
+ if ((player->getClass() == CLASS_HUNTER) || (player->getClass() == CLASS_WARLOCK))
+ {
+ if (Pet *pet = player->GetPet())
+ {
+ pet->SavePetToDB(PET_SAVE_AS_CURRENT);
+ // not let dismiss dead pet
+ if (pet && pet->isAlive())
+ player->RemovePet(pet,PET_SAVE_NOT_IN_SLOT);
+ }
+ }
+
+ //m_session->GetPlayer()->CastSpell(player,spellID,false);
+ if (SpellEntry const *spellInfo = sSpellStore.LookupEntry(9454))
+ Aura::TryCreate(spellInfo, player, player);
+
+ //save player
+ player->SaveToDB();
+ }
+ return true;
+}
+
+bool ChatHandler::HandleUnFreezeCommand(const char *args)
+{
+ std::string name;
+ Player *player;
+ char *TargetName = strtok((char*)args, " "); //get entered name
+ if (!TargetName) //if no name entered use target
+ {
+ player = getSelectedPlayer();
+ if (player) //prevent crash with creature as target
+ name = player->GetName();
+ }
+
+ else // if name entered
+ {
+ name = TargetName;
+ normalizePlayerName(name);
+ player = objmgr.GetPlayer(name.c_str()); //get player by name
+ }
+
+ //effect
+ if (player)
+ {
+ PSendSysMessage(LANG_COMMAND_UNFREEZE,name.c_str());
+
+ //Reset player faction + allow combat + allow duels
+ player->setFactionForRace(player->getRace());
+ player->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+
+ //allow movement and spells
+ player->RemoveAurasDueToSpell(9454);
+
+ //save player
+ player->SaveToDB();
+ }
+
+ if (!player)
+ {
+ if (TargetName)
+ {
+ //check for offline players
+ QueryResult_AutoPtr result = CharacterDatabase.PQuery("SELECT characters.guid FROM characters WHERE characters.name = '%s'",name.c_str());
+ if (!result)
+ {
+ SendSysMessage(LANG_COMMAND_FREEZE_WRONG);
+ return true;
+ }
+ //if player found: delete his freeze aura
+ Field *fields=result->Fetch();
+ uint64 pguid = fields[0].GetUInt64();
+
+ CharacterDatabase.PQuery("DELETE FROM character_aura WHERE character_aura.spell = 9454 AND character_aura.guid = '%u'",pguid);
+ PSendSysMessage(LANG_COMMAND_UNFREEZE,name.c_str());
+ return true;
+ }
+ else
+ {
+ SendSysMessage(LANG_COMMAND_FREEZE_WRONG);
+ return true;
+ }
+ }
+
+ return true;
+}
+
+bool ChatHandler::HandleListFreezeCommand(const char * /*args*/)
+{
+ //Get names from DB
+ QueryResult_AutoPtr result = CharacterDatabase.Query("SELECT characters.name FROM characters LEFT JOIN character_aura ON (characters.guid = character_aura.guid) WHERE character_aura.spell = 9454");
+ if (!result)
+ {
+ SendSysMessage(LANG_COMMAND_NO_FROZEN_PLAYERS);
+ return true;
+ }
+ //Header of the names
+ PSendSysMessage(LANG_COMMAND_LIST_FREEZE);
+
+ //Output of the results
+ do
+ {
+ Field *fields = result->Fetch();
+ std::string fplayers = fields[0].GetCppString();
+ PSendSysMessage(LANG_COMMAND_FROZEN_PLAYERS,fplayers.c_str());
+ } while (result->NextRow());
+
+ return true;
+}
+
+bool ChatHandler::HandleGroupLeaderCommand(const char *args)
+{
+ Player* plr = NULL;
+ Group* group = NULL;
+ uint64 guid = 0;
+ char* cname = strtok((char*)args, " ");
+
+ if (GetPlayerGroupAndGUIDByName(cname, plr, group, guid))
+ if (group && group->GetLeaderGUID() != guid)
+ group->ChangeLeader(guid);
+
+ return true;
+}
+
+bool ChatHandler::HandleGroupDisbandCommand(const char *args)
+{
+ Player* plr = NULL;
+ Group* group = NULL;
+ uint64 guid = 0;
+ char* cname = strtok((char*)args, " ");
+
+ if (GetPlayerGroupAndGUIDByName(cname, plr, group, guid))
+ if (group)
+ group->Disband();
+
+ return true;
+}
+
+bool ChatHandler::HandleGroupRemoveCommand(const char *args)
+{
+ Player* plr = NULL;
+ Group* group = NULL;
+ uint64 guid = 0;
+ char* cname = strtok((char*)args, " ");
+
+ if (GetPlayerGroupAndGUIDByName(cname, plr, group, guid, true))
+ if (group)
+ group->RemoveMember(guid, 0);
+
+ return true;
+}
+
+bool ChatHandler::HandlePossessCommand(const char * /*args*/)
+{
+ Unit *pUnit = getSelectedUnit();
+ if (!pUnit)
+ return false;
+
+ m_session->GetPlayer()->CastSpell(pUnit, 530, true);
+ return true;
+}
+
+bool ChatHandler::HandleUnPossessCommand(const char * /*args*/)
+{
+ Unit *pUnit = getSelectedUnit();
+ if (!pUnit)
+ pUnit = m_session->GetPlayer();
+
+ pUnit->RemoveCharmAuras();
+
+ return true;
+}
+
+bool ChatHandler::HandleBindSightCommand(const char * /*args*/)
+{
+ Unit *pUnit = getSelectedUnit();
+ if (!pUnit)
+ return false;
+
+ m_session->GetPlayer()->CastSpell(pUnit, 6277, true);
+ return true;
+}
+
+bool ChatHandler::HandleUnbindSightCommand(const char * /*args*/)
+{
+ if (m_session->GetPlayer()->isPossessing())
+ return false;
+
+ m_session->GetPlayer()->StopCastingBindSight();
+ return true;
+}