1
0
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:
RaidMax
2018-05-17 18:31:58 -05:00
parent a0ac6c5dc9
commit 270f7f81b3
13 changed files with 517 additions and 34 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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
}
}
}

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

View File

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