mirror of
https://github.com/RaidMax/IW4M-Admin.git
synced 2025-06-27 15:40:32 -05:00
abstracting rcon parsing and event parsing
changed Event to GameEvent finally fixed the stats NaN check ip for bans consolidated console, profile, and logout into dropdown make sure game is iw4 before using :^ in say fix pm not showing from name if in web console show time left of temban on profile
This commit is contained in:
@ -68,7 +68,7 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
|
||||
double newAverage = (previousAverage * (hitLoc.HitCount - 1) + angle) / hitLoc.HitCount;
|
||||
hitLoc.HitOffsetAverage = (float)newAverage;
|
||||
|
||||
if (hitLoc.HitOffsetAverage == float.NaN)
|
||||
if (double.IsNaN(hitLoc.HitOffsetAverage))
|
||||
{
|
||||
Log.WriteWarning("[Detection::ProcessKill] HitOffsetAvgerage NaN");
|
||||
Log.WriteDebug($"{previousAverage}-{hitLoc.HitCount}-{hitLoc}-{newAverage}");
|
||||
@ -269,7 +269,7 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
|
||||
|
||||
public DetectionPenaltyResult ProcessTotalRatio(EFClientStatistics stats)
|
||||
{
|
||||
int totalChestKills = stats.HitLocations.Single(c => c.Location == IW4Info.HitLocation.left_arm_upper).HitCount;
|
||||
int totalChestKills = stats.HitLocations.Single(c => c.Location == IW4Info.HitLocation.torso_upper).HitCount;
|
||||
|
||||
if (totalChestKills >= 60)
|
||||
{
|
||||
@ -279,7 +279,7 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
|
||||
double chestAbdomenRatioLerpValueForFlag = Thresholds.Lerp(Thresholds.ChestAbdomenRatioThresholdHighSample(3.0), Thresholds.ChestAbdomenRatioThresholdHighSample(2), lerpAmount) + marginOfError;
|
||||
double chestAbdomenLerpValueForBan = Thresholds.Lerp(Thresholds.ChestAbdomenRatioThresholdHighSample(4.0), Thresholds.ChestAbdomenRatioThresholdHighSample(4.0), lerpAmount) + marginOfError;
|
||||
|
||||
double currentChestAbdomenRatio = stats.HitLocations.Single(hl => hl.Location == IW4Info.HitLocation.torso_upper).HitCount /
|
||||
double currentChestAbdomenRatio = totalChestKills /
|
||||
stats.HitLocations.Single(hl => hl.Location == IW4Info.HitLocation.torso_lower).HitCount;
|
||||
|
||||
if (currentChestAbdomenRatio > chestAbdomenRatioLerpValueForFlag)
|
||||
|
@ -13,7 +13,7 @@ namespace IW4MAdmin.Plugins.Stats.Commands
|
||||
{
|
||||
public ResetStats() : base("resetstats", "reset your stats to factory-new", "rs", Player.Permission.User, false) { }
|
||||
|
||||
public override async Task ExecuteAsync(Event E)
|
||||
public override async Task ExecuteAsync(GameEvent E)
|
||||
{
|
||||
if (E.Origin.ClientNumber >= 0)
|
||||
{
|
||||
|
@ -14,7 +14,7 @@ namespace IW4MAdmin.Plugins.Stats.Commands
|
||||
{
|
||||
public TopStats() : base("topstats", "view the top 5 players on this server", "ts", Player.Permission.User, false) { }
|
||||
|
||||
public override async Task ExecuteAsync(Event E)
|
||||
public override async Task ExecuteAsync(GameEvent E)
|
||||
{
|
||||
var statsSvc = new GenericRepository<EFClientStatistics>();
|
||||
int serverId = E.Owner.GetHashCode();
|
||||
|
@ -22,7 +22,7 @@ namespace IW4MAdmin.Plugins.Stats.Commands
|
||||
})
|
||||
{ }
|
||||
|
||||
public override async Task ExecuteAsync(Event E)
|
||||
public override async Task ExecuteAsync(GameEvent E)
|
||||
{
|
||||
if (E.Target?.ClientNumber < 0)
|
||||
{
|
||||
|
@ -193,7 +193,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
||||
detectionStats.TryRemove(pl.ClientId, out Cheat.Detection removedValue2);
|
||||
|
||||
// sync their stats before they leave
|
||||
UpdateStats(clientStats);
|
||||
clientStats = UpdateStats(clientStats);
|
||||
|
||||
// todo: should this be saved every disconnect?
|
||||
statsSvc.ClientStatSvc.Update(clientStats);
|
||||
@ -211,12 +211,9 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
||||
string damage, string weapon, string killOrigin, string deathOrigin, string viewAngles, string offset, string isKillstreakKill, string Ads)
|
||||
{
|
||||
var statsSvc = ContextThreads[serverId];
|
||||
|
||||
|
||||
Vector3 vDeathOrigin = null;
|
||||
Vector3 vKillOrigin = null;
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
vDeathOrigin = Vector3.Parse(deathOrigin);
|
||||
@ -295,7 +292,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
||||
if (attacker.Level != Player.Permission.User)
|
||||
break;
|
||||
var flagCmd = new CFlag();
|
||||
await flagCmd.ExecuteAsync(new Event(Event.GType.Flag, $"{(int)penalty.Bone}-{Math.Round(penalty.RatioAmount, 2).ToString()}@{penalty.KillCount}", new Player()
|
||||
await flagCmd.ExecuteAsync(new GameEvent(GameEvent.EventType.Flag, $"{(int)penalty.Bone}-{Math.Round(penalty.RatioAmount, 2).ToString()}@{penalty.KillCount}", new Player()
|
||||
{
|
||||
ClientId = 1,
|
||||
Level = Player.Permission.Console,
|
||||
@ -356,12 +353,20 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
||||
await attacker.Tell(streakMessage);
|
||||
|
||||
// fixme: why?
|
||||
if (victimStats.SPM == double.NaN || victimStats.Skill == double.NaN)
|
||||
if (double.IsNaN(victimStats.SPM) || double.IsNaN(victimStats.Skill))
|
||||
{
|
||||
Log.WriteDebug($"[StatManager::AddStandardKill] victim SPM/SKILL {victimStats.SPM} {victimStats.Skill}");
|
||||
victimStats.SPM = 0.0;
|
||||
victimStats.Skill = 0.0;
|
||||
}
|
||||
|
||||
if (double.IsNaN(attackerStats.SPM) || double.IsNaN(attackerStats.Skill))
|
||||
{
|
||||
Log.WriteDebug($"[StatManager::AddStandardKill] attacker SPM/SKILL {victimStats.SPM} {victimStats.Skill}");
|
||||
attackerStats.SPM = 0.0;
|
||||
attackerStats.Skill = 0.0;
|
||||
}
|
||||
|
||||
// todo: do we want to save this immediately?
|
||||
var statsSvc = ContextThreads[serverId];
|
||||
statsSvc.ClientStatSvc.Update(attackerStats);
|
||||
@ -393,7 +398,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
||||
victimStats.KillStreak = 0;
|
||||
|
||||
// process the attacker's stats after the kills
|
||||
UpdateStats(attackerStats);
|
||||
attackerStats = UpdateStats(attackerStats);
|
||||
|
||||
// update after calculation
|
||||
attackerStats.TimePlayed += (int)(DateTime.UtcNow - attackerStats.LastActive).TotalSeconds;
|
||||
@ -410,7 +415,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
||||
private EFClientStatistics UpdateStats(EFClientStatistics clientStats)
|
||||
{
|
||||
// prevent NaN or inactive time lowering SPM
|
||||
if ((DateTime.UtcNow - clientStats.LastStatCalculation).TotalSeconds / 60.0 < 0.1 ||
|
||||
if ((DateTime.UtcNow - clientStats.LastStatCalculation).TotalSeconds / 60.0 < 0.01 ||
|
||||
(DateTime.UtcNow - clientStats.LastActive).TotalSeconds / 60.0 > 3 ||
|
||||
clientStats.SessionScore < 1)
|
||||
return clientStats;
|
||||
@ -439,13 +444,11 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
||||
|
||||
// calculate the new weight against average times the weight against play time
|
||||
clientStats.SPM = (killSPM * SPMAgainstPlayWeight) + (clientStats.SPM * (1 - SPMAgainstPlayWeight));
|
||||
|
||||
clientStats.SPM = Math.Round(clientStats.SPM, 3);
|
||||
|
||||
clientStats.Skill = Math.Round((clientStats.SPM * KDRWeight), 3);
|
||||
|
||||
// fixme: how does this happen?
|
||||
if (clientStats.SPM == double.NaN || clientStats.Skill == double.NaN)
|
||||
if (double.IsNaN(clientStats.SPM) || double.IsNaN(clientStats.Skill))
|
||||
{
|
||||
Log.WriteWarning("[StatManager::UpdateStats] clientStats SPM/Skill NaN");
|
||||
Log.WriteDebug($"{killSPM}-{KDRWeight}-{totalPlayTime}-{SPMAgainstPlayWeight}-{clientStats.SPM}-{clientStats.Skill}-{scoreDifference}");
|
||||
|
@ -28,50 +28,50 @@ namespace IW4MAdmin.Plugins.Stats
|
||||
private IManager ServerManager;
|
||||
public static BaseConfigurationHandler<StatsConfiguration> Config { get; private set; }
|
||||
|
||||
public async Task OnEventAsync(Event E, Server S)
|
||||
public async Task OnEventAsync(GameEvent E, Server S)
|
||||
{
|
||||
switch (E.Type)
|
||||
{
|
||||
case Event.GType.Start:
|
||||
case GameEvent.EventType.Start:
|
||||
Manager.AddServer(S);
|
||||
break;
|
||||
case Event.GType.Stop:
|
||||
case GameEvent.EventType.Stop:
|
||||
break;
|
||||
case Event.GType.Connect:
|
||||
case GameEvent.EventType.Connect:
|
||||
await Manager.AddPlayer(E.Origin);
|
||||
break;
|
||||
case Event.GType.Disconnect:
|
||||
case GameEvent.EventType.Disconnect:
|
||||
await Manager.RemovePlayer(E.Origin);
|
||||
break;
|
||||
case Event.GType.Say:
|
||||
case GameEvent.EventType.Say:
|
||||
if (E.Data != string.Empty && E.Data.Trim().Length > 0 && E.Message.Trim()[0] != '!' && E.Origin.ClientId > 1)
|
||||
await Manager.AddMessageAsync(E.Origin.ClientId, E.Owner.GetHashCode(), E.Data);
|
||||
break;
|
||||
case Event.GType.MapChange:
|
||||
case GameEvent.EventType.MapChange:
|
||||
Manager.ResetKillstreaks(S.GetHashCode());
|
||||
await Manager.Sync(S);
|
||||
break;
|
||||
case Event.GType.MapEnd:
|
||||
case GameEvent.EventType.MapEnd:
|
||||
break;
|
||||
case Event.GType.Broadcast:
|
||||
case GameEvent.EventType.Broadcast:
|
||||
break;
|
||||
case Event.GType.Tell:
|
||||
case GameEvent.EventType.Tell:
|
||||
break;
|
||||
case Event.GType.Kick:
|
||||
case GameEvent.EventType.Kick:
|
||||
break;
|
||||
case Event.GType.Ban:
|
||||
case GameEvent.EventType.Ban:
|
||||
break;
|
||||
case Event.GType.Remote:
|
||||
case GameEvent.EventType.Remote:
|
||||
break;
|
||||
case Event.GType.Unknown:
|
||||
case GameEvent.EventType.Unknown:
|
||||
break;
|
||||
case Event.GType.Report:
|
||||
case GameEvent.EventType.Report:
|
||||
break;
|
||||
case Event.GType.Flag:
|
||||
case GameEvent.EventType.Flag:
|
||||
break;
|
||||
case Event.GType.Script:
|
||||
case GameEvent.EventType.Script:
|
||||
break;
|
||||
case Event.GType.Kill:
|
||||
case GameEvent.EventType.Kill:
|
||||
string[] killInfo = (E.Data != null) ? E.Data.Split(';') : new string[0];
|
||||
if (killInfo.Length >= 9 && killInfo[0].Contains("ScriptKill") && E.Owner.CustomCallback)
|
||||
await Manager.AddScriptKill(E.Origin, E.Target, S.GetHashCode(), S.CurrentMap.Name, killInfo[7], killInfo[8],
|
||||
@ -79,7 +79,7 @@ namespace IW4MAdmin.Plugins.Stats
|
||||
else if (!E.Owner.CustomCallback)
|
||||
await Manager.AddStandardKill(E.Origin, E.Target);
|
||||
break;
|
||||
case Event.GType.Death:
|
||||
case GameEvent.EventType.Death:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user