190 lines
4.9 KiB
C++
190 lines
4.9 KiB
C++
// Copyright (C) 2007 EQ2EMulator Development Team - GNU GPL v3+ License
|
|
|
|
#pragma once
|
|
|
|
#include <iostream>
|
|
#include <iomanip>
|
|
#include <cstdio>
|
|
#include <cstring>
|
|
|
|
#include "eq_packet.hpp"
|
|
#include "../debug.hpp"
|
|
#include "../types.hpp"
|
|
#include "../servertalk.hpp"
|
|
#include "../stream/eq_stream.hpp"
|
|
|
|
using namespace std;
|
|
|
|
class ServerPacket;
|
|
|
|
// Function declarations
|
|
void DumpPacketAscii(const uchar* buf, int32 size, int32 cols = 16, int32 skip = 0);
|
|
void DumpPacketHex(const uchar* buf, int32 size, int32 cols = 16, int32 skip = 0);
|
|
void DumpPacketBin(const void* data, int32 len);
|
|
void DumpPacket(const uchar* buf, int32 size);
|
|
void DumpPacket(const ServerPacket* pack, bool iShowInfo = false);
|
|
void DumpPacketBin(const ServerPacket* pack);
|
|
void DumpPacketBin(int32 data);
|
|
void DumpPacketBin(int16 data);
|
|
void DumpPacketBin(int8 data);
|
|
|
|
// Outputs packet buffer as ASCII characters with formatted columns
|
|
// Non-printable characters are displayed as dots
|
|
void DumpPacketAscii(const uchar* buf, int32 size, int32 cols, int32 skip)
|
|
{
|
|
for(int32 i = skip; i < size; i++) {
|
|
if ((i - skip) % cols == 0) {
|
|
cout << endl << setw(3) << setfill(' ') << i - skip << ":";
|
|
}
|
|
else if ((i - skip) % (cols / 2) == 0) {
|
|
cout << " - ";
|
|
}
|
|
|
|
if (buf[i] > 32 && buf[i] < 127) {
|
|
cout << buf[i];
|
|
}
|
|
else {
|
|
cout << '.';
|
|
}
|
|
}
|
|
cout << endl << endl;
|
|
}
|
|
|
|
// Outputs packet buffer as hexadecimal with ASCII representation sidebar
|
|
// Includes offset addresses and formatted column layout
|
|
void DumpPacketHex(const uchar* buf, int32 size, int32 cols, int32 skip)
|
|
{
|
|
if (size == 0 || size > 39565)
|
|
return;
|
|
|
|
char output[4];
|
|
int j = 0;
|
|
auto ascii = std::make_unique<char[]>(cols + 1);
|
|
memset(ascii.get(), 0, cols + 1);
|
|
|
|
int32 i;
|
|
for(i = skip; i < size; i++) {
|
|
if ((i - skip) % cols == 0) {
|
|
if (i != skip)
|
|
cout << " | " << ascii.get() << endl;
|
|
cout << setw(4) << setfill(' ') << i - skip << ": ";
|
|
memset(ascii.get(), 0, cols + 1);
|
|
j = 0;
|
|
}
|
|
else if ((i - skip) % (cols / 2) == 0) {
|
|
cout << "- ";
|
|
}
|
|
|
|
sprintf(output, "%02X ", static_cast<unsigned char>(buf[i]));
|
|
cout << output;
|
|
|
|
if (buf[i] >= 32 && buf[i] < 127) {
|
|
ascii[j++] = buf[i];
|
|
}
|
|
else {
|
|
ascii[j++] = '.';
|
|
}
|
|
}
|
|
|
|
int32 k = ((i - skip) - 1) % cols;
|
|
if (k < 8)
|
|
cout << " ";
|
|
for (int32 h = k + 1; h < cols; h++) {
|
|
cout << " ";
|
|
}
|
|
cout << " | " << ascii.get() << endl;
|
|
}
|
|
|
|
// Simple wrapper to dump packet in hexadecimal format
|
|
void DumpPacket(const uchar* buf, int32 size)
|
|
{
|
|
DumpPacketHex(buf, size);
|
|
}
|
|
|
|
// Dumps ServerPacket with optional header information display
|
|
// Shows opcode and size when iShowInfo is true
|
|
void DumpPacket(const ServerPacket* pack, bool iShowInfo)
|
|
{
|
|
if (iShowInfo) {
|
|
cout << "Dumping ServerPacket: 0x" << hex << setfill('0') << setw(4) << pack->opcode << dec;
|
|
cout << " size:" << pack->size << endl;
|
|
}
|
|
DumpPacketHex(pack->pBuffer, pack->size);
|
|
}
|
|
|
|
// Wrapper to dump ServerPacket buffer in binary format
|
|
void DumpPacketBin(const ServerPacket* pack)
|
|
{
|
|
DumpPacketBin(pack->pBuffer, pack->size);
|
|
}
|
|
|
|
// Dumps 32-bit integer in binary format
|
|
void DumpPacketBin(int32 data)
|
|
{
|
|
DumpPacketBin(reinterpret_cast<const uchar*>(&data), sizeof(int32));
|
|
}
|
|
|
|
// Dumps 16-bit integer in binary format
|
|
void DumpPacketBin(int16 data)
|
|
{
|
|
DumpPacketBin(reinterpret_cast<const uchar*>(&data), sizeof(int16));
|
|
}
|
|
|
|
// Dumps 8-bit integer in binary format
|
|
void DumpPacketBin(int8 data)
|
|
{
|
|
DumpPacketBin(reinterpret_cast<const uchar*>(&data), sizeof(int8));
|
|
}
|
|
|
|
// Outputs data buffer in binary format with hexadecimal values sidebar
|
|
// Each byte is displayed as 8 binary digits with offset addressing
|
|
void DumpPacketBin(const void* iData, int32 len)
|
|
{
|
|
if (!len)
|
|
return;
|
|
|
|
const int8* data = static_cast<const int8*>(iData);
|
|
int32 k = 0;
|
|
|
|
for (k = 0; k < len; k++) {
|
|
if (k % 4 == 0) {
|
|
if (k != 0) {
|
|
cout << " | " << hex << setw(2) << setfill('0') << static_cast<int>(data[k-4]) << dec;
|
|
cout << " " << hex << setw(2) << setfill('0') << static_cast<int>(data[k-3]) << dec;
|
|
cout << " " << hex << setw(2) << setfill('0') << static_cast<int>(data[k-2]) << dec;
|
|
cout << " " << hex << setw(2) << setfill('0') << static_cast<int>(data[k-1]) << dec;
|
|
cout << endl;
|
|
}
|
|
cout << setw(4) << setfill('0') << k << ":";
|
|
}
|
|
else if (k % 2 == 0)
|
|
cout << " ";
|
|
|
|
cout << " ";
|
|
|
|
// Output each bit of the byte
|
|
for (int bit = 0; bit < 8; bit++) {
|
|
cout << ((data[k] & (1 << bit)) ? "1" : "0");
|
|
}
|
|
}
|
|
|
|
// Handle final line formatting
|
|
int8 tmp = (k % 4);
|
|
if (!tmp)
|
|
tmp = 4;
|
|
if (tmp <= 3)
|
|
cout << " ";
|
|
if (tmp <= 2)
|
|
cout << " ";
|
|
if (tmp <= 1)
|
|
cout << " ";
|
|
|
|
cout << " | " << hex << setw(2) << setfill('0') << static_cast<int>(data[k-4]) << dec;
|
|
if (tmp > 1)
|
|
cout << " " << hex << setw(2) << setfill('0') << static_cast<int>(data[k-3]) << dec;
|
|
if (tmp > 2)
|
|
cout << " " << hex << setw(2) << setfill('0') << static_cast<int>(data[k-2]) << dec;
|
|
if (tmp > 3)
|
|
cout << " " << hex << setw(2) << setfill('0') << static_cast<int>(data[k-1]) << dec;
|
|
cout << endl;
|
|
} |