/*
* Ascent MMORPG Server
* Copyright (C) 2005-2007 Ascent Team
*
* 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 3 of the License, or
* 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, see .
*
*/
//
// WorldSession.cpp
//
#include "StdAfx.h"
#define WORLDSOCKET_TIMEOUT 80
OpcodeHandler WorldPacketHandlers[NUM_MSG_TYPES];
WorldSession::WorldSession(uint32 id, string Name, WorldSocket *sock) : _player(0), _socket(sock), _accountId(id), _accountName(Name),
_logoutTime(0), permissions(NULL), permissioncount(0), _loggingOut(false), instanceId(0)
{
memset(movement_packet, 0, sizeof(movement_packet));
m_currMsTime = getMSTime();
bDeleted = false;
m_bIsWLevelSet = false;
floodLines = 0;
floodTime = World::UNIXTIME;
_updatecount = 0;
m_moveDelayTime=0;
for(uint32 x=0;x<8;x++)
sAccountData[x].data=NULL;
}
WorldSession::~WorldSession()
{
deleteMutex.Acquire();
if(HasFlag(ACCOUNT_FLAG_XTEND_INFO))
sWorld.RemoveExtendedSession(this);
if(HasGMPermissions())
sWorld.gmList.erase(this);
if(_player)
{
sLog.outError("warning: logged out player in worldsession destructor");
LogoutPlayer(true);
}
if(permissions)
delete [] permissions;
WorldPacket *packet;
while((packet = _recvQueue.Pop()))
delete packet;
for(uint32 x=0;x<8;x++)
{
if(sAccountData[x].data)
delete [] sAccountData[x].data;
}
#ifndef CLUSTERING
if(_socket)
_socket->SetSession(0);
#endif
deleteMutex.Release();
}
int WorldSession::Update(uint32 InstanceID)
{
m_currMsTime = getMSTime();
WorldPacket *packet;
OpcodeHandler * Handler;
if(InstanceID != instanceId)
{
// We're being updated by the wrong thread.
// "Remove us!" - 2
return 2;
}
// Socket disconnection.
if(!_socket)
{
// Check if the player is in the process of being moved. We can't delete him
// if we are.
if(_player && _player->m_beingPushed)
{
// Abort..
return 0;
}
if(_player && _player->DuelingWith)
_player->EndDuel(DUEL_WINNER_RETREAT);
bDeleted = true;
LogoutPlayer(true);
// 1 - Delete session completely.
return 1;
}
while ((packet = _recvQueue.Pop()))
{
ASSERT(packet);
if(packet->GetOpcode() >= NUM_MSG_TYPES)
sLog.outDebug("[Session] Received out of range packet with opcode 0x%.4X", packet->GetOpcode());
else
{
Handler = &WorldPacketHandlers[packet->GetOpcode()];
if(Handler->status == STATUS_LOGGEDIN && !_player && Handler->handler != 0)
{
sLog.outDebug("[Session] Received unexpected/wrong state packet with opcode %s (0x%.4X)",
LookupName(packet->GetOpcode(), g_worldOpcodeNames), packet->GetOpcode());
}
else
{
// Valid Packet :>
if(Handler->handler == 0)
{
sLog.outDebug("[Session] Received unhandled packet with opcode %s (0x%.4X)",
LookupName(packet->GetOpcode(), g_worldOpcodeNames), packet->GetOpcode());
}
else
{
(this->*Handler->handler)(*packet);
}
}
}
delete packet;
if(InstanceID != instanceId)
{
// If we hit this -> means a packet has changed our map.
return 2;
}
}
if(InstanceID != instanceId)
{
// If we hit this -> means a packet has changed our map.
return 2;
}
if( _logoutTime && (m_currMsTime >= _logoutTime) && instanceId == InstanceID)
{
// Check if the player is in the process of being moved. We can't delete him
// if we are.
if(_player && _player->m_beingPushed)
{
// Abort..
return 0;
}
if(_player && _player->m_Group)
_player->m_Group->RemovePlayer(_player->m_playerInfo, _player, true);
LogoutPlayer(true);
}
if(m_lastPing + WORLDSOCKET_TIMEOUT < (uint32)time(NULL))
{
// Check if the player is in the process of being moved. We can't delete him
// if we are.
if(_player && _player->m_beingPushed)
{
// Abort..
return 0;
}
// ping timeout!
Disconnect();
bDeleted = true;
LogoutPlayer(true);
// 1 - Complete deletion
return 1;
}
#ifndef CLUSTERING
// 0 - OK!
if(!((++_updatecount) % 2) && _socket)
_socket->UpdateQueuedPackets();
#endif
return 0;
}
void WorldSession::LogoutPlayer(bool Save)
{
if(_loggingOut)
return;
_loggingOut = true;
if (_player)
{
if(_player->m_currentLoot && _player->IsInWorld())
{
Object * obj = _player->GetMapMgr()->_GetObject(_player->m_currentLoot);
if(obj)
{
switch(obj->GetTypeId())
{
case TYPEID_UNIT:
((Creature*)obj)->loot.looters.erase(_player->GetGUID());
break;
case TYPEID_GAMEOBJECT:
((GameObject*)obj)->loot.looters.erase(_player->GetGUID());
break;
}
}
}
if(_player->m_CurrentTransporter)
_player->m_CurrentTransporter->RemovePlayer(_player);
// cancel current spell
if(_player->m_currentSpell)
_player->m_currentSpell->cancel();
sSocialMgr.LoggedOut(_player);
// messages
if(HasGMPermissions())
{
sWorld.BroadcastExtendedMessage(this, "[SM:GMLOGOUT]%s", _player->GetName());
}
if(_player->GetTeam() == 1)
sWorld.HordePlayers--;
else
sWorld.AlliancePlayers--;
if(_player->m_bg)
_player->m_bg->RemovePlayer(_player, true);
if(_player->m_bgIsQueued)
BattlegroundManager.RemovePlayerFromQueues(_player);
// send info
sWorld.BroadcastExtendedMessage(0, "[SM:INFO:%u:%u]", sWorld.HordePlayers, sWorld.AlliancePlayers);
//Duel Cancel on Leave
if(_player->DuelingWith != NULL)
_player->EndDuel(DUEL_WINNER_RETREAT);
// wipe our attacker list and target list
_player->clearAttackers(true);
//Issue a message telling all guild members that this player signed off
if(_player->IsInGuild())
{
Guild *pGuild = objmgr.GetGuild( _player->GetGuildId() );
if(pGuild)
{
//Update Offline info
pGuild->GuildMemberLogoff(_player);
WorldPacket data(SMSG_GUILD_EVENT, 11+strlen(_player->GetName()));
data << uint8(GUILD_EVENT_HASGONEOFFLINE);
data << uint8(0x01);
data << _player->GetName();
data << _player->GetGUID();
pGuild->SendMessageToGuild(0,&data,G_MSGTYPE_ALL);
}
}
_player->GetItemInterface()->EmptyBuyBack();
// Remove ourself from a group
Group * group = _player->GetGroup();
for(int i=0;i<3;++i)
{
if(_player->LfgDungeonId[i] != 0)
sLfgMgr.RemoveFromLfgQueue(_player,_player->LfgDungeonId[i]);
}
// Save HP/Mana
_player->load_health = _player->GetUInt32Value(UNIT_FIELD_HEALTH);
_player->load_mana = _player->GetUInt32Value(UNIT_FIELD_POWER1);
objmgr.RemovePlayer(_player);
_player->ok_to_remove = true;
if(_player->GetSummon() != NULL)
_player->GetSummon()->Remove(false, true, false);
// _player->SaveAuras();
if(Save)
_player->SaveToDB(false);
_player->RemoveAllAuras();
if(_player->IsInWorld())
_player->RemoveFromWorld();
if(group)
{
group->RemovePlayer(_player->m_playerInfo, NULL, false);
_player->m_Group =NULL;
}
// Remove the "player locked" flag, to allow movement on next login
if ( GetPlayer( )->GetUInt32Value(UNIT_FIELD_FLAGS) & U_FIELD_FLAG_LOCK_PLAYER )
GetPlayer( )->RemoveFlag( UNIT_FIELD_FLAGS, U_FIELD_FLAG_LOCK_PLAYER );
// Save Honor Points
_player->SaveHonorFields();
// Update any dirty account_data fields.
/*bool dirty=false;
std::stringstream ss;
ss << "UPDATE accounts SET ";
for(uint32 ui=0;ui<8;ui++)
{
if(sAccountData[ui].bIsDirty)
{
if(dirty)
ss <<",";
ss << "uiconfig"<< ui <<"=\"";
if(sAccountData[ui].data)
ss.write(sAccountData[ui].data,sAccountData[ui].sz);
ss << "\"";
dirty=true;
}
}
if(dirty)
{
ss <<" WHERE acct="<< _accountId <<";";
sLogonDatabase.Execute(ss.str().c_str());
}*/
delete _player;
_player = NULL;
OutPacket(SMSG_LOGOUT_COMPLETE, 0, NULL);
sLog.outDebug( "SESSION: Sent SMSG_LOGOUT_COMPLETE Message" );
}
_loggingOut = false;
SetLogoutTimer(0);
}
void WorldSession::BuildItemPushResult(WorldPacket *data, uint64 guid, uint32 type, uint32 count, uint32 itemid, uint32 randomprop, uint8 unk, uint32 unk2, uint32 unk3, uint32 count_have)
{
ItemPrototype *proto = ItemPrototypeStorage.LookupEntry(itemid);
if(!proto) return;
data->Initialize(SMSG_ITEM_PUSH_RESULT);
*data << guid;
*data << type << unk2;
*data << uint32(1); // show msg
*data << unk;
*data << unk3;
*data << itemid;
//not sure if random property.
//For quest items also sent at loot list but it's changing in time.
//in SMSG_ITEM_PUSH_RESULT packet it's used as sent in first occurance of lootlist packet
*data << randomprop;
*data << proto->Quality;
*data << count;
*data << count_have;
}
void WorldSession::SendBuyFailed(uint64 guid, uint32 itemid, uint8 error)
{
WorldPacket data(13);
data.SetOpcode(SMSG_BUY_FAILED);
data << guid << itemid << error;
_socket->SendPacket(&data);
}
void WorldSession::SendSellItem(uint64 vendorguid, uint64 itemid, uint8 error)
{
WorldPacket data(17);
data.SetOpcode(SMSG_SELL_ITEM);
data << vendorguid << itemid << error;
_socket->SendPacket(&data);
}
void WorldSession::LoadSecurity(std::string securitystring)
{
std::list tmp;
bool hasa = false;
for(uint32 i = 0; i < securitystring.length(); ++i)
{
char c = securitystring.at(i);
c = towlower(c);
if(c == '4' || c == '3')
c = 'a'; // for the lazy people
if(c == 'a')
{
// all permissions
tmp.push_back('a');
hasa = true;
}
else if(!hasa && (c == '0') && i == 0)
break;
else if(!hasa || (hasa && (c == 'z')))
{
tmp.push_back(c);
}
}
permissions = new char[tmp.size()+1];
memset(permissions, 0, tmp.size()+1);
permissioncount = tmp.size();
int k = 0;
for(std::list::iterator itr = tmp.begin(); itr != tmp.end(); ++itr)
permissions[k++] = (*itr);
if(permissions[tmp.size()] != 0)
permissions[tmp.size()] = 0;
sLog.outDebug("Loaded permissions for %u. (%u) : [%s]", this->GetAccountId(), permissioncount, securitystring.c_str());
}
void WorldSession::SetSecurity(std::string securitystring)
{
delete [] permissions;
LoadSecurity(securitystring);
// update db
CharacterDatabase.Execute("UPDATE accounts SET gm=\"%s\" WHERE acct=%u", CharacterDatabase.EscapeString(string(permissions)).c_str(), _accountId);
}
bool WorldSession::CanUseCommand(char cmdstr)
{
if(permissioncount == 0)
return false;
if(cmdstr == 0)
return true;
if(permissions[0] == 'a' && cmdstr != 'z') // all
return true;
for(int i = 0; i < permissioncount; ++i)
if(permissions[i] == cmdstr)
return true;
return false;
}
void WorldSession::SendNotification(const char *message, ...)
{
if( !message ) return;
va_list ap;
va_start(ap, message);
char msg1[1024];
vsnprintf(msg1,1024, message,ap);
WorldPacket data(SMSG_NOTIFICATION, strlen(msg1) + 1);
data << msg1;
SendPacket(&data);
}
void WorldSession::InitPacketHandlerTable()
{
// Nullify Everything, default to STATUS_LOGGEDIN
for(uint32 i = 0; i < NUM_MSG_TYPES; ++i)
{
WorldPacketHandlers[i].status = STATUS_LOGGEDIN;
WorldPacketHandlers[i].handler = 0;
}
// Login
WorldPacketHandlers[CMSG_CHAR_ENUM].handler = &WorldSession::HandleCharEnumOpcode;
WorldPacketHandlers[CMSG_CHAR_ENUM].status = STATUS_AUTHED;
WorldPacketHandlers[CMSG_CHAR_CREATE].handler = &WorldSession::HandleCharCreateOpcode;
WorldPacketHandlers[CMSG_CHAR_CREATE].status = STATUS_AUTHED;
WorldPacketHandlers[CMSG_CHAR_DELETE].handler = &WorldSession::HandleCharDeleteOpcode;
WorldPacketHandlers[CMSG_CHAR_DELETE].status = STATUS_AUTHED;
WorldPacketHandlers[CMSG_CHAR_RENAME].handler = &WorldSession::HandleCharRenameOpcode;
WorldPacketHandlers[CMSG_CHAR_RENAME].status = STATUS_AUTHED;
WorldPacketHandlers[CMSG_PLAYER_LOGIN].handler = &WorldSession::HandlePlayerLoginOpcode;
WorldPacketHandlers[CMSG_PLAYER_LOGIN].status = STATUS_AUTHED;
// Queries
WorldPacketHandlers[MSG_CORPSE_QUERY].handler = &WorldSession::HandleCorpseQueryOpcode;
WorldPacketHandlers[CMSG_NAME_QUERY].handler = &WorldSession::HandleNameQueryOpcode;
WorldPacketHandlers[CMSG_QUERY_TIME].handler = &WorldSession::HandleQueryTimeOpcode;
WorldPacketHandlers[CMSG_CREATURE_QUERY].handler = &WorldSession::HandleCreatureQueryOpcode;
WorldPacketHandlers[CMSG_GAMEOBJECT_QUERY].handler = &WorldSession::HandleGameObjectQueryOpcode;
WorldPacketHandlers[CMSG_PAGE_TEXT_QUERY].handler = &WorldSession::HandlePageTextQueryOpcode;
WorldPacketHandlers[CMSG_ITEM_NAME_QUERY].handler = &WorldSession::HandleItemNameQueryOpcode;
// Movement
WorldPacketHandlers[MSG_MOVE_HEARTBEAT].handler = &WorldSession::HandleMovementOpcodes;
WorldPacketHandlers[MSG_MOVE_WORLDPORT_ACK].handler = &WorldSession::HandleMoveWorldportAckOpcode;
WorldPacketHandlers[MSG_MOVE_JUMP].handler = &WorldSession::HandleMovementOpcodes;
WorldPacketHandlers[CMSG_FLY_PITCH_UP_Z].handler = &WorldSession::HandleMovementOpcodes;
WorldPacketHandlers[CMSG_FLY_PITCH_DOWN_AFTER_UP].handler = &WorldSession::HandleMovementOpcodes;
WorldPacketHandlers[MSG_MOVE_START_FORWARD].handler = &WorldSession::HandleMovementOpcodes;
WorldPacketHandlers[MSG_MOVE_START_BACKWARD].handler = &WorldSession::HandleMovementOpcodes;
WorldPacketHandlers[MSG_MOVE_SET_FACING].handler = &WorldSession::HandleMovementOpcodes;
WorldPacketHandlers[MSG_MOVE_START_STRAFE_LEFT].handler = &WorldSession::HandleMovementOpcodes;
WorldPacketHandlers[MSG_MOVE_START_STRAFE_RIGHT].handler = &WorldSession::HandleMovementOpcodes;
WorldPacketHandlers[MSG_MOVE_STOP_STRAFE].handler = &WorldSession::HandleMovementOpcodes;
WorldPacketHandlers[MSG_MOVE_START_TURN_LEFT].handler = &WorldSession::HandleBasicMovementOpcodes;
WorldPacketHandlers[MSG_MOVE_START_TURN_RIGHT].handler = &WorldSession::HandleBasicMovementOpcodes;
WorldPacketHandlers[MSG_MOVE_STOP_TURN].handler = &WorldSession::HandleBasicMovementOpcodes;
WorldPacketHandlers[MSG_MOVE_START_PITCH_UP].handler = &WorldSession::HandleBasicMovementOpcodes;
WorldPacketHandlers[MSG_MOVE_START_PITCH_DOWN].handler = &WorldSession::HandleBasicMovementOpcodes;
WorldPacketHandlers[MSG_MOVE_STOP_PITCH].handler = &WorldSession::HandleBasicMovementOpcodes;
WorldPacketHandlers[MSG_MOVE_SET_RUN_MODE].handler = &WorldSession::HandleBasicMovementOpcodes;
WorldPacketHandlers[MSG_MOVE_SET_WALK_MODE].handler = &WorldSession::HandleBasicMovementOpcodes;
WorldPacketHandlers[MSG_MOVE_SET_PITCH].handler = &WorldSession::HandleBasicMovementOpcodes;
WorldPacketHandlers[MSG_MOVE_START_SWIM].handler = &WorldSession::HandleMovementOpcodes;
WorldPacketHandlers[MSG_MOVE_STOP_SWIM].handler = &WorldSession::HandleMovementOpcodes;
WorldPacketHandlers[MSG_MOVE_FALL_LAND].handler = &WorldSession::HandleMovementOpcodes;
WorldPacketHandlers[MSG_MOVE_STOP].handler = &WorldSession::HandleMoveStopOpcode;
WorldPacketHandlers[CMSG_MOVE_FLY_START_AND_END].handler = &WorldSession::HandleBasicMovementOpcodes;
WorldPacketHandlers[CMSG_FLY_PITCH_UP_Z].handler = &WorldSession::HandleBasicMovementOpcodes;
WorldPacketHandlers[CMSG_FLY_PITCH_DOWN_AFTER_UP].handler = &WorldSession::HandleBasicMovementOpcodes;
WorldPacketHandlers[CMSG_MOVE_TIME_SKIPPED].handler = &WorldSession::HandleMoveTimeSkippedOpcode;
WorldPacketHandlers[CMSG_MOVE_NOT_ACTIVE_MOVER].handler = &WorldSession::HandleMoveNotActiveMoverOpcode;
WorldPacketHandlers[CMSG_SET_ACTIVE_MOVER].handler = &WorldSession::HandleSetActiveMoverOpcode;
WorldPacketHandlers[CMSG_TRANSPORT_STEP_IN_OUT].handler = &WorldSession::HandleMovementOpcodes;
// ACK
WorldPacketHandlers[MSG_MOVE_TELEPORT_ACK].handler = &WorldSession::HandleMoveTeleportAckOpcode;
WorldPacketHandlers[CMSG_FORCE_WALK_SPEED_CHANGE_ACK].handler = &WorldSession::HandleAcknowledgementOpcodes;
WorldPacketHandlers[CMSG_MOVE_FEATHER_FALL_ACK].handler = &WorldSession::HandleAcknowledgementOpcodes;
WorldPacketHandlers[CMSG_MOVE_WATER_WALK_ACK].handler = &WorldSession::HandleAcknowledgementOpcodes;
WorldPacketHandlers[CMSG_FORCE_SWIM_BACK_SPEED_CHANGE_ACK].handler = &WorldSession::HandleAcknowledgementOpcodes;
WorldPacketHandlers[CMSG_FORCE_TURN_RATE_CHANGE_ACK].handler = &WorldSession::HandleAcknowledgementOpcodes;
WorldPacketHandlers[CMSG_FORCE_RUN_SPEED_CHANGE_ACK].handler = &WorldSession::HandleAcknowledgementOpcodes;
WorldPacketHandlers[CMSG_FORCE_RUN_BACK_SPEED_CHANGE_ACK].handler = &WorldSession::HandleAcknowledgementOpcodes;
WorldPacketHandlers[CMSG_FORCE_SWIM_SPEED_CHANGE_ACK].handler = &WorldSession::HandleAcknowledgementOpcodes;
WorldPacketHandlers[CMSG_FORCE_MOVE_ROOT_ACK].handler = &WorldSession::HandleAcknowledgementOpcodes;
WorldPacketHandlers[CMSG_FORCE_MOVE_UNROOT_ACK].handler = &WorldSession::HandleAcknowledgementOpcodes;
WorldPacketHandlers[CMSG_MOVE_KNOCK_BACK_ACK].handler = &WorldSession::HandleAcknowledgementOpcodes;
WorldPacketHandlers[CMSG_MOVE_HOVER_ACK].handler = &WorldSession::HandleAcknowledgementOpcodes;
WorldPacketHandlers[MSG_MOVE_FLY_DOWN_UNK].handler = &WorldSession::HandleMovementOpcodes;
// Action Buttons
WorldPacketHandlers[CMSG_SET_ACTION_BUTTON].handler = &WorldSession::HandleSetActionButtonOpcode;
WorldPacketHandlers[CMSG_REPOP_REQUEST].handler = &WorldSession::HandleRepopRequestOpcode;
// Loot
WorldPacketHandlers[CMSG_AUTOSTORE_LOOT_ITEM].handler = &WorldSession::HandleAutostoreLootItemOpcode;
WorldPacketHandlers[CMSG_LOOT_MONEY].handler = &WorldSession::HandleLootMoneyOpcode;
WorldPacketHandlers[CMSG_LOOT].handler = &WorldSession::HandleLootOpcode;
WorldPacketHandlers[CMSG_LOOT_RELEASE].handler = &WorldSession::HandleLootReleaseOpcode;
WorldPacketHandlers[CMSG_LOOT_ROLL].handler = &WorldSession::HandleLootRollOpcode;
WorldPacketHandlers[CMSG_LOOT_MASTER_GIVE].handler = &WorldSession::HandleLootMasterGiveOpcode;
// Player Interaction
WorldPacketHandlers[CMSG_WHO].handler = &WorldSession::HandleWhoOpcode;
WorldPacketHandlers[CMSG_LOGOUT_REQUEST].handler = &WorldSession::HandleLogoutRequestOpcode;
WorldPacketHandlers[CMSG_PLAYER_LOGOUT].handler = &WorldSession::HandlePlayerLogoutOpcode;
WorldPacketHandlers[CMSG_LOGOUT_CANCEL].handler = &WorldSession::HandleLogoutCancelOpcode;
WorldPacketHandlers[CMSG_ZONEUPDATE].handler = &WorldSession::HandleZoneUpdateOpcode;
WorldPacketHandlers[CMSG_SET_TARGET_OBSOLETE].handler = &WorldSession::HandleSetTargetOpcode;
WorldPacketHandlers[CMSG_SET_SELECTION].handler = &WorldSession::HandleSetSelectionOpcode;
WorldPacketHandlers[CMSG_STANDSTATECHANGE].handler = &WorldSession::HandleStandStateChangeOpcode;
WorldPacketHandlers[CMSG_DISMOUNT].handler = &WorldSession::HandleDismountOpcode;
// Friends
WorldPacketHandlers[CMSG_FRIEND_LIST].handler = &WorldSession::HandleFriendListOpcode;
WorldPacketHandlers[CMSG_ADD_FRIEND].handler = &WorldSession::HandleAddFriendOpcode;
WorldPacketHandlers[CMSG_DEL_FRIEND].handler = &WorldSession::HandleDelFriendOpcode;
WorldPacketHandlers[CMSG_ADD_IGNORE].handler = &WorldSession::HandleAddIgnoreOpcode;
WorldPacketHandlers[CMSG_DEL_IGNORE].handler = &WorldSession::HandleDelIgnoreOpcode;
WorldPacketHandlers[CMSG_BUG].handler = &WorldSession::HandleBugOpcode;
// Areatrigger
WorldPacketHandlers[CMSG_AREATRIGGER].handler = &WorldSession::HandleAreaTriggerOpcode;
// Account Data
WorldPacketHandlers[CMSG_UPDATE_ACCOUNT_DATA].handler = &WorldSession::HandleUpdateAccountData;
WorldPacketHandlers[CMSG_REQUEST_ACCOUNT_DATA].handler = &WorldSession::HandleRequestAccountData;
WorldPacketHandlers[CMSG_SET_FACTION_ATWAR].handler = &WorldSession::HandleSetAtWarOpcode;
WorldPacketHandlers[CMSG_SET_WATCHED_FACTION_INDEX].handler = &WorldSession::HandleSetWatchedFactionIndexOpcode;
WorldPacketHandlers[CMSG_TOGGLE_PVP].handler = &WorldSession::HandleTogglePVPOpcode;
// Player Interaction
WorldPacketHandlers[CMSG_GAMEOBJ_USE].handler = &WorldSession::HandleGameObjectUse;
WorldPacketHandlers[CMSG_PLAYED_TIME].handler = &WorldSession::HandlePlayedTimeOpcode;
WorldPacketHandlers[CMSG_SETSHEATHED].handler = &WorldSession::HandleSetSheathedOpcode;
WorldPacketHandlers[CMSG_MESSAGECHAT].handler = &WorldSession::HandleMessagechatOpcode;
WorldPacketHandlers[CMSG_TEXT_EMOTE].handler = &WorldSession::HandleTextEmoteOpcode;
// Channels
WorldPacketHandlers[CMSG_JOIN_CHANNEL].handler = &WorldSession::HandleChannelJoin;
WorldPacketHandlers[CMSG_LEAVE_CHANNEL].handler = &WorldSession::HandleChannelLeave;
WorldPacketHandlers[CMSG_CHANNEL_LIST].handler = &WorldSession::HandleChannelList;
WorldPacketHandlers[CMSG_CHANNEL_PASSWORD].handler = &WorldSession::HandleChannelPassword;
WorldPacketHandlers[CMSG_CHANNEL_SET_OWNER].handler = &WorldSession::HandleChannelSetOwner;
WorldPacketHandlers[CMSG_CHANNEL_OWNER].handler = &WorldSession::HandleChannelOwner;
WorldPacketHandlers[CMSG_CHANNEL_MODERATOR].handler = &WorldSession::HandleChannelModerator;
WorldPacketHandlers[CMSG_CHANNEL_UNMODERATOR].handler = &WorldSession::HandleChannelUnmoderator;
WorldPacketHandlers[CMSG_CHANNEL_MUTE].handler = &WorldSession::HandleChannelMute;
WorldPacketHandlers[CMSG_CHANNEL_UNMUTE].handler = &WorldSession::HandleChannelUnmute;
WorldPacketHandlers[CMSG_CHANNEL_INVITE].handler = &WorldSession::HandleChannelInvite;
WorldPacketHandlers[CMSG_CHANNEL_KICK].handler = &WorldSession::HandleChannelKick;
WorldPacketHandlers[CMSG_CHANNEL_BAN].handler = &WorldSession::HandleChannelBan;
WorldPacketHandlers[CMSG_CHANNEL_UNBAN].handler = &WorldSession::HandleChannelUnban;
WorldPacketHandlers[CMSG_CHANNEL_ANNOUNCEMENTS].handler = &WorldSession::HandleChannelAnnounce;
WorldPacketHandlers[CMSG_CHANNEL_MODERATE].handler = &WorldSession::HandleChannelModerate;
// Groups / Raids
WorldPacketHandlers[CMSG_GROUP_INVITE].handler = &WorldSession::HandleGroupInviteOpcode;
WorldPacketHandlers[CMSG_GROUP_CANCEL].handler = &WorldSession::HandleGroupCancelOpcode;
WorldPacketHandlers[CMSG_GROUP_ACCEPT].handler = &WorldSession::HandleGroupAcceptOpcode;
WorldPacketHandlers[CMSG_GROUP_DECLINE].handler = &WorldSession::HandleGroupDeclineOpcode;
WorldPacketHandlers[CMSG_GROUP_UNINVITE].handler = &WorldSession::HandleGroupUninviteOpcode;
WorldPacketHandlers[CMSG_GROUP_UNINVITE_GUID].handler = &WorldSession::HandleGroupUninviteGuildOpcode;
WorldPacketHandlers[CMSG_GROUP_SET_LEADER].handler = &WorldSession::HandleGroupSetLeaderOpcode;
WorldPacketHandlers[CMSG_GROUP_DISBAND].handler = &WorldSession::HandleGroupDisbandOpcode;
WorldPacketHandlers[CMSG_LOOT_METHOD].handler = &WorldSession::HandleLootMethodOpcode;
WorldPacketHandlers[MSG_MINIMAP_PING].handler = &WorldSession::HandleMinimapPingOpcode;
WorldPacketHandlers[CMSG_GROUP_RAID_CONVERT].handler = &WorldSession::HandleConvertGroupToRaidOpcode;
WorldPacketHandlers[CMSG_GROUP_CHANGE_SUB_GROUP].handler = &WorldSession::HandleGroupChangeSubGroup;
WorldPacketHandlers[CMSG_GROUP_ASSISTANT_LEADER].handler = &WorldSession::HandleGroupAssistantLeader;
WorldPacketHandlers[CMSG_REQUEST_RAID_INFO].handler = &WorldSession::HandleRequestRaidInfoOpcode;
WorldPacketHandlers[CMSG_RAID_READYCHECK].handler = &WorldSession::HandleReadyCheckOpcode;
WorldPacketHandlers[MSG_GROUP_SET_PLAYER_ICON].handler = &WorldSession::HandleSetPlayerIconOpcode;
WorldPacketHandlers[CMSG_REQUEST_PARTY_MEMBER_STATS].handler = &WorldSession::HandlePartyMemberStatsOpcode;
// LFG System
WorldPacketHandlers[CMSG_SET_LOOKING_FOR_GROUP_COMMENT].handler = &WorldSession::HandleSetLookingForGroupComment;
WorldPacketHandlers[MSG_LOOKING_FOR_GROUP].handler = &WorldSession::HandleMsgLookingForGroup;
WorldPacketHandlers[CMSG_SET_LOOKING_FOR_GROUP].handler = &WorldSession::HandleSetLookingForGroup;
WorldPacketHandlers[CMSG_ENABLE_AUTOJOIN].handler = &WorldSession::HandleEnableAutoJoin;
WorldPacketHandlers[CMSG_DISABLE_AUTOJOIN].handler = &WorldSession::HandleDisableAutoJoin;
WorldPacketHandlers[CMSG_ENABLE_AUTOADD_MEMBERS].handler = &WorldSession::HandleEnableAutoAddMembers;
WorldPacketHandlers[CMSG_DISABLE_AUTOADD_MEMBERS].handler = &WorldSession::HandleDisableAutoAddMembers;
// Taxi / NPC Interaction
WorldPacketHandlers[CMSG_TAXINODE_STATUS_QUERY].handler = &WorldSession::HandleTaxiNodeStatusQueryOpcode;
WorldPacketHandlers[CMSG_TAXIQUERYAVAILABLENODES].handler = &WorldSession::HandleTaxiQueryAvaibleNodesOpcode;
WorldPacketHandlers[CMSG_ACTIVATETAXI].handler = &WorldSession::HandleActivateTaxiOpcode;
WorldPacketHandlers[MSG_TABARDVENDOR_ACTIVATE].handler = &WorldSession::HandleTabardVendorActivateOpcode;
WorldPacketHandlers[CMSG_BANKER_ACTIVATE].handler = &WorldSession::HandleBankerActivateOpcode;
WorldPacketHandlers[CMSG_BUY_BANK_SLOT].handler = &WorldSession::HandleBuyBankSlotOpcode;
WorldPacketHandlers[CMSG_TRAINER_LIST].handler = &WorldSession::HandleTrainerListOpcode;
WorldPacketHandlers[CMSG_TRAINER_BUY_SPELL].handler = &WorldSession::HandleTrainerBuySpellOpcode;
WorldPacketHandlers[CMSG_PETITION_SHOWLIST].handler = &WorldSession::HandleCharterShowListOpcode;
WorldPacketHandlers[MSG_AUCTION_HELLO].handler = &WorldSession::HandleAuctionHelloOpcode;
WorldPacketHandlers[CMSG_GOSSIP_HELLO].handler = &WorldSession::HandleGossipHelloOpcode;
WorldPacketHandlers[CMSG_GOSSIP_SELECT_OPTION].handler = &WorldSession::HandleGossipSelectOptionOpcode;
WorldPacketHandlers[CMSG_SPIRIT_HEALER_ACTIVATE].handler = &WorldSession::HandleSpiritHealerActivateOpcode;
WorldPacketHandlers[CMSG_NPC_TEXT_QUERY].handler = &WorldSession::HandleNpcTextQueryOpcode;
WorldPacketHandlers[CMSG_BINDER_ACTIVATE].handler = &WorldSession::HandleBinderActivateOpcode;
WorldPacketHandlers[CMSG_ACTIVATE_MULTIPLE_TAXI].handler = &WorldSession::HandleMultipleActivateTaxiOpcode;
// Item / Vendors
WorldPacketHandlers[CMSG_SWAP_INV_ITEM].handler = &WorldSession::HandleSwapInvItemOpcode;
WorldPacketHandlers[CMSG_SWAP_ITEM].handler = &WorldSession::HandleSwapItemOpcode;
WorldPacketHandlers[CMSG_DESTROYITEM].handler = &WorldSession::HandleDestroyItemOpcode;
WorldPacketHandlers[CMSG_AUTOEQUIP_ITEM].handler = &WorldSession::HandleAutoEquipItemOpcode;
WorldPacketHandlers[CMSG_ITEM_QUERY_SINGLE].handler = &WorldSession::HandleItemQuerySingleOpcode;
WorldPacketHandlers[CMSG_SELL_ITEM].handler = &WorldSession::HandleSellItemOpcode;
WorldPacketHandlers[CMSG_BUY_ITEM_IN_SLOT].handler = &WorldSession::HandleBuyItemInSlotOpcode;
WorldPacketHandlers[CMSG_BUY_ITEM].handler = &WorldSession::HandleBuyItemOpcode;
WorldPacketHandlers[CMSG_LIST_INVENTORY].handler = &WorldSession::HandleListInventoryOpcode;
WorldPacketHandlers[CMSG_AUTOSTORE_BAG_ITEM].handler = &WorldSession::HandleAutoStoreBagItemOpcode;
WorldPacketHandlers[CMSG_SET_AMMO].handler = &WorldSession::HandleAmmoSetOpcode;
WorldPacketHandlers[CMSG_BUYBACK_ITEM].handler = &WorldSession::HandleBuyBackOpcode;
WorldPacketHandlers[CMSG_SPLIT_ITEM].handler = &WorldSession::HandleSplitOpcode;
WorldPacketHandlers[CMSG_READ_ITEM].handler = &WorldSession::HandleReadItemOpcode;
WorldPacketHandlers[CMSG_REPAIR_ITEM].handler = &WorldSession::HandleRepairItemOpcode;
WorldPacketHandlers[CMSG_AUTOBANK_ITEM].handler = &WorldSession::HandleAutoBankItemOpcode;
WorldPacketHandlers[CMSG_AUTOSTORE_BANK_ITEM].handler = &WorldSession::HandleAutoStoreBankItemOpcode;
WorldPacketHandlers[CMSG_CANCEL_TEMPORARY_ENCHANTMENT].handler = &WorldSession::HandleCancelTemporaryEnchantmentOpcode;
WorldPacketHandlers[CMSG_SOCKET_GEMS].handler = &WorldSession::HandleInsertGemOpcode;
// Spell System / Talent System
WorldPacketHandlers[CMSG_USE_ITEM].handler = &WorldSession::HandleUseItemOpcode;
WorldPacketHandlers[CMSG_CAST_SPELL].handler = &WorldSession::HandleCastSpellOpcode;
WorldPacketHandlers[CMSG_CANCEL_CAST].handler = &WorldSession::HandleCancelCastOpcode;
WorldPacketHandlers[CMSG_CANCEL_AURA].handler = &WorldSession::HandleCancelAuraOpcode;
WorldPacketHandlers[CMSG_CANCEL_CHANNELLING].handler = &WorldSession::HandleCancelChannellingOpcode;
WorldPacketHandlers[CMSG_CANCEL_AUTO_REPEAT_SPELL].handler = &WorldSession::HandleCancelAutoRepeatSpellOpcode;
WorldPacketHandlers[CMSG_LEARN_TALENT].handler = &WorldSession::HandleLearnTalentOpcode;
WorldPacketHandlers[CMSG_UNLEARN_TALENTS].handler = &WorldSession::HandleUnlearnTalents;
WorldPacketHandlers[MSG_TALENT_WIPE_CONFIRM].handler = &WorldSession::HandleUnlearnTalents;
// Combat / Duel
WorldPacketHandlers[CMSG_ATTACKSWING].handler = &WorldSession::HandleAttackSwingOpcode;
WorldPacketHandlers[CMSG_ATTACKSTOP].handler = &WorldSession::HandleAttackStopOpcode;
WorldPacketHandlers[CMSG_DUEL_ACCEPTED].handler = &WorldSession::HandleDuelAccepted;
WorldPacketHandlers[CMSG_DUEL_CANCELLED].handler = &WorldSession::HandleDuelCancelled;
// Trade
WorldPacketHandlers[CMSG_INITIATE_TRADE].handler = &WorldSession::HandleInitiateTrade;
WorldPacketHandlers[CMSG_BEGIN_TRADE].handler = &WorldSession::HandleBeginTrade;
WorldPacketHandlers[CMSG_BUSY_TRADE].handler = &WorldSession::HandleBusyTrade;
WorldPacketHandlers[CMSG_IGNORE_TRADE].handler = &WorldSession::HandleIgnoreTrade;
WorldPacketHandlers[CMSG_ACCEPT_TRADE].handler = &WorldSession::HandleAcceptTrade;
WorldPacketHandlers[CMSG_UNACCEPT_TRADE].handler = &WorldSession::HandleUnacceptTrade;
WorldPacketHandlers[CMSG_CANCEL_TRADE].handler = &WorldSession::HandleCancelTrade;
WorldPacketHandlers[CMSG_SET_TRADE_ITEM].handler = &WorldSession::HandleSetTradeItem;
WorldPacketHandlers[CMSG_CLEAR_TRADE_ITEM].handler = &WorldSession::HandleClearTradeItem;
WorldPacketHandlers[CMSG_SET_TRADE_GOLD].handler = &WorldSession::HandleSetTradeGold;
// Quest System
WorldPacketHandlers[CMSG_QUESTGIVER_STATUS_QUERY].handler = &WorldSession::HandleQuestgiverStatusQueryOpcode;
WorldPacketHandlers[CMSG_QUESTGIVER_HELLO].handler = &WorldSession::HandleQuestgiverHelloOpcode;
WorldPacketHandlers[CMSG_QUESTGIVER_ACCEPT_QUEST].handler = &WorldSession::HandleQuestgiverAcceptQuestOpcode;
WorldPacketHandlers[CMSG_QUESTGIVER_CANCEL].handler = &WorldSession::HandleQuestgiverCancelOpcode;
WorldPacketHandlers[CMSG_QUESTGIVER_CHOOSE_REWARD].handler = &WorldSession::HandleQuestgiverChooseRewardOpcode;
WorldPacketHandlers[CMSG_QUESTGIVER_REQUEST_REWARD].handler = &WorldSession::HandleQuestgiverRequestRewardOpcode;
WorldPacketHandlers[CMSG_QUEST_QUERY].handler = &WorldSession::HandleQuestQueryOpcode;
WorldPacketHandlers[CMSG_QUESTGIVER_QUERY_QUEST].handler = &WorldSession::HandleQuestGiverQueryQuestOpcode;
WorldPacketHandlers[CMSG_QUESTGIVER_COMPLETE_QUEST].handler = &WorldSession::HandleQuestgiverCompleteQuestOpcode;
WorldPacketHandlers[CMSG_QUESTLOG_REMOVE_QUEST].handler = &WorldSession::HandleQuestlogRemoveQuestOpcode;
WorldPacketHandlers[CMSG_RECLAIM_CORPSE].handler = &WorldSession::HandleCorpseReclaimOpcode;
WorldPacketHandlers[CMSG_RESURRECT_RESPONSE].handler = &WorldSession::HandleResurrectResponseOpcode;
WorldPacketHandlers[CMSG_PUSHQUESTTOPARTY].handler = &WorldSession::HandlePushQuestToPartyOpcode;
WorldPacketHandlers[MSG_QUEST_PUSH_RESULT].handler = &WorldSession::HandleQuestPushResult;
// Auction System
WorldPacketHandlers[CMSG_AUCTION_LIST_ITEMS].handler = &WorldSession::HandleAuctionListItems;
WorldPacketHandlers[CMSG_AUCTION_LIST_BIDDER_ITEMS].handler = &WorldSession::HandleAuctionListBidderItems;
WorldPacketHandlers[CMSG_AUCTION_SELL_ITEM].handler = &WorldSession::HandleAuctionSellItem;
WorldPacketHandlers[CMSG_AUCTION_LIST_OWNER_ITEMS].handler = &WorldSession::HandleAuctionListOwnerItems;
WorldPacketHandlers[CMSG_AUCTION_PLACE_BID].handler = &WorldSession::HandleAuctionPlaceBid;
WorldPacketHandlers[CMSG_AUCTION_REMOVE_ITEM].handler = &WorldSession::HandleCancelAuction;
// Mail System
WorldPacketHandlers[CMSG_GET_MAIL_LIST].handler = &WorldSession::HandleGetMail;
WorldPacketHandlers[CMSG_ITEM_TEXT_QUERY].handler = &WorldSession::HandleItemTextQuery;
WorldPacketHandlers[CMSG_SEND_MAIL].handler = &WorldSession::HandleSendMail;
WorldPacketHandlers[CMSG_MAIL_TAKE_MONEY].handler = &WorldSession::HandleTakeMoney;
WorldPacketHandlers[CMSG_MAIL_TAKE_ITEM].handler = &WorldSession::HandleTakeItem;
WorldPacketHandlers[CMSG_MAIL_MARK_AS_READ].handler = &WorldSession::HandleMarkAsRead;
WorldPacketHandlers[CMSG_MAIL_RETURN_TO_SENDER].handler = &WorldSession::HandleReturnToSender;
WorldPacketHandlers[CMSG_MAIL_DELETE].handler = &WorldSession::HandleMailDelete;
WorldPacketHandlers[MSG_QUERY_NEXT_MAIL_TIME].handler = &WorldSession::HandleMailTime;
WorldPacketHandlers[CMSG_MAIL_CREATE_TEXT_ITEM].handler = &WorldSession::HandleMailCreateTextItem;
// Guild Query (called when not logged in sometimes)
WorldPacketHandlers[CMSG_GUILD_QUERY].handler = &WorldSession::HandleGuildQuery;
WorldPacketHandlers[CMSG_GUILD_QUERY].status = STATUS_AUTHED;
// Guild System
WorldPacketHandlers[CMSG_GUILD_CREATE].handler = &WorldSession::HandleCreateGuild;
WorldPacketHandlers[CMSG_GUILD_INVITE].handler = &WorldSession::HandleInviteToGuild;
WorldPacketHandlers[CMSG_GUILD_ACCEPT].handler = &WorldSession::HandleGuildAccept;
WorldPacketHandlers[CMSG_GUILD_DECLINE].handler = &WorldSession::HandleGuildDecline;
WorldPacketHandlers[CMSG_GUILD_INFO].handler = &WorldSession::HandleGuildInfo;
WorldPacketHandlers[CMSG_GUILD_ROSTER].handler = &WorldSession::HandleGuildRoster;
WorldPacketHandlers[CMSG_GUILD_PROMOTE].handler = &WorldSession::HandleGuildPromote;
WorldPacketHandlers[CMSG_GUILD_DEMOTE].handler = &WorldSession::HandleGuildDemote;
WorldPacketHandlers[CMSG_GUILD_LEAVE].handler = &WorldSession::HandleGuildLeave;
WorldPacketHandlers[CMSG_GUILD_REMOVE].handler = &WorldSession::HandleGuildRemove;
WorldPacketHandlers[CMSG_GUILD_DISBAND].handler = &WorldSession::HandleGuildDisband;
WorldPacketHandlers[CMSG_GUILD_LEADER].handler = &WorldSession::HandleGuildLeader;
WorldPacketHandlers[CMSG_GUILD_MOTD].handler = &WorldSession::HandleGuildMotd;
WorldPacketHandlers[CMSG_GUILD_RANK].handler = &WorldSession::HandleGuildRank;
WorldPacketHandlers[CMSG_GUILD_ADD_RANK].handler = &WorldSession::HandleGuildAddRank;
WorldPacketHandlers[CMSG_GUILD_DEL_RANK].handler = &WorldSession::HandleGuildDelRank;
WorldPacketHandlers[CMSG_GUILD_SET_PUBLIC_NOTE].handler = &WorldSession::HandleGuildSetPublicNote;
WorldPacketHandlers[CMSG_GUILD_SET_OFFICER_NOTE].handler = &WorldSession::HandleGuildSetOfficerNote;
WorldPacketHandlers[CMSG_PETITION_BUY].handler = &WorldSession::HandleCharterBuy;
WorldPacketHandlers[CMSG_PETITION_SHOW_SIGNATURES].handler = &WorldSession::HandleCharterShowSignatures;
WorldPacketHandlers[CMSG_TURN_IN_PETITION].handler = &WorldSession::HandleCharterTurnInCharter;
WorldPacketHandlers[CMSG_PETITION_QUERY].handler = &WorldSession::HandleCharterQuery;
WorldPacketHandlers[CMSG_OFFER_PETITION].handler = &WorldSession::HandleCharterOffer;
WorldPacketHandlers[CMSG_PETITION_SIGN].handler = &WorldSession::HandleCharterSign;
WorldPacketHandlers[MSG_PETITION_RENAME].handler = &WorldSession::HandleCharterRename;
WorldPacketHandlers[MSG_SAVE_GUILD_EMBLEM].handler = &WorldSession::HandleSaveGuildEmblem;
WorldPacketHandlers[CMSG_SET_GUILD_INFORMATION].handler = &WorldSession::HandleSetGuildInformation;
// Tutorials
WorldPacketHandlers[CMSG_TUTORIAL_FLAG].handler = &WorldSession::HandleTutorialFlag;
WorldPacketHandlers[CMSG_TUTORIAL_CLEAR].handler = &WorldSession::HandleTutorialClear;
WorldPacketHandlers[CMSG_TUTORIAL_RESET].handler = &WorldSession::HandleTutorialReset;
// Pets
WorldPacketHandlers[CMSG_PET_ACTION].handler = &WorldSession::HandlePetAction;
WorldPacketHandlers[CMSG_REQUEST_PET_INFO].handler = &WorldSession::HandlePetInfo;
WorldPacketHandlers[CMSG_PET_NAME_QUERY].handler = &WorldSession::HandlePetNameQuery;
WorldPacketHandlers[CMSG_BUY_STABLE_SLOT].handler = &WorldSession::HandleBuyStableSlot;
WorldPacketHandlers[CMSG_STABLE_PET].handler = &WorldSession::HandleStablePet;
WorldPacketHandlers[CMSG_UNSTABLE_PET].handler = &WorldSession::HandleUnstablePet;
WorldPacketHandlers[MSG_LIST_STABLED_PETS].handler = &WorldSession::HandleStabledPetList;
WorldPacketHandlers[CMSG_PET_SET_ACTION].handler = &WorldSession::HandlePetSetActionOpcode;
WorldPacketHandlers[CMSG_PET_RENAME].handler = &WorldSession::HandlePetRename;
WorldPacketHandlers[CMSG_PET_ABANDON].handler = &WorldSession::HandlePetAbandon;
// Battlegrounds
WorldPacketHandlers[CMSG_BATTLEFIELD_PORT].handler = &WorldSession::HandleBattlefieldPortOpcode;
WorldPacketHandlers[CMSG_BATTLEFIELD_STATUS].handler = &WorldSession::HandleBattlefieldStatusOpcode;
WorldPacketHandlers[CMSG_BATTLEFIELD_LIST].handler = &WorldSession::HandleBattlefieldListOpcode;
WorldPacketHandlers[CMSG_BATTLEMASTER_HELLO].handler = &WorldSession::HandleBattleMasterHelloOpcode;
WorldPacketHandlers[CMSG_ARENA_JOIN].handler = &WorldSession::HandleArenaJoinOpcode;
WorldPacketHandlers[CMSG_BATTLEMASTER_JOIN].handler = &WorldSession::HandleBattleMasterJoinOpcode;
WorldPacketHandlers[CMSG_LEAVE_BATTLEFIELD].handler = &WorldSession::HandleLeaveBattlefieldOpcode;
WorldPacketHandlers[CMSG_AREA_SPIRIT_HEALER_QUERY].handler = &WorldSession::HandleAreaSpiritHealerQueryOpcode;
WorldPacketHandlers[CMSG_AREA_SPIRIT_HEALER_QUEUE].handler = &WorldSession::HandleAreaSpiritHealerQueueOpcode;
WorldPacketHandlers[MSG_BATTLEGROUND_PLAYER_POSITIONS].handler = &WorldSession::HandleBattlegroundPlayerPositionsOpcode;
WorldPacketHandlers[MSG_PVP_LOG_DATA].handler = &WorldSession::HandlePVPLogDataOpcode;
WorldPacketHandlers[MSG_INSPECT_HONOR_STATS].handler = &WorldSession::HandleInspectHonorStatsOpcode;
WorldPacketHandlers[CMSG_SET_ACTIONBAR_TOGGLES].handler = &WorldSession::HandleSetActionBarTogglesOpcode;
WorldPacketHandlers[CMSG_MOVE_SPLINE_DONE].handler = &WorldSession::HandleMoveSplineCompleteOpcode;
// GM Ticket System
WorldPacketHandlers[CMSG_GMTICKET_CREATE].handler = &WorldSession::HandleGMTicketCreateOpcode;
WorldPacketHandlers[CMSG_GMTICKET_UPDATETEXT].handler = &WorldSession::HandleGMTicketUpdateOpcode;
WorldPacketHandlers[CMSG_GMTICKET_DELETETICKET].handler = &WorldSession::HandleGMTicketDeleteOpcode;
WorldPacketHandlers[CMSG_GMTICKET_GETTICKET].handler = &WorldSession::HandleGMTicketGetTicketOpcode;
WorldPacketHandlers[CMSG_GMTICKET_SYSTEMSTATUS].handler = &WorldSession::HandleGMTicketSystemStatusOpcode;
WorldPacketHandlers[CMSG_GMTICKETSYSTEM_TOGGLE].handler = &WorldSession::HandleGMTicketToggleSystemStatusOpcode;
WorldPacketHandlers[CMSG_UNLEARN_SKILL].handler = &WorldSession::HandleUnlearnSkillOpcode;
// Meeting Stone / Instances
WorldPacketHandlers[CMSG_SUMMON_RESPONSE].handler = &WorldSession::HandleSummonResponseOpcode;
WorldPacketHandlers[CMSG_RESET_INSTANCE].handler = &WorldSession::HandleResetInstanceOpcode;
WorldPacketHandlers[CMSG_SELF_RES].handler = &WorldSession::HandleSelfResurrectOpcode;
WorldPacketHandlers[MSG_RANDOM_ROLL].handler = &WorldSession::HandleRandomRollOpcode;
WorldPacketHandlers[CMSG_DUNGEON_DIFFICULTY].handler = &WorldSession::HandleDungeonDifficultyOpcode;
// Misc
WorldPacketHandlers[CMSG_OPEN_ITEM].handler = &WorldSession::HandleOpenItemOpcode;
WorldPacketHandlers[CMSG_COMPLETE_CINEMATIC].handler = &WorldSession::HandleCompleteCinematic;
WorldPacketHandlers[CMSG_MOUNTSPECIAL_ANIM].handler = &WorldSession::HandleMountSpecialAnimOpcode;
WorldPacketHandlers[CMSG_TOGGLE_CLOAK].handler = &WorldSession::HandleToggleCloakOpcode;
WorldPacketHandlers[CMSG_TOGGLE_HELM].handler = &WorldSession::HandleToggleHelmOpcode;
WorldPacketHandlers[CMSG_SET_VISIBLE_RANK].handler = &WorldSession::HandleSetVisibleRankOpcode;
WorldPacketHandlers[CMSG_REPORT_SPAM].handler = &WorldSession::HandleReportSpamOpcode;
WorldPacketHandlers[MSG_ADD_DYNAMIC_TARGET_OBSOLETE].handler = &WorldSession::HandleAddDynamicTargetOpcode;
#ifdef CLUSTERING
WorldPacketHandlers[CMSG_PING].handler = &WorldSession::HandlePingOpcode;
#endif
}
void WorldSession::CHECK_PACKET_SIZE(WorldPacket& data, uint32 size)
{
if(data.size() < size && size)
{
// write to file
sCheatLog.writefromsession(this, "kicked for invalid packet (opcode %u), size %u less than %u", data.GetOpcode(), data.size(), size);
// disconnect
Disconnect();
}
}
void SessionLogWriter::writefromsession(WorldSession* session, const char* format, ...)
{
if(!IsOpen())
return;
va_list ap;
va_start(ap, format);
char out[32768];
time_t t = time(NULL);
tm* aTm = localtime(&t);
snprintf(out, 32768, "[%-4d-%02d-%02d %02d:%02d:%02d] ",aTm->tm_year+1900,aTm->tm_mon+1,aTm->tm_mday,aTm->tm_hour,aTm->tm_min,aTm->tm_sec);
int l = strlen(out);
snprintf(&out[l], 32768 - l, "Account %u [%s], IP %s, Player %s :: ", (unsigned int)session->GetAccountId(), session->GetAccountName().c_str(),
session->GetSocket() ? session->GetSocket()->GetRemoteIP().c_str() : "NOIP",
session->GetPlayer() ? session->GetPlayer()->GetName() : "nologin");
l = strlen(out);
vsnprintf(&out[l], 32768 - l, format, ap);
fprintf(m_file, "%s\n", out);
fflush(m_file);
va_end(ap);
}
#ifdef CLUSTERING
void WorldSession::HandlePingOpcode(WorldPacket& recvPacket)
{
uint32 pong;
recvPacket >> pong;
WorldPacket data(SMSG_PONG, 4);
data << pong;
SendPacket(&data);
}
#endif