mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
Optimize logging and make world packet parser callback-safe
This commit is contained in:
parent
85c8b5d5f4
commit
4ea4cb761c
5 changed files with 49 additions and 27 deletions
|
|
@ -74,6 +74,7 @@ private:
|
|||
std::mutex mutex;
|
||||
std::ofstream fileStream;
|
||||
bool fileReady = false;
|
||||
bool echoToStdout_ = true;
|
||||
std::chrono::steady_clock::time_point lastFlushTime_{};
|
||||
uint32_t flushIntervalMs_ = 250;
|
||||
void ensureFile();
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ public:
|
|||
Packet() = default;
|
||||
explicit Packet(uint16_t opcode);
|
||||
Packet(uint16_t opcode, const std::vector<uint8_t>& data);
|
||||
Packet(uint16_t opcode, std::vector<uint8_t>&& data);
|
||||
|
||||
void writeUInt8(uint8_t value);
|
||||
void writeUInt16(uint16_t value);
|
||||
|
|
|
|||
|
|
@ -16,6 +16,11 @@ Logger& Logger::getInstance() {
|
|||
void Logger::ensureFile() {
|
||||
if (fileReady) return;
|
||||
fileReady = true;
|
||||
if (const char* logStdout = std::getenv("WOWEE_LOG_STDOUT")) {
|
||||
if (logStdout[0] == '0') {
|
||||
echoToStdout_ = false;
|
||||
}
|
||||
}
|
||||
if (const char* flushMs = std::getenv("WOWEE_LOG_FLUSH_MS")) {
|
||||
char* end = nullptr;
|
||||
unsigned long parsed = std::strtoul(flushMs, &end, 10);
|
||||
|
|
@ -67,7 +72,9 @@ void Logger::log(LogLevel level, const std::string& message) {
|
|||
|
||||
line << "] " << message;
|
||||
|
||||
std::cout << line.str() << '\n';
|
||||
if (echoToStdout_) {
|
||||
std::cout << line.str() << '\n';
|
||||
}
|
||||
if (fileStream.is_open()) {
|
||||
fileStream << line.str() << '\n';
|
||||
bool shouldFlush = (level >= LogLevel::WARNING);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include "network/packet.hpp"
|
||||
#include <cstring>
|
||||
#include <utility>
|
||||
|
||||
namespace wowee {
|
||||
namespace network {
|
||||
|
|
@ -9,6 +10,9 @@ Packet::Packet(uint16_t opcode) : opcode(opcode) {}
|
|||
Packet::Packet(uint16_t opcode, const std::vector<uint8_t>& data)
|
||||
: opcode(opcode), data(data), readPos(0) {}
|
||||
|
||||
Packet::Packet(uint16_t opcode, std::vector<uint8_t>&& data)
|
||||
: opcode(opcode), data(std::move(data)), readPos(0) {}
|
||||
|
||||
void Packet::writeUInt8(uint8_t value) {
|
||||
data.push_back(value);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -325,27 +325,31 @@ void WorldSocket::update() {
|
|||
void WorldSocket::tryParsePackets() {
|
||||
// World server packets have 4-byte incoming header: size(2) + opcode(2)
|
||||
int parsedThisTick = 0;
|
||||
while (receiveBuffer.size() >= 4 && parsedThisTick < kMaxParsedPacketsPerUpdate) {
|
||||
size_t parseOffset = 0;
|
||||
size_t localHeaderBytesDecrypted = headerBytesDecrypted;
|
||||
std::vector<Packet> parsedPackets;
|
||||
parsedPackets.reserve(32);
|
||||
while ((receiveBuffer.size() - parseOffset) >= 4 && parsedThisTick < kMaxParsedPacketsPerUpdate) {
|
||||
uint8_t rawHeader[4] = {0, 0, 0, 0};
|
||||
std::memcpy(rawHeader, receiveBuffer.data(), 4);
|
||||
std::memcpy(rawHeader, receiveBuffer.data() + parseOffset, 4);
|
||||
|
||||
// Decrypt header bytes in-place if encryption is enabled
|
||||
// Only decrypt bytes we haven't already decrypted
|
||||
if (encryptionEnabled && headerBytesDecrypted < 4) {
|
||||
size_t toDecrypt = 4 - headerBytesDecrypted;
|
||||
if (encryptionEnabled && localHeaderBytesDecrypted < 4) {
|
||||
size_t toDecrypt = 4 - localHeaderBytesDecrypted;
|
||||
if (useVanillaCrypt) {
|
||||
vanillaCrypt.decrypt(receiveBuffer.data() + headerBytesDecrypted, toDecrypt);
|
||||
vanillaCrypt.decrypt(receiveBuffer.data() + parseOffset + localHeaderBytesDecrypted, toDecrypt);
|
||||
} else {
|
||||
decryptCipher.process(receiveBuffer.data() + headerBytesDecrypted, toDecrypt);
|
||||
decryptCipher.process(receiveBuffer.data() + parseOffset + localHeaderBytesDecrypted, toDecrypt);
|
||||
}
|
||||
headerBytesDecrypted = 4;
|
||||
localHeaderBytesDecrypted = 4;
|
||||
}
|
||||
|
||||
// Parse header (now decrypted in-place).
|
||||
// Size: 2 bytes big-endian. For world packets, this includes opcode bytes.
|
||||
uint16_t size = (receiveBuffer[0] << 8) | receiveBuffer[1];
|
||||
uint16_t size = (receiveBuffer[parseOffset + 0] << 8) | receiveBuffer[parseOffset + 1];
|
||||
// Opcode: 2 bytes little-endian.
|
||||
uint16_t opcode = receiveBuffer[2] | (receiveBuffer[3] << 8);
|
||||
uint16_t opcode = receiveBuffer[parseOffset + 2] | (receiveBuffer[parseOffset + 3] << 8);
|
||||
if (size < 2) {
|
||||
LOG_ERROR("World packet framing desync: invalid size=", size,
|
||||
" rawHdr=", std::hex,
|
||||
|
|
@ -381,45 +385,50 @@ void WorldSocket::tryParsePackets() {
|
|||
static_cast<int>(rawHeader[2]), " ",
|
||||
static_cast<int>(rawHeader[3]),
|
||||
" dec=",
|
||||
static_cast<int>(receiveBuffer[0]), " ",
|
||||
static_cast<int>(receiveBuffer[1]), " ",
|
||||
static_cast<int>(receiveBuffer[2]), " ",
|
||||
static_cast<int>(receiveBuffer[3]),
|
||||
static_cast<int>(receiveBuffer[parseOffset + 0]), " ",
|
||||
static_cast<int>(receiveBuffer[parseOffset + 1]), " ",
|
||||
static_cast<int>(receiveBuffer[parseOffset + 2]), " ",
|
||||
static_cast<int>(receiveBuffer[parseOffset + 3]),
|
||||
std::dec,
|
||||
" size=", size,
|
||||
" payload=", payloadLen,
|
||||
" opcode=0x", std::hex, opcode, std::dec,
|
||||
" buffered=", receiveBuffer.size());
|
||||
" buffered=", (receiveBuffer.size() - parseOffset));
|
||||
--headerTracePacketsLeft;
|
||||
}
|
||||
if (isLoginPipelineSmsg(opcode)) {
|
||||
LOG_INFO("WS RX LOGIN opcode=0x", std::hex, opcode, std::dec,
|
||||
" size=", size, " payload=", payloadLen,
|
||||
" buffered=", receiveBuffer.size(),
|
||||
" buffered=", (receiveBuffer.size() - parseOffset),
|
||||
" enc=", encryptionEnabled ? "yes" : "no");
|
||||
}
|
||||
|
||||
if (receiveBuffer.size() < totalSize) {
|
||||
if ((receiveBuffer.size() - parseOffset) < totalSize) {
|
||||
// Not enough data yet - header stays decrypted in buffer
|
||||
break;
|
||||
}
|
||||
|
||||
// Extract payload (skip header)
|
||||
std::vector<uint8_t> packetData(receiveBuffer.begin() + 4,
|
||||
receiveBuffer.begin() + totalSize);
|
||||
std::vector<uint8_t> packetData(receiveBuffer.begin() + parseOffset + 4,
|
||||
receiveBuffer.begin() + parseOffset + totalSize);
|
||||
|
||||
// Create packet with opcode and payload
|
||||
Packet packet(opcode, packetData);
|
||||
// Queue packet; callbacks run after buffer state is finalized.
|
||||
parsedPackets.emplace_back(opcode, std::move(packetData));
|
||||
parseOffset += totalSize;
|
||||
localHeaderBytesDecrypted = 0;
|
||||
++parsedThisTick;
|
||||
}
|
||||
|
||||
// Remove parsed data from buffer and reset header decryption counter
|
||||
receiveBuffer.erase(receiveBuffer.begin(), receiveBuffer.begin() + totalSize);
|
||||
headerBytesDecrypted = 0;
|
||||
if (parseOffset > 0) {
|
||||
receiveBuffer.erase(receiveBuffer.begin(), receiveBuffer.begin() + parseOffset);
|
||||
}
|
||||
headerBytesDecrypted = localHeaderBytesDecrypted;
|
||||
|
||||
// Call callback if set
|
||||
if (packetCallback) {
|
||||
if (packetCallback) {
|
||||
for (const auto& packet : parsedPackets) {
|
||||
if (!connected) break;
|
||||
packetCallback(packet);
|
||||
}
|
||||
++parsedThisTick;
|
||||
}
|
||||
|
||||
if (parsedThisTick >= kMaxParsedPacketsPerUpdate && receiveBuffer.size() >= 4) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue