diff --git a/src/server/game/Server/Protocol/PacketLog.cpp b/src/server/game/Server/Protocol/PacketLog.cpp
index b17bab26b..7af5fa09e 100644
--- a/src/server/game/Server/Protocol/PacketLog.cpp
+++ b/src/server/game/Server/Protocol/PacketLog.cpp
@@ -4,14 +4,42 @@
* Copyright (C) 2005-2009 MaNGOS
*/
-#include "ByteBuffer.h"
-#include "Config.h"
#include "PacketLog.h"
+#include "Config.h"
+#include "Timer.h"
#include "WorldPacket.h"
+#pragma pack(push, 1)
+
+ // Packet logging structures in PKT 3.1 format
+struct LogHeader
+{
+ char Signature[3];
+ uint16 FormatVersion;
+ uint8 SnifferId;
+ uint32 Build;
+ char Locale[4];
+ uint8 SessionKey[40];
+ uint32 SniffStartUnixtime;
+ uint32 SniffStartTicks;
+ uint32 OptionalDataSize;
+};
+
+struct PacketHeader
+{
+ char Direction[4];
+ uint32 ConnectionId;
+ uint32 ArrivalTicks;
+ uint32 OptionalDataSize;
+ uint32 Length;
+ uint32 Opcode;
+};
+
+#pragma pack(pop)
+
PacketLog::PacketLog() : _file(nullptr)
{
- Initialize();
+ std::call_once(_initializeFlag, &PacketLog::Initialize, this);
}
PacketLog::~PacketLog()
@@ -38,20 +66,41 @@ void PacketLog::Initialize()
std::string logname = sConfigMgr->GetOption("PacketLogFile", "");
if (!logname.empty())
+ {
_file = fopen((logsDir + logname).c_str(), "wb");
+
+ LogHeader header;
+ header.Signature[0] = 'P'; header.Signature[1] = 'K'; header.Signature[2] = 'T';
+ header.FormatVersion = 0x0301;
+ header.SnifferId = 'T';
+ header.Build = 12340;
+ header.Locale[0] = 'e'; header.Locale[1] = 'n'; header.Locale[2] = 'U'; header.Locale[3] = 'S';
+ std::memset(header.SessionKey, 0, sizeof(header.SessionKey));
+ header.SniffStartUnixtime = time(nullptr);
+ header.SniffStartTicks = getMSTime();
+ header.OptionalDataSize = 0;
+
+ fwrite(&header, sizeof(header), 1, _file);
+ }
}
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 << uint32(time(nullptr));
- data << uint8(direction);
+ std::lock_guard lock(_logPacketLock);
- for (uint32 i = 0; i < packet.size(); i++)
- data << packet[i];
+ PacketHeader header;
+ *reinterpret_cast(header.Direction) = direction == CLIENT_TO_SERVER ? 0x47534d43 : 0x47534d53;
+ header.ConnectionId = 0;
+ header.ArrivalTicks = getMSTime();
+ header.OptionalDataSize = 0;
+ header.Length = packet.size() + 4;
+ header.Opcode = packet.GetOpcode();
+
+ fwrite(&header, sizeof(header), 1, _file);
+ if (!packet.empty())
+ {
+ fwrite(packet.contents(), 1, packet.size(), _file);
+ }
- fwrite(data.contents(), 1, data.size(), _file);
fflush(_file);
}
diff --git a/src/server/game/Server/Protocol/PacketLog.h b/src/server/game/Server/Protocol/PacketLog.h
index 3b1d264b0..5d2bcbaf0 100644
--- a/src/server/game/Server/Protocol/PacketLog.h
+++ b/src/server/game/Server/Protocol/PacketLog.h
@@ -8,6 +8,7 @@
#define ACORE_PACKETLOG_H
#include "Common.h"
+#include
enum Direction
{
@@ -22,6 +23,8 @@ class PacketLog
private:
PacketLog();
~PacketLog();
+ std::mutex _logPacketLock;
+ std::once_flag _initializeFlag;
public:
static PacketLog* instance();
diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
index e6e7ced63..d1f03a7c8 100644
--- a/src/server/worldserver/worldserver.conf.dist
+++ b/src/server/worldserver/worldserver.conf.dist
@@ -67,14 +67,6 @@ RealmID = 1
DataDir = "."
-#
-# PidFile
-# Description: World daemon PID file
-# Example: "./world.pid" - (Enabled)
-# Default: "" - (Disabled)
-
-PidFile = ""
-
#
# LogsDir
# Description: Logs directory setting.
@@ -460,6 +452,29 @@ SetAllCreaturesWithWaypointMovementActive = 0
#
###################################################################################################
+###################################################################################################
+# SERVER LOGGING
+#
+# PidFile
+# Description: World daemon PID file.
+# Example: "./world.pid" - (Enabled)
+# Default: "" - (Disabled)
+
+PidFile = ""
+
+#
+# PacketLogFile
+# Description: Binary packet logging file for the world server.
+# Filename extension must be .pkt to be parsable with WowPacketParser.
+# Example: "World.pkt" - (Enabled)
+# Default: "" - (Disabled)
+
+PacketLogFile = ""
+
+# Extended Logging system configuration moved to end of file (on purpose)
+#
+###################################################################################################
+
###################################################################################################
# SERVER SETTINGS
#