Beispiel #1
0
        public static void HandleLoginRequest(SOEClient sender, SOEMessage message)
        {
            // Setup a reader
            SOEReader reader = new SOEReader(message);

            // Get the login details
            string clientToken = reader.ReadASCIIString();

            reader.ReadUInt64();
            string clientVersion = reader.ReadASCIIString();

            // Correct client version?
            Log.DebugFormat("Received login request from client {0}, token: {1}, version: {2}", sender.GetClientID(), clientToken, clientVersion);
            string expectedClientVersion = Server.ApplicationConfiguration["ClientVersion"];

            if (clientVersion != expectedClientVersion)
            {
                // Error!
                Log.ErrorFormat("Received login request from outdated client: {0}", clientVersion);

                SendLoginResponse(sender, false);
                sender.Disconnect((ushort)SOEDisconnectReasons.Application);
                return;
            }

            // Create a login request and enqueue it
            LoginRequest request = new LoginRequest(sender, clientToken, clientVersion);

            LoginQueue.Enqueue(request);
        }
Beispiel #2
0
        public SOEReader(SOEMessage message)
        {
            Stream = new MemoryStream(message.GetRaw());

            // Skip the message OpCode
            ReadHostInt16();
        }
Beispiel #3
0
        public SOEWriter(SOEMessage message)
        {
            // Message information
            Data = new List<byte>(message.GetRaw());
            OpCode = message.GetOpCode();

            // We're a message!
            IsMessage = true;
        }
Beispiel #4
0
        public static void SendLoginResponse(SOEClient client, bool success)
        {
            // Login Reply
            SOEWriter writer = new SOEWriter((ushort)LoginMessages.LoginResponse, true);

            // Success?
            writer.AddBoolean(success);

            // Send the reply!
            SOEMessage reply = writer.GetFinalSOEMessage(client);

            client.SendMessage(reply);
        }
Beispiel #5
0
        public void HandleMultiData(SOEClient sender, SOEMessage message)
        {
            // Setup a reader and skip the OpCode
            SOEReader reader = new SOEReader(message);
            int offset = 2;

            // Get the data length
            int dataLength = message.GetLength();

            // Get the packets
            while (offset < dataLength)
            {
                // Message size
                int MessageSize = reader.ReadByte();
                byte extendedMessageAmount = 0;

                // If the first byte is 0xFF then:
                // Read how many bytes to add, and then add that many
                if (MessageSize == 0xFF)
                {
                    // How many bytes are there?
                    extendedMessageAmount = reader.ReadByte();

                    // Add that many bytes
                    for (int i = 0; i < extendedMessageAmount; i++)
                    {
                        MessageSize += reader.ReadByte();
                    }

                    extendedMessageAmount++;
                }

                // Read the Message data from the size
                byte[] data = reader.ReadBytes(MessageSize);

                // Handle the Message
                sender.ReceiveMessage(data);

                // Move along
                offset += MessageSize + extendedMessageAmount + 1;
            }
        }
Beispiel #6
0
        public void HandleMultiData(SOEClient sender, SOEMessage message)
        {
            // Setup a reader and skip the OpCode
            SOEReader reader = new SOEReader(message);
            int       offset = 2;

            // Get the data length
            int dataLength = message.GetLength();

            // Get the packets
            while (offset < dataLength)
            {
                // Message size
                int  MessageSize           = reader.ReadByte();
                byte extendedMessageAmount = 0;

                // If the first byte is 0xFF then:
                // Read how many bytes to add, and then add that many
                if (MessageSize == 0xFF)
                {
                    // How many bytes are there?
                    extendedMessageAmount = reader.ReadByte();

                    // Add that many bytes
                    for (int i = 0; i < extendedMessageAmount; i++)
                    {
                        MessageSize += reader.ReadByte();
                    }

                    extendedMessageAmount++;
                }

                // Read the Message data from the size
                byte[] data = reader.ReadBytes(MessageSize);

                // Handle the Message
                sender.ReceiveMessage(data);

                // Move along
                offset += MessageSize + extendedMessageAmount + 1;
            }
        }
        public static void HandleEnqueueCommand(SOEClient sender, SOEMessage message)
        {
            // Is this client even authed?
            if (AccountManager.GetAccount(sender) == null)
            {
                Log.ErrorFormat("Unauthorized client tried enqueing command!");
                sender.Disconnect((ushort)SOEDisconnectReasons.Terminated);
                return;
            }

            // Setup a reader
            SOEReader reader = new SOEReader(message);

            // Get the length
            bool hasLength = reader.ReadBoolean(); // assuming this even is "has length" or just a random 01

            byte[] command = hasLength ? reader.ReadBlob() : reader.ReadToEnd();

            // Handle command!
            HandleCommand(sender, command);
        }
Beispiel #8
0
        public SOEMessage GetFinalSOEMessage(SOEClient client)
        {
            // Are we a packet?
            if (!IsMessage)
            {
                // Yes, and there really isn't a nice way to deal with this..
                client.Server.Log("[ERROR] Tried Calling 'GetFinalSOEMessage' on written SOEPacket. Returning null.");

                // Welp, goodbye world! :'(
                return null;
            }

            // Make our message
            SOEMessage message = new SOEMessage(OpCode, GetRaw());

            // Does this message have to be fragmented?
            if (Data.Count > client.GetBufferSize())
            {
                // Setup a reader and keep track of our size
                SOEReader reader = new SOEReader(GetRaw());
                int size = message.GetLength();

                // While there are fragments to be added..
                while (size > 0)
                {
                    // Store the next fragment
                    byte[] raw;

                    // Is this fragment going to be smaller than the buffer size?
                    if (size < client.GetBufferSize())
                    {
                        raw = reader.ReadBytes(size);
                        size = 0;
                    }
                    else
                    {
                        raw = reader.ReadBytes((int)client.GetBufferSize());
                        size -= (int)client.GetBufferSize();
                    }

                    // Add the finalized fragment
                    message.AddFragment(raw);
                }
            }

            // Return the message we made
            return message;
        }
Beispiel #9
0
        public void AddMessage(SOEMessage message)
        {
            if (IsMessage)
            {
                // Handle multi messages
                if (OpCode == (ushort)SOEOPCodes.MULTI_MESSAGE)
                {
                    if (message.GetOpCode() == (ushort)SOEOPCodes.MULTI_MESSAGE)
                    {
                        // Setup a reader
                        SOEReader reader = new SOEReader(message);

                        // Get the messages and add them
                        byte[] messages = reader.ReadToEnd();
                        AddBytes(messages);
                    }
                    else
                    {
                        // Get the size of the message
                        int size = message.GetLength();

                        // Is the size bigger than 255?
                        if (size > 0xFF)
                        {
                            // Do the stupid >255 thing
                            AddByte(0xFF);
                            size -= 0xFF;

                            // Get how many bytes to add
                            byte toAdd = (byte)((size / 0xFF) + (size % 0xFF) & 0xFF);
                            AddByte(toAdd);

                            // Add sizes until we're at a value of 0
                            while (size > 0)
                            {
                                // Do we not want to add 0xFF?
                                if (size < 0xFF)
                                {
                                    // Add the rest of the size
                                    AddByte((byte)size);
                                    size = 0;
                                }
                                else
                                {
                                    // Add 0xFF
                                    AddByte(0xFF);
                                    size -= 0xFF;
                                }
                            }
                        }
                        else
                        {
                            // Just do the regular size adding
                            AddByte((byte)(size & 0xFF));
                        }

                        // Add the actual message
                        AddBytes(message.GetRaw());
                    }
                }
            }
            else
            {
                // Just add the message
                AddBytes(message.GetRaw());
            }
        }
Beispiel #10
0
        public void SendMessage(SOEMessage message)
        {
            // Send the message through the data channel
            DataChannel.Send(message);

            // This client is still alive
            Interact();
        }
Beispiel #11
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
        }
Beispiel #12
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());
            }
        }
Beispiel #13
0
 public void Send(SOEMessage message)
 {
     if (message.IsFragmented)
     {
         SendFragmentedMessage(message);
     }
     else
     {
         SendMessage(message);
     }
 }
Beispiel #14
0
        public static void HandleLoginRequest(LoginRequest request)
        {
            // Get variables
            string  loginServer = Server.ApplicationConfiguration["LoginServer"];
            string  apiRequest  = loginServer + "consumeToken/";
            JObject response    = null;

            using (var client = new WebClient {
                Proxy = null
            })
            {
                var values = new NameValueCollection();
                values["token"] = request.Token;

                var responseRaw    = client.UploadValues(apiRequest, values);
                var responseString = Encoding.ASCII.GetString(responseRaw);
                try
                {
                    response = JObject.Parse(responseString);
                }
                catch (Exception)
                {
                    Log.Fatal("Received bad response from login server!");
                    Environment.Exit(0);
                }
            }

            if (response != null)
            {
                bool success = response["success"].ToObject <bool>();

                if (success)
                {
                    // Get the account!
                    Account userAccount = response["account"].ToObject <Account>();

                    // Is the user banned?
                    if (userAccount.Banned)
                    {
                        // Report the attempt and disconnect them
                        Log.ErrorFormat("Received successful login for client {0} but this user is banned!",
                                        request.Client.GetClientID());
                        SendLoginResponse(request.Client, false);

                        request.Client.Disconnect((ushort)SOEDisconnectReasons.Application);
                    }
                    else
                    {
                        // Check if they're allowed to be on this server
                        if (userAccount.AccessLevel < (int)Server.ApplicationConfiguration["MinimumAccessLevel"])
                        {
                            // Log the attempt
                            Log.ErrorFormat("Received successful login for client {0} but this user doesn't meet the required minimum access level!",
                                            request.Client.GetClientID());
                            SendLoginResponse(request.Client, false);

                            // Disconnect them
                            request.Client.Disconnect((ushort)SOEDisconnectReasons.Application);
                            return;
                        }

                        // Send the succesful login response!
                        Log.Info("Successful login!");
                        SendLoginResponse(request.Client, true);

                        // Manage the account on the gateway
                        AccountManager.AddAccount(request.Client, userAccount);

                        // Send the connection to the world server
                        // Server.InternalManager.GetConnection("World").RouteConnection(request.Client, response.ToString());
                        // Gateway.InternalWorldConnection.RouteConnection(request.Client, response.ToString());

                        // The world server will then do a: 'Which internal connection is managing this connection?',
                        // assign the client a world-clientID, map clients to internal servers, and then send packets
                        // to us with a tagged "reciever". "reciever" will be the clientId on our side..

                        // Gateway1 -> { Client, 0x01 } -> World { Client, Gateway1, 0x01, 0x04 }
                        // Client (0x01) <- Gateway1 <- { 0x01, data } <- World { 0x04 -> 0x01 (Gateway1) }

                        // TODO: ^

                        // The world server would then send the client the Environment, World, Character, etc..
                        // For now, send that stuff from the gateway:

                        // Environment
                        SOEWriter commandWriter = new SOEWriter(0xA6, true);
                        commandWriter.AddASCIIString("live");
                        byte[] environmentCommand = commandWriter.GetRaw();

                        SOEWriter writer = new SOEWriter((ushort)GatewayMessages.EnqueueCommand, true);
                        writer.AddBoolean(true);
                        writer.AddHostUInt32((uint)environmentCommand.Length);
                        writer.AddBytes(environmentCommand);
                        SOEMessage environmentMessage = writer.GetFinalSOEMessage(request.Client);

                        // ZoneInfo
                        commandWriter = new SOEWriter(0x2B, true);
                        commandWriter.AddASCIIString("FabledRealms");
                        commandWriter.AddHostUInt32(2);
                        commandWriter.AddHostUInt32(0);
                        commandWriter.AddHostUInt32(0);
                        commandWriter.AddUInt32(5);
                        commandWriter.AddHostUInt32(0);
                        commandWriter.AddBoolean(false);
                        byte[] worldCommand = commandWriter.GetRaw();

                        writer = new SOEWriter((ushort)GatewayMessages.EnqueueCommand, true);
                        writer.AddBoolean(true);
                        writer.AddHostUInt32((uint)worldCommand.Length);
                        writer.AddBytes(worldCommand);
                        SOEMessage worldMessage = writer.GetFinalSOEMessage(request.Client);

                        // Send!
                        request.Client.SendMessage(environmentMessage);
                        request.Client.SendMessage(worldMessage);
                    }
                }
                else
                {
                    // Send an unsucessful login response
                    Log.ErrorFormat("Received invalid token from client {0}!", request.Client.GetClientID());
                    SendLoginResponse(request.Client, false);

                    // Disconnect the requesting Client
                    request.Client.Disconnect((ushort)SOEDisconnectReasons.Application);
                }
            }
        }
Beispiel #15
0
        public void HandleMessage(SOEClient sender, SOEMessage message)
        {
            // Handlers
            if (MessageHandlers.HasHandler(ProtocolString, message.GetOpCode()))
            {
                // Log
                string messageName = MessageHandlers.Protocol2MessageName[ProtocolString][message.GetOpCode()];
                Log("Received 0x{0:X}, {1}_{2}!", message.GetOpCode(), Server.GAME_NAME, messageName);

                // Handle it
                MessageHandlers.GetHandler(ProtocolString, message.GetOpCode())(sender, message);
            }
            else
            {
                // Log
                Log("Received Unknown SOEMessage {0}!", message.GetOpCode());
                foreach (byte b in message.GetRaw())
                {
                    Console.Write("0x{0:X2} ", b);
                }
                Console.WriteLine();
            }
        }
Beispiel #16
0
        public void HandleMessage(SOEClient sender, byte[] rawMessage)
        {
            // Read the message...
            SOEReader reader = new SOEReader(rawMessage);
            ushort opCode = reader.ReadHostUInt16();

            // Make the message
            SOEMessage message = new SOEMessage(opCode, rawMessage);

            // Handle it
            HandleMessage(sender, message);
        }