private void JoinRoomAndReport <T>(IRoom roomToJoin, Guid sessionId, IPeer peer, Dictionary <byte, object> joinProperties, T successResponse, T errorResponse) where T : ResponseBase { LinkSessionToRoom(sessionId, roomToJoin); if (!roomToJoin.AddPeerToRoom(peer, joinProperties)) { _messageSender.Send(errorResponse, peer); return; } _gameMetrics.TrackPeerJoin(); _taskScheduler.ScheduleOnceOnNow(async() => { try { if (await roomToJoin.PeerJoined(peer, joinProperties)) { _messageSender.Send(successResponse, peer); } else { // peer.Disconnect(DisconnectReason.JustBecause); _messageSender.Send(errorResponse, peer); } } catch (Exception ex) { _logger.Error($"JoinRoom failed for player {peer.GetSessionId()}: {ex}"); _messageSender.Send(errorResponse, peer); } }); }
public void PeerDisconnected(IPeer peer, IDisconnectInfo info) { lock (_syncPeersList) { var sessionId = peer.GetSessionId(); if (!_sessionsToRooms.TryGetValue(sessionId, out var room)) { _logger.Error($"PeerDisconnected error: Can not get room for peer {sessionId}"); return; } if (room.PeerDisconnected(sessionId, info)) { _gameMetrics.TrackPeerDisconnected(); } _sessionsToRooms.TryRemove(sessionId, out _); _messageSender.CleanupPeerData(peer); if (room.IsGameFinished()) { DeleteRoom(room.GetRoomId()); } } }
public bool AddPeerToRoom(IPeer peer, Dictionary <byte, object> peerProperties) { if (!_roomPlayers.TryAdd(peer.GetSessionId(), new RoomPlayer(peer, peerProperties))) { _logger.Error($"Error adding player to peer collection"); return(false); } return(true); }
public async Task <bool> PeerJoined(IPeer peer, Dictionary <byte, object> peerProperties) { if (_roomController == null) { _logger.Error($"GameModeController == null while peer joining"); return(false); } try { return(await _roomController.ProcessNewPlayer(peer.GetSessionId(), peerProperties) && _roomPlayers.ContainsKey(peer.GetSessionId()));// if player still in room } catch (Exception ex) { _logger.Error($"PeerJoined error for player with sessionId = {peer.GetSessionId()}: {ex}"); return(false); } }
public void ProcessMessage(ushort operationCode, Payload message, DeliveryOptions deliveryOptions, IPeer peer) { try { //room manager handles only room flow messages, others are sent to particular room var sessionId = peer.GetSessionId(); switch (operationCode) { case ShamanOperationCode.JoinRandomRoom: var joinRandomRoomMessage = _serializer.DeserializeAs <DirectJoinRandomRoomRequest>(message.Buffer, message.Offset, message.Length); var roomToRandomJoin = GetRandomRoomOrCreateOne(sessionId, joinRandomRoomMessage.RoomProperties); if (roomToRandomJoin == null) { var msg = $"Error joining random room"; _logger.Error(msg); _messageSender.Send(new JoinRoomResponse() { ResultCode = ResultCode.RequestProcessingError }, peer); } else { JoinRoomAndReport(roomToRandomJoin, sessionId, peer, joinRandomRoomMessage.JoinProperties, new DirectJoinRandomRoomResponse(roomToRandomJoin.GetRoomId()), new DirectJoinRandomRoomResponse() { ResultCode = ResultCode.RequestProcessingError }); } break; case ShamanOperationCode.JoinRoom: var joinMessage = _serializer.DeserializeAs <JoinRoomRequest>(message.Buffer, message.Offset, message.Length); var roomToJoin = GetRoomById(joinMessage.RoomId); if (roomToJoin == null) { var msg = $"Peer {sessionId} attempted to join to non-exist room {joinMessage.RoomId}"; _logger.Error(msg); _messageSender.Send(new JoinRoomResponse() { ResultCode = ResultCode.RequestProcessingError }, peer); } else { JoinRoomAndReport(roomToJoin, sessionId, peer, joinMessage.Properties, new JoinRoomResponse(), new JoinRoomResponse() { ResultCode = ResultCode.RequestProcessingError }); } break; case ShamanOperationCode.LeaveRoom: PeerDisconnected(peer, new SimpleDisconnectInfo(ShamanDisconnectReason.PeerLeave)); break; case ShamanOperationCode.Bundle: if (_sessionsToRooms.TryGetValue(peer.GetSessionId(), out var room)) { room.ProcessMessage(message, deliveryOptions, peer.GetSessionId()); } else { _logger.Error($"ProcessMessage error: Can not get room for peer {peer.GetSessionId()}"); _messageSender.Send(new ErrorResponse() { ResultCode = ResultCode.MessageProcessingError }, peer); } break; default: throw new RoomManagerException($"Unknown operation code received: {operationCode}"); } } catch (Exception ex) { _logger.Error($"RoomManager.ProcessMessage: Error processing {operationCode} message: {ex}"); _messageSender.Send(new ErrorResponse() { ResultCode = ResultCode.MessageProcessingError }, peer); } }