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 + "!"); } }
private static void OnIncomingRPCCommand_PrivledgedMessage(byte[] payload) { //Read header RPCOpcode opcode = (RPCOpcode)BitConverter.ToInt32(payload, 2); ObjectId serverId = BinaryTool.ReadMongoID(payload, 6); int payloadCount = BitConverter.ToInt32(payload, 18); //Clone list List <RPCConnection> clientsSafe = new List <RPCConnection>(); lock (connections) clientsSafe.AddRange(connections); //Begin reading array int offset = 22; for (int i = 0; i < payloadCount; i++) { //Read header data int tribeId = BitConverter.ToInt32(payload, offset + 0); int payloadLength = BitConverter.ToInt32(payload, offset + 4); offset += 8; //Decode payload JObject data = JsonConvert.DeserializeObject <JObject>(Encoding.UTF8.GetString(payload, offset, payloadLength)); //Create filter and command ISockFilter filter = new ServerTribeSockFilter(serverId, tribeId); var cmd = new SendRPCMessageCommand(opcode.ToString(), serverId, data); //Search to send messages foreach (var c in clientsSafe) { //Filter if (!filter.CheckFilter(c)) { continue; } //Send c.EnqueueMessage(cmd); } } }
/// <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); }