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());
                }
            }
        }
Example #3
0
 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);
 }
Example #4
0
        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);
            }
        }