public void HandleDisconnect(SOEClient sender, SOEPacket packet) { // Setup a reader SOEReader reader = new SOEReader(packet); // Get the data from the packet uint sessionID = reader.ReadUInt32(); ushort reason = reader.ReadUInt16(); // Handle if (sessionID == sender.GetSessionID()) { Console.WriteLine("Disconnecting"); Server.ConnectionManager.DisconnectClient(sender, reason, true); } }
private void ReceiveMessage(SOEPacket packet) { SOEReader reader = new SOEReader(packet); // Have we received in order? ushort sequenceNumber = reader.ReadUInt16(); if ((sequenceNumber != LastReceivedSequenceNumber + 1) && (sequenceNumber != 0)) { ReceivedSequenceOutOfOrder(sequenceNumber); return; } // Acknowledge Acknowledge(sequenceNumber); LastReceivedSequenceNumber = sequenceNumber; // Get the SOEMessage byte[] data = reader.ReadToEnd(); // Handle! Client.ReceiveMessage(data); }
private byte[] DecryptPacket(SOEClient sender, byte[] packet) { // Compressable? if (!sender.IsEncrypted()) { return packet; } // Setup our streams SOEReader reader = new SOEReader(packet); SOEWriter newPacket = new SOEWriter(reader.ReadUInt16()); // Skip the compression flag reader.ReadByte(); // Get our data int blockCount = (packet.Length - 3) / 4; int byteCount = (packet.Length - 3) % 4; uint key = sender.GetCRCSeed(); // Decrypt the blocks of 4 bytes for (int i = 0; i < blockCount; i++) { uint temp = reader.ReadUInt32(); uint value = temp ^ key; key = temp; newPacket.AddUInt32(value); } // Decrypt the rest of the singular bytes byte newKey = (byte)((key >> 24) & 0xFF); for (int i = 0; i < byteCount; i++) { byte value = (byte)(reader.ReadByte() ^ newKey); newPacket.AddByte(value); } // Return the decrypted packet return newPacket.GetRaw(); }
private void ReceiveFragment(SOEPacket packet) { // Setup a reader SOEReader reader = new SOEReader(packet); reader.ReadUInt16(); // Have we already started a fragmented packet? if (StartedFragmentedPacket) { // One less fragment till we need to acknowledge! FragmentsTillAck--; // Get our sequence number uint previousFragmentSequenceNumber = FragmentSequenceNumber; FragmentSequenceNumber = reader.ReadUInt16(); // Did we get a correct sequence number? if (FragmentSequenceNumber != previousFragmentSequenceNumber + 1) { // Out of order! ReceivedSequenceOutOfOrder(FragmentSequenceNumber); return; } // Append the rest of the packet to the fragmented data for (int i = 4; i < FragmentedData.Length; i++) { FragmentedData[ReceivedFragmentsSize] = reader.ReadByte(); ReceivedFragmentsSize++; } } else { // We're expecting the starting packet FragmentSequenceNumber = reader.ReadUInt16(); uint totalSize = reader.ReadUInt32(); // Is this a valid sequence number? if ((FragmentSequenceNumber != LastReceivedSequenceNumber + 1) && (FragmentSequenceNumber != 0)) { // Out of order! ReceivedSequenceOutOfOrder(FragmentSequenceNumber); return; } // Get the total size FragmentedData = new byte[totalSize]; // How many fragments till we need to acknowledge FragmentsTillAck = 4; // Append the rest of the packet to the fragmented data for (int i = 8; i < FragmentedData.Length; i++) { FragmentedData[ReceivedFragmentsSize] = reader.ReadByte(); ReceivedFragmentsSize++; } // Started a fragmented packet StartedFragmentedPacket = true; } // Are we finished with the fragmented data? if (ReceivedFragmentsSize >= FragmentedData.Length) { // Finish fragmented packet StartedFragmentedPacket = false; FragmentsTillAck = 0; // Handle the fragmented packet as a RELIABLE_DATA packet SOEWriter writer = new SOEWriter((ushort)SOEOPCodes.RELIABLE_DATA); writer.AddBytes(FragmentedData); SOEPacket wholePacket = writer.GetFinalSOEPacket(Client, false, false); // Receive this packet! Receive(wholePacket); return; } // Do we need to acknowledge? if (FragmentsTillAck == 0) { Acknowledge(FragmentSequenceNumber); FragmentsTillAck = 5; } }
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)); }