private byte[] DecompressPacket(SOEClient sender, byte[] packet) { // Compressable? if (!sender.IsCompressable()) { return(packet); } // Remove the OpCode and compression flag byte[] data = new byte[packet.Length - 3]; for (int i = 3; i < packet.Length; i++) { data[i - 3] = packet[i]; } byte[] decompressedData = data; // Decompress the old packet.. MemoryStream dataStream = new MemoryStream(data); MemoryStream decompressed = new MemoryStream(); if (packet[2] == 0x01) { using (ZlibStream zlibStream = new ZlibStream(dataStream, CompressionMode.Decompress)) { zlibStream.CopyTo(decompressed); } // Reconstruct the packet.. decompressedData = decompressed.ToArray(); } // Reconstruct the packet.. byte[] newPacket = new byte[decompressedData.Length + 2]; // OpCode int place = 0; for (int i = 0; i < 2; i++) { newPacket[place] = packet[i]; place++; } // Data for (int i = 0; i < decompressedData.Length; i++) { newPacket[place] = decompressedData[i]; place++; } // And.. return! return(newPacket); }
public void HandlePacket(SOEClient sender, byte[] rawPacket) { // Read the packet SOEReader reader = new SOEReader(rawPacket); ushort opCode = reader.ReadUInt16(); bool goodPacket = true; // Get the packet data byte[] data = new byte[rawPacket.Length - (int)sender.GetCRCLength()]; for (int i = 0; i < data.Length; i++) { data[i] = rawPacket[i]; } // Get the CRC32 checksum for the packet uint crc32 = sender.GetCRC32Checksum(data); // Get our expected CRC32 checksum uint expectedCRC32 = 0; uint place = sender.GetCRCLength() - 1; for (int i = rawPacket.Length - (int)sender.GetCRCLength(); i < rawPacket.Length; i++) { expectedCRC32 += (uint)(rawPacket[i] << (8 * (int)place)); place--; } // We have our CRCs! Check if the packet is formed correctly! byte[] crc = BitConverter.GetBytes(crc32).Reverse().ToArray(); byte[] expectedCRC = BitConverter.GetBytes(expectedCRC32).Reverse().ToArray(); int start = 4 - (int)sender.GetCRCLength(); for (int i = start; i < sender.GetCRCLength(); i++) { // If they're not the same, we're a bad packet if (crc[i] != expectedCRC[i]) { // Set that we're bad, and get outta the loop goodPacket = false; break; } } // Are we malformed? if (!goodPacket) { Log("[WARNING] Received malformed packet! Incorrect CRC Appended!"); return; } // Remove the CRC rawPacket = data; // Do we need to worry about decryption/decompression? if (sender.HasSession()) { // Is the client encrypted? if (sender.IsEncrypted()) { rawPacket = DecryptPacket(sender, rawPacket); } // Is the client compressable? if (sender.IsCompressable()) { // It seems that all packets after 0x02 are compressable.. rawPacket = DecompressPacket(sender, rawPacket); } } // Handle the decompressed/decrypted packet! HandlePacket(sender, new SOEPacket(opCode, rawPacket)); }
private byte[] DecompressPacket(SOEClient sender, byte[] packet) { // Compressable? if (!sender.IsCompressable()) { return packet; } // Remove the OpCode and compression flag byte[] data = new byte[packet.Length - 3]; for (int i = 3; i < packet.Length; i++) { data[i - 3] = packet[i]; } byte[] decompressedData = data; // Decompress the old packet.. MemoryStream dataStream = new MemoryStream(data); MemoryStream decompressed = new MemoryStream(); if (packet[2] == 0x01) { using (ZlibStream zlibStream = new ZlibStream(dataStream, CompressionMode.Decompress)) { zlibStream.CopyTo(decompressed); } // Reconstruct the packet.. decompressedData = decompressed.ToArray(); } // Reconstruct the packet.. byte[] newPacket = new byte[decompressedData.Length + 2]; // OpCode int place = 0; for (int i = 0; i < 2; i++) { newPacket[place] = packet[i]; place++; } // Data for (int i = 0; i < decompressedData.Length; i++) { newPacket[place] = decompressedData[i]; place++; } // And.. return! return newPacket; }
public SOEPacket GetFinalSOEPacket(SOEClient client, bool compressed, bool appendCRC) { // Data byte[] originalPacket = GetRaw(); byte[] rawData = new byte[Data.Count - 2]; byte[] newPacket; // Fail-safe ushort originalOpCode = 0; // Are we a message? if (IsMessage) { // Yes, so we'll try make a data packet. // Can we fit into one packet? SOEMessage message = GetFinalSOEMessage(client); if (message.IsFragmented) { // We're gonna have to fragment, so we can't handle this gracefully... client.Server.Log("[ERROR] Tried to handle 'GetFinalSOEPacket' call on written SOEMessage gracefully but failed due to fragmentation. Returning null."); client.Server.Log("[INFO] Call 'GetFinalSOEMessage' as it deals with fragmentation!"); // Welp, goodbye world! :'( return null; } // Make the new packet Data = new List<byte>(); AddUInt16(client.GetNextSequenceNumber()); AddBytes(originalPacket); // Set our raw data rawData = GetRaw(); // Change our OpCode so that we're a reliable data packet originalOpCode = OpCode; OpCode = (ushort)SOEOPCodes.RELIABLE_DATA; // Because we're reliable data, take compression into consideration and append a CRC compressed = true; appendCRC = true; // We handled it gracefully! :) client.Server.Log("[INFO] Handled 'GetFinalSOEPacket' call on written SOEMessage gracefully."); } else { // Get just the data for this packet. (Remove the OP Code) byte[] completeRawData = GetRaw(); for (int i = 2; i < completeRawData.Length; i++) { rawData[i - 2] = completeRawData[i]; } } // Start a new packet Data = new List<byte>(); AddUInt16(OpCode); // Are we compressable? if (client.IsCompressable()) { if (compressed) { AddBoolean(rawData.Length > 100); if (rawData.Length > 100) { rawData = client.Compress(rawData); } } } // Are we encrypted? if (client.IsEncrypted()) { // Encrypt the SOE Packet rawData = client.Encrypt(rawData); } // Add the raw data AddBytes(rawData); // Appended CRC32? if (appendCRC) { AddBytes(client.GetAppendedCRC32(GetRaw())); } // Set our new packet newPacket = GetRaw(); // Get our old message before compression/encryption Data = new List<byte>(originalPacket); // If we are a message, set our OpCode back if (IsMessage) { // Set our OpCode back too.. OpCode = originalOpCode; } // Return the compressed/encrypted packet return new SOEPacket(OpCode, newPacket); }