예제 #1
0
        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;
                }
            }
        }