Ejemplo n.º 1
0
        /// <summary>
        /// Method for handling a login request for a new client.
        /// </summary>
        /// <param name="id">The ID of the client.</param>
        /// <param name="endPoint">The IP endpoint of the client.</param>
        /// <param name="loginRequest">The LoginRequest packet data.</param>
        /// <param name="updateManager">The update manager for the client.</param>
        /// <returns>true if the login request was approved, false otherwise.</returns>
        private bool OnLoginRequest(
            ushort id,
            IPEndPoint endPoint,
            LoginRequest loginRequest,
            ServerUpdateManager updateManager
            )
        {
            Logger.Get().Info(this, $"Received login request from IP: {endPoint.Address}, username: {loginRequest.Username}");

            if (_banList.IsIpBanned(endPoint.Address.ToString()) || _banList.Contains(loginRequest.AuthKey))
            {
                updateManager.SetLoginResponse(new LoginResponse {
                    LoginResponseStatus = LoginResponseStatus.Banned
                });
                return(false);
            }

            if (_whiteList.IsEnabled)
            {
                if (!_whiteList.Contains(loginRequest.AuthKey))
                {
                    if (!_whiteList.IsPreListed(loginRequest.Username))
                    {
                        updateManager.SetLoginResponse(new LoginResponse {
                            LoginResponseStatus = LoginResponseStatus.NotWhiteListed
                        });
                        return(false);
                    }

                    Logger.Get().Info(this, "  Username was pre-listed, auth key has been added to whitelist");

                    _whiteList.Add(loginRequest.AuthKey);
                    _whiteList.RemovePreList(loginRequest.Username);
                }
            }

            // Check whether the username is not already in use
            foreach (var existingPlayerData in _playerData.GetCopy().Values)
            {
                if (existingPlayerData.Username.ToLower().Equals(loginRequest.Username.ToLower()))
                {
                    updateManager.SetLoginResponse(new LoginResponse {
                        LoginResponseStatus = LoginResponseStatus.InvalidUsername
                    });
                    return(false);
                }
            }

            var addonData = loginRequest.AddonData;

            // Construct a string that contains all addons and respective versions by mapping the items in the addon data
            var addonStringList = string.Join(", ", addonData.Select(addon => $"{addon.Identifier} v{addon.Version}"));

            Logger.Get().Info(this, $"  Client tries to connect with following addons: {addonStringList}");

            // If there is a mismatch between the number of networked addons of the client and the server,
            // we can immediately invalidate the request
            if (addonData.Count != AddonManager.GetNetworkedAddonData().Count)
            {
                HandleInvalidLoginAddons(updateManager);
                return(false);
            }

            // Create a byte list denoting the order of the addons on the server
            var addonOrder = new List <byte>();

            foreach (var addon in addonData)
            {
                // Check and retrieve the server addon with the same name and version
                if (!AddonManager.TryGetNetworkedAddon(
                        addon.Identifier,
                        addon.Version,
                        out var correspondingServerAddon
                        ))
                {
                    // There was no corresponding server addon, so we send a login response with an invalid status
                    // and the addon data that is present on the server, so the client knows what is invalid
                    HandleInvalidLoginAddons(updateManager);
                    return(false);
                }

                if (!correspondingServerAddon.Id.HasValue)
                {
                    continue;
                }

                // If the addon is also present on the server, we append the addon order with the correct index
                addonOrder.Add(correspondingServerAddon.Id.Value);
            }

            var loginResponse = new LoginResponse {
                LoginResponseStatus = LoginResponseStatus.Success,
                AddonOrder          = addonOrder.ToArray()
            };

            updateManager.SetLoginResponse(loginResponse);

            // Create new player data and store it
            var playerData = new ServerPlayerData(
                id,
                endPoint.Address.ToString(),
                loginRequest.Username,
                loginRequest.AuthKey,
                _authorizedList
                );

            _playerData[id] = playerData;

            return(true);
        }