protected override void HandleConnectToServerRequest(ConnectToServerRequest packet, MessageOrigin origin)
        {
            if (serverList.TryGetValue(packet.code, out var server))
            {
                var isConnectionOwner = packet.userId == server.UserId;
                var correctPassword   = server.Password != string.Empty ? packet.password == server.Password : true;
                if (correctPassword)
                {
                    SendReliableRequest(1u, server.EndPoint, PrepareForConnectionRequest.pool.Obtain().Init(packet.userId, packet.userName, origin.endPoint, packet.random, packet.publicKey, isConnectionOwner, false));
                    SendReliableResponse(1u, origin.endPoint, packet, ConnectToServerResponse.pool.Obtain().InitForSuccess(server.UserId, server.Username, server.Secret, server.DiscoveryPolicy, server.InvitePolicy, server.MaxPlayerCount, server.Configuration, isConnectionOwner, false, server.EndPoint, server.Random, server.PublicKey));
                }
                else
                {
                    SendReliableResponse(1u, origin.endPoint, packet, ConnectToServerResponse.pool.Obtain().InitForFailure(ConnectToServerResponse.Result.InvalidPassword));
                }
            }
            else
            {
                SendReliableResponse(1u, origin.endPoint, packet, ConnectToServerResponse.pool.Obtain().InitForFailure(ConnectToServerResponse.Result.InvalidCode));
            }

            packet.Release();
        }
Exemplo n.º 2
0
        /// <summary>
        /// This is used by the framework dont use this from your own code
        /// </summary>
        /// <param name="request"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public override async Task <ConnectToServerResponse> ClientConnectToServer(ConnectToServerRequest request, ServerCallContext context)
        {
            try
            {
                //Add Client
                //TODO:Write Client to db
                AddClient(request.ClientId);
                LogEventOccurred(new LogEvent {
                    ClientId = request.ClientId, Description = "Client are connected"
                });

                return(new ConnectToServerResponse {
                    Response = "Client are connected", ServerDateTime = Timestamp.FromDateTime(DateTime.UtcNow)
                });
            }
            catch (Exception ex)
            {
                LogErrorOccurred(ex, new CoreComMessage {
                    ClientId = request.ClientId
                });
                return(null);
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Open the channel to the server. this is trigger first time on connect or if the server has restared.
        /// </summary>
        /// <returns></returns>
        private async Task <bool> OpenChannel()
        {
            try
            {
                if (_connectionStatus == ConnectionStatusEnum.Connecting)
                {
                    return(false);
                }

                ConnectionStatusChange(ConnectionStatusEnum.Connecting);
                //this is so you can debug on mac and emulator the server has "EndpointDefaults": { "Protocols": "Http1"
                // Return `true` to allow certificates that are untrusted/invalid
                if (_coreComOptions.DangerousAcceptAnyServerCertificateValidator)
                {
                    _httpHandler = new GrpcWebHandler(GrpcWebMode.GrpcWebText, new HttpClientHandler {
                        ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
                    });
                }
                else
                {
                    _httpHandler = new GrpcWebHandler(GrpcWebMode.GrpcWebText, new HttpClientHandler());
                }

                //Check if the channel is open den shutdown before create new
                if (_channel != null)
                {
                    await _channel.ShutdownAsync();
                }

                _channel = GrpcChannel.ForAddress($"{_coreComOptions.ServerAddress}", new GrpcChannelOptions
                {
                    HttpHandler           = _httpHandler,
                    MaxReceiveMessageSize = null, // 5 * 1024 * 1024, // 5 MB
                    MaxSendMessageSize    = null  //2 * 1024 * 1024 // 2 MB
                });

                if (_coreComClient != null)
                {
                    _coreComClient = null;
                }

                _coreComClient = new Proto.CoreCom.CoreComClient(_channel);

                //Wait for channel to open for 5 sec default
                //Log outgoing meesage
                var connectMessage = new ConnectToServerRequest {
                    ClientId = _coreComOptions.ClientId
                };

                var connectEvent = new LogEvent {
                    Description = "Connected to Server ", TransferStatus = TransferStatusEnum.Transferred, MessageSize = connectMessage.CalculateSize()
                };
                LogEventOccurred(connectEvent);
                var response = await _coreComClient.ClientConnectToServerAsync(connectMessage, GetCallOptions(true).WithWaitForReady(true));

                //log request

                //log response
                LogEventOccurred(new LogEvent {
                    Description = response.Response, TransferStatus = TransferStatusEnum.Recived, MessageSize = response.CalculateSize()
                });
                Console.WriteLine("Connected to Server " + _coreComOptions.ServerAddress);

                ConnectionStatusChange(ConnectionStatusEnum.Connected);
                //Start timmer for check queue server and client
                if (_coreComOptions.GrpcOptions.RequestServerQueueIntervalSec > 0)
                {
                    _checkQueueTimer.Enabled = true;
                }

                LatestRpcExceptionChange(null);


                return(true);
            }
            catch (RpcException ex)
            {
                LatestRpcExceptionChange(ex);

                ConnectionStatusChange(ConnectionStatusEnum.Disconnected);
                LogEventOccurred(new LogEvent {
                    Description = ex.Message, ConnectionStatus = _connectionStatus
                });
                _timer.Enabled = true;

                return(false);
            }
            catch (Exception ex)
            {
                ConnectionStatusChange(ConnectionStatusEnum.Disconnected);
                LogErrorOccurred(ex, new CoreComMessageResponse {
                    ClientId = _coreComOptions.ClientId
                });
                _timer.Enabled = true;
                return(false);
            }
        }
Exemplo n.º 4
0
        public async Task <ConnectToServerResponse> ConnectToServer(ISession session, ConnectToServerRequest request)
        {
            _logger.Verbose(
                $"Handling {nameof(ConnectToServerRequest)} " +
                $"(UserId='{request.UserId}', " +
                $"UserName='******', " +
                $"Random='{BitConverter.ToString(request.Random)}', " +
                $"PublicKey='{BitConverter.ToString(request.PublicKey)}', " +
                $"Secret='{request.Secret}', " +
                $"Code='{request.Code}', " +
                $"Password='******', " +
                $"UseRelay={request.UseRelay})."
                );

            Server server = null;

            if (!string.IsNullOrEmpty(request.Code))
            {
                server = await _serverRepository.GetServerByCode(request.Code);

                if (server == null)
                {
                    return new ConnectToServerResponse()
                           {
                               Result = ConnectToServerResponse.ResultCode.InvalidCode
                           }
                }
                ;
            }
            else if (!string.IsNullOrEmpty(request.Secret))
            {
                server = await _serverRepository.GetServer(request.Secret);

                if (server == null)
                {
                    return new ConnectToServerResponse()
                           {
                               Result = ConnectToServerResponse.ResultCode.InvalidSecret
                           }
                }
                ;
            }

            if (server.CurrentPlayerCount >= server.MaximumPlayerCount)
            {
                return new ConnectToServerResponse()
                       {
                           Result = ConnectToServerResponse.ResultCode.ServerAtCapacity
                       }
            }
            ;

            if (!_sessionService.TryGetSession(server.RemoteEndPoint, out var hostSession))
            {
                _logger.Warning(
                    "Failed to retrieve server host session while handling " +
                    $"{nameof(ConnectToServerRequest)} " +
                    $"(EndPoint='{server.RemoteEndPoint}')."
                    );

                return(new ConnectToServerResponse()
                {
                    Result = ConnectToServerResponse.ResultCode.UnknownError
                });
            }

            // Let the host know that someone is about to connect (hole-punch)
            await _messageDispatcher.Send(hostSession, new PrepareForConnectionRequest()
            {
                UserId            = request.UserId,
                UserName          = request.UserName,
                RemoteEndPoint    = (IPEndPoint)session.EndPoint,
                Random            = request.Random,
                PublicKey         = request.PublicKey,
                IsConnectionOwner = false,
                IsDedicatedServer = false
            });

            if (!await _serverRepository.IncrementCurrentPlayerCount(server.Secret))
            {
                _logger.Warning(
                    "Failed to increment player count " +
                    $"(Secret='{server.Secret}')."
                    );
                return(new ConnectToServerResponse()
                {
                    Result = ConnectToServerResponse.ResultCode.UnknownError
                });
            }

            session.Secret = request.Secret;

            return(new ConnectToServerResponse()
            {
                Result = ConnectToServerResponse.ResultCode.Success,
                UserId = server.Host.UserId,
                UserName = server.Host.UserName,
                Secret = server.Secret,
                DiscoveryPolicy = (DiscoveryPolicy)server.DiscoveryPolicy,
                InvitePolicy = (InvitePolicy)server.InvitePolicy,
                MaximumPlayerCount = server.MaximumPlayerCount,
                Configuration = new GameplayServerConfiguration()
                {
                    BeatmapDifficultyMask = (BeatmapDifficultyMask)server.BeatmapDifficultyMask,
                    GameplayModifiersMask = (GameplayModifiersMask)server.GameplayModifiersMask,
                    SongPackBloomFilterTop = server.SongPackBloomFilterTop,
                    SongPackBloomFilterBottom = server.SongPackBloomFilterBottom
                },
                IsConnectionOwner = true,
                IsDedicatedServer = false,
                RemoteEndPoint = server.RemoteEndPoint,
                Random = server.Random,
                PublicKey = server.PublicKey
            });
        }
Exemplo n.º 5
0
        public async Task <ConnectToServerResponse> ConnectToServer(MasterServerSession session, ConnectToServerRequest request)
        {
            _logger.Verbose(
                $"Handling {nameof(ConnectToServerRequest)} " +
                $"(UserId='{request.UserId}', " +
                $"UserName='******', " +
                $"Random='{BitConverter.ToString(request.Random)}', " +
                $"PublicKey='{BitConverter.ToString(request.PublicKey)}', " +
                $"Secret='{request.Secret}', " +
                $"Code='{request.Code}', " +
                $"Password='******', " +
                $"UseRelay={request.UseRelay})."
                );

            Server server = null;

            if (!String.IsNullOrEmpty(request.Code))
            {
                server = await _serverRepository.GetServerByCode(request.Code);
            }
            else if (!String.IsNullOrEmpty(request.Secret))
            {
                server = await _serverRepository.GetServer(request.Secret);
            }

            if (server is null)
            {
                return new ConnectToServerResponse
                       {
                           Result = ConnectToServerResponse.ResultCode.InvalidCode
                       }
            }
            ;

            if (server.CurrentPlayerCount >= server.MaximumPlayerCount)
            {
                return new ConnectToServerResponse
                       {
                           Result = ConnectToServerResponse.ResultCode.ServerAtCapacity
                       }
            }
            ;

            if (!_sessionService.TryGetSession(server.RemoteEndPoint, out var hostSession))
            {
                _logger.Warning(
                    "Failed to retrieve server host session while handling " +
                    $"{nameof(ConnectToServerRequest)} " +
                    $"(RemoteEndPoint='{server.RemoteEndPoint}', " +
                    $"UserId='{request.UserId}', " +
                    $"UserName='******', " +
                    $"Random='{BitConverter.ToString(request.Random)}', " +
                    $"PublicKey='{BitConverter.ToString(request.PublicKey)}', " +
                    $"Secret='{request.Secret}', " +
                    $"Code='{request.Code}', " +
                    $"Password='******', " +
                    $"UseRelay={request.UseRelay})."
                    );

                return(new ConnectToServerResponse
                {
                    Result = ConnectToServerResponse.ResultCode.UnknownError
                });
            }

            var connectingEndPoint = (IPEndPoint)session.EndPoint;
            var remoteEndPoint     = (IPEndPoint)hostSession.EndPoint;

            if (request.UseRelay)
            {
                GetAvailableRelayServerResponse getAvailableRelayServerResponse;
                try
                {
                    getAvailableRelayServerResponse = await _relayServerService.GetAvailableRelayServer(
                        new GetAvailableRelayServerRequest(
                            session.EndPoint.ToString() !,
                            hostSession.EndPoint.ToString() !
                            )
                        );
                }
                catch (TimeoutException e)
                {
                    _logger.Error(e,
                                  "Failed to get an available relay server while handling " +
                                  $"{nameof(ConnectToServerRequest)} " +
                                  $"(RemoteEndPoint='{server.RemoteEndPoint}', " +
                                  $"UserId='{request.UserId}', " +
                                  $"UserName='******', " +
                                  $"Random='{BitConverter.ToString(request.Random)}', " +
                                  $"PublicKey='{BitConverter.ToString(request.PublicKey)}', " +
                                  $"Secret='{request.Secret}', " +
                                  $"Code='{request.Code}', " +
                                  $"Password='******', " +
                                  $"UseRelay={request.UseRelay})."
                                  );
                    return(new ConnectToServerResponse
                    {
                        Result = ConnectToServerResponse.ResultCode.NoAvailableDedicatedServers
                    });
                }
                if (!getAvailableRelayServerResponse.Success)
                {
                    _logger.Warning(
                        "No available relay servers while handling " +
                        $"{nameof(ConnectToServerRequest)} " +
                        $"(RemoteEndPoint='{server.RemoteEndPoint}', " +
                        $"UserId='{request.UserId}', " +
                        $"UserName='******', " +
                        $"Random='{BitConverter.ToString(request.Random)}', " +
                        $"PublicKey='{BitConverter.ToString(request.PublicKey)}', " +
                        $"Secret='{request.Secret}', " +
                        $"Code='{request.Code}', " +
                        $"Password='******', " +
                        $"UseRelay={request.UseRelay})."
                        );
                    return(new ConnectToServerResponse
                    {
                        Result = ConnectToServerResponse.ResultCode.NoAvailableDedicatedServers
                    });
                }
                remoteEndPoint     = IPEndPoint.Parse(getAvailableRelayServerResponse.RemoteEndPoint);
                connectingEndPoint = remoteEndPoint;
            }

            // Let the host know that someone is about to connect (hole-punch)
            await _messageDispatcher.SendWithRetry(hostSession, new PrepareForConnectionRequest
            {
                UserId            = request.UserId,
                UserName          = request.UserName,
                RemoteEndPoint    = connectingEndPoint,
                Random            = request.Random,
                PublicKey         = request.PublicKey,
                IsConnectionOwner = false,
                IsDedicatedServer = false
            });

            session.Secret = request.Secret;

            _logger.Information(
                "Successfully connected to server " +
                $"(RemoteEndPoint='{remoteEndPoint}', " +
                $"UserId='{request.UserId}', " +
                $"UserName='******', " +
                $"Random='{BitConverter.ToString(request.Random)}', " +
                $"PublicKey='{BitConverter.ToString(request.PublicKey)}', " +
                $"Secret='{request.Secret}', " +
                $"Code='{request.Code}', " +
                $"Password='******', " +
                $"UseRelay={request.UseRelay})."
                );
            return(new ConnectToServerResponse
            {
                Result = ConnectToServerResponse.ResultCode.Success,
                UserId = server.Host.UserId,
                UserName = server.Host.UserName,
                Secret = server.Secret,
                DiscoveryPolicy = (DiscoveryPolicy)server.DiscoveryPolicy,
                InvitePolicy = (InvitePolicy)server.InvitePolicy,
                MaximumPlayerCount = server.MaximumPlayerCount,
                Configuration = new GameplayServerConfiguration()
                {
                    BeatmapDifficultyMask = (BeatmapDifficultyMask)server.BeatmapDifficultyMask,
                    GameplayModifiersMask = (GameplayModifiersMask)server.GameplayModifiersMask,
                    SongPackBloomFilterTop = server.SongPackBloomFilterTop,
                    SongPackBloomFilterBottom = server.SongPackBloomFilterBottom
                },
                IsConnectionOwner = true,
                IsDedicatedServer = false,
                RemoteEndPoint = remoteEndPoint,
                Random = server.Random,
                PublicKey = server.PublicKey
            });
        }