Ejemplo n.º 1
0
        public void HandlePing(SOEClient sender)
        {
            // Setup a writer
            SOEWriter writer = new SOEWriter((ushort)SOEOPCodes.PING);
            SOEPacket pong = writer.GetFinalSOEPacket(sender, false, false);

            // Send a pong!
            sender.SendPacket(pong);
        }
Ejemplo n.º 2
0
        public void HandleSessionRequest(SOEClient sender, SOEPacket packet)
        {
            // Setup a reader
            SOEReader reader = new SOEReader(packet);

            // Get the data from the packet
            uint crcLength = reader.ReadUInt32();
            uint sessionID = reader.ReadUInt32();
            uint udpBufferSize = reader.ReadUInt32();
            string protocol = reader.ReadNullTerminatedString();

            // Is the client using the correct protocol?
            if (ProtocolString == protocol)
            {
                // Can we encrypt/compress?
                bool encryptable = false;
                bool compressable = true;

                // Start the session and manage the client
                sender.StartSession(crcLength, sessionID, udpBufferSize);
                sender.SetCompressable(compressable);
                sender.SetEncryptable(encryptable);

                Server.ConnectionManager.AddNewClient(sender);

                // Setup a writer
                SOEWriter writer = new SOEWriter((ushort)SOEOPCodes.SESSION_RESPONSE);

                // Write a response
                writer.AddUInt32(sessionID);
                writer.AddUInt32(sender.GetCRCSeed());
                writer.AddByte((byte)crcLength);
                writer.AddBoolean(compressable);
                writer.AddBoolean(encryptable);
                writer.AddUInt32(udpBufferSize);
                writer.AddUInt32(3);

                // Get the response
                SOEPacket response = writer.GetFinalSOEPacket(sender, false, false);

                // Send the response!
                sender.SendPacket(response);
            }
            else
            {
                // They aren't using the right protocol...
                Log("Got connection request from client with incorrect protocol. Client: {0}, Server: {1}", protocol, ProtocolString);
            }
        }
Ejemplo n.º 3
0
        public void DisconnectClient(SOEClient client, ushort reason, bool clientBased = false)
        {
            // Disconnect
            Log("Disconnecting client on {0} (ID: {1}) for reason: {2}", client.GetClientAddress(), client.GetClientID(), (SOEDisconnectReasons)reason);

            // Are they a connected client?
            if (Clients.Contains(client))
            {
                // We don't care about them anymore
                // Open their ID as a space
                Host2ClientID.Remove(client.Client);
                SessionID2ClientID.Remove(client.GetSessionID());
                Clients[client.GetClientID()] = null;
            }

            // Was this a disconnect request from the client itself?
            if (!clientBased)
            {
                // Tell them we're disconnecting them
                SOEWriter packetWriter = new SOEWriter((ushort)SOEOPCodes.DISCONNECT);

                // Arguments
                packetWriter.AddUInt32(client.GetSessionID());
                packetWriter.AddUInt16(reason);

                // Send!
                SOEPacket packet = packetWriter.GetFinalSOEPacket(client, true, false);
                client.SendPacket(packet);
            }
        }
Ejemplo n.º 4
0
        private void SendFragmentedMessage(SOEMessage message)
        {
            // Are we already busy?
            if (BusySendingFragmentedPacket)
            {
                // The already-busy thread will pick up our message..
                FragmentedQueue.Enqueue(message);
                return;
            }

            // Set that we're busy IMMEDIATELY! (thread-safe)
            BusySendingFragmentedPacket = true;

            // Setup the for loop
            SOEWriter writer;
            SOEPacket packet;
            ushort sequenceNumber;
            bool sentInitial = false;

            // The rest aren't any different
            for (int i = 0; i < message.GetFragmentCount(); i++)
            {
                // Setup a new writer
                writer = new SOEWriter((ushort)SOEOPCodes.FRAGMENTED_RELIABLE_DATA);

                // Are we the first packet?
                if (!sentInitial)
                {
                    // Add the total message length
                    writer.AddUInt32((uint)message.GetLength());
                    sentInitial = true;
                }

                // Sequence number
                sequenceNumber = GetNextSequenceNumber();
                writer.AddUInt16(sequenceNumber);

                // Add the message fragment
                writer.AddBytes(message.GetFragment(i));

                // Get the final packet and send it!
                packet = writer.GetFinalSOEPacket(Client, true, true);
                Client.SendPacket(packet);
            }

            // Did any other thread add a fragmented packet?
            if (FragmentedQueue.Count > 0)
            {
                BusySendingFragmentedPacket = false;
                SendFragmentedMessage(FragmentedQueue.Dequeue());
            }
        }
Ejemplo n.º 5
0
        private void SendMessage(SOEMessage message)
        {
            // Setup a writer
            SOEWriter writer = new SOEWriter((ushort)SOEOPCodes.RELIABLE_DATA);

            // Sequence number
            ushort sequenceNumber = GetNextSequenceNumber();
            writer.AddUInt16(sequenceNumber);

            // Add the message
            writer.AddMessage(message);

            // Get the final packet and send it!
            SOEPacket packet = writer.GetFinalSOEPacket(Client, true, true);
            Client.SendPacket(packet);

            // TODO repeat-till-acknowledged
        }
Ejemplo n.º 6
0
        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;
            }
        }
Ejemplo n.º 7
0
        private void ReceivedSequenceOutOfOrder(ushort sequenceNumber)
        {
            // Setup a writer
            SOEWriter writer = new SOEWriter((ushort)SOEOPCodes.OUT_OF_ORDER_RELIABLE_DATA);

            // Where abouts did the sending mess up?
            writer.AddUInt16(sequenceNumber);

            // Send the packet
            SOEPacket packet = writer.GetFinalSOEPacket(Client, true, true);
            Client.SendPacket(packet);
        }
Ejemplo n.º 8
0
        private void Acknowledge(ushort sequenceNumber)
        {
            // Setup a writer
            SOEWriter writer = new SOEWriter((ushort)SOEOPCodes.ACK_RELIABLE_DATA);

            // Compressed? (Always false)
            writer.AddBoolean(false);

            // Add the sequence number
            writer.AddUInt16(sequenceNumber);

            // Send the packet
            SOEPacket packet = writer.GetFinalSOEPacket(Client, true, true);
            Client.SendPacket(packet);
        }
Ejemplo n.º 9
0
        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();
        }
Ejemplo n.º 10
0
        public byte[] Encrypt(SOEClient client, byte[] data)
        {
            SOEReader reader = new SOEReader(data);
            SOEWriter newPacket = new SOEWriter();

            int blockCount = data.Length / 4;
            int byteCount = data.Length % 4;

            uint key = client.GetCRCSeed();

            // Encrypt the blocks of 4 bytes
            for (int i = 0; i < blockCount; i++)
            {
                uint value = key = reader.ReadUInt32() ^ key;
                newPacket.AddUInt32(value);
            }

            // Encrypt 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 encrypted packet
            return newPacket.GetRaw();
        }