/// <inheritdoc /> public void Execute(ICommandSender commandSender, string[] args) { if (args.Length < 2) { SendUsage(commandSender); return; } var action = args[1].ToLower(); if (action == "on") { if (_whiteList.IsEnabled) { commandSender.SendMessage("Whitelist was already enabled"); return; } _whiteList.IsEnabled = true; commandSender.SendMessage("Whitelist has been enabled"); } else if (action == "off") { if (!_whiteList.IsEnabled) { commandSender.SendMessage("Whitelist was already disabled"); return; } _whiteList.IsEnabled = false; commandSender.SendMessage("Whitelist has been disabled"); } else if (action == "add" || action == "remove") { if (args.Length < 3) { commandSender.SendMessage($"Invalid usage: {Trigger} <add|remove> <auth key|username>"); return; } // Store whether the action is to add or whether to remove var addAction = action == "add"; var identifier = args[2]; if (AuthUtil.IsValidAuthKey(identifier)) { if (addAction) { _whiteList.Add(identifier); commandSender.SendMessage("Auth key has been added to whitelist"); } else { _whiteList.Remove(identifier); commandSender.SendMessage("Auth key has been removed from whitelist"); } } else { // Since the given argument was not a valid auth key, we try player names instead if (!CommandUtil.TryGetPlayerByName(_serverManager.Players, identifier, out var player)) { if (addAction) { _whiteList.AddPreList(identifier); commandSender.SendMessage( $"Added player name '{identifier}' to pre-list. The next player that logs in with that name will be whitelisted."); } else { _whiteList.RemovePreList(identifier); commandSender.SendMessage( $"Removed player name '{identifier}' from pre-list. The next player that logs in with that name will no longer be whitelisted."); } return; } var playerData = (ServerPlayerData)player; if (addAction) { _whiteList.Add(playerData.AuthKey); commandSender.SendMessage( $"Auth key of player '{player.Username}' has been added to whitelist"); } else { _whiteList.Remove(playerData.AuthKey); commandSender.SendMessage( $"Auth key of player '{player.Username}' has been removed from whitelist"); } } } else if (action == "prelist") { commandSender.SendMessage($"Pre-listed player names: {_whiteList.GetPreListed()}"); } else if (action == "clear") { if (args.Length < 3) { _whiteList.Clear(); commandSender.SendMessage("Cleared whitelist"); return; } if (args[2] == "prelist") { _whiteList.ClearPreList(); commandSender.SendMessage("Clear pre-list of whitelist"); } else { commandSender.SendMessage($"Invalid usage: '{Trigger} clear prelist' to clear pre-list"); } } else { SendUsage(commandSender); } }
/// <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); }