/// <summary> /// Initializes a new instance of the <see cref="PlayerEventProcessor"/> class. /// </summary> /// <param name="sst">The main class.</param> public PlayerEventProcessor(SynServerTool sst) { _sst = sst; _qlRanksHelper = new QlRanksHelper(); _seenDb = new DbSeenDates(); _cfgHandler = new ConfigHandler(); }
/// <summary> /// Handles the setting or updating of Elo from the players command text. /// </summary> /// <param name="qlranksHelper">The QLRanks helper.</param> /// <param name="player">The player.</param> private void HandleEloFromPlayersText(QlRanksHelper qlranksHelper, string player) { // Set cached Elo or update if (qlranksHelper.DoesCachedEloExist(player)) { if (!qlranksHelper.IsCachedEloDataOutdated(player)) { qlranksHelper.SetCachedEloData( _sst.ServerInfo.CurrentPlayers, player); Log.Write(string.Format( "Setting non-expired cached Elo result for {0} from database", player), _logClassType, _logPrefix); } else { qlranksHelper.CreateNewPlayerEloData( _sst.ServerInfo.CurrentPlayers, player); _qlranksToUpdateFromPlayers.Add(player); Log.Write(string.Format( "Outdated cached elo data found in DB for {0}. Adding to queue to update.", player), _logClassType, _logPrefix); } } else { qlranksHelper.CreateNewPlayerEloData( _sst.ServerInfo.CurrentPlayers, player); _qlranksToUpdateFromPlayers.Add(player); } }
/// <summary> /// Initializes a new instance of the <see cref="SuggestTeamsCmd"/> class. /// </summary> /// <param name="sst">The main class.</param> public SuggestTeamsCmd(SynServerTool sst) { QlMinArgs = 0; _sst = sst; _qlrHelper = new QlRanksHelper(); _teamBalancer = new TeamBalancer(); _users = new DbUsers(); _balancedRedTeam = new List <PlayerInfo>(); _balancedBlueTeam = new List <PlayerInfo>(); _suggestionTimer = new Timer(); }
/// <summary> /// Checks to see if the player meets the elo requirement on connect. /// </summary> /// <param name="player">The player.</param> public async Task CheckPlayerEloRequirement(string player) { var playerElo = QlRanksHelper.GetEloForGameType(_sst.ServerInfo, player); // Likely invalid, skip. if (playerElo == 0) { return; } await KickPlayerIfEloNotMet(player); }
/// <summary> /// Removes players from server who do not meet the specified Elo requirements immediately /// after enabling the elo limiter. /// </summary> public async Task BatchRemoveEloPlayers() { // disable var qlrHelper = new QlRanksHelper(); // First make sure that the elo is correct and fetch if not var playersToUpdate = (from player in _sst.ServerInfo.CurrentPlayers where qlrHelper.PlayerHasInvalidEloData(player.Value) select player.Key).ToList(); if (playersToUpdate.Any()) { var qlr = await qlrHelper.RetrieveEloDataFromApiAsync(_sst.ServerInfo.CurrentPlayers, playersToUpdate); if (qlr == null) { await _sst.QlCommands.QlCmdSay( "^1[ERROR]^7 Unable to retrieve QLRanks data. Elo limit might not be enforced.", false); Log.Write("QLRanks Elo data could not be retrieved. Elo limit might not be enforced.", _logClassType, _logPrefix); } } // Kick the players from the server... foreach (var player in _sst.ServerInfo.CurrentPlayers.ToList()) { // Still have invalid elo data...skip. if (qlrHelper.PlayerHasInvalidEloData(player.Value)) { Log.Write( string.Format( "Still have invalid Elo data for player {0}; player won't be evaluated for kicking.", player.Key), _logClassType, _logPrefix); break; } await KickPlayerIfEloNotMet(player.Key); } }
/// <summary> /// Handles the player information from the 'players' command and performs various actions /// based on the data. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="playersText">The players text.</param> /// <remarks> /// playersText is sent as an IEnumerable, with each element representing a line of the text /// containing the player information from the /players command. /// </remarks> public async Task HandlePlayersFromPlayersCmd <T>( IEnumerable <T> playersText) { _qlranksToUpdateFromPlayers.Clear(); var qlranksHelper = new QlRanksHelper(); foreach (var line in playersText) { var text = line.ToString(); var playerNameOnly = text.Substring( text.LastIndexOf(" ", StringComparison.Ordinal) + 1) .ToLowerInvariant(); // Try to create the player info (name, clan, id) if (!CreatePlayerFromPlayersText(text)) { return; } // Set the cached Elo for a player or add to list to be updated HandleEloFromPlayersText(qlranksHelper, playerNameOnly); // Store user's last seen date _seenDb.UpdateLastSeenDate(playerNameOnly, DateTime.Now); } // Clear _sst.QlCommands.ClearBothQlConsoles(); // Do any necessary Elo updates if (_qlranksToUpdateFromPlayers.Any()) { await qlranksHelper.RetrieveEloDataFromApiAsync( _sst.ServerInfo.CurrentPlayers, _qlranksToUpdateFromPlayers); } // If any players should be kicked (i.e. due to a module), then do so, but wait a few // (10) seconds since we might have to hit network for retrieval (i.e. QLRanks) await Task.Delay(10000); await DoRequiredPlayerKicks(); }
/// <summary> /// Gets the missing player Elo values if applicable. /// </summary> /// <returns><c>true</c> if the ELo values could be retried, otherwise <c>false</c>.</returns> private async Task <bool> GetMissingEloVals() { var qlrHelper = new QlRanksHelper(); var playersToUpdate = (from player in _sst.ServerInfo.CurrentPlayers where qlrHelper.PlayerHasInvalidEloData(player.Value) select player.Key).ToList(); if (playersToUpdate.Any()) { var qlr = await qlrHelper.RetrieveEloDataFromApiAsync(_sst.ServerInfo.CurrentPlayers, playersToUpdate); if (qlr == null) { Log.Write("QLRanks Elo data could not be retrieved when listing server Elos.", _logClassType, _logPrefix); return(false); } } return(true); }
/// <summary> /// Initializes a new instance of the <see cref="EloCmd"/> class. /// </summary> /// <param name="sst">The main class.</param> public EloCmd(SynServerTool sst) { _sst = sst; _qlrHelper = new QlRanksHelper(); }
/// <summary> /// Kicks the player if player does not meet the server's elo requirements. /// </summary> /// <param name="player">The player.</param> private async Task KickPlayerIfEloNotMet(string player) { // Module values have(n't) been set? var hasMaxEloSpecified = MaximumRequiredElo != 0; var hasMinEloSpecified = MinimumRequiredElo != 0; if (!hasMinEloSpecified) { return; } // Elo limits don't apply to SuperUsers or higher if (_users.GetUserLevel(player) >= UserLevel.SuperUser) { return; } // Can't kick ourselves, though QL doesn't allow it anyway, don't show kick msg. if (player.Equals(_sst.AccountName, StringComparison.InvariantCultureIgnoreCase)) { return; } // Get Elo for the current gametype var playerElo = QlRanksHelper.GetEloForGameType(_sst.ServerInfo, player); // Player Elo is either invalid or we're not in a QLRanks-supported gametype. Abort. if (playerElo == 0) { return; } // Handle minimum if (playerElo < MinimumRequiredElo) { Log.Write( string.Format("{0}'s {1} Elo is less than minimum required ({2})...Will kick player shortly.", player, GameType.ToString().ToUpper(), MinimumRequiredElo), _logClassType, _logPrefix); if (_configHandler.ReadConfiguration().EloLimitOptions.showKickSoonMessage) { await _sst.QlCommands.QlCmdSay( string.Format( "^3[=> KICK SOON]: ^1{0}^7 ({1} Elo:^1 {2}^7) does not meet this server's Elo requirements. Min:^2 {3} {4}", player, GameType.ToString().ToUpper(), playerElo, MinimumRequiredElo, hasMaxEloSpecified ? string.Format("^7Max:^1 {0}", MaximumRequiredElo) : ""), false); } // Wait before notifying and kicking, so user's screen doesn't freeze on "awaiting // snapshot", especially when connecting await _sst.QlCommands.QlCmdDelayedTell( string.Format( "^3You will be kicked because your {0} QLRanks Elo (^1{1}^3) doesn't meet this server's requirements. Min: ^1{2} {3}", GameType.ToString().ToUpper(), playerElo, MinimumRequiredElo, hasMaxEloSpecified ? string.Format("^3Max:^1 {0}", MaximumRequiredElo) : ""), player, _kickTellDelaySecs); await _sst.QlCommands.CustCmdDelayedKickban(player, (_kickDelaySecs + 2)); return; } // Handle range if (!hasMaxEloSpecified) { return; } if (playerElo <= MaximumRequiredElo) { return; } Log.Write( string.Format("{0}'s {1} Elo is greater than maximum allowed ({2})...Will kick player shortly.", player, GameType.ToString().ToUpper(), MaximumRequiredElo), _logClassType, _logPrefix); if (_configHandler.ReadConfiguration().EloLimitOptions.showKickSoonMessage) { await _sst.QlCommands.QlCmdSay( string.Format( "^3[=> KICK SOON]: ^1{0}^7 ({1} Elo:^1 {2}^7) does not meet this server's Elo requirements. Min:^2 {3} ^7Max:^1 {4}", player, GameType.ToString().ToUpper(), playerElo, MinimumRequiredElo, MaximumRequiredElo), false); } await _sst.QlCommands.QlCmdDelayedTell( string.Format( "^3You will be kicked because your {0} QLRanks Elo (^1{1}^3) doesn't meet this server's requirements. Min: ^1{2}^3 Max: ^1{3}", GameType.ToString().ToUpper(), playerElo, MinimumRequiredElo, MaximumRequiredElo), player, _kickTellDelaySecs); await _sst.QlCommands.CustCmdDelayedKickban(player, (_kickDelaySecs + 2)); }