Core/Logging: Add optional binary packet logger usable with WowPacketParser, and remove the now useless WorldLog.

TODO: Port this to .pkt 3.1 format
This commit is contained in:
kaelima
2012-06-04 08:52:12 +02:00
parent 31a08f5ddc
commit d86246b861
5 changed files with 89 additions and 186 deletions
@@ -0,0 +1,61 @@
/*
* Copyright (C) 2008-2012 TrinityCore <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, see <http://www.gnu.org/licenses/>.
*/
#include "PacketLog.h"
#include "Config.h"
#include "ByteBuffer.h"
PacketLog::PacketLog() : _file(NULL)
{
Initialize();
}
PacketLog::~PacketLog()
{
if (_file)
fclose(_file);
_file = NULL;
}
void PacketLog::Initialize()
{
std::string logsDir = ConfigMgr::GetStringDefault("LogsDir", "");
if (!logsDir.empty())
if ((logsDir.at(logsDir.length()-1) != '/') && (logsDir.at(logsDir.length()-1) != '\\'))
logsDir.push_back('/');
std::string logname = ConfigMgr::GetStringDefault("PacketLogFile", "");
if (!logname.empty())
_file = fopen((logsDir + logname).c_str(), "wb");
}
void PacketLog::LogPacket(WorldPacket const& packet, Direction direction)
{
ByteBuffer data(4+4+4+1+packet.size());
data << int32(packet.GetOpcode());
data << int32(packet.size());
data << int32(time(NULL));
data << uint8(direction);
for (uint32 i = 0; i < packet.size(); i++)
data << const_cast<WorldPacket&>(packet)[i];
fwrite(data.contents(), 1, data.size(), _file);
fflush(_file);
}
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
* 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
@@ -16,46 +15,34 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/// \addtogroup u2w
/// @{
/// \file
#ifndef TRINITY_WORLDLOG_H
#define TRINITY_WORLDLOG_H
#ifndef TRINITY_PACKETLOG_H
#define TRINITY_PACKETLOG_H
#include "Common.h"
#include <ace/Singleton.h>
#include "Errors.h"
#include <stdarg.h>
/// %Log packets to a file
class WorldLog
enum Direction
{
friend class ACE_Singleton<WorldLog, ACE_Thread_Mutex>;
CLIENT_TO_SERVER,
SERVER_TO_CLIENT
};
class PacketLog
{
friend class ACE_Singleton<PacketLog, ACE_Thread_Mutex>;
private:
WorldLog();
~WorldLog();
WorldLog(const WorldLog &);
WorldLog& operator=(const WorldLog &);
ACE_Thread_Mutex Lock;
PacketLog();
~PacketLog();
public:
void Initialize();
/// Is the world logger active?
bool LogWorld(void) const { return (i_file != NULL); }
/// %Log to the file
void outLog(char const* fmt, ...);
void outTimestampLog(char const* fmt, ...);
bool CanLogPacket() const { return (_file != NULL); }
void LogPacket(WorldPacket const& packet, Direction direction);
private:
FILE* i_file;
bool m_dbWorld;
FILE* _file;
};
#define sWorldLog ACE_Singleton<WorldLog, ACE_Thread_Mutex>::instance()
#define sPacketLog ACE_Singleton<PacketLog, ACE_Thread_Mutex>::instance()
#endif
/// @}
@@ -1,114 +0,0 @@
/*
* Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
* 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, see <http://www.gnu.org/licenses/>.
*/
/** \file
\ingroup u2w
*/
#include "WorldLog.h"
#include "Config.h"
#include "Log.h"
#include "DatabaseWorkerPool.h"
WorldLog::WorldLog() : i_file(NULL)
{
Initialize();
}
WorldLog::~WorldLog()
{
if (i_file != NULL)
fclose(i_file);
i_file = NULL;
}
/// Open the log file (if specified so in the configuration file)
void WorldLog::Initialize()
{
std::string logsDir = ConfigMgr::GetStringDefault("LogsDir", "");
if (!logsDir.empty())
{
if ((logsDir.at(logsDir.length()-1) != '/') && (logsDir.at(logsDir.length()-1) != '\\'))
logsDir.push_back('/');
}
std::string logname = ConfigMgr::GetStringDefault("WorldLogFile", "");
if (!logname.empty())
{
i_file = fopen((logsDir+logname).c_str(), "w");
}
m_dbWorld = ConfigMgr::GetBoolDefault("LogDB.World", false); // can be VERY heavy if enabled
}
void WorldLog::outTimestampLog(char const* fmt, ...)
{
if (LogWorld())
{
TRINITY_GUARD(ACE_Thread_Mutex, Lock);
ASSERT(i_file);
Log::outTimestamp(i_file);
va_list args;
va_start(args, fmt);
vfprintf(i_file, fmt, args);
//fprintf(i_file, "\n");
va_end(args);
fflush(i_file);
}
if (sLog->GetLogDB() && m_dbWorld)
{
va_list ap2;
va_start(ap2, fmt);
char nnew_str[MAX_QUERY_LEN];
vsnprintf(nnew_str, MAX_QUERY_LEN, fmt, ap2);
sLog->outDB(LOG_TYPE_WORLD, nnew_str);
va_end(ap2);
}
}
void WorldLog::outLog(char const* fmt, ...)
{
if (LogWorld())
{
TRINITY_GUARD(ACE_Thread_Mutex, Lock);
ASSERT(i_file);
va_list args;
va_start(args, fmt);
vfprintf(i_file, fmt, args);
//fprintf(i_file, "\n");
va_end(args);
fflush(i_file);
}
if (sLog->GetLogDB() && m_dbWorld)
{
va_list ap2;
va_start(ap2, fmt);
char nnew_str[MAX_QUERY_LEN];
vsnprintf(nnew_str, MAX_QUERY_LEN, fmt, ap2);
sLog->outDB(LOG_TYPE_WORLD, nnew_str);
va_end(ap2);
}
}
+7 -39
View File
@@ -42,7 +42,7 @@
#include "WorldSession.h"
#include "WorldSocketMgr.h"
#include "Log.h"
#include "WorldLog.h"
#include "PacketLog.h"
#include "ScriptMgr.h"
#include "AccountMgr.h"
@@ -152,7 +152,7 @@ const std::string& WorldSocket::GetRemoteAddress (void) const
return m_Address;
}
int WorldSocket::SendPacket(const WorldPacket& pct)
int WorldSocket::SendPacket(WorldPacket const& pct)
{
ACE_GUARD_RETURN (LockType, Guard, m_OutBufferLock, -1);
@@ -160,24 +160,8 @@ int WorldSocket::SendPacket(const WorldPacket& pct)
return -1;
// Dump outgoing packet.
if (sWorldLog->LogWorld())
{
sWorldLog->outTimestampLog ("SERVER:\nSOCKET: %u\nLENGTH: %u\nOPCODE: %s (0x%.4X)\nDATA:\n",
(uint32) get_handle(),
pct.size(),
LookupOpcodeName (pct.GetOpcode()),
pct.GetOpcode());
uint32 p = 0;
while (p < pct.size())
{
for (uint32 j = 0; j < 16 && p < pct.size(); j++)
sWorldLog->outLog("%.2X ", const_cast<WorldPacket&>(pct)[p++]);
sWorldLog->outLog("\n");
}
sWorldLog->outLog("\n");
}
if (sPacketLog->CanLogPacket())
sPacketLog->LogPacket(pct, SERVER_TO_CLIENT);
// Create a copy of the original packet; this is to avoid issues if a hook modifies it.
sScriptMgr->OnPacketSend(this, WorldPacket(pct));
@@ -674,7 +658,7 @@ int WorldSocket::schedule_wakeup_output (GuardType& g)
return 0;
}
int WorldSocket::ProcessIncoming (WorldPacket* new_pct)
int WorldSocket::ProcessIncoming(WorldPacket* new_pct)
{
ACE_ASSERT (new_pct);
@@ -687,24 +671,8 @@ int WorldSocket::ProcessIncoming (WorldPacket* new_pct)
return -1;
// Dump received packet.
if (sWorldLog->LogWorld())
{
sWorldLog->outTimestampLog ("CLIENT:\nSOCKET: %u\nLENGTH: %u\nOPCODE: %s (0x%.4X)\nDATA:\n",
(uint32) get_handle(),
new_pct->size(),
LookupOpcodeName (new_pct->GetOpcode()),
new_pct->GetOpcode());
uint32 p = 0;
while (p < new_pct->size())
{
for (uint32 j = 0; j < 16 && p < new_pct->size(); j++)
sWorldLog->outLog ("%.2X ", (*new_pct)[p++]);
sWorldLog->outLog ("\n");
}
sWorldLog->outLog ("\n");
}
if (sPacketLog->CanLogPacket())
sPacketLog->LogPacket(*new_pct, CLIENT_TO_SERVER);
try
{
+5 -4
View File
@@ -483,12 +483,13 @@ LogFileLevel = 0
DebugLogMask = 0
#
# WorldLogFile
# Description: Packet logging file for the world server.
# Example: "World.log" - (Enabled)
# PacketLogFile
# Description: Binary packet logging file for the world server.
# Filename extension must be .bin to be parsable with WowPacketParser.
# Example: "World.bin" - (Enabled)
# Default: "" - (Disabled)
WorldLogFile = ""
PacketLogFile = ""
#
# DBErrorLogFile