mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-22 18:15:31 +01:00
Core: Free memory allocated for opcode handlers at shutdown.
This commit is contained in:
@@ -19,46 +19,44 @@
|
||||
#include "Opcodes.h"
|
||||
#include "WorldSession.h"
|
||||
|
||||
OpcodeHandler* opcodeTable[NUM_OPCODE_HANDLERS] = { };
|
||||
OpcodeTable opcodeTable;
|
||||
|
||||
template<bool isInValidRange, bool isNonZero>
|
||||
inline void ValidateAndSetOpcode(uint16 /*opcode*/, char const* /*name*/, SessionStatus /*status*/, PacketProcessing /*processing*/, pOpcodeHandler /*handler*/)
|
||||
void OpcodeTable::ValidateAndSetOpcode(uint16 /*opcode*/, char const* /*name*/, SessionStatus /*status*/, PacketProcessing /*processing*/, pOpcodeHandler /*handler*/)
|
||||
{
|
||||
// if for some reason we are here, that means NUM_OPCODE_HANDLERS == 0 (or your compiler is broken)
|
||||
}
|
||||
|
||||
template<>
|
||||
void ValidateAndSetOpcode<true, true>(uint16 opcode, char const* name, SessionStatus status, PacketProcessing processing, pOpcodeHandler handler)
|
||||
void OpcodeTable::ValidateAndSetOpcode<true, true>(uint16 opcode, char const* name, SessionStatus status, PacketProcessing processing, pOpcodeHandler handler)
|
||||
{
|
||||
if (opcodeTable[opcode] != NULL)
|
||||
if (_internalTable[opcode] != NULL)
|
||||
{
|
||||
sLog->outError(LOG_FILTER_NETWORKIO, "Tried to override handler of %s with %s (opcode %u)", opcodeTable[opcode]->name, name, opcode);
|
||||
sLog->outError(LOG_FILTER_NETWORKIO, "Tried to override handler of %s with %s (opcode %u)", opcodeTable[opcode]->Name, name, opcode);
|
||||
return;
|
||||
}
|
||||
|
||||
opcodeTable[opcode] = new OpcodeHandler(name, status, processing, handler);
|
||||
_internalTable[opcode] = new OpcodeHandler(name, status, processing, handler);
|
||||
}
|
||||
|
||||
template<>
|
||||
void ValidateAndSetOpcode<false, true>(uint16 opcode, char const* /*name*/, SessionStatus /*status*/, PacketProcessing /*processing*/, pOpcodeHandler /*handler*/)
|
||||
void OpcodeTable::ValidateAndSetOpcode<false, true>(uint16 opcode, char const* /*name*/, SessionStatus /*status*/, PacketProcessing /*processing*/, pOpcodeHandler /*handler*/)
|
||||
{
|
||||
sLog->outError(LOG_FILTER_NETWORKIO, "Tried to set handler for an invalid opcode %d", opcode);
|
||||
}
|
||||
|
||||
template<>
|
||||
void ValidateAndSetOpcode<true, false>(uint16 /*opcode*/, char const* name, SessionStatus /*status*/, PacketProcessing /*processing*/, pOpcodeHandler /*handler*/)
|
||||
void OpcodeTable::ValidateAndSetOpcode<true, false>(uint16 /*opcode*/, char const* name, SessionStatus /*status*/, PacketProcessing /*processing*/, pOpcodeHandler /*handler*/)
|
||||
{
|
||||
sLog->outError(LOG_FILTER_NETWORKIO, "Opcode %s got value 0", name);
|
||||
}
|
||||
|
||||
/// Correspondence between opcodes and their names
|
||||
void OpcodeTable::Initialize()
|
||||
{
|
||||
#define DEFINE_OPCODE_HANDLER(opcode, status, processing, handler) \
|
||||
ValidateAndSetOpcode<(opcode < NUM_OPCODE_HANDLERS), (opcode != 0)>(opcode, #opcode, status, processing, handler);
|
||||
|
||||
/// Correspondence between opcodes and their names
|
||||
void InitOpcodes()
|
||||
{
|
||||
memset(opcodeTable, 0, sizeof(opcodeTable));
|
||||
|
||||
DEFINE_OPCODE_HANDLER(CMSG_ACCEPT_LEVEL_GRANT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAcceptGrantLevel );
|
||||
DEFINE_OPCODE_HANDLER(CMSG_ACCEPT_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAcceptTradeOpcode );
|
||||
DEFINE_OPCODE_HANDLER(CMSG_ACTIVATETAXI, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleActivateTaxiOpcode );
|
||||
|
||||
@@ -1420,15 +1420,48 @@ struct OpcodeHandler
|
||||
{
|
||||
OpcodeHandler() {}
|
||||
OpcodeHandler(char const* _name, SessionStatus _status, PacketProcessing _processing, pOpcodeHandler _handler)
|
||||
: name(_name), status(_status), packetProcessing(_processing), handler(_handler) {}
|
||||
: Name(_name), Status(_status), ProcessingPlace(_processing), Handler(_handler) {}
|
||||
|
||||
char const* name;
|
||||
SessionStatus status;
|
||||
PacketProcessing packetProcessing;
|
||||
pOpcodeHandler handler;
|
||||
char const* Name;
|
||||
SessionStatus Status;
|
||||
PacketProcessing ProcessingPlace;
|
||||
pOpcodeHandler Handler;
|
||||
};
|
||||
|
||||
extern OpcodeHandler* opcodeTable[NUM_OPCODE_HANDLERS];
|
||||
class OpcodeTable
|
||||
{
|
||||
public:
|
||||
OpcodeTable()
|
||||
{
|
||||
memset(_internalTable, 0, sizeof(_internalTable));
|
||||
}
|
||||
|
||||
~OpcodeTable()
|
||||
{
|
||||
for (uint16 i = 0; i < NUM_OPCODE_HANDLERS; ++i)
|
||||
delete _internalTable[i];
|
||||
}
|
||||
|
||||
void Initialize();
|
||||
|
||||
OpcodeHandler const* operator[](uint32 index) const
|
||||
{
|
||||
return _internalTable[index];
|
||||
}
|
||||
|
||||
private:
|
||||
template<bool isInValidRange, bool isNonZero>
|
||||
void ValidateAndSetOpcode(uint16 opcode, char const* name, SessionStatus status, PacketProcessing processing, pOpcodeHandler handler);
|
||||
|
||||
// Prevent copying this structure
|
||||
OpcodeTable(OpcodeTable const&);
|
||||
OpcodeTable& operator=(OpcodeTable& const);
|
||||
|
||||
OpcodeHandler* _internalTable[NUM_OPCODE_HANDLERS];
|
||||
};
|
||||
|
||||
extern OpcodeTable opcodeTable;
|
||||
|
||||
void InitOpcodes();
|
||||
|
||||
/// Lookup opcode name for human understandable logging
|
||||
@@ -1440,9 +1473,9 @@ inline std::string GetOpcodeNameForLogging(Opcodes id)
|
||||
|
||||
if (id < UNKNOWN_OPCODE)
|
||||
{
|
||||
if (OpcodeHandler* handler = opcodeTable[uint32(id) & 0x7FFF])
|
||||
if (OpcodeHandler const* handler = opcodeTable[uint32(id) & 0x7FFF])
|
||||
{
|
||||
ss << handler->name;
|
||||
ss << handler->Name;
|
||||
if (opcode & COMPRESSED_OPCODE_MASK)
|
||||
ss << "_COMPRESSED";
|
||||
}
|
||||
|
||||
@@ -52,11 +52,11 @@ bool MapSessionFilter::Process(WorldPacket* packet)
|
||||
OpcodeHandler const* opHandle = opcodeTable[opcode];
|
||||
|
||||
//let's check if our opcode can be really processed in Map::Update()
|
||||
if (opHandle->packetProcessing == PROCESS_INPLACE)
|
||||
if (opHandle->ProcessingPlace == PROCESS_INPLACE)
|
||||
return true;
|
||||
|
||||
//we do not process thread-unsafe packets
|
||||
if (opHandle->packetProcessing == PROCESS_THREADUNSAFE)
|
||||
if (opHandle->ProcessingPlace == PROCESS_THREADUNSAFE)
|
||||
return false;
|
||||
|
||||
Player* player = m_pSession->GetPlayer();
|
||||
@@ -74,11 +74,11 @@ bool WorldSessionFilter::Process(WorldPacket* packet)
|
||||
Opcodes opcode = DropHighBytes(packet->GetOpcode());
|
||||
OpcodeHandler const* opHandle = opcodeTable[opcode];
|
||||
//check if packet handler is supposed to be safe
|
||||
if (opHandle->packetProcessing == PROCESS_INPLACE)
|
||||
if (opHandle->ProcessingPlace == PROCESS_INPLACE)
|
||||
return true;
|
||||
|
||||
//thread-unsafe packets should be processed in World::UpdateSessions()
|
||||
if (opHandle->packetProcessing == PROCESS_THREADUNSAFE)
|
||||
if (opHandle->ProcessingPlace == PROCESS_THREADUNSAFE)
|
||||
return true;
|
||||
|
||||
//no player attached? -> our client! ^^
|
||||
@@ -213,8 +213,8 @@ void WorldSession::SendPacket(WorldPacket const* packet, bool forced /*= false*/
|
||||
|
||||
if (!forced)
|
||||
{
|
||||
OpcodeHandler* handler = opcodeTable[packet->GetOpcode()];
|
||||
if (!handler || handler->status == STATUS_UNHANDLED)
|
||||
OpcodeHandler const* handler = opcodeTable[packet->GetOpcode()];
|
||||
if (!handler || handler->Status == STATUS_UNHANDLED)
|
||||
{
|
||||
sLog->outError(LOG_FILTER_OPCODES, "Prevented sending disabled opcode %s to %s", GetOpcodeNameForLogging(packet->GetOpcode()).c_str(), GetPlayerName(false).c_str());
|
||||
return;
|
||||
@@ -307,11 +307,11 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
|
||||
!_recvQueue.empty() && _recvQueue.peek(true) != firstDelayedPacket &&
|
||||
_recvQueue.next(packet, updater))
|
||||
{
|
||||
const OpcodeHandler* opHandle = opcodeTable[packet->GetOpcode()];
|
||||
OpcodeHandler const* opHandle = opcodeTable[packet->GetOpcode()];
|
||||
|
||||
try
|
||||
{
|
||||
switch (opHandle->status)
|
||||
switch (opHandle->Status)
|
||||
{
|
||||
case STATUS_LOGGEDIN:
|
||||
if (!_player)
|
||||
@@ -335,7 +335,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
|
||||
else if (_player->IsInWorld())
|
||||
{
|
||||
sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet));
|
||||
(this->*opHandle->handler)(*packet);
|
||||
(this->*opHandle->Handler)(*packet);
|
||||
if (sLog->ShouldLog(LOG_FILTER_NETWORKIO, LOG_LEVEL_TRACE) && packet->rpos() < packet->wpos())
|
||||
LogUnprocessedTail(packet);
|
||||
}
|
||||
@@ -349,7 +349,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
|
||||
{
|
||||
// not expected _player or must checked in packet hanlder
|
||||
sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet));
|
||||
(this->*opHandle->handler)(*packet);
|
||||
(this->*opHandle->Handler)(*packet);
|
||||
if (sLog->ShouldLog(LOG_FILTER_NETWORKIO, LOG_LEVEL_TRACE) && packet->rpos() < packet->wpos())
|
||||
LogUnprocessedTail(packet);
|
||||
}
|
||||
@@ -362,7 +362,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
|
||||
else
|
||||
{
|
||||
sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet));
|
||||
(this->*opHandle->handler)(*packet);
|
||||
(this->*opHandle->Handler)(*packet);
|
||||
if (sLog->ShouldLog(LOG_FILTER_NETWORKIO, LOG_LEVEL_TRACE) && packet->rpos() < packet->wpos())
|
||||
LogUnprocessedTail(packet);
|
||||
}
|
||||
@@ -381,7 +381,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
|
||||
m_playerRecentlyLogout = false;
|
||||
|
||||
sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet));
|
||||
(this->*opHandle->handler)(*packet);
|
||||
(this->*opHandle->Handler)(*packet);
|
||||
if (sLog->ShouldLog(LOG_FILTER_NETWORKIO, LOG_LEVEL_TRACE) && packet->rpos() < packet->wpos())
|
||||
LogUnprocessedTail(packet);
|
||||
break;
|
||||
|
||||
@@ -731,8 +731,8 @@ int WorldSocket::ProcessIncoming(WorldPacket* new_pct)
|
||||
return -1;
|
||||
}
|
||||
|
||||
OpcodeHandler* handler = opcodeTable[opcode];
|
||||
if (!handler || handler->status == STATUS_UNHANDLED)
|
||||
OpcodeHandler const* handler = opcodeTable[opcode];
|
||||
if (!handler || handler->Status == STATUS_UNHANDLED)
|
||||
{
|
||||
sLog->outError(LOG_FILTER_OPCODES, "No defined handler for opcode %s sent by %s", GetOpcodeNameForLogging(new_pct->GetOpcode()).c_str(), m_Session->GetPlayerName(false).c_str());
|
||||
return 0;
|
||||
|
||||
@@ -1776,7 +1776,7 @@ void World::SetInitialWorldSettings()
|
||||
LoadCharacterNameData();
|
||||
|
||||
sLog->outInfo(LOG_FILTER_GENERAL, "Initializing Opcodes...");
|
||||
InitOpcodes();
|
||||
opcodeTable.Initialize();
|
||||
|
||||
sLog->outInfo(LOG_FILTER_GENERAL, "Loading hotfix info...");
|
||||
sObjectMgr->LoadHotfixData();
|
||||
|
||||
Reference in New Issue
Block a user