1
0
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:
RaidMax
2018-04-13 01:32:30 -05:00
parent 15372d0726
commit b9c11d48c2
34 changed files with 519 additions and 272 deletions

View File

@ -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)

View File

@ -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)
{

View File

@ -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();

View File

@ -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)
{

View File

@ -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}");

View File

@ -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;
}
}