mirror of
https://github.com/RaidMax/IW4M-Admin.git
synced 2025-06-10 23:31:13 -05:00
set default elo rating
maybe fix deadlock again :c changed "skill" to Performance (Skill + Elo / 2)
This commit is contained in:
@ -27,9 +27,9 @@
|
|||||||
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.4.0" />
|
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.4.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<!--<PropertyGroup>
|
<PropertyGroup>
|
||||||
<ServerGarbageCollection>true</ServerGarbageCollection>
|
<ServerGarbageCollection>true</ServerGarbageCollection>
|
||||||
</PropertyGroup>-->
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\SharedLibraryCore\SharedLibraryCore.csproj">
|
<ProjectReference Include="..\SharedLibraryCore\SharedLibraryCore.csproj">
|
||||||
|
@ -332,7 +332,7 @@ namespace IW4MAdmin.Application
|
|||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SendHeartbeat(object state)
|
private async Task SendHeartbeat(object state)
|
||||||
{
|
{
|
||||||
var heartbeatState = (HeartbeatState)state;
|
var heartbeatState = (HeartbeatState)state;
|
||||||
|
|
||||||
@ -342,7 +342,7 @@ namespace IW4MAdmin.Application
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Heartbeat.Send(this, true).Wait(5000);
|
await Heartbeat.Send(this, true);
|
||||||
heartbeatState.Connected = true;
|
heartbeatState.Connected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -357,7 +357,7 @@ namespace IW4MAdmin.Application
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Heartbeat.Send(this).Wait(5000);
|
await Heartbeat.Send(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (System.Net.Http.HttpRequestException e)
|
catch (System.Net.Http.HttpRequestException e)
|
||||||
@ -393,7 +393,7 @@ namespace IW4MAdmin.Application
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Task.Delay(30000).Wait();
|
await Task.Delay(30000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -447,16 +447,16 @@ namespace IW4MAdmin.Application
|
|||||||
while (Running)
|
while (Running)
|
||||||
{
|
{
|
||||||
// wait for new event to be added
|
// wait for new event to be added
|
||||||
OnEvent.Wait(5000);
|
OnEvent.Wait();
|
||||||
|
|
||||||
// todo: sequencially or parallelize?
|
// todo: sequencially or parallelize?
|
||||||
while ((queuedEvent = Handler.GetNextEvent()) != null)
|
while ((queuedEvent = Handler.GetNextEvent()) != null)
|
||||||
{
|
{
|
||||||
eventList.Add(processEvent(queuedEvent));
|
await processEvent(queuedEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
// this should allow parallel processing of events
|
// this should allow parallel processing of events
|
||||||
await Task.WhenAll(eventList);
|
// await Task.WhenAll(eventList);
|
||||||
|
|
||||||
// signal that all events have been processed
|
// signal that all events have been processed
|
||||||
OnEvent.Reset();
|
OnEvent.Reset();
|
||||||
|
@ -127,7 +127,7 @@ namespace Application.RconParsers
|
|||||||
}
|
}
|
||||||
|
|
||||||
// this happens if status is requested while map is rotating
|
// this happens if status is requested while map is rotating
|
||||||
if (Status[1] == "Rotating map...")
|
if (Status[1] == "Server Initialization")
|
||||||
{
|
{
|
||||||
throw new ServerException("Server is rotating map");
|
throw new ServerException("Server is rotating map");
|
||||||
}
|
}
|
||||||
|
@ -126,7 +126,7 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
double currentStrain = Strain.GetStrain(isDamage, kill.Damage, kill.ViewAngles, Math.Max(50, kill.TimeOffset - LastOffset));
|
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;
|
LastOffset = kill.TimeOffset;
|
||||||
|
|
||||||
if (currentStrain > ClientStats.MaxStrain)
|
if (currentStrain > ClientStats.MaxStrain)
|
||||||
@ -134,7 +134,7 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
|
|||||||
ClientStats.MaxStrain = currentStrain;
|
ClientStats.MaxStrain = currentStrain;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentStrain > Thresholds.MaxStrainFlag)
|
if (currentWeightedStrain > Thresholds.MaxStrainFlag)
|
||||||
{
|
{
|
||||||
Tracker.OnChange(Strain);
|
Tracker.OnChange(Strain);
|
||||||
|
|
||||||
@ -151,25 +151,25 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
|
|||||||
}
|
}
|
||||||
|
|
||||||
// flag
|
// flag
|
||||||
if (currentStrain > Thresholds.MaxStrainFlag)
|
if (currentWeightedStrain > Thresholds.MaxStrainFlag)
|
||||||
{
|
{
|
||||||
return new DetectionPenaltyResult()
|
return new DetectionPenaltyResult()
|
||||||
{
|
{
|
||||||
ClientPenalty = Penalty.PenaltyType.Flag,
|
ClientPenalty = Penalty.PenaltyType.Flag,
|
||||||
Value = currentStrain,
|
Value = currentWeightedStrain,
|
||||||
HitCount = HitCount,
|
HitCount = HitCount,
|
||||||
Type = DetectionType.Strain
|
Type = DetectionType.Strain
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// ban
|
// ban
|
||||||
if (currentStrain > Thresholds.MaxStrainBan
|
if (currentWeightedStrain > Thresholds.MaxStrainBan
|
||||||
&& Kills > Thresholds.LowSampleMinKills)
|
&& Kills > Thresholds.LowSampleMinKills)
|
||||||
{
|
{
|
||||||
return new DetectionPenaltyResult()
|
return new DetectionPenaltyResult()
|
||||||
{
|
{
|
||||||
ClientPenalty = Penalty.PenaltyType.Flag,
|
ClientPenalty = Penalty.PenaltyType.Ban,
|
||||||
Value = currentStrain,
|
Value = currentWeightedStrain,
|
||||||
HitCount = HitCount,
|
HitCount = HitCount,
|
||||||
Type = DetectionType.Strain
|
Type = DetectionType.Strain
|
||||||
};
|
};
|
||||||
|
@ -26,6 +26,8 @@ namespace IW4MAdmin.Plugins.Stats.Commands
|
|||||||
stats.SPM = 0.0;
|
stats.SPM = 0.0;
|
||||||
stats.Skill = 0.0;
|
stats.Skill = 0.0;
|
||||||
stats.TimePlayed = 0;
|
stats.TimePlayed = 0;
|
||||||
|
// todo: make this more dynamic
|
||||||
|
stats.EloRating = 200.0;
|
||||||
|
|
||||||
// reset the cached version
|
// reset the cached version
|
||||||
Plugin.Manager.ResetStats(E.Origin.ClientId, E.Owner.GetHashCode());
|
Plugin.Manager.ResetStats(E.Origin.ClientId, E.Owner.GetHashCode());
|
||||||
|
@ -39,18 +39,17 @@ namespace IW4MAdmin.Plugins.Stats.Commands
|
|||||||
where stats.TimePlayed >= 3600
|
where stats.TimePlayed >= 3600
|
||||||
where client.Level != Player.Permission.Banned
|
where client.Level != Player.Permission.Banned
|
||||||
where client.LastConnection >= thirtyDaysAgo
|
where client.LastConnection >= thirtyDaysAgo
|
||||||
orderby stats.Skill descending
|
orderby stats.Performance descending
|
||||||
select new
|
select new
|
||||||
{
|
{
|
||||||
stats.KDR,
|
stats.KDR,
|
||||||
stats.Skill,
|
stats.Performance,
|
||||||
stats.EloRating,
|
|
||||||
alias.Name
|
alias.Name
|
||||||
})
|
})
|
||||||
.Take(5);
|
.Take(5);
|
||||||
|
|
||||||
var statsList = (await iqStats.ToListAsync())
|
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);
|
topStatsText.AddRange(statsList);
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ namespace IW4MAdmin.Plugins.Stats.Commands
|
|||||||
{
|
{
|
||||||
var loc = Utilities.CurrentLocalization.LocalizationIndex;
|
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"]);
|
await E.Origin.Tell(loc["PLUGINS_STATS_COMMANDS_VIEW_FAIL_INGAME"]);
|
||||||
return;
|
return;
|
||||||
@ -36,7 +36,7 @@ namespace IW4MAdmin.Plugins.Stats.Commands
|
|||||||
{
|
{
|
||||||
await E.Origin.Tell(loc["PLUGINS_STATS_COMMANDS_VIEW_FAIL_INGAME_SELF"]);
|
await E.Origin.Tell(loc["PLUGINS_STATS_COMMANDS_VIEW_FAIL_INGAME_SELF"]);
|
||||||
return;
|
return;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
String statLine;
|
String statLine;
|
||||||
EFClientStatistics pStats;
|
EFClientStatistics pStats;
|
||||||
@ -53,13 +53,13 @@ namespace IW4MAdmin.Plugins.Stats.Commands
|
|||||||
if (E.Target != null)
|
if (E.Target != null)
|
||||||
{
|
{
|
||||||
pStats = clientStats.Find(c => c.ServerId == serverId && c.ClientId == E.Target.ClientId).First();
|
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
|
else
|
||||||
{
|
{
|
||||||
pStats = pStats = clientStats.Find(c => c.ServerId == serverId && c.ClientId == E.Origin.ClientId).First();
|
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())
|
if (E.Message.IsBroadcastCommand())
|
||||||
|
@ -146,11 +146,17 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
//await statsSvc.ClientStatSvc.SaveChangesAsync();
|
//await statsSvc.ClientStatSvc.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// for stats before rating
|
||||||
if (clientStats.EloRating == 0.0)
|
if (clientStats.EloRating == 0.0)
|
||||||
{
|
{
|
||||||
clientStats.EloRating = clientStats.Skill;
|
clientStats.EloRating = clientStats.Skill;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (clientStats.RollingWeightedKDR == 0)
|
||||||
|
{
|
||||||
|
clientStats.RollingWeightedKDR = clientStats.KDR;
|
||||||
|
}
|
||||||
|
|
||||||
// set these on connecting
|
// set these on connecting
|
||||||
clientStats.LastActive = DateTime.UtcNow;
|
clientStats.LastActive = DateTime.UtcNow;
|
||||||
clientStats.LastStatCalculation = DateTime.UtcNow;
|
clientStats.LastStatCalculation = DateTime.UtcNow;
|
||||||
@ -497,10 +503,10 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
.Average(cs => cs.Value.EloRating);
|
.Average(cs => cs.Value.EloRating);
|
||||||
|
|
||||||
double attackerEloDifference = Math.Log(attackerLobbyRating) - Math.Log(attackerStats.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 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);
|
attackerStats.EloRating += 24.0 * (1 - winPercentage);
|
||||||
victimStats.EloRating -= 24.0 * winPercentage;
|
victimStats.EloRating -= 24.0 * winPercentage;
|
||||||
@ -551,8 +557,10 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
|
|
||||||
// calculate how much the KDR should weigh
|
// calculate how much the KDR should weigh
|
||||||
// 1.637 is a Eddie-Generated number that weights the KDR nicely
|
// 1.637 is a Eddie-Generated number that weights the KDR nicely
|
||||||
double kdr = clientStats.Deaths == 0 ? clientStats.Kills : clientStats.KDR;
|
double currentKDR = clientStats.SessionDeaths == 0 ? clientStats.SessionKills : clientStats.SessionKills / clientStats.SessionDeaths;
|
||||||
double KDRWeight = Math.Round(Math.Pow(kdr, 1.637 / Math.E), 3);
|
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
|
// calculate the weight of the new play time against last 10 hours of gameplay
|
||||||
int totalPlayTime = (clientStats.TimePlayed == 0) ?
|
int totalPlayTime = (clientStats.TimePlayed == 0) ?
|
||||||
@ -632,6 +640,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
stats.SPM = 0;
|
stats.SPM = 0;
|
||||||
stats.Skill = 0;
|
stats.Skill = 0;
|
||||||
stats.TimePlayed = 0;
|
stats.TimePlayed = 0;
|
||||||
|
stats.EloRating = 200;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task AddMessageAsync(int clientId, int serverId, string message)
|
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 int Deaths { get; set; }
|
||||||
public double EloRating { get; set; }
|
public double EloRating { get; set; }
|
||||||
public virtual ICollection<EFHitLocationCount> HitLocations { 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]
|
[NotMapped]
|
||||||
public double KDR
|
public double KDR
|
||||||
{
|
{
|
||||||
@ -57,6 +63,8 @@ namespace IW4MAdmin.Plugins.Stats.Models
|
|||||||
public int LastScore { get; set; }
|
public int LastScore { get; set; }
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
public DateTime LastActive { get; set; }
|
public DateTime LastActive { get; set; }
|
||||||
|
[NotMapped]
|
||||||
|
public double MaxSessionStrain { get; set; }
|
||||||
public void StartNewSession()
|
public void StartNewSession()
|
||||||
{
|
{
|
||||||
KillStreak = 0;
|
KillStreak = 0;
|
||||||
|
@ -114,9 +114,9 @@ namespace IW4MAdmin.Plugins.Stats
|
|||||||
int kills = clientStats.Sum(c => c.Kills);
|
int kills = clientStats.Sum(c => c.Kills);
|
||||||
int deaths = clientStats.Sum(c => c.Deaths);
|
int deaths = clientStats.Sum(c => c.Deaths);
|
||||||
double kdr = Math.Round(kills / (double)deaths, 2);
|
double kdr = Math.Round(kills / (double)deaths, 2);
|
||||||
var validSkillValues = clientStats.Where(c => c.Skill > 0);
|
var validPerformanceValues = clientStats.Where(c => c.Performance > 0);
|
||||||
int skillPlayTime = validSkillValues.Sum(s => s.TimePlayed);
|
int performancePlayTime = validPerformanceValues.Sum(s => s.TimePlayed);
|
||||||
double skill = Math.Round(validSkillValues.Sum(c => c.Skill * c.TimePlayed / skillPlayTime), 2);
|
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);
|
double spm = Math.Round(clientStats.Sum(c => c.SPM) / clientStats.Where(c => c.SPM > 0).Count(), 1);
|
||||||
|
|
||||||
return new List<ProfileMeta>()
|
return new List<ProfileMeta>()
|
||||||
@ -138,8 +138,8 @@ namespace IW4MAdmin.Plugins.Stats
|
|||||||
},
|
},
|
||||||
new ProfileMeta()
|
new ProfileMeta()
|
||||||
{
|
{
|
||||||
Key = Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_STATS_TEXT_SKILL"],
|
Key = Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_STATS_COMMANDS_PERFORMANCE"],
|
||||||
Value = skill
|
Value = performance
|
||||||
},
|
},
|
||||||
new ProfileMeta()
|
new ProfileMeta()
|
||||||
{
|
{
|
||||||
|
438
SharedLibraryCore/Migrations/20180517223349_AddRollingKDR.Designer.cs
generated
Normal file
438
SharedLibraryCore/Migrations/20180517223349_AddRollingKDR.Designer.cs
generated
Normal file
@ -0,0 +1,438 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.Internal;
|
||||||
|
using SharedLibraryCore.Database;
|
||||||
|
using SharedLibraryCore.Objects;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace SharedLibraryCore.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(DatabaseContext))]
|
||||||
|
[Migration("20180517223349_AddRollingKDR")]
|
||||||
|
partial class AddRollingKDR
|
||||||
|
{
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "2.0.2-rtm-10011");
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientKill", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("KillId")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<bool>("Active");
|
||||||
|
|
||||||
|
b.Property<int>("AttackerId");
|
||||||
|
|
||||||
|
b.Property<int>("Damage");
|
||||||
|
|
||||||
|
b.Property<int?>("DeathOriginVector3Id");
|
||||||
|
|
||||||
|
b.Property<int>("DeathType");
|
||||||
|
|
||||||
|
b.Property<int>("HitLoc");
|
||||||
|
|
||||||
|
b.Property<int?>("KillOriginVector3Id");
|
||||||
|
|
||||||
|
b.Property<int>("Map");
|
||||||
|
|
||||||
|
b.Property<int>("ServerId");
|
||||||
|
|
||||||
|
b.Property<int>("VictimId");
|
||||||
|
|
||||||
|
b.Property<int?>("ViewAnglesVector3Id");
|
||||||
|
|
||||||
|
b.Property<int>("Weapon");
|
||||||
|
|
||||||
|
b.Property<DateTime>("When");
|
||||||
|
|
||||||
|
b.HasKey("KillId");
|
||||||
|
|
||||||
|
b.HasIndex("AttackerId");
|
||||||
|
|
||||||
|
b.HasIndex("DeathOriginVector3Id");
|
||||||
|
|
||||||
|
b.HasIndex("KillOriginVector3Id");
|
||||||
|
|
||||||
|
b.HasIndex("ServerId");
|
||||||
|
|
||||||
|
b.HasIndex("VictimId");
|
||||||
|
|
||||||
|
b.HasIndex("ViewAnglesVector3Id");
|
||||||
|
|
||||||
|
b.ToTable("EFClientKills");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientMessage", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("MessageId")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<bool>("Active");
|
||||||
|
|
||||||
|
b.Property<int>("ClientId");
|
||||||
|
|
||||||
|
b.Property<string>("Message");
|
||||||
|
|
||||||
|
b.Property<int>("ServerId");
|
||||||
|
|
||||||
|
b.Property<DateTime>("TimeSent");
|
||||||
|
|
||||||
|
b.HasKey("MessageId");
|
||||||
|
|
||||||
|
b.HasIndex("ClientId");
|
||||||
|
|
||||||
|
b.HasIndex("ServerId");
|
||||||
|
|
||||||
|
b.ToTable("EFClientMessages");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientStatistics", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ClientId");
|
||||||
|
|
||||||
|
b.Property<int>("ServerId");
|
||||||
|
|
||||||
|
b.Property<bool>("Active");
|
||||||
|
|
||||||
|
b.Property<int>("Deaths");
|
||||||
|
|
||||||
|
b.Property<double>("EloRating");
|
||||||
|
|
||||||
|
b.Property<int>("Kills");
|
||||||
|
|
||||||
|
b.Property<double>("MaxStrain");
|
||||||
|
|
||||||
|
b.Property<double>("RollingWeightedKDR");
|
||||||
|
|
||||||
|
b.Property<double>("SPM");
|
||||||
|
|
||||||
|
b.Property<double>("Skill");
|
||||||
|
|
||||||
|
b.Property<int>("TimePlayed");
|
||||||
|
|
||||||
|
b.HasKey("ClientId", "ServerId");
|
||||||
|
|
||||||
|
b.HasIndex("ServerId");
|
||||||
|
|
||||||
|
b.ToTable("EFClientStatistics");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFHitLocationCount", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("HitLocationCountId")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<bool>("Active");
|
||||||
|
|
||||||
|
b.Property<int>("ClientId")
|
||||||
|
.HasColumnName("EFClientStatistics_ClientId");
|
||||||
|
|
||||||
|
b.Property<int>("HitCount");
|
||||||
|
|
||||||
|
b.Property<float>("HitOffsetAverage");
|
||||||
|
|
||||||
|
b.Property<int>("Location");
|
||||||
|
|
||||||
|
b.Property<float>("MaxAngleDistance");
|
||||||
|
|
||||||
|
b.Property<int>("ServerId")
|
||||||
|
.HasColumnName("EFClientStatistics_ServerId");
|
||||||
|
|
||||||
|
b.HasKey("HitLocationCountId");
|
||||||
|
|
||||||
|
b.HasIndex("ServerId");
|
||||||
|
|
||||||
|
b.HasIndex("ClientId", "ServerId");
|
||||||
|
|
||||||
|
b.ToTable("EFHitLocationCounts");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFServer", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ServerId");
|
||||||
|
|
||||||
|
b.Property<bool>("Active");
|
||||||
|
|
||||||
|
b.Property<int>("Port");
|
||||||
|
|
||||||
|
b.HasKey("ServerId");
|
||||||
|
|
||||||
|
b.ToTable("EFServers");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFServerStatistics", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("StatisticId")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<bool>("Active");
|
||||||
|
|
||||||
|
b.Property<int>("ServerId");
|
||||||
|
|
||||||
|
b.Property<long>("TotalKills");
|
||||||
|
|
||||||
|
b.Property<long>("TotalPlayTime");
|
||||||
|
|
||||||
|
b.HasKey("StatisticId");
|
||||||
|
|
||||||
|
b.HasIndex("ServerId");
|
||||||
|
|
||||||
|
b.ToTable("EFServerStatistics");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFAlias", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("AliasId")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<bool>("Active");
|
||||||
|
|
||||||
|
b.Property<DateTime>("DateAdded");
|
||||||
|
|
||||||
|
b.Property<int>("IPAddress");
|
||||||
|
|
||||||
|
b.Property<int>("LinkId");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasKey("AliasId");
|
||||||
|
|
||||||
|
b.HasIndex("LinkId");
|
||||||
|
|
||||||
|
b.ToTable("EFAlias");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFAliasLink", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("AliasLinkId")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<bool>("Active");
|
||||||
|
|
||||||
|
b.HasKey("AliasLinkId");
|
||||||
|
|
||||||
|
b.ToTable("EFAliasLinks");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFClient", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ClientId")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<bool>("Active");
|
||||||
|
|
||||||
|
b.Property<int>("AliasLinkId");
|
||||||
|
|
||||||
|
b.Property<int>("Connections");
|
||||||
|
|
||||||
|
b.Property<int>("CurrentAliasId");
|
||||||
|
|
||||||
|
b.Property<DateTime>("FirstConnection");
|
||||||
|
|
||||||
|
b.Property<DateTime>("LastConnection");
|
||||||
|
|
||||||
|
b.Property<int>("Level");
|
||||||
|
|
||||||
|
b.Property<bool>("Masked");
|
||||||
|
|
||||||
|
b.Property<long>("NetworkId");
|
||||||
|
|
||||||
|
b.Property<string>("Password");
|
||||||
|
|
||||||
|
b.Property<string>("PasswordSalt");
|
||||||
|
|
||||||
|
b.Property<int>("TotalConnectionTime");
|
||||||
|
|
||||||
|
b.HasKey("ClientId");
|
||||||
|
|
||||||
|
b.HasIndex("AliasLinkId");
|
||||||
|
|
||||||
|
b.HasIndex("CurrentAliasId");
|
||||||
|
|
||||||
|
b.HasIndex("NetworkId")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("EFClients");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFPenalty", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("PenaltyId")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<bool>("Active");
|
||||||
|
|
||||||
|
b.Property<DateTime>("Expires");
|
||||||
|
|
||||||
|
b.Property<int>("LinkId");
|
||||||
|
|
||||||
|
b.Property<int>("OffenderId");
|
||||||
|
|
||||||
|
b.Property<string>("Offense")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Property<int>("PunisherId");
|
||||||
|
|
||||||
|
b.Property<int>("Type");
|
||||||
|
|
||||||
|
b.Property<DateTime>("When");
|
||||||
|
|
||||||
|
b.HasKey("PenaltyId");
|
||||||
|
|
||||||
|
b.HasIndex("LinkId");
|
||||||
|
|
||||||
|
b.HasIndex("OffenderId");
|
||||||
|
|
||||||
|
b.HasIndex("PunisherId");
|
||||||
|
|
||||||
|
b.ToTable("EFPenalties");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("SharedLibraryCore.Helpers.Vector3", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Vector3Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<float>("X");
|
||||||
|
|
||||||
|
b.Property<float>("Y");
|
||||||
|
|
||||||
|
b.Property<float>("Z");
|
||||||
|
|
||||||
|
b.HasKey("Vector3Id");
|
||||||
|
|
||||||
|
b.ToTable("Vector3");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientKill", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Attacker")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("AttackerId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("SharedLibraryCore.Helpers.Vector3", "DeathOrigin")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("DeathOriginVector3Id");
|
||||||
|
|
||||||
|
b.HasOne("SharedLibraryCore.Helpers.Vector3", "KillOrigin")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("KillOriginVector3Id");
|
||||||
|
|
||||||
|
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ServerId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Victim")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("VictimId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("SharedLibraryCore.Helpers.Vector3", "ViewAngles")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ViewAnglesVector3Id");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientMessage", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ClientId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ServerId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientStatistics", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ClientId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ServerId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFHitLocationCount", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ClientId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ServerId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFClientStatistics")
|
||||||
|
.WithMany("HitLocations")
|
||||||
|
.HasForeignKey("ClientId", "ServerId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFServerStatistics", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ServerId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFAlias", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFAliasLink", "Link")
|
||||||
|
.WithMany("Children")
|
||||||
|
.HasForeignKey("LinkId")
|
||||||
|
.OnDelete(DeleteBehavior.Restrict);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFClient", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFAliasLink", "AliasLink")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("AliasLinkId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFAlias", "CurrentAlias")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("CurrentAliasId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFPenalty", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFAliasLink", "Link")
|
||||||
|
.WithMany("ReceivedPenalties")
|
||||||
|
.HasForeignKey("LinkId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Offender")
|
||||||
|
.WithMany("ReceivedPenalties")
|
||||||
|
.HasForeignKey("OffenderId")
|
||||||
|
.OnDelete(DeleteBehavior.Restrict);
|
||||||
|
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Punisher")
|
||||||
|
.WithMany("AdministeredPenalties")
|
||||||
|
.HasForeignKey("PunisherId")
|
||||||
|
.OnDelete(DeleteBehavior.Restrict);
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
25
SharedLibraryCore/Migrations/20180517223349_AddRollingKDR.cs
Normal file
25
SharedLibraryCore/Migrations/20180517223349_AddRollingKDR.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace SharedLibraryCore.Migrations
|
||||||
|
{
|
||||||
|
public partial class AddRollingKDR : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<double>(
|
||||||
|
name: "RollingWeightedKDR",
|
||||||
|
table: "EFClientStatistics",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "RollingWeightedKDR",
|
||||||
|
table: "EFClientStatistics");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -108,6 +108,8 @@ namespace SharedLibraryCore.Migrations
|
|||||||
|
|
||||||
b.Property<double>("MaxStrain");
|
b.Property<double>("MaxStrain");
|
||||||
|
|
||||||
|
b.Property<double>("RollingWeightedKDR");
|
||||||
|
|
||||||
b.Property<double>("SPM");
|
b.Property<double>("SPM");
|
||||||
|
|
||||||
b.Property<double>("Skill");
|
b.Property<double>("Skill");
|
||||||
|
Reference in New Issue
Block a user