Initial Commit for client version change to 4.2.2 (14545)
- added known opcodes (handlers are commented till not updated) - added bitstream support to bytebuffer - updated realm auth for 14545 - updated world auth - fixed char_enum,create,delete handlers - added DB2 reader - added opcode logging to debuglogmask (ignores loglevel) - fixed compile in win64, others not yet tested - using db2 values for item models at char_enum to prevent client crash Lots of Thanks to All SingularityCore Members
This commit is contained in:
@@ -43,16 +43,26 @@
|
||||
#include "ScriptMgr.h"
|
||||
#include "Transport.h"
|
||||
|
||||
Opcodes PacketFilter::DropHighBytes(Opcodes opcode)
|
||||
{
|
||||
if (opcode & 0xFFFF0000) // check if any High byte is present
|
||||
return Opcodes(opcode >> 16);
|
||||
|
||||
else
|
||||
return Opcodes(opcode);
|
||||
}
|
||||
|
||||
bool MapSessionFilter::Process(WorldPacket* packet)
|
||||
{
|
||||
OpcodeHandler const &opHandle = opcodeTable[packet->GetOpcode()];
|
||||
Opcodes opcode = DropHighBytes(packet->GetOpcode());
|
||||
const OpcodeHandler* opHandle = opcodeTable[opcode];
|
||||
|
||||
//let's check if our opcode can be really processed in Map::Update()
|
||||
if (opHandle.packetProcessing == PROCESS_INPLACE)
|
||||
if (opHandle->packetProcessing == PROCESS_INPLACE)
|
||||
return true;
|
||||
|
||||
//we do not process thread-unsafe packets
|
||||
if (opHandle.packetProcessing == PROCESS_THREADUNSAFE)
|
||||
if (opHandle->packetProcessing == PROCESS_THREADUNSAFE)
|
||||
return false;
|
||||
|
||||
Player* player = m_pSession->GetPlayer();
|
||||
@@ -67,13 +77,14 @@ bool MapSessionFilter::Process(WorldPacket* packet)
|
||||
//OR packet handler is not thread-safe!
|
||||
bool WorldSessionFilter::Process(WorldPacket* packet)
|
||||
{
|
||||
OpcodeHandler const &opHandle = opcodeTable[packet->GetOpcode()];
|
||||
Opcodes opcode = DropHighBytes(packet->GetOpcode());
|
||||
const OpcodeHandler* opHandle = opcodeTable[opcode];
|
||||
//check if packet handler is supposed to be safe
|
||||
if (opHandle.packetProcessing == PROCESS_INPLACE)
|
||||
if (opHandle->packetProcessing == PROCESS_INPLACE)
|
||||
return true;
|
||||
|
||||
//thread-unsafe packets should be processed in World::UpdateSessions()
|
||||
if (opHandle.packetProcessing == PROCESS_THREADUNSAFE)
|
||||
if (opHandle->packetProcessing == PROCESS_THREADUNSAFE)
|
||||
return true;
|
||||
|
||||
//no player attached? -> our client! ^^
|
||||
@@ -148,6 +159,14 @@ void WorldSession::SendPacket(WorldPacket const* packet)
|
||||
if (!m_Socket)
|
||||
return;
|
||||
|
||||
if (packet->GetOpcode() == UNKNOWN_OPCODE)
|
||||
{
|
||||
sLog->outError("Sending unknown opcode - prevented. Trace:");
|
||||
ACE_Stack_Trace trace;
|
||||
sLog->outError("%s", trace.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef TRINITY_DEBUG
|
||||
// Code for network use statistic
|
||||
static uint64 sendPacketCount = 0;
|
||||
@@ -224,99 +243,91 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
|
||||
WorldPacket* packet = NULL;
|
||||
while (m_Socket && !m_Socket->IsClosed() && _recvQueue.next(packet, updater))
|
||||
{
|
||||
if (packet->GetOpcode() >= NUM_MSG_TYPES)
|
||||
const OpcodeHandler* opHandle = opcodeTable[packet->GetOpcode()];
|
||||
try
|
||||
{
|
||||
sLog->outError("SESSION: received non-existed opcode %s (0x%.4X)", LookupOpcodeName(packet->GetOpcode()), packet->GetOpcode());
|
||||
sScriptMgr->OnUnknownPacketReceive(m_Socket, WorldPacket(*packet));
|
||||
}
|
||||
else
|
||||
{
|
||||
OpcodeHandler &opHandle = opcodeTable[packet->GetOpcode()];
|
||||
try
|
||||
switch (opHandle->status)
|
||||
{
|
||||
switch (opHandle.status)
|
||||
{
|
||||
case STATUS_LOGGEDIN:
|
||||
if (!_player)
|
||||
{
|
||||
// skip STATUS_LOGGEDIN opcode unexpected errors if player logout sometime ago - this can be network lag delayed packets
|
||||
if (!m_playerRecentlyLogout)
|
||||
LogUnexpectedOpcode(packet, "STATUS_LOGGEDIN", "the player has not logged in yet");
|
||||
}
|
||||
else if (_player->IsInWorld())
|
||||
{
|
||||
sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet));
|
||||
(this->*opHandle.handler)(*packet);
|
||||
if (sLog->IsOutDebug() && packet->rpos() < packet->wpos())
|
||||
LogUnprocessedTail(packet);
|
||||
}
|
||||
// lag can cause STATUS_LOGGEDIN opcodes to arrive after the player started a transfer
|
||||
break;
|
||||
case STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT:
|
||||
if (!_player && !m_playerRecentlyLogout)
|
||||
LogUnexpectedOpcode(packet, "STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT",
|
||||
"the player has not logged in yet and not recently logout");
|
||||
else
|
||||
{
|
||||
// not expected _player or must checked in packet hanlder
|
||||
sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet));
|
||||
(this->*opHandle.handler)(*packet);
|
||||
if (sLog->IsOutDebug() && packet->rpos() < packet->wpos())
|
||||
LogUnprocessedTail(packet);
|
||||
}
|
||||
break;
|
||||
case STATUS_TRANSFER:
|
||||
if (!_player)
|
||||
LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player has not logged in yet");
|
||||
else if (_player->IsInWorld())
|
||||
LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player is still in world");
|
||||
else
|
||||
{
|
||||
sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet));
|
||||
(this->*opHandle.handler)(*packet);
|
||||
if (sLog->IsOutDebug() && packet->rpos() < packet->wpos())
|
||||
LogUnprocessedTail(packet);
|
||||
}
|
||||
break;
|
||||
case STATUS_AUTHED:
|
||||
// prevent cheating with skip queue wait
|
||||
if (m_inQueue)
|
||||
{
|
||||
LogUnexpectedOpcode(packet, "STATUS_AUTHED", "the player not pass queue yet");
|
||||
break;
|
||||
}
|
||||
|
||||
// single from authed time opcodes send in to after logout time
|
||||
// and before other STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT opcodes.
|
||||
if (packet->GetOpcode() != CMSG_SET_ACTIVE_VOICE_CHANNEL)
|
||||
m_playerRecentlyLogout = false;
|
||||
|
||||
case STATUS_LOGGEDIN:
|
||||
if (!_player)
|
||||
{
|
||||
// skip STATUS_LOGGEDIN opcode unexpected errors if player logout sometime ago - this can be network lag delayed packets
|
||||
if (!m_playerRecentlyLogout)
|
||||
LogUnexpectedOpcode(packet, "STATUS_LOGGEDIN", "the player has not logged in yet");
|
||||
}
|
||||
else if (_player->IsInWorld())
|
||||
{
|
||||
sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet));
|
||||
(this->*opHandle.handler)(*packet);
|
||||
(this->*opHandle->handler)(*packet);
|
||||
if (sLog->IsOutDebug() && packet->rpos() < packet->wpos())
|
||||
LogUnprocessedTail(packet);
|
||||
}
|
||||
// lag can cause STATUS_LOGGEDIN opcodes to arrive after the player started a transfer
|
||||
break;
|
||||
case STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT:
|
||||
if (!_player && !m_playerRecentlyLogout)
|
||||
LogUnexpectedOpcode(packet, "STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT",
|
||||
"the player has not logged in yet and not recently logout");
|
||||
else
|
||||
{
|
||||
// not expected _player or must checked in packet hanlder
|
||||
sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet));
|
||||
(this->*opHandle->handler)(*packet);
|
||||
if (sLog->IsOutDebug() && packet->rpos() < packet->wpos())
|
||||
LogUnprocessedTail(packet);
|
||||
}
|
||||
break;
|
||||
case STATUS_TRANSFER:
|
||||
if (!_player)
|
||||
LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player has not logged in yet");
|
||||
else if (_player->IsInWorld())
|
||||
LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player is still in world");
|
||||
else
|
||||
{
|
||||
sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet));
|
||||
(this->*opHandle->handler)(*packet);
|
||||
if (sLog->IsOutDebug() && packet->rpos() < packet->wpos())
|
||||
LogUnprocessedTail(packet);
|
||||
}
|
||||
break;
|
||||
case STATUS_AUTHED:
|
||||
// prevent cheating with skip queue wait
|
||||
if (m_inQueue)
|
||||
{
|
||||
LogUnexpectedOpcode(packet, "STATUS_AUTHED", "the player not pass queue yet");
|
||||
break;
|
||||
case STATUS_NEVER:
|
||||
sLog->outError("SESSION (account: %u, guidlow: %u, char: %s): received not allowed opcode %s (0x%.4X)",
|
||||
GetAccountId(), m_GUIDLow, _player ? _player->GetName() : "<none>",
|
||||
LookupOpcodeName(packet->GetOpcode()), packet->GetOpcode());
|
||||
break;
|
||||
case STATUS_UNHANDLED:
|
||||
sLog->outDebug(LOG_FILTER_NETWORKIO, "SESSION (account: %u, guidlow: %u, char: %s): received not handled opcode %s (0x%.4X)",
|
||||
GetAccountId(), m_GUIDLow, _player ? _player->GetName() : "<none>",
|
||||
LookupOpcodeName(packet->GetOpcode()), packet->GetOpcode());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// single from authed time opcodes send in to after logout time
|
||||
// and before other STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT opcodes.
|
||||
if (packet->GetOpcode() != CMSG_SET_ACTIVE_VOICE_CHANNEL)
|
||||
m_playerRecentlyLogout = false;
|
||||
|
||||
sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet));
|
||||
(this->*opHandle->handler)(*packet);
|
||||
if (sLog->IsOutDebug() && packet->rpos() < packet->wpos())
|
||||
LogUnprocessedTail(packet);
|
||||
break;
|
||||
case STATUS_NEVER:
|
||||
sLog->outError("SESSION (account: %u, guidlow: %u, char: %s): received not allowed opcode %s (0x%.4X)",
|
||||
GetAccountId(), m_GUIDLow, _player ? _player->GetName() : "<none>",
|
||||
LookupOpcodeName(packet->GetOpcode()), packet->GetOpcode());
|
||||
break;
|
||||
case STATUS_UNHANDLED:
|
||||
sLog->outDebug(LOG_FILTER_NETWORKIO, "SESSION (account: %u, guidlow: %u, char: %s): received not handled opcode %s (0x%.4X)",
|
||||
GetAccountId(), m_GUIDLow, _player ? _player->GetName() : "<none>",
|
||||
LookupOpcodeName(packet->GetOpcode()), packet->GetOpcode());
|
||||
break;
|
||||
}
|
||||
catch(ByteBufferException &)
|
||||
}
|
||||
catch(ByteBufferException &)
|
||||
{
|
||||
sLog->outError("WorldSession::Update ByteBufferException occured while parsing a packet (opcode: %u) from client %s, accountid=%i. Skipped packet.",
|
||||
packet->GetOpcode(), GetRemoteAddress().c_str(), GetAccountId());
|
||||
if (sLog->IsOutDebug())
|
||||
{
|
||||
sLog->outError("WorldSession::Update ByteBufferException occured while parsing a packet (opcode: %u) from client %s, accountid=%i. Skipped packet.",
|
||||
packet->GetOpcode(), GetRemoteAddress().c_str(), GetAccountId());
|
||||
if (sLog->IsOutDebug())
|
||||
{
|
||||
sLog->outDebug(LOG_FILTER_NETWORKIO, "Dumping error causing packet:");
|
||||
packet->hexlike();
|
||||
}
|
||||
sLog->outDebug(LOG_FILTER_NETWORKIO, "Dumping error causing packet:");
|
||||
packet->hexlike();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user