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:
Rat
2011-11-20 18:28:18 +01:00
parent 10b89d976f
commit d1affc4340
43 changed files with 4130 additions and 3045 deletions
+102 -91
View File
@@ -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();
}
}