using LightReflectiveMirror.Endpoints; using System; namespace LightReflectiveMirror { public partial class RelayHandler { /// /// Invoked when a client connects to this LRM server. /// /// The ID of the client who connected. public void ClientConnected(int clientId) { _pendingAuthentication.Add(clientId); var buffer = _sendBuffers.Rent(1); int pos = 0; buffer.WriteByte(ref pos, (byte)OpCodes.AuthenticationRequest); Program.transport.ServerSend(clientId, 0, new ArraySegment(buffer, 0, pos)); _sendBuffers.Return(buffer); } /// /// Handles the processing of data from a client. /// /// The client who sent the data /// The binary data /// The channel the client sent the data on public void HandleMessage(int clientId, ArraySegment segmentData, int channel) { try { var data = segmentData.Array; int pos = segmentData.Offset; OpCodes opcode = (OpCodes)data.ReadByte(ref pos); if (_pendingAuthentication.Contains(clientId)) { if (opcode == OpCodes.AuthenticationResponse) { string authResponse = data.ReadString(ref pos); if (authResponse == Program.conf.AuthenticationKey) { _pendingAuthentication.Remove(clientId); int writePos = 0; var sendBuffer = _sendBuffers.Rent(1); sendBuffer.WriteByte(ref writePos, (byte)OpCodes.Authenticated); Program.transport.ServerSend(clientId, 0, new ArraySegment(sendBuffer, 0, writePos)); } else { Program.WriteLogMessage($"Client {clientId} sent wrong auth key! Removing from LRM node."); Program.transport.ServerDisconnect(clientId); } } return; } switch (opcode) { case OpCodes.CreateRoom: CreateRoom(clientId, data.ReadInt(ref pos), data.ReadString(ref pos), data.ReadBool(ref pos), data.ReadString(ref pos), data.ReadBool(ref pos), data.ReadString(ref pos), data.ReadBool(ref pos), data.ReadInt(ref pos)); break; case OpCodes.RequestID: SendClientID(clientId); break; case OpCodes.LeaveRoom: LeaveRoom(clientId); break; case OpCodes.JoinServer: JoinRoom(clientId, data.ReadString(ref pos), data.ReadBool(ref pos), data.ReadString(ref pos)); break; case OpCodes.KickPlayer: LeaveRoom(data.ReadInt(ref pos), clientId); break; case OpCodes.SendData: ProcessData(clientId, data.ReadBytes(ref pos), channel, data.ReadInt(ref pos)); break; case OpCodes.UpdateRoomData: var plyRoom = _cachedClientRooms[clientId]; if (plyRoom == null || plyRoom.hostId != clientId) return; if (data.ReadBool(ref pos)) plyRoom.serverName = data.ReadString(ref pos); if (data.ReadBool(ref pos)) plyRoom.serverData = data.ReadString(ref pos); if (data.ReadBool(ref pos)) plyRoom.isPublic = data.ReadBool(ref pos); if (data.ReadBool(ref pos)) plyRoom.maxPlayers = data.ReadInt(ref pos); Endpoint.RoomsModified(); break; } } catch { // Do Nothing. Client probably sent some invalid data. } } /// /// Invoked when a client disconnects from the relay. /// /// The ID of the client who disconnected public void HandleDisconnect(int clientId) => LeaveRoom(clientId); } }