private static void ServerPacketsProcessor(AuthenticationServer ui) { //TODO: make it work for multiple servers, we need a list holding fragments for different servers and logic to manage it. Fragmentation fragment = new Fragmentation(8192); while (_continueServerProcessing) { PacketContainer cont; if (_queuedServerPackets.TryDequeue(out cont)) { PacketsProcessor dataProcessor = new PacketsProcessor(); dataProcessor.ExtractPackets(cont, ref fragment); foreach (PacketContent p in cont.extractedPackets) { GameServer.Received(ui, p, GetServerByIndex(cont.serverID)); } } else { Thread.Sleep(5); } } }
public void ExtractPackets(PacketContainer cont, ref Fragmentation f) { bool stillReading = true; int packetLen; //Extreme case const int PACKET_SIZE_HEADER = 4; // 4 bytes if (f.pendingFragment) { if (f.sizeSplitted) { f.sizeSplitted = false; Buffer.BlockCopy(cont.buffer, 0, f.sizeBuffer, f.sizeAlreadyFilledBytes, f.sizeMissingBytes); readOffset += f.sizeMissingBytes; f.missingBytes = BitConverter.ToInt32(f.sizeBuffer, 0); f.sizeAlreadyFilledBytes = 0; f.sizeMissingBytes = 0; } if (f.missingBytes + readOffset <= cont.size) { Buffer.BlockCopy(cont.buffer, readOffset, f.buffer, f.alreadyFilledBytes, f.missingBytes); readOffset += f.missingBytes; cont.extractedPackets.Add(new PacketContent(ref f.buffer, 0, f.alreadyFilledBytes + f.missingBytes)); f.pendingFragment = false; f.alreadyFilledBytes = 0; f.missingBytes = 0; } else { f.missingBytes -= cont.size; f.alreadyFilledBytes += cont.size; Buffer.BlockCopy(cont.buffer, readOffset, f.buffer, f.alreadyFilledBytes, cont.size); readOffset += cont.size; } } while (stillReading && readOffset < cont.size) { //size of single packet if (cont.size < 8192) { if (1 == 1) { } } packetLen = BitConverter.ToInt32(cont.buffer, readOffset); readOffset += 4; if (packetLen + readOffset > cont.size) // fill Fragmentation { f.pendingFragment = true; f.alreadyFilledBytes = cont.size - readOffset; f.missingBytes = packetLen - f.alreadyFilledBytes; if (f.alreadyFilledBytes == 0) break; Buffer.BlockCopy(cont.buffer, readOffset, f.buffer, 0, f.alreadyFilledBytes); readOffset += f.alreadyFilledBytes; break; } else // just read it { cont.extractedPackets.Add(new PacketContent(ref cont.buffer, readOffset, packetLen)); readOffset += packetLen; } if ((cont.size - readOffset) <= 0) { stillReading = false; break; } //Extreme case - packet header splitted between packets if ((cont.size - readOffset) < PACKET_SIZE_HEADER) { f.pendingFragment = true; f.sizeSplitted = true; f.sizeAlreadyFilledBytes = cont.size - readOffset; f.sizeMissingBytes = PACKET_SIZE_HEADER - f.sizeAlreadyFilledBytes; Buffer.BlockCopy(cont.buffer, readOffset, f.sizeBuffer, 0, f.sizeAlreadyFilledBytes); stillReading = false; } } }