예제 #1
0
 private static ISockFilter DecodeCommandFilter(byte[] payload, byte type, byte length, int offset, out ObjectId?serverId)
 {
     if (type == 0)
     {
         //User ID, not targetting a server
         ObjectId user = BinaryTool.ReadMongoID(payload, offset);
         serverId = null;
         return(new UserSockFilter(user));
     }
     else if (type == 1)
     {
         //User ID, targetting server
         ObjectId user = BinaryTool.ReadMongoID(payload, offset);
         serverId = BinaryTool.ReadMongoID(payload, offset + 12);
         return(new UserSockFilter(user));
     }
     else if (type == 2)
     {
         //Server ID, all tribes
         serverId = BinaryTool.ReadMongoID(payload, offset);
         return(new ServerSockFilter(serverId.Value));
     }
     else if (type == 3)
     {
         //Server ID, specific tribe
         serverId = BinaryTool.ReadMongoID(payload, offset);
         int tribeId = BinaryTool.ReadInt32(payload, offset + 12);
         return(new ServerTribeSockFilter(serverId.Value, tribeId));
     }
     else
     {
         throw new Exception("Unknown filter type " + type + "!");
     }
 }
예제 #2
0
        /// <summary>
        /// Handles the first binary message we get. It will always be for authentication.
        /// </summary>
        /// <param name="data"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        private async Task HandleAuthentication(byte[] data, int length)
        {
            //This message follows the following format:
            //  256 bytes: Authentication key
            //  8 bytes: Program identification name
            //  4 bytes: System version

            //Verify
            if (length != 256 + 8 + 4)
            {
                Log("AUTHENTICATION", "Authentication length mismatch!");
                await DisconnectAsync(WebSocketCloseStatus.InvalidPayloadData, "DELTA_RPC_DISCONNECT_INVALID_AUTHENTICATION_PAYLOAD");

                return;
            }

            //Extract info
            byte[] key = BinaryTool.CopyFromArray(data, 0, 256);
            program_identity = Encoding.ASCII.GetString(data, 256, 8);
            version          = BinaryTool.ReadInt32(data, 264);

            //Validate the key
            if (!BinaryTool.CompareBytes(Program.master_key, key))
            {
                authenticated = false;
                Log("AUTHENTICATION", "Authentication failed!");
                await DisconnectAsync(WebSocketCloseStatus.PolicyViolation, "DELTA_RPC_DISCONNECT_INVALID_AUTHENTICATION_KEY");

                return;
            }

            //We're now ready for authentication!
            authenticated = true;
            Log("AUTHENTICATION", "Authentication OK!");
            await WriteResponse(0, 0);
        }
예제 #3
0
        /// <summary>
        /// Handles an RPC message: opcode 1. This will fire events to clients by a filter
        /// </summary>
        /// <param name="data"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        private async Task HandleRPCMessage(byte[] data, int length, ulong index)
        {
            //This follows the following format, starting at byte 10
            //  4 bytes: int - Payload length "x"
            //  x bytes: string - Payload
            //  2 bytes: ushort - Filter type
            //  [Dependant on filter type]

            //Read the length of the payload and read the payload
            int payloadLength = BinaryTool.ReadInt32(data, 10);

            byte[] payload = BinaryTool.CopyFromArray(data, 14, payloadLength);
            Log("RPC-MESSAGE", "Payload length " + payloadLength);

            //Read the filter code
            ushort filterCode = BinaryTool.ReadUInt16(data, 14 + payloadLength);

            Log("RPC-MESSAGE", "Filter type " + filterCode);

            //Pack contents
            PackedWebSocketMessage packed = new PackedWebSocketMessage(payload, payloadLength, WebSocketMessageType.Text);

            //Read the filter and send messages
            Task pending;

            if (filterCode == 0)
            {
                //USER_ID - Read the user ID
                //  12 bytes: MongoDB ID - User ID
                ObjectId userId = BinaryTool.ReadMongoID(data, 14 + payloadLength + 2);
                pending = RPCEventDispatcher.SendDataToUserById(RPCType.RPCSession, userId, packed);
            }
            else if (filterCode == 1)
            {
                //SERVER - Sends to all members of a server
                //  12 bytes: MongoDB ID - Server ID
                ObjectId serverId = BinaryTool.ReadMongoID(data, 14 + payloadLength + 2);
                pending = RPCEventDispatcher.SendDataToServerById(RPCType.RPCSession, serverId, packed);
            }
            else if (filterCode == 2)
            {
                //SERVER_TRIBE - Sends to a tribe of a server
                //  12 bytes: MongoDB ID - Server ID
                //  4 bytes: Int - ARK Tribe ID
                ObjectId serverId = BinaryTool.ReadMongoID(data, 14 + payloadLength + 2);
                int      tribeId  = BinaryTool.ReadInt32(data, 14 + payloadLength + 2 + 12);
                pending = RPCEventDispatcher.SendDataToServerTribeById(RPCType.RPCSession, serverId, tribeId, packed);
            }
            else
            {
                await WriteResponse(index, 400);

                return;
            }

            //Wait for sending to complete
            Log("RPC-MESSAGE", "Sending message....pending...");
            await pending;

            Log("RPC-MESSAGE", "Message sent OK!");

            //Send OK
            await WriteResponse(index, 0);
        }