Figured some stuff out. The packet format is:
Example packet dump:
If the packet is compressed:
dataSize appears to be equal to decompressedStreamSize + hdrSize so it is the full size of the packet after it has been decompressed. The data, as well as the 7 byte header that is prefixed to it is compressed with a classic zlib inflate (15 windowbits).
Decompression (should be done after decryption, requires Ionic.Zlib):
Some information regarding the flags (partial):
Full protocol dump from the Gunz2 NA client:
Code:
uint32 flags;
uint32 pktCounter;
ushort pktID;
ushort checksum;
uint32 datalen;
ushort pktID2;
uchar nullseperator;
uchar[datalen - 7] data;
Code:
29 03 00 00 6D 64 9A 02 26 0C A6 08 0D 00 00 00 26 0C 00 11 04 00 00 00 00
29 03 00 00 -> Flags
6D 64 9A 02 -> Counter
26 0C -> ID (C26, 3110)
A6 08 -> Checksum
0D 00 00 00 -> Data size
26 0C -> ID (again.)
00 -> (start data section)
11 04 00 00 00 00 -> Data (CPT_USHORT, 2 bytes (11 04, 0x411) -> Empty blob, 2 bytes type size (00 00) , 2 bytes blob count (00 00), 0 bytes data (invalid login))
dataSize appears to be equal to decompressedStreamSize + hdrSize so it is the full size of the packet after it has been decompressed. The data, as well as the 7 byte header that is prefixed to it is compressed with a classic zlib inflate (15 windowbits).
Decompression (should be done after decryption, requires Ionic.Zlib):
Code:
var fullSize = BitConverter.ToUInt32(buffer, 12);
byte[] decompressedBuffer = new byte[fullSize - 12];
byte[] cpyArray = new byte[size - 16];
Buffer.BlockCopy(buffer, 16, cpyArray, 0, buffer.Length - 16);
Console.WriteLine("This packet is compressed. Length: {0}", fullSize);
using (ZlibStream zlib = new ZlibStream(new MemoryStream(cpyArray), CompressionMode.Decompress))
{
zlib.Read(decompressedBuffer, 0, (int)fullSize - 12);
}
Array.Resize(ref buffer, (int)fullSize);
Buffer.BlockCopy(decompressedBuffer, 0, buffer, 12, (int)fullSize - 12);
Code:
this.size = (uint)(0x7FFFFF & (temp >> 5));
this.normal = (byte)((temp >> 0) & 1) == 1;
this.ping = (byte)((temp >> 1) & 1) == 1; //used for keepalive. Normal is set to false for keepalive packets.
this.unkFlag3 = (byte)((temp >> 2) & 1) == 1;
this.encrypted = (byte)((temp >> 3) & 1) == 1;
this.compressed = (byte)((temp >> 4) & 1) == 1;
You must be registered to see links
Last edited: