mirror of
https://github.com/RaidMax/IW4M-Admin.git
synced 2025-06-23 21:50:44 -05:00
set default elo rating
maybe fix deadlock again :c changed "skill" to Performance (Skill + Elo / 2)
This commit is contained in:
@ -126,7 +126,7 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
|
||||
#endif
|
||||
}
|
||||
double currentStrain = Strain.GetStrain(isDamage, kill.Damage, kill.ViewAngles, Math.Max(50, kill.TimeOffset - LastOffset));
|
||||
currentStrain *= ClientStats.SPM / 179.0;
|
||||
double currentWeightedStrain = (currentStrain * ClientStats.SPM) / 170.0;
|
||||
LastOffset = kill.TimeOffset;
|
||||
|
||||
if (currentStrain > ClientStats.MaxStrain)
|
||||
@ -134,7 +134,7 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
|
||||
ClientStats.MaxStrain = currentStrain;
|
||||
}
|
||||
|
||||
if (currentStrain > Thresholds.MaxStrainFlag)
|
||||
if (currentWeightedStrain > Thresholds.MaxStrainFlag)
|
||||
{
|
||||
Tracker.OnChange(Strain);
|
||||
|
||||
@ -151,25 +151,25 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
|
||||
}
|
||||
|
||||
// flag
|
||||
if (currentStrain > Thresholds.MaxStrainFlag)
|
||||
if (currentWeightedStrain > Thresholds.MaxStrainFlag)
|
||||
{
|
||||
return new DetectionPenaltyResult()
|
||||
{
|
||||
ClientPenalty = Penalty.PenaltyType.Flag,
|
||||
Value = currentStrain,
|
||||
Value = currentWeightedStrain,
|
||||
HitCount = HitCount,
|
||||
Type = DetectionType.Strain
|
||||
};
|
||||
}
|
||||
|
||||
// ban
|
||||
if (currentStrain > Thresholds.MaxStrainBan
|
||||
if (currentWeightedStrain > Thresholds.MaxStrainBan
|
||||
&& Kills > Thresholds.LowSampleMinKills)
|
||||
{
|
||||
return new DetectionPenaltyResult()
|
||||
{
|
||||
ClientPenalty = Penalty.PenaltyType.Flag,
|
||||
Value = currentStrain,
|
||||
ClientPenalty = Penalty.PenaltyType.Ban,
|
||||
Value = currentWeightedStrain,
|
||||
HitCount = HitCount,
|
||||
Type = DetectionType.Strain
|
||||
};
|
||||
|
@ -26,6 +26,8 @@ namespace IW4MAdmin.Plugins.Stats.Commands
|
||||
stats.SPM = 0.0;
|
||||
stats.Skill = 0.0;
|
||||
stats.TimePlayed = 0;
|
||||
// todo: make this more dynamic
|
||||
stats.EloRating = 200.0;
|
||||
|
||||
// reset the cached version
|
||||
Plugin.Manager.ResetStats(E.Origin.ClientId, E.Owner.GetHashCode());
|
||||
|
@ -39,18 +39,17 @@ namespace IW4MAdmin.Plugins.Stats.Commands
|
||||
where stats.TimePlayed >= 3600
|
||||
where client.Level != Player.Permission.Banned
|
||||
where client.LastConnection >= thirtyDaysAgo
|
||||
orderby stats.Skill descending
|
||||
orderby stats.Performance descending
|
||||
select new
|
||||
{
|
||||
stats.KDR,
|
||||
stats.Skill,
|
||||
stats.EloRating,
|
||||
stats.Performance,
|
||||
alias.Name
|
||||
})
|
||||
.Take(5);
|
||||
|
||||
var statsList = (await iqStats.ToListAsync())
|
||||
.Select(stats => $"^3{stats.Name}^7 - ^5{stats.KDR} ^7{Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_STATS_TEXT_KDR"]} | ^5{stats.Skill} ^7{Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_STATS_TEXT_SKILL"]} | ^5{stats.EloRating} ^7{Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_STATS_COMMANDS_TOPSTATS_RATING"]}");
|
||||
.Select(stats => $"^3{stats.Name}^7 - ^5{stats.KDR} ^7{Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_STATS_TEXT_KDR"]} | ^5{stats.Performance} ^7{Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_STATS_COMMANDS_PERFORMANCE"]}");
|
||||
|
||||
topStatsText.AddRange(statsList);
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ namespace IW4MAdmin.Plugins.Stats.Commands
|
||||
{
|
||||
var loc = Utilities.CurrentLocalization.LocalizationIndex;
|
||||
|
||||
if (E.Target?.ClientNumber < 0)
|
||||
/*if (E.Target?.ClientNumber < 0)
|
||||
{
|
||||
await E.Origin.Tell(loc["PLUGINS_STATS_COMMANDS_VIEW_FAIL_INGAME"]);
|
||||
return;
|
||||
@ -36,7 +36,7 @@ namespace IW4MAdmin.Plugins.Stats.Commands
|
||||
{
|
||||
await E.Origin.Tell(loc["PLUGINS_STATS_COMMANDS_VIEW_FAIL_INGAME_SELF"]);
|
||||
return;
|
||||
}
|
||||
}*/
|
||||
|
||||
String statLine;
|
||||
EFClientStatistics pStats;
|
||||
@ -53,13 +53,13 @@ namespace IW4MAdmin.Plugins.Stats.Commands
|
||||
if (E.Target != null)
|
||||
{
|
||||
pStats = clientStats.Find(c => c.ServerId == serverId && c.ClientId == E.Target.ClientId).First();
|
||||
statLine = $"^5{pStats.Kills} ^7{loc["PLUGINS_STATS_TEXT_KILLS"]} | ^5{pStats.Deaths} ^7{loc["PLUGINS_STATS_TEXT_DEATHS"]} | ^5{pStats.KDR} ^7KDR | ^5{pStats.Skill} ^7{loc["PLUGINS_STATS_TEXT_SKILL"]} | ^5{pStats.EloRating} ^7{loc["PLUGINS_STATS_COMMANDS_TOPSTATS_RATING"].ToUpper()}";
|
||||
statLine = $"^5{pStats.Kills} ^7{loc["PLUGINS_STATS_TEXT_KILLS"]} | ^5{pStats.Deaths} ^7{loc["PLUGINS_STATS_TEXT_DEATHS"]} | ^5{pStats.KDR} ^7KDR | ^5{pStats.Performance} ^7{loc["PLUGINS_STATS_COMMANDS_PERFORMANCE"].ToUpper()}";
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
pStats = pStats = clientStats.Find(c => c.ServerId == serverId && c.ClientId == E.Origin.ClientId).First();
|
||||
statLine = $"^5{pStats.Kills} ^7{loc["PLUGINS_STATS_TEXT_KILLS"]} | ^5{pStats.Deaths} ^7{loc["PLUGINS_STATS_TEXT_DEATHS"]} | ^5{pStats.KDR} ^7KDR | ^5{pStats.Skill} ^7{loc["PLUGINS_STATS_TEXT_SKILL"]} | ^5{pStats.EloRating} ^7{loc["PLUGINS_STATS_COMMANDS_TOPSTATS_RATING"].ToUpper()}";
|
||||
statLine = $"^5{pStats.Kills} ^7{loc["PLUGINS_STATS_TEXT_KILLS"]} | ^5{pStats.Deaths} ^7{loc["PLUGINS_STATS_TEXT_DEATHS"]} | ^5{pStats.KDR} ^7KDR | ^5{pStats.Performance} ^7{loc["PLUGINS_STATS_COMMANDS_PERFORMANCE"].ToUpper()}";
|
||||
}
|
||||
|
||||
if (E.Message.IsBroadcastCommand())
|
||||
|
@ -146,11 +146,17 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
||||
//await statsSvc.ClientStatSvc.SaveChangesAsync();
|
||||
}
|
||||
|
||||
// for stats before rating
|
||||
if (clientStats.EloRating == 0.0)
|
||||
{
|
||||
clientStats.EloRating = clientStats.Skill;
|
||||
}
|
||||
|
||||
if (clientStats.RollingWeightedKDR == 0)
|
||||
{
|
||||
clientStats.RollingWeightedKDR = clientStats.KDR;
|
||||
}
|
||||
|
||||
// set these on connecting
|
||||
clientStats.LastActive = DateTime.UtcNow;
|
||||
clientStats.LastStatCalculation = DateTime.UtcNow;
|
||||
@ -497,10 +503,10 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
||||
.Average(cs => cs.Value.EloRating);
|
||||
|
||||
double attackerEloDifference = Math.Log(attackerLobbyRating) - Math.Log(attackerStats.EloRating);
|
||||
double winPercentage = 1.0 / (1 + Math.Pow(10, attackerEloDifference / 3.0));
|
||||
double winPercentage = 1.0 / (1 + Math.Pow(10, attackerEloDifference / 0.5));
|
||||
|
||||
double victimEloDifference = Math.Log(victimLobbyRating) - Math.Log(victimStats.EloRating);
|
||||
double lossPercentage = 1.0 / (1 + Math.Pow(10, victimEloDifference / 3.0));
|
||||
double lossPercentage = 1.0 / (1 + Math.Pow(10, victimEloDifference / 0.5));
|
||||
|
||||
attackerStats.EloRating += 24.0 * (1 - winPercentage);
|
||||
victimStats.EloRating -= 24.0 * winPercentage;
|
||||
@ -551,8 +557,10 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
||||
|
||||
// calculate how much the KDR should weigh
|
||||
// 1.637 is a Eddie-Generated number that weights the KDR nicely
|
||||
double kdr = clientStats.Deaths == 0 ? clientStats.Kills : clientStats.KDR;
|
||||
double KDRWeight = Math.Round(Math.Pow(kdr, 1.637 / Math.E), 3);
|
||||
double currentKDR = clientStats.SessionDeaths == 0 ? clientStats.SessionKills : clientStats.SessionKills / clientStats.SessionDeaths;
|
||||
double alpha = Math.Sqrt(2) / Math.Min(600, clientStats.Kills + clientStats.Deaths);
|
||||
clientStats.RollingWeightedKDR = (alpha * currentKDR) + (1.0 - alpha) * currentKDR;
|
||||
double KDRWeight = Math.Round(Math.Pow(clientStats.RollingWeightedKDR, 1.637 / Math.E), 3);
|
||||
|
||||
// calculate the weight of the new play time against last 10 hours of gameplay
|
||||
int totalPlayTime = (clientStats.TimePlayed == 0) ?
|
||||
@ -632,6 +640,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
||||
stats.SPM = 0;
|
||||
stats.Skill = 0;
|
||||
stats.TimePlayed = 0;
|
||||
stats.EloRating = 200;
|
||||
}
|
||||
|
||||
public async Task AddMessageAsync(int clientId, int serverId, string message)
|
||||
|
@ -24,6 +24,12 @@ namespace IW4MAdmin.Plugins.Stats.Models
|
||||
public int Deaths { get; set; }
|
||||
public double EloRating { get; set; }
|
||||
public virtual ICollection<EFHitLocationCount> HitLocations { get; set; }
|
||||
public double RollingWeightedKDR { get; set; }
|
||||
[NotMapped]
|
||||
public double Performance
|
||||
{
|
||||
get => Math.Round((EloRating + Skill) / 2.0, 2);
|
||||
}
|
||||
[NotMapped]
|
||||
public double KDR
|
||||
{
|
||||
@ -57,6 +63,8 @@ namespace IW4MAdmin.Plugins.Stats.Models
|
||||
public int LastScore { get; set; }
|
||||
[NotMapped]
|
||||
public DateTime LastActive { get; set; }
|
||||
[NotMapped]
|
||||
public double MaxSessionStrain { get; set; }
|
||||
public void StartNewSession()
|
||||
{
|
||||
KillStreak = 0;
|
||||
|
@ -114,9 +114,9 @@ namespace IW4MAdmin.Plugins.Stats
|
||||
int kills = clientStats.Sum(c => c.Kills);
|
||||
int deaths = clientStats.Sum(c => c.Deaths);
|
||||
double kdr = Math.Round(kills / (double)deaths, 2);
|
||||
var validSkillValues = clientStats.Where(c => c.Skill > 0);
|
||||
int skillPlayTime = validSkillValues.Sum(s => s.TimePlayed);
|
||||
double skill = Math.Round(validSkillValues.Sum(c => c.Skill * c.TimePlayed / skillPlayTime), 2);
|
||||
var validPerformanceValues = clientStats.Where(c => c.Performance > 0);
|
||||
int performancePlayTime = validPerformanceValues.Sum(s => s.TimePlayed);
|
||||
double performance = Math.Round(validPerformanceValues.Sum(c => c.Performance * c.TimePlayed / performancePlayTime), 2);
|
||||
double spm = Math.Round(clientStats.Sum(c => c.SPM) / clientStats.Where(c => c.SPM > 0).Count(), 1);
|
||||
|
||||
return new List<ProfileMeta>()
|
||||
@ -138,8 +138,8 @@ namespace IW4MAdmin.Plugins.Stats
|
||||
},
|
||||
new ProfileMeta()
|
||||
{
|
||||
Key = Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_STATS_TEXT_SKILL"],
|
||||
Value = skill
|
||||
Key = Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_STATS_COMMANDS_PERFORMANCE"],
|
||||
Value = performance
|
||||
},
|
||||
new ProfileMeta()
|
||||
{
|
||||
|
Reference in New Issue
Block a user