anticheat tweaks
- reset recoil state on map change - refactor config - remove m21 from chest detection - allow ignored client ids
This commit is contained in:
parent
7f11921757
commit
1f1f4de67a
@ -20,7 +20,8 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
|
|||||||
Offset,
|
Offset,
|
||||||
Strain,
|
Strain,
|
||||||
Recoil,
|
Recoil,
|
||||||
Snap
|
Snap,
|
||||||
|
Button
|
||||||
};
|
};
|
||||||
|
|
||||||
public ChangeTracking<EFACSnapshot> Tracker { get; private set; }
|
public ChangeTracking<EFACSnapshot> Tracker { get; private set; }
|
||||||
@ -38,11 +39,12 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
|
|||||||
ILogger Log;
|
ILogger Log;
|
||||||
Strain Strain;
|
Strain Strain;
|
||||||
readonly DateTime ConnectionTime = DateTime.UtcNow;
|
readonly DateTime ConnectionTime = DateTime.UtcNow;
|
||||||
private double sessionAverageRecoilAmount;
|
private double mapAverageRecoilAmount;
|
||||||
private double sessionAverageSnapAmount;
|
private double sessionAverageSnapAmount;
|
||||||
private int sessionSnapHits;
|
private int sessionSnapHits;
|
||||||
private EFClientKill lastHit;
|
private EFClientKill lastHit;
|
||||||
private int validRecoilHitCount;
|
private int validRecoilHitCount;
|
||||||
|
private int validButtonHitCount;
|
||||||
|
|
||||||
private class HitInfo
|
private class HitInfo
|
||||||
{
|
{
|
||||||
@ -282,18 +284,30 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
|
|||||||
|
|
||||||
#region RECOIL
|
#region RECOIL
|
||||||
float hitRecoilAverage = 0;
|
float hitRecoilAverage = 0;
|
||||||
if (!Plugin.Config.Configuration().RecoilessWeapons.Any(_weaponRegex => Regex.IsMatch(hit.Weapon.ToString(), _weaponRegex)))
|
bool shouldIgnoreDetection = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
shouldIgnoreDetection = Plugin.Config.Configuration().AnticheatConfiguration.IgnoredDetectionSpecification[hit.GameName][DetectionType.Recoil]
|
||||||
|
.Any(_weaponRegex => Regex.IsMatch(hit.Weapon.ToString(), _weaponRegex));
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (KeyNotFoundException)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!shouldIgnoreDetection)
|
||||||
{
|
{
|
||||||
validRecoilHitCount++;
|
validRecoilHitCount++;
|
||||||
hitRecoilAverage = (hit.AnglesList.Sum(_angle => _angle.Z) + hit.ViewAngles.Z) / (hit.AnglesList.Count + 1);
|
hitRecoilAverage = (hit.AnglesList.Sum(_angle => _angle.Z) + hit.ViewAngles.Z) / (hit.AnglesList.Count + 1);
|
||||||
sessionAverageRecoilAmount = (sessionAverageRecoilAmount * (validRecoilHitCount - 1) + hitRecoilAverage) / validRecoilHitCount;
|
mapAverageRecoilAmount = (mapAverageRecoilAmount * (validRecoilHitCount - 1) + hitRecoilAverage) / validRecoilHitCount;
|
||||||
|
|
||||||
if (validRecoilHitCount >= Thresholds.LowSampleMinKills && Kills > Thresholds.LowSampleMinKillsRecoil && sessionAverageRecoilAmount == 0)
|
if (validRecoilHitCount >= Thresholds.LowSampleMinKills && Kills > Thresholds.LowSampleMinKillsRecoil && mapAverageRecoilAmount == 0)
|
||||||
{
|
{
|
||||||
results.Add(new DetectionPenaltyResult()
|
results.Add(new DetectionPenaltyResult()
|
||||||
{
|
{
|
||||||
ClientPenalty = EFPenalty.PenaltyType.Ban,
|
ClientPenalty = EFPenalty.PenaltyType.Ban,
|
||||||
Value = sessionAverageRecoilAmount,
|
Value = mapAverageRecoilAmount,
|
||||||
HitCount = HitCount,
|
HitCount = HitCount,
|
||||||
Type = DetectionType.Recoil
|
Type = DetectionType.Recoil
|
||||||
});
|
});
|
||||||
@ -301,6 +315,37 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region BUTTON
|
||||||
|
try
|
||||||
|
{
|
||||||
|
shouldIgnoreDetection = false;
|
||||||
|
shouldIgnoreDetection = Plugin.Config.Configuration().AnticheatConfiguration.IgnoredDetectionSpecification[hit.GameName][DetectionType.Button]
|
||||||
|
.Any(_weaponRegex => Regex.IsMatch(hit.Weapon.ToString(), _weaponRegex));
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (KeyNotFoundException)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!shouldIgnoreDetection)
|
||||||
|
{
|
||||||
|
validButtonHitCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
double lastDiff = hit.TimeOffset - hit.TimeSinceLastAttack;
|
||||||
|
if (validButtonHitCount > 0 && lastDiff <= 0)
|
||||||
|
{
|
||||||
|
results.Add(new DetectionPenaltyResult()
|
||||||
|
{
|
||||||
|
ClientPenalty = EFPenalty.PenaltyType.Ban,
|
||||||
|
Value = lastDiff,
|
||||||
|
HitCount = HitCount,
|
||||||
|
Type = DetectionType.Button
|
||||||
|
});
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region SESSION_RATIOS
|
#region SESSION_RATIOS
|
||||||
if (Kills >= Thresholds.LowSampleMinKills)
|
if (Kills >= Thresholds.LowSampleMinKills)
|
||||||
{
|
{
|
||||||
@ -384,7 +429,19 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
|
|||||||
#region CHEST_ABDOMEN_RATIO_SESSION
|
#region CHEST_ABDOMEN_RATIO_SESSION
|
||||||
int chestHits = HitLocationCount[IW4Info.HitLocation.torso_upper].Count;
|
int chestHits = HitLocationCount[IW4Info.HitLocation.torso_upper].Count;
|
||||||
|
|
||||||
if (chestHits >= Thresholds.MediumSampleMinKills)
|
try
|
||||||
|
{
|
||||||
|
shouldIgnoreDetection = false; // reset previous value
|
||||||
|
shouldIgnoreDetection = Plugin.Config.Configuration().AnticheatConfiguration.IgnoredDetectionSpecification[hit.GameName][DetectionType.Chest]
|
||||||
|
.Any(_weaponRegex => Regex.IsMatch(hit.Weapon.ToString(), _weaponRegex));
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (KeyNotFoundException)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chestHits >= Thresholds.MediumSampleMinKills && !shouldIgnoreDetection)
|
||||||
{
|
{
|
||||||
double marginOfError = Thresholds.GetMarginOfError(chestHits);
|
double marginOfError = Thresholds.GetMarginOfError(chestHits);
|
||||||
double lerpAmount = Math.Min(1.0, (chestHits - Thresholds.MediumSampleMinKills) / (double)(Thresholds.HighSampleMinKills - Thresholds.LowSampleMinKills));
|
double lerpAmount = Math.Min(1.0, (chestHits - Thresholds.MediumSampleMinKills) / (double)(Thresholds.HighSampleMinKills - Thresholds.LowSampleMinKills));
|
||||||
@ -466,5 +523,11 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
|
|||||||
|
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void OnMapChange()
|
||||||
|
{
|
||||||
|
mapAverageRecoilAmount = 0;
|
||||||
|
validRecoilHitCount = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
24
Plugins/Stats/Config/AnticheatConfiguration.cs
Normal file
24
Plugins/Stats/Config/AnticheatConfiguration.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using static IW4MAdmin.Plugins.Stats.Cheat.Detection;
|
||||||
|
using static SharedLibraryCore.Server;
|
||||||
|
|
||||||
|
namespace Stats.Config
|
||||||
|
{
|
||||||
|
public class AnticheatConfiguration
|
||||||
|
{
|
||||||
|
public bool Enable { get; set; }
|
||||||
|
public IDictionary<long, DetectionType[]> ServerDetectionTypes { get; set; } = new Dictionary<long, DetectionType[]>();
|
||||||
|
public IList<long> IgnoredClientIds { get; set; } = new List<long>();
|
||||||
|
public IDictionary<Game, IDictionary<DetectionType, string[]>> IgnoredDetectionSpecification{ get; set; } = new Dictionary<Game, IDictionary<DetectionType, string[]>>
|
||||||
|
{
|
||||||
|
{
|
||||||
|
Game.IW4, new Dictionary<DetectionType, string[]>
|
||||||
|
{
|
||||||
|
{ DetectionType.Chest, new[] { "m21.+" } },
|
||||||
|
{ DetectionType.Recoil, new[] { "ranger.*_mp", "model1887.*_mp", ".+shotgun.*_mp" } },
|
||||||
|
{ DetectionType.Button, new[] { ".*akimbo.*" } }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
using SharedLibraryCore;
|
using SharedLibraryCore;
|
||||||
using SharedLibraryCore.Interfaces;
|
using SharedLibraryCore.Interfaces;
|
||||||
using Stats.Config;
|
using Stats.Config;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using static IW4MAdmin.Plugins.Stats.Cheat.Detection;
|
using static IW4MAdmin.Plugins.Stats.Cheat.Detection;
|
||||||
|
|
||||||
@ -8,21 +9,41 @@ namespace IW4MAdmin.Plugins.Stats.Config
|
|||||||
{
|
{
|
||||||
public class StatsConfiguration : IBaseConfiguration
|
public class StatsConfiguration : IBaseConfiguration
|
||||||
{
|
{
|
||||||
public bool EnableAntiCheat { get; set; }
|
[Obsolete]
|
||||||
|
public bool? EnableAntiCheat { get; set; }
|
||||||
public List<StreakMessageConfiguration> KillstreakMessages { get; set; }
|
public List<StreakMessageConfiguration> KillstreakMessages { get; set; }
|
||||||
public List<StreakMessageConfiguration> DeathstreakMessages { get; set; }
|
public List<StreakMessageConfiguration> DeathstreakMessages { get; set; }
|
||||||
public List<string> RecoilessWeapons { get; set; }
|
|
||||||
public int TopPlayersMinPlayTime { get; set; }
|
public int TopPlayersMinPlayTime { get; set; }
|
||||||
public bool StoreClientKills { get; set; }
|
public bool StoreClientKills { get; set; }
|
||||||
public int MostKillsMaxInactivityDays { get; set; } = 30;
|
public int MostKillsMaxInactivityDays { get; set; } = 30;
|
||||||
public int MostKillsClientLimit { get; set; } = 5;
|
public int MostKillsClientLimit { get; set; } = 5;
|
||||||
public IDictionary<DetectionType, DistributionConfiguration> DetectionDistributions { get; set; }
|
[Obsolete]
|
||||||
public IDictionary<long, DetectionType[]> ServerDetectionTypes { get; set; }
|
public IDictionary<long, DetectionType[]> ServerDetectionTypes { get; set; }
|
||||||
|
public AnticheatConfiguration AnticheatConfiguration { get; set; } = new AnticheatConfiguration();
|
||||||
|
|
||||||
|
#pragma warning disable CS0612 // Type or member is obsolete
|
||||||
|
public void ApplyMigration()
|
||||||
|
{
|
||||||
|
if (ServerDetectionTypes != null)
|
||||||
|
{
|
||||||
|
AnticheatConfiguration.ServerDetectionTypes = ServerDetectionTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerDetectionTypes = null;
|
||||||
|
|
||||||
|
if (EnableAntiCheat != null)
|
||||||
|
{
|
||||||
|
AnticheatConfiguration.Enable = EnableAntiCheat.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
EnableAntiCheat = null;
|
||||||
|
}
|
||||||
|
#pragma warning restore CS0612 // Type or member is obsolete
|
||||||
|
|
||||||
public string Name() => "StatsPluginSettings";
|
public string Name() => "StatsPluginSettings";
|
||||||
public IBaseConfiguration Generate()
|
public IBaseConfiguration Generate()
|
||||||
{
|
{
|
||||||
EnableAntiCheat = Utilities.PromptBool(Utilities.CurrentLocalization.LocalizationIndex["PLUGIN_STATS_SETUP_ENABLEAC"]);
|
AnticheatConfiguration.Enable = Utilities.PromptBool(Utilities.CurrentLocalization.LocalizationIndex["PLUGIN_STATS_SETUP_ENABLEAC"]);
|
||||||
KillstreakMessages = new List<StreakMessageConfiguration>()
|
KillstreakMessages = new List<StreakMessageConfiguration>()
|
||||||
{
|
{
|
||||||
new StreakMessageConfiguration(){
|
new StreakMessageConfiguration(){
|
||||||
@ -57,16 +78,9 @@ namespace IW4MAdmin.Plugins.Stats.Config
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
RecoilessWeapons = new List<string>()
|
|
||||||
{
|
|
||||||
"ranger.*_mp",
|
|
||||||
"model1887.*_mp",
|
|
||||||
".+shotgun.*_mp"
|
|
||||||
};
|
|
||||||
|
|
||||||
TopPlayersMinPlayTime = 3600 * 3;
|
TopPlayersMinPlayTime = 3600 * 3;
|
||||||
StoreClientKills = false;
|
StoreClientKills = false;
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -481,7 +481,8 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
IsKill = !isDamage,
|
IsKill = !isDamage,
|
||||||
AnglesList = snapshotAngles,
|
AnglesList = snapshotAngles,
|
||||||
IsAlive = isAlive == "1",
|
IsAlive = isAlive == "1",
|
||||||
TimeSinceLastAttack = long.Parse(lastAttackTime)
|
TimeSinceLastAttack = long.Parse(lastAttackTime),
|
||||||
|
GameName = attacker.CurrentServer.GameName
|
||||||
};
|
};
|
||||||
|
|
||||||
if (hit.HitLoc == IW4Info.HitLocation.shield)
|
if (hit.HitLoc == IW4Info.HitLocation.shield)
|
||||||
@ -539,7 +540,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Plugin.Config.Configuration().EnableAntiCheat && !attacker.IsBot && attacker.ClientId != victim.ClientId)
|
if (Plugin.Config.Configuration().AnticheatConfiguration.Enable && !attacker.IsBot && attacker.ClientId != victim.ClientId)
|
||||||
{
|
{
|
||||||
clientDetection.TrackedHits.Add(hit);
|
clientDetection.TrackedHits.Add(hit);
|
||||||
|
|
||||||
@ -555,10 +556,12 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
|
|
||||||
if (oldestHit.IsAlive)
|
if (oldestHit.IsAlive)
|
||||||
{
|
{
|
||||||
var result = DeterminePenaltyResult(clientDetection.ProcessHit(oldestHit), attacker.CurrentServer.EndPoint);
|
var result = DeterminePenaltyResult(clientDetection.ProcessHit(oldestHit), attacker);
|
||||||
#if !DEBUG
|
|
||||||
await ApplyPenalty(result, attacker);
|
if (Utilities.IsDevelopment)
|
||||||
#endif
|
{
|
||||||
|
await ApplyPenalty(result, attacker);
|
||||||
|
}
|
||||||
|
|
||||||
if (clientDetection.Tracker.HasChanges && result.ClientPenalty != EFPenalty.PenaltyType.Any)
|
if (clientDetection.Tracker.HasChanges && result.ClientPenalty != EFPenalty.PenaltyType.Any)
|
||||||
{
|
{
|
||||||
@ -594,10 +597,10 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private DetectionPenaltyResult DeterminePenaltyResult(IEnumerable<DetectionPenaltyResult> results, long serverId)
|
private DetectionPenaltyResult DeterminePenaltyResult(IEnumerable<DetectionPenaltyResult> results, EFClient client)
|
||||||
{
|
{
|
||||||
// allow disabling of certain detection types
|
// allow disabling of certain detection types
|
||||||
results = results.Where(_result => ShouldUseDetection(serverId, _result.Type));
|
results = results.Where(_result => ShouldUseDetection(client.CurrentServer, _result.Type, client.ClientId));
|
||||||
return results.FirstOrDefault(_result => _result.ClientPenalty == EFPenalty.PenaltyType.Ban) ??
|
return results.FirstOrDefault(_result => _result.ClientPenalty == EFPenalty.PenaltyType.Ban) ??
|
||||||
results.FirstOrDefault(_result => _result.ClientPenalty == EFPenalty.PenaltyType.Flag) ??
|
results.FirstOrDefault(_result => _result.ClientPenalty == EFPenalty.PenaltyType.Flag) ??
|
||||||
new DetectionPenaltyResult()
|
new DetectionPenaltyResult()
|
||||||
@ -617,21 +620,24 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool ShouldUseDetection(long serverId, DetectionType detectionType)
|
private bool ShouldUseDetection(Server server, DetectionType detectionType, long clientId)
|
||||||
{
|
{
|
||||||
var detectionTypes = Plugin.Config.Configuration().ServerDetectionTypes;
|
bool shouldRun = true;
|
||||||
|
var detectionTypes = Plugin.Config.Configuration().AnticheatConfiguration.ServerDetectionTypes;
|
||||||
|
var ignoredClients = Plugin.Config.Configuration().AnticheatConfiguration.IgnoredClientIds;
|
||||||
|
|
||||||
if (detectionTypes == null)
|
try
|
||||||
{
|
{
|
||||||
return true;
|
shouldRun &= !detectionTypes[server.EndPoint].Contains(detectionType);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!detectionTypes.ContainsKey(serverId))
|
catch (KeyNotFoundException)
|
||||||
{
|
{
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return detectionTypes[serverId].Contains(detectionType);
|
shouldRun &= !ignoredClients.Any(_clientId => _clientId == clientId);
|
||||||
|
return shouldRun;
|
||||||
}
|
}
|
||||||
|
|
||||||
async Task ApplyPenalty(DetectionPenaltyResult penalty, EFClient attacker)
|
async Task ApplyPenalty(DetectionPenaltyResult penalty, EFClient attacker)
|
||||||
@ -1139,10 +1145,15 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
|
|
||||||
public void ResetKillstreaks(Server sv)
|
public void ResetKillstreaks(Server sv)
|
||||||
{
|
{
|
||||||
foreach (var stat in sv.GetClientsAsList()
|
foreach (var session in sv.GetClientsAsList()
|
||||||
.Select(_client => _client.GetAdditionalProperty<EFClientStatistics>(CLIENT_STATS_KEY)))
|
.Select(_client => new
|
||||||
|
{
|
||||||
|
stat = _client.GetAdditionalProperty<EFClientStatistics>(CLIENT_STATS_KEY),
|
||||||
|
detection = _client.GetAdditionalProperty<Detection>(CLIENT_DETECTIONS_KEY)
|
||||||
|
}))
|
||||||
{
|
{
|
||||||
stat?.StartNewSession();
|
session.stat?.StartNewSession();
|
||||||
|
session.detection?.OnMapChange();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ using System.ComponentModel.DataAnnotations.Schema;
|
|||||||
using SharedLibraryCore.Helpers;
|
using SharedLibraryCore.Helpers;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using static SharedLibraryCore.Server;
|
||||||
|
|
||||||
namespace IW4MAdmin.Plugins.Stats.Models
|
namespace IW4MAdmin.Plugins.Stats.Models
|
||||||
{
|
{
|
||||||
@ -44,6 +45,8 @@ namespace IW4MAdmin.Plugins.Stats.Models
|
|||||||
public float AdsPercent { get; set; }
|
public float AdsPercent { get; set; }
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
public List<Vector3> AnglesList { get; set; }
|
public List<Vector3> AnglesList { get; set; }
|
||||||
|
[NotMapped]
|
||||||
|
public Game GameName { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Indicates if the attacker was alive after last captured angle
|
/// Indicates if the attacker was alive after last captured angle
|
||||||
|
@ -182,8 +182,9 @@ namespace IW4MAdmin.Plugins.Stats
|
|||||||
if (Config.Configuration() == null)
|
if (Config.Configuration() == null)
|
||||||
{
|
{
|
||||||
Config.Set((StatsConfiguration)new StatsConfiguration().Generate());
|
Config.Set((StatsConfiguration)new StatsConfiguration().Generate());
|
||||||
await Config.Save();
|
|
||||||
}
|
}
|
||||||
|
Config.Configuration().ApplyMigration();
|
||||||
|
await Config.Save();
|
||||||
|
|
||||||
// register the topstats page
|
// register the topstats page
|
||||||
// todo:generate the URL/Location instead of hardcoding
|
// todo:generate the URL/Location instead of hardcoding
|
||||||
@ -405,7 +406,7 @@ namespace IW4MAdmin.Plugins.Stats
|
|||||||
return (await _chatQueryHelper.QueryResource(query)).Results;
|
return (await _chatQueryHelper.QueryResource(query)).Results;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Config.Configuration().EnableAntiCheat)
|
if (Config.Configuration().AnticheatConfiguration.Enable)
|
||||||
{
|
{
|
||||||
_metaService.AddRuntimeMeta<ClientPaginationRequest, InformationResponse>(MetaType.Information, getAnticheatInfo);
|
_metaService.AddRuntimeMeta<ClientPaginationRequest, InformationResponse>(MetaType.Information, getAnticheatInfo);
|
||||||
}
|
}
|
||||||
@ -496,6 +497,6 @@ namespace IW4MAdmin.Plugins.Stats
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="s"></param>
|
/// <param name="s"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private bool ShouldOverrideAnticheatSetting(Server s) => Config.Configuration().EnableAntiCheat && s.GameName == Server.Game.IW5;
|
private bool ShouldOverrideAnticheatSetting(Server s) => Config.Configuration().AnticheatConfiguration.Enable && s.GameName == Server.Game.IW5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -772,8 +772,6 @@ namespace SharedLibraryCore.Commands
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class ListAdminsCommand : Command
|
public class ListAdminsCommand : Command
|
||||||
{
|
{
|
||||||
private readonly CommandConfiguration _config;
|
|
||||||
|
|
||||||
public ListAdminsCommand(CommandConfiguration config, ITranslationLookup translationLookup) : base(config, translationLookup)
|
public ListAdminsCommand(CommandConfiguration config, ITranslationLookup translationLookup) : base(config, translationLookup)
|
||||||
{
|
{
|
||||||
Name = "admins";
|
Name = "admins";
|
||||||
@ -781,8 +779,6 @@ namespace SharedLibraryCore.Commands
|
|||||||
Alias = "a";
|
Alias = "a";
|
||||||
Permission = Permission.User;
|
Permission = Permission.User;
|
||||||
RequiresTarget = false;
|
RequiresTarget = false;
|
||||||
|
|
||||||
_config = config;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string OnlineAdmins(Server S, ITranslationLookup lookup)
|
public static string OnlineAdmins(Server S, ITranslationLookup lookup)
|
||||||
@ -901,8 +897,6 @@ namespace SharedLibraryCore.Commands
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class ListRulesCommands : Command
|
public class ListRulesCommands : Command
|
||||||
{
|
{
|
||||||
private readonly CommandConfiguration _config;
|
|
||||||
|
|
||||||
public ListRulesCommands(CommandConfiguration config, ITranslationLookup translationLookup) : base(config, translationLookup)
|
public ListRulesCommands(CommandConfiguration config, ITranslationLookup translationLookup) : base(config, translationLookup)
|
||||||
{
|
{
|
||||||
Name = "rules";
|
Name = "rules";
|
||||||
@ -910,8 +904,6 @@ namespace SharedLibraryCore.Commands
|
|||||||
Alias = "r";
|
Alias = "r";
|
||||||
Permission = Permission.User;
|
Permission = Permission.User;
|
||||||
RequiresTarget = false;
|
RequiresTarget = false;
|
||||||
|
|
||||||
_config = config;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task ExecuteAsync(GameEvent E)
|
public override Task ExecuteAsync(GameEvent E)
|
||||||
|
Loading…
Reference in New Issue
Block a user