diff --git a/Data/Context/DatabaseContext.cs b/Data/Context/DatabaseContext.cs index 0a4d5200..60311d74 100644 --- a/Data/Context/DatabaseContext.cs +++ b/Data/Context/DatabaseContext.cs @@ -56,7 +56,8 @@ namespace Data.Context public DbSet ZombieMatchClientStats { get; set; } public DbSet ZombieRoundClientStats { get; set; } public DbSet ZombieClientStatAggregates { get; set; } - + public DbSet ZombieClientStatRecords { get; set; } + #endregion private void SetAuditColumns() @@ -175,6 +176,7 @@ namespace Data.Context modelBuilder.Entity(typeof(ZombieRoundClientStat)).ToTable($"EF{nameof(ZombieRoundClientStat)}"); modelBuilder.Entity(typeof(ZombieAggregateClientStat)).ToTable($"EF{nameof(ZombieAggregateClientStat)}"); modelBuilder.Entity(typeof(ZombieClientStat)).ToTable($"EF{nameof(ZombieClientStat)}"); + modelBuilder.Entity(typeof(ZombieClientStatRecord)).ToTable($"EF{nameof(ZombieClientStatRecord)}"); Models.Configuration.StatsModelConfiguration.Configure(modelBuilder); diff --git a/Data/Migrations/Sqlite/20230502032705_AddZombieStatsInitial.Designer.cs b/Data/Migrations/Sqlite/20230502032705_AddZombieStatsInitial.Designer.cs deleted file mode 100644 index 13109d2f..00000000 --- a/Data/Migrations/Sqlite/20230502032705_AddZombieStatsInitial.Designer.cs +++ /dev/null @@ -1,1909 +0,0 @@ -// -using System; -using Data.MigrationContext; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; - -#nullable disable - -namespace Data.Migrations.Sqlite -{ - [DbContext(typeof(SqliteDatabaseContext))] - [Migration("20230502032705_AddZombieStatsInitial")] - partial class AddZombieStatsInitial - { - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder.HasAnnotation("ProductVersion", "6.0.1"); - - modelBuilder.Entity("Data.Models.Client.EFACSnapshotVector3", b => - { - b.Property("ACSnapshotVector3Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("Active") - .HasColumnType("INTEGER"); - - b.Property("SnapshotId") - .HasColumnType("INTEGER"); - - b.Property("Vector3Id") - .HasColumnType("INTEGER"); - - b.HasKey("ACSnapshotVector3Id"); - - b.HasIndex("SnapshotId"); - - b.HasIndex("Vector3Id"); - - b.ToTable("EFACSnapshotVector3", (string)null); - }); - - modelBuilder.Entity("Data.Models.Client.EFClient", b => - { - b.Property("ClientId") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("Active") - .HasColumnType("INTEGER"); - - b.Property("AliasLinkId") - .HasColumnType("INTEGER"); - - b.Property("Connections") - .HasColumnType("INTEGER"); - - b.Property("CurrentAliasId") - .HasColumnType("INTEGER"); - - b.Property("FirstConnection") - .HasColumnType("TEXT"); - - b.Property("GameName") - .HasColumnType("INTEGER"); - - b.Property("LastConnection") - .HasColumnType("TEXT"); - - b.Property("Level") - .HasColumnType("INTEGER"); - - b.Property("Masked") - .HasColumnType("INTEGER"); - - b.Property("NetworkId") - .HasColumnType("INTEGER"); - - b.Property("Password") - .HasColumnType("TEXT"); - - b.Property("PasswordSalt") - .HasColumnType("TEXT"); - - b.Property("TotalConnectionTime") - .HasColumnType("INTEGER"); - - b.HasKey("ClientId"); - - b.HasAlternateKey("NetworkId", "GameName"); - - b.HasIndex("AliasLinkId"); - - b.HasIndex("CurrentAliasId"); - - b.HasIndex("LastConnection"); - - b.HasIndex("NetworkId"); - - b.ToTable("EFClients", (string)null); - }); - - modelBuilder.Entity("Data.Models.Client.EFClientConnectionHistory", b => - { - b.Property("ClientConnectionId") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("ClientId") - .HasColumnType("INTEGER"); - - b.Property("ConnectionType") - .HasColumnType("INTEGER"); - - b.Property("CreatedDateTime") - .HasColumnType("TEXT"); - - b.Property("ServerId") - .HasColumnType("INTEGER"); - - b.Property("UpdatedDateTime") - .HasColumnType("TEXT"); - - b.HasKey("ClientConnectionId"); - - b.HasIndex("ClientId"); - - b.HasIndex("CreatedDateTime"); - - b.HasIndex("ServerId"); - - b.ToTable("EFClientConnectionHistory", (string)null); - }); - - modelBuilder.Entity("Data.Models.Client.EFClientKill", b => - { - b.Property("KillId") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("Active") - .HasColumnType("INTEGER"); - - b.Property("AttackerId") - .HasColumnType("INTEGER"); - - b.Property("Damage") - .HasColumnType("INTEGER"); - - b.Property("DeathOriginVector3Id") - .HasColumnType("INTEGER"); - - b.Property("DeathType") - .HasColumnType("INTEGER"); - - b.Property("Fraction") - .HasColumnType("REAL"); - - b.Property("HitLoc") - .HasColumnType("INTEGER"); - - b.Property("IsKill") - .HasColumnType("INTEGER"); - - b.Property("KillOriginVector3Id") - .HasColumnType("INTEGER"); - - b.Property("Map") - .HasColumnType("INTEGER"); - - b.Property("ServerId") - .HasColumnType("INTEGER"); - - b.Property("VictimId") - .HasColumnType("INTEGER"); - - b.Property("ViewAnglesVector3Id") - .HasColumnType("INTEGER"); - - b.Property("VisibilityPercentage") - .HasColumnType("REAL"); - - b.Property("Weapon") - .HasColumnType("INTEGER"); - - b.Property("WeaponReference") - .HasColumnType("TEXT"); - - b.Property("When") - .HasColumnType("TEXT"); - - b.HasKey("KillId"); - - b.HasIndex("AttackerId"); - - b.HasIndex("DeathOriginVector3Id"); - - b.HasIndex("KillOriginVector3Id"); - - b.HasIndex("ServerId"); - - b.HasIndex("VictimId"); - - b.HasIndex("ViewAnglesVector3Id"); - - b.ToTable("EFClientKills", (string)null); - }); - - modelBuilder.Entity("Data.Models.Client.EFClientMessage", b => - { - b.Property("MessageId") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("Active") - .HasColumnType("INTEGER"); - - b.Property("ClientId") - .HasColumnType("INTEGER"); - - b.Property("Message") - .HasColumnType("TEXT"); - - b.Property("SentIngame") - .HasColumnType("INTEGER"); - - b.Property("ServerId") - .HasColumnType("INTEGER"); - - b.Property("TimeSent") - .HasColumnType("TEXT"); - - b.HasKey("MessageId"); - - b.HasIndex("ClientId"); - - b.HasIndex("ServerId"); - - b.HasIndex("TimeSent"); - - b.ToTable("EFClientMessages", (string)null); - }); - - modelBuilder.Entity("Data.Models.Client.Stats.EFACSnapshot", b => - { - b.Property("SnapshotId") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("Active") - .HasColumnType("INTEGER"); - - b.Property("ClientId") - .HasColumnType("INTEGER"); - - b.Property("CurrentSessionLength") - .HasColumnType("INTEGER"); - - b.Property("CurrentStrain") - .HasColumnType("REAL"); - - b.Property("CurrentViewAngleId") - .HasColumnType("INTEGER"); - - b.Property("Deaths") - .HasColumnType("INTEGER"); - - b.Property("Distance") - .HasColumnType("REAL"); - - b.Property("EloRating") - .HasColumnType("REAL"); - - b.Property("HitDestinationId") - .HasColumnType("INTEGER"); - - b.Property("HitLocation") - .HasColumnType("INTEGER"); - - b.Property("HitLocationReference") - .HasColumnType("TEXT"); - - b.Property("HitOriginId") - .HasColumnType("INTEGER"); - - b.Property("HitType") - .HasColumnType("INTEGER"); - - b.Property("Hits") - .HasColumnType("INTEGER"); - - b.Property("Kills") - .HasColumnType("INTEGER"); - - b.Property("LastStrainAngleId") - .HasColumnType("INTEGER"); - - b.Property("RecoilOffset") - .HasColumnType("REAL"); - - b.Property("ServerId") - .HasColumnType("INTEGER"); - - b.Property("SessionAngleOffset") - .HasColumnType("REAL"); - - b.Property("SessionAverageSnapValue") - .HasColumnType("REAL"); - - b.Property("SessionSPM") - .HasColumnType("REAL"); - - b.Property("SessionScore") - .HasColumnType("INTEGER"); - - b.Property("SessionSnapHits") - .HasColumnType("INTEGER"); - - b.Property("StrainAngleBetween") - .HasColumnType("REAL"); - - b.Property("TimeSinceLastEvent") - .HasColumnType("INTEGER"); - - b.Property("WeaponId") - .HasColumnType("INTEGER"); - - b.Property("WeaponReference") - .HasColumnType("TEXT"); - - b.Property("When") - .HasColumnType("TEXT"); - - b.HasKey("SnapshotId"); - - b.HasIndex("ClientId"); - - b.HasIndex("CurrentViewAngleId"); - - b.HasIndex("HitDestinationId"); - - b.HasIndex("HitOriginId"); - - b.HasIndex("LastStrainAngleId"); - - b.HasIndex("ServerId"); - - b.ToTable("EFACSnapshot", (string)null); - }); - - modelBuilder.Entity("Data.Models.Client.Stats.EFClientHitStatistic", b => - { - b.Property("ClientHitStatisticId") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("ClientId") - .HasColumnType("INTEGER"); - - b.Property("CreatedDateTime") - .HasColumnType("TEXT"); - - b.Property("DamageInflicted") - .HasColumnType("INTEGER"); - - b.Property("DamageReceived") - .HasColumnType("INTEGER"); - - b.Property("DeathCount") - .HasColumnType("INTEGER"); - - b.Property("HitCount") - .HasColumnType("INTEGER"); - - b.Property("HitLocationId") - .HasColumnType("INTEGER"); - - b.Property("KillCount") - .HasColumnType("INTEGER"); - - b.Property("MeansOfDeathId") - .HasColumnType("INTEGER"); - - b.Property("ReceivedHitCount") - .HasColumnType("INTEGER"); - - b.Property("Score") - .HasColumnType("INTEGER"); - - b.Property("ServerId") - .HasColumnType("INTEGER"); - - b.Property("SuicideCount") - .HasColumnType("INTEGER"); - - b.Property("UpdatedDateTime") - .HasColumnType("TEXT"); - - b.Property("UsageSeconds") - .HasColumnType("INTEGER"); - - b.Property("WeaponAttachmentComboId") - .HasColumnType("INTEGER"); - - b.Property("WeaponId") - .HasColumnType("INTEGER"); - - b.HasKey("ClientHitStatisticId"); - - b.HasIndex("ClientId"); - - b.HasIndex("HitLocationId"); - - b.HasIndex("MeansOfDeathId"); - - b.HasIndex("ServerId"); - - b.HasIndex("WeaponAttachmentComboId"); - - b.HasIndex("WeaponId"); - - b.ToTable("EFClientHitStatistics", (string)null); - }); - - modelBuilder.Entity("Data.Models.Client.Stats.EFClientRankingHistory", b => - { - b.Property("ClientRankingHistoryId") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("ClientId") - .HasColumnType("INTEGER"); - - b.Property("CreatedDateTime") - .HasColumnType("TEXT"); - - b.Property("Newest") - .HasColumnType("INTEGER"); - - b.Property("PerformanceMetric") - .HasColumnType("REAL"); - - b.Property("Ranking") - .HasColumnType("INTEGER"); - - b.Property("ServerId") - .HasColumnType("INTEGER"); - - b.Property("UpdatedDateTime") - .HasColumnType("TEXT"); - - b.Property("ZScore") - .HasColumnType("REAL"); - - b.HasKey("ClientRankingHistoryId"); - - b.HasIndex("ClientId"); - - b.HasIndex("CreatedDateTime"); - - b.HasIndex("Ranking"); - - b.HasIndex("ServerId"); - - b.HasIndex("UpdatedDateTime"); - - b.HasIndex("ZScore"); - - b.ToTable("EFClientRankingHistory", (string)null); - }); - - modelBuilder.Entity("Data.Models.Client.Stats.EFClientRatingHistory", b => - { - b.Property("RatingHistoryId") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("Active") - .HasColumnType("INTEGER"); - - b.Property("ClientId") - .HasColumnType("INTEGER"); - - b.HasKey("RatingHistoryId"); - - b.HasIndex("ClientId"); - - b.ToTable("EFClientRatingHistory", (string)null); - }); - - modelBuilder.Entity("Data.Models.Client.Stats.EFClientStatistics", b => - { - b.Property("ClientId") - .HasColumnType("INTEGER"); - - b.Property("ServerId") - .HasColumnType("INTEGER"); - - b.Property("Active") - .HasColumnType("INTEGER"); - - b.Property("AverageSnapValue") - .HasColumnType("REAL"); - - b.Property("Deaths") - .HasColumnType("INTEGER"); - - b.Property("EloRating") - .HasColumnType("REAL"); - - b.Property("Kills") - .HasColumnType("INTEGER"); - - b.Property("MaxStrain") - .HasColumnType("REAL"); - - b.Property("RollingWeightedKDR") - .HasColumnType("REAL"); - - b.Property("SPM") - .HasColumnType("REAL"); - - b.Property("Skill") - .HasColumnType("REAL"); - - b.Property("SnapHitCount") - .HasColumnType("INTEGER"); - - b.Property("TimePlayed") - .HasColumnType("INTEGER"); - - b.Property("UpdatedAt") - .HasColumnType("TEXT"); - - b.Property("ZScore") - .HasColumnType("REAL"); - - b.HasKey("ClientId", "ServerId"); - - b.HasIndex("ServerId"); - - b.HasIndex("ZScore"); - - b.HasIndex("ClientId", "TimePlayed", "ZScore"); - - b.ToTable("EFClientStatistics", (string)null); - }); - - modelBuilder.Entity("Data.Models.Client.Stats.EFHitLocationCount", b => - { - b.Property("HitLocationCountId") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("Active") - .HasColumnType("INTEGER"); - - b.Property("EFClientStatisticsClientId") - .HasColumnType("INTEGER") - .HasColumnName("EFClientStatisticsClientId"); - - b.Property("EFClientStatisticsServerId") - .HasColumnType("INTEGER") - .HasColumnName("EFClientStatisticsServerId"); - - b.Property("HitCount") - .HasColumnType("INTEGER"); - - b.Property("HitOffsetAverage") - .HasColumnType("REAL"); - - b.Property("Location") - .HasColumnType("INTEGER"); - - b.Property("MaxAngleDistance") - .HasColumnType("REAL"); - - b.HasKey("HitLocationCountId"); - - b.HasIndex("EFClientStatisticsServerId"); - - b.HasIndex("EFClientStatisticsClientId", "EFClientStatisticsServerId"); - - b.ToTable("EFHitLocationCounts", (string)null); - }); - - modelBuilder.Entity("Data.Models.Client.Stats.EFRating", b => - { - b.Property("RatingId") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("Active") - .HasColumnType("INTEGER"); - - b.Property("ActivityAmount") - .HasColumnType("INTEGER"); - - b.Property("Newest") - .HasColumnType("INTEGER"); - - b.Property("Performance") - .HasColumnType("REAL"); - - b.Property("Ranking") - .HasColumnType("INTEGER"); - - b.Property("RatingHistoryId") - .HasColumnType("INTEGER"); - - b.Property("ServerId") - .HasColumnType("INTEGER"); - - b.Property("When") - .HasColumnType("TEXT"); - - b.HasKey("RatingId"); - - b.HasIndex("RatingHistoryId"); - - b.HasIndex("ServerId"); - - b.HasIndex("Performance", "Ranking", "When"); - - b.HasIndex("When", "ServerId", "Performance", "ActivityAmount"); - - b.ToTable("EFRating", (string)null); - }); - - modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFHitLocation", b => - { - b.Property("HitLocationId") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("CreatedDateTime") - .HasColumnType("TEXT"); - - b.Property("Game") - .HasColumnType("INTEGER"); - - b.Property("Name") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("UpdatedDateTime") - .HasColumnType("TEXT"); - - b.HasKey("HitLocationId"); - - b.HasIndex("Name"); - - b.ToTable("EFHitLocations", (string)null); - }); - - modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFMap", b => - { - b.Property("MapId") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("CreatedDateTime") - .HasColumnType("TEXT"); - - b.Property("Game") - .HasColumnType("INTEGER"); - - b.Property("Name") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("UpdatedDateTime") - .HasColumnType("TEXT"); - - b.HasKey("MapId"); - - b.ToTable("EFMaps", (string)null); - }); - - modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFMeansOfDeath", b => - { - b.Property("MeansOfDeathId") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("CreatedDateTime") - .HasColumnType("TEXT"); - - b.Property("Game") - .HasColumnType("INTEGER"); - - b.Property("Name") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("UpdatedDateTime") - .HasColumnType("TEXT"); - - b.HasKey("MeansOfDeathId"); - - b.ToTable("EFMeansOfDeath", (string)null); - }); - - modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFWeapon", b => - { - b.Property("WeaponId") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("CreatedDateTime") - .HasColumnType("TEXT"); - - b.Property("Game") - .HasColumnType("INTEGER"); - - b.Property("Name") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("UpdatedDateTime") - .HasColumnType("TEXT"); - - b.HasKey("WeaponId"); - - b.HasIndex("Name"); - - b.ToTable("EFWeapons", (string)null); - }); - - modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFWeaponAttachment", b => - { - b.Property("WeaponAttachmentId") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("CreatedDateTime") - .HasColumnType("TEXT"); - - b.Property("Game") - .HasColumnType("INTEGER"); - - b.Property("Name") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("UpdatedDateTime") - .HasColumnType("TEXT"); - - b.HasKey("WeaponAttachmentId"); - - b.ToTable("EFWeaponAttachments", (string)null); - }); - - modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFWeaponAttachmentCombo", b => - { - b.Property("WeaponAttachmentComboId") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("Attachment1Id") - .HasColumnType("INTEGER"); - - b.Property("Attachment2Id") - .HasColumnType("INTEGER"); - - b.Property("Attachment3Id") - .HasColumnType("INTEGER"); - - b.Property("CreatedDateTime") - .HasColumnType("TEXT"); - - b.Property("Game") - .HasColumnType("INTEGER"); - - b.Property("UpdatedDateTime") - .HasColumnType("TEXT"); - - b.HasKey("WeaponAttachmentComboId"); - - b.HasIndex("Attachment1Id"); - - b.HasIndex("Attachment2Id"); - - b.HasIndex("Attachment3Id"); - - b.ToTable("EFWeaponAttachmentCombos", (string)null); - }); - - modelBuilder.Entity("Data.Models.EFAlias", b => - { - b.Property("AliasId") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("Active") - .HasColumnType("INTEGER"); - - b.Property("DateAdded") - .HasColumnType("TEXT"); - - b.Property("IPAddress") - .HasColumnType("INTEGER"); - - b.Property("LinkId") - .HasColumnType("INTEGER"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(24) - .HasColumnType("TEXT"); - - b.Property("SearchableIPAddress") - .ValueGeneratedOnAddOrUpdate() - .HasMaxLength(255) - .HasColumnType("TEXT") - .HasComputedColumnSql("((IPAddress & 255) || '.' || ((IPAddress >> 8) & 255)) || '.' || ((IPAddress >> 16) & 255) || '.' || ((IPAddress >> 24) & 255)", true); - - b.Property("SearchableName") - .HasMaxLength(24) - .HasColumnType("TEXT"); - - b.HasKey("AliasId"); - - b.HasIndex("IPAddress"); - - b.HasIndex("LinkId"); - - b.HasIndex("Name"); - - b.HasIndex("SearchableIPAddress"); - - b.HasIndex("SearchableName"); - - b.HasIndex("Name", "IPAddress"); - - b.ToTable("EFAlias", (string)null); - }); - - modelBuilder.Entity("Data.Models.EFAliasLink", b => - { - b.Property("AliasLinkId") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("Active") - .HasColumnType("INTEGER"); - - b.HasKey("AliasLinkId"); - - b.ToTable("EFAliasLinks", (string)null); - }); - - modelBuilder.Entity("Data.Models.EFChangeHistory", b => - { - b.Property("ChangeHistoryId") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("Active") - .HasColumnType("INTEGER"); - - b.Property("Comment") - .HasMaxLength(128) - .HasColumnType("TEXT"); - - b.Property("CurrentValue") - .HasColumnType("TEXT"); - - b.Property("ImpersonationEntityId") - .HasColumnType("INTEGER"); - - b.Property("OriginEntityId") - .HasColumnType("INTEGER"); - - b.Property("PreviousValue") - .HasColumnType("TEXT"); - - b.Property("TargetEntityId") - .HasColumnType("INTEGER"); - - b.Property("TimeChanged") - .HasColumnType("TEXT"); - - b.Property("TypeOfChange") - .HasColumnType("INTEGER"); - - b.HasKey("ChangeHistoryId"); - - b.ToTable("EFChangeHistory"); - }); - - modelBuilder.Entity("Data.Models.EFMeta", b => - { - b.Property("MetaId") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("Active") - .HasColumnType("INTEGER"); - - b.Property("ClientId") - .HasColumnType("INTEGER"); - - b.Property("Created") - .HasColumnType("TEXT"); - - b.Property("Extra") - .HasColumnType("TEXT"); - - b.Property("Key") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("TEXT"); - - b.Property("LinkedMetaId") - .HasColumnType("INTEGER"); - - b.Property("Updated") - .HasColumnType("TEXT"); - - b.Property("Value") - .IsRequired() - .HasColumnType("TEXT"); - - b.HasKey("MetaId"); - - b.HasIndex("ClientId"); - - b.HasIndex("Key"); - - b.HasIndex("LinkedMetaId"); - - b.ToTable("EFMeta"); - }); - - modelBuilder.Entity("Data.Models.EFPenalty", b => - { - b.Property("PenaltyId") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("Active") - .HasColumnType("INTEGER"); - - b.Property("AutomatedOffense") - .HasColumnType("TEXT"); - - b.Property("Expires") - .HasColumnType("TEXT"); - - b.Property("IsEvadedOffense") - .HasColumnType("INTEGER"); - - b.Property("LinkId") - .HasColumnType("INTEGER"); - - b.Property("OffenderId") - .HasColumnType("INTEGER"); - - b.Property("Offense") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("PunisherId") - .HasColumnType("INTEGER"); - - b.Property("Type") - .HasColumnType("INTEGER"); - - b.Property("When") - .HasColumnType("TEXT"); - - b.HasKey("PenaltyId"); - - b.HasIndex("LinkId"); - - b.HasIndex("OffenderId"); - - b.HasIndex("PunisherId"); - - b.ToTable("EFPenalties", (string)null); - }); - - modelBuilder.Entity("Data.Models.EFPenaltyIdentifier", b => - { - b.Property("PenaltyIdentifierId") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("CreatedDateTime") - .HasColumnType("TEXT"); - - b.Property("IPv4Address") - .HasColumnType("INTEGER"); - - b.Property("NetworkId") - .HasColumnType("INTEGER"); - - b.Property("PenaltyId") - .HasColumnType("INTEGER"); - - b.Property("UpdatedDateTime") - .HasColumnType("TEXT"); - - b.HasKey("PenaltyIdentifierId"); - - b.HasIndex("IPv4Address"); - - b.HasIndex("NetworkId"); - - b.HasIndex("PenaltyId"); - - b.ToTable("EFPenaltyIdentifiers", (string)null); - }); - - modelBuilder.Entity("Data.Models.Misc.EFInboxMessage", b => - { - b.Property("InboxMessageId") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("CreatedDateTime") - .HasColumnType("TEXT"); - - b.Property("DestinationClientId") - .HasColumnType("INTEGER"); - - b.Property("IsDelivered") - .HasColumnType("INTEGER"); - - b.Property("Message") - .HasColumnType("TEXT"); - - b.Property("ServerId") - .HasColumnType("INTEGER"); - - b.Property("SourceClientId") - .HasColumnType("INTEGER"); - - b.Property("UpdatedDateTime") - .HasColumnType("TEXT"); - - b.HasKey("InboxMessageId"); - - b.HasIndex("DestinationClientId"); - - b.HasIndex("ServerId"); - - b.HasIndex("SourceClientId"); - - b.ToTable("InboxMessages"); - }); - - modelBuilder.Entity("Data.Models.Server.EFServer", b => - { - b.Property("ServerId") - .HasColumnType("INTEGER"); - - b.Property("Active") - .HasColumnType("INTEGER"); - - b.Property("EndPoint") - .HasColumnType("TEXT"); - - b.Property("GameName") - .HasColumnType("INTEGER"); - - b.Property("HostName") - .HasColumnType("TEXT"); - - b.Property("IsPasswordProtected") - .HasColumnType("INTEGER"); - - b.Property("Port") - .HasColumnType("INTEGER"); - - b.HasKey("ServerId"); - - b.ToTable("EFServers", (string)null); - }); - - modelBuilder.Entity("Data.Models.Server.EFServerSnapshot", b => - { - b.Property("ServerSnapshotId") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("Active") - .HasColumnType("INTEGER"); - - b.Property("CapturedAt") - .HasColumnType("TEXT"); - - b.Property("ClientCount") - .HasColumnType("INTEGER"); - - b.Property("ConnectionInterrupted") - .HasColumnType("INTEGER"); - - b.Property("MapId") - .HasColumnType("INTEGER"); - - b.Property("PeriodBlock") - .HasColumnType("INTEGER"); - - b.Property("ServerId") - .HasColumnType("INTEGER"); - - b.HasKey("ServerSnapshotId"); - - b.HasIndex("MapId"); - - b.HasIndex("ServerId"); - - b.ToTable("EFServerSnapshot", (string)null); - }); - - modelBuilder.Entity("Data.Models.Server.EFServerStatistics", b => - { - b.Property("StatisticId") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("Active") - .HasColumnType("INTEGER"); - - b.Property("ServerId") - .HasColumnType("INTEGER"); - - b.Property("TotalKills") - .HasColumnType("INTEGER"); - - b.Property("TotalPlayTime") - .HasColumnType("INTEGER"); - - b.HasKey("StatisticId"); - - b.HasIndex("ServerId"); - - b.ToTable("EFServerStatistics", (string)null); - }); - - modelBuilder.Entity("Data.Models.Vector3", b => - { - b.Property("Vector3Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("X") - .HasColumnType("REAL"); - - b.Property("Y") - .HasColumnType("REAL"); - - b.Property("Z") - .HasColumnType("REAL"); - - b.HasKey("Vector3Id"); - - b.ToTable("Vector3", (string)null); - }); - - modelBuilder.Entity("Data.Models.Zombie.ZombieClientStat", b => - { - b.Property("ZombieClientStatId") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("ClientId") - .HasColumnType("INTEGER"); - - b.Property("DamageDealt") - .HasColumnType("INTEGER"); - - b.Property("DamageReceived") - .HasColumnType("INTEGER"); - - b.Property("Deaths") - .HasColumnType("INTEGER"); - - b.Property("Downs") - .HasColumnType("INTEGER"); - - b.Property("Headshots") - .HasColumnType("INTEGER"); - - b.Property("Kills") - .HasColumnType("INTEGER"); - - b.Property("MatchId") - .HasColumnType("INTEGER"); - - b.Property("Melees") - .HasColumnType("INTEGER"); - - b.Property("PerksConsumed") - .HasColumnType("INTEGER"); - - b.Property("PointsEarned") - .HasColumnType("INTEGER"); - - b.Property("PointsSpent") - .HasColumnType("INTEGER"); - - b.Property("PowerupsGrabbed") - .HasColumnType("INTEGER"); - - b.Property("Revives") - .HasColumnType("INTEGER"); - - b.HasKey("ZombieClientStatId"); - - b.HasIndex("ClientId"); - - b.HasIndex("MatchId"); - - b.ToTable("EFZombieClientStat", (string)null); - }); - - modelBuilder.Entity("Data.Models.Zombie.ZombieMatch", b => - { - b.Property("ZombieMatchId") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("EFClientClientId") - .HasColumnType("INTEGER"); - - b.Property("MapId") - .HasColumnType("INTEGER"); - - b.Property("MatchEndDate") - .HasColumnType("TEXT"); - - b.Property("MatchStartDate") - .HasColumnType("TEXT"); - - b.Property("ServerId") - .HasColumnType("INTEGER"); - - b.HasKey("ZombieMatchId"); - - b.HasIndex("EFClientClientId"); - - b.HasIndex("MapId"); - - b.HasIndex("ServerId"); - - b.ToTable("EFZombieMatch", (string)null); - }); - - modelBuilder.Entity("Data.Models.Zombie.ZombieAggregateClientStat", b => - { - b.HasBaseType("Data.Models.Zombie.ZombieClientStat"); - - b.Property("AlivePercentage") - .HasColumnType("REAL"); - - b.Property("AverageDowns") - .HasColumnType("REAL"); - - b.Property("AverageKillsPerDown") - .HasColumnType("REAL"); - - b.Property("AverageMelees") - .HasColumnType("REAL"); - - b.Property("AveragePoints") - .HasColumnType("REAL"); - - b.Property("AverageRevives") - .HasColumnType("REAL"); - - b.Property("AverageRoundReached") - .HasColumnType("REAL"); - - b.Property("EFClientClientId") - .HasColumnType("INTEGER"); - - b.Property("HeadshotPercentage") - .HasColumnType("REAL"); - - b.Property("HighestRound") - .HasColumnType("INTEGER"); - - b.Property("RankingMetric") - .HasColumnType("REAL"); - - b.Property("TotalMatchesPlayed") - .HasColumnType("INTEGER"); - - b.Property("TotalRoundsPlayed") - .HasColumnType("INTEGER"); - - b.HasIndex("EFClientClientId"); - - b.ToTable("EFZombieAggregateClientStat", (string)null); - }); - - modelBuilder.Entity("Data.Models.Zombie.ZombieMatchClientStat", b => - { - b.HasBaseType("Data.Models.Zombie.ZombieClientStat"); - - b.Property("EFClientClientId") - .HasColumnType("INTEGER"); - - b.HasIndex("EFClientClientId"); - - b.ToTable("EFZombieMatchClientStat", (string)null); - }); - - modelBuilder.Entity("Data.Models.Zombie.ZombieRoundClientStat", b => - { - b.HasBaseType("Data.Models.Zombie.ZombieClientStat"); - - b.Property("Duration") - .HasColumnType("TEXT"); - - b.Property("EFClientClientId") - .HasColumnType("INTEGER"); - - b.Property("EndTime") - .HasColumnType("TEXT"); - - b.Property("Points") - .HasColumnType("INTEGER"); - - b.Property("RoundNumber") - .HasColumnType("INTEGER"); - - b.Property("StartTime") - .HasColumnType("TEXT"); - - b.Property("TimeAlive") - .HasColumnType("TEXT"); - - b.HasIndex("EFClientClientId"); - - b.ToTable("EFZombieRoundClientStat", (string)null); - }); - - modelBuilder.Entity("Data.Models.Client.EFACSnapshotVector3", b => - { - b.HasOne("Data.Models.Client.Stats.EFACSnapshot", "Snapshot") - .WithMany("PredictedViewAngles") - .HasForeignKey("SnapshotId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Data.Models.Vector3", "Vector") - .WithMany() - .HasForeignKey("Vector3Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Snapshot"); - - b.Navigation("Vector"); - }); - - modelBuilder.Entity("Data.Models.Client.EFClient", b => - { - b.HasOne("Data.Models.EFAliasLink", "AliasLink") - .WithMany() - .HasForeignKey("AliasLinkId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Data.Models.EFAlias", "CurrentAlias") - .WithMany() - .HasForeignKey("CurrentAliasId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("AliasLink"); - - b.Navigation("CurrentAlias"); - }); - - modelBuilder.Entity("Data.Models.Client.EFClientConnectionHistory", b => - { - b.HasOne("Data.Models.Client.EFClient", "Client") - .WithMany() - .HasForeignKey("ClientId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Data.Models.Server.EFServer", "Server") - .WithMany() - .HasForeignKey("ServerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Client"); - - b.Navigation("Server"); - }); - - modelBuilder.Entity("Data.Models.Client.EFClientKill", b => - { - b.HasOne("Data.Models.Client.EFClient", "Attacker") - .WithMany() - .HasForeignKey("AttackerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Data.Models.Vector3", "DeathOrigin") - .WithMany() - .HasForeignKey("DeathOriginVector3Id"); - - b.HasOne("Data.Models.Vector3", "KillOrigin") - .WithMany() - .HasForeignKey("KillOriginVector3Id"); - - b.HasOne("Data.Models.Server.EFServer", "Server") - .WithMany() - .HasForeignKey("ServerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Data.Models.Client.EFClient", "Victim") - .WithMany() - .HasForeignKey("VictimId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Data.Models.Vector3", "ViewAngles") - .WithMany() - .HasForeignKey("ViewAnglesVector3Id"); - - b.Navigation("Attacker"); - - b.Navigation("DeathOrigin"); - - b.Navigation("KillOrigin"); - - b.Navigation("Server"); - - b.Navigation("Victim"); - - b.Navigation("ViewAngles"); - }); - - modelBuilder.Entity("Data.Models.Client.EFClientMessage", b => - { - b.HasOne("Data.Models.Client.EFClient", "Client") - .WithMany() - .HasForeignKey("ClientId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Data.Models.Server.EFServer", "Server") - .WithMany() - .HasForeignKey("ServerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Client"); - - b.Navigation("Server"); - }); - - modelBuilder.Entity("Data.Models.Client.Stats.EFACSnapshot", b => - { - b.HasOne("Data.Models.Client.EFClient", "Client") - .WithMany() - .HasForeignKey("ClientId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Data.Models.Vector3", "CurrentViewAngle") - .WithMany() - .HasForeignKey("CurrentViewAngleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Data.Models.Vector3", "HitDestination") - .WithMany() - .HasForeignKey("HitDestinationId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Data.Models.Vector3", "HitOrigin") - .WithMany() - .HasForeignKey("HitOriginId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Data.Models.Vector3", "LastStrainAngle") - .WithMany() - .HasForeignKey("LastStrainAngleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Data.Models.Server.EFServer", "Server") - .WithMany() - .HasForeignKey("ServerId"); - - b.Navigation("Client"); - - b.Navigation("CurrentViewAngle"); - - b.Navigation("HitDestination"); - - b.Navigation("HitOrigin"); - - b.Navigation("LastStrainAngle"); - - b.Navigation("Server"); - }); - - modelBuilder.Entity("Data.Models.Client.Stats.EFClientHitStatistic", b => - { - b.HasOne("Data.Models.Client.EFClient", "Client") - .WithMany() - .HasForeignKey("ClientId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Data.Models.Client.Stats.Reference.EFHitLocation", "HitLocation") - .WithMany() - .HasForeignKey("HitLocationId"); - - b.HasOne("Data.Models.Client.Stats.Reference.EFMeansOfDeath", "MeansOfDeath") - .WithMany() - .HasForeignKey("MeansOfDeathId"); - - b.HasOne("Data.Models.Server.EFServer", "Server") - .WithMany() - .HasForeignKey("ServerId"); - - b.HasOne("Data.Models.Client.Stats.Reference.EFWeaponAttachmentCombo", "WeaponAttachmentCombo") - .WithMany() - .HasForeignKey("WeaponAttachmentComboId"); - - b.HasOne("Data.Models.Client.Stats.Reference.EFWeapon", "Weapon") - .WithMany() - .HasForeignKey("WeaponId"); - - b.Navigation("Client"); - - b.Navigation("HitLocation"); - - b.Navigation("MeansOfDeath"); - - b.Navigation("Server"); - - b.Navigation("Weapon"); - - b.Navigation("WeaponAttachmentCombo"); - }); - - modelBuilder.Entity("Data.Models.Client.Stats.EFClientRankingHistory", b => - { - b.HasOne("Data.Models.Client.EFClient", "Client") - .WithMany() - .HasForeignKey("ClientId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Data.Models.Server.EFServer", "Server") - .WithMany() - .HasForeignKey("ServerId"); - - b.Navigation("Client"); - - b.Navigation("Server"); - }); - - modelBuilder.Entity("Data.Models.Client.Stats.EFClientRatingHistory", b => - { - b.HasOne("Data.Models.Client.EFClient", "Client") - .WithMany() - .HasForeignKey("ClientId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Client"); - }); - - modelBuilder.Entity("Data.Models.Client.Stats.EFClientStatistics", b => - { - b.HasOne("Data.Models.Client.EFClient", "Client") - .WithMany() - .HasForeignKey("ClientId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Data.Models.Server.EFServer", "Server") - .WithMany() - .HasForeignKey("ServerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Client"); - - b.Navigation("Server"); - }); - - modelBuilder.Entity("Data.Models.Client.Stats.EFHitLocationCount", b => - { - b.HasOne("Data.Models.Client.EFClient", "Client") - .WithMany() - .HasForeignKey("EFClientStatisticsClientId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Data.Models.Server.EFServer", "Server") - .WithMany() - .HasForeignKey("EFClientStatisticsServerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Data.Models.Client.Stats.EFClientStatistics", null) - .WithMany("HitLocations") - .HasForeignKey("EFClientStatisticsClientId", "EFClientStatisticsServerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Client"); - - b.Navigation("Server"); - }); - - modelBuilder.Entity("Data.Models.Client.Stats.EFRating", b => - { - b.HasOne("Data.Models.Client.Stats.EFClientRatingHistory", "RatingHistory") - .WithMany("Ratings") - .HasForeignKey("RatingHistoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Data.Models.Server.EFServer", "Server") - .WithMany() - .HasForeignKey("ServerId"); - - b.Navigation("RatingHistory"); - - b.Navigation("Server"); - }); - - modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFWeaponAttachmentCombo", b => - { - b.HasOne("Data.Models.Client.Stats.Reference.EFWeaponAttachment", "Attachment1") - .WithMany() - .HasForeignKey("Attachment1Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Data.Models.Client.Stats.Reference.EFWeaponAttachment", "Attachment2") - .WithMany() - .HasForeignKey("Attachment2Id"); - - b.HasOne("Data.Models.Client.Stats.Reference.EFWeaponAttachment", "Attachment3") - .WithMany() - .HasForeignKey("Attachment3Id"); - - b.Navigation("Attachment1"); - - b.Navigation("Attachment2"); - - b.Navigation("Attachment3"); - }); - - modelBuilder.Entity("Data.Models.EFAlias", b => - { - b.HasOne("Data.Models.EFAliasLink", "Link") - .WithMany("Children") - .HasForeignKey("LinkId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Link"); - }); - - modelBuilder.Entity("Data.Models.EFMeta", b => - { - b.HasOne("Data.Models.Client.EFClient", "Client") - .WithMany("Meta") - .HasForeignKey("ClientId"); - - b.HasOne("Data.Models.EFMeta", "LinkedMeta") - .WithMany() - .HasForeignKey("LinkedMetaId") - .OnDelete(DeleteBehavior.SetNull); - - b.Navigation("Client"); - - b.Navigation("LinkedMeta"); - }); - - modelBuilder.Entity("Data.Models.EFPenalty", b => - { - b.HasOne("Data.Models.EFAliasLink", "Link") - .WithMany("ReceivedPenalties") - .HasForeignKey("LinkId"); - - b.HasOne("Data.Models.Client.EFClient", "Offender") - .WithMany("ReceivedPenalties") - .HasForeignKey("OffenderId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("Data.Models.Client.EFClient", "Punisher") - .WithMany("AdministeredPenalties") - .HasForeignKey("PunisherId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Link"); - - b.Navigation("Offender"); - - b.Navigation("Punisher"); - }); - - modelBuilder.Entity("Data.Models.EFPenaltyIdentifier", b => - { - b.HasOne("Data.Models.EFPenalty", "Penalty") - .WithMany() - .HasForeignKey("PenaltyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Penalty"); - }); - - modelBuilder.Entity("Data.Models.Misc.EFInboxMessage", b => - { - b.HasOne("Data.Models.Client.EFClient", "DestinationClient") - .WithMany() - .HasForeignKey("DestinationClientId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Data.Models.Server.EFServer", "Server") - .WithMany() - .HasForeignKey("ServerId"); - - b.HasOne("Data.Models.Client.EFClient", "SourceClient") - .WithMany() - .HasForeignKey("SourceClientId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("DestinationClient"); - - b.Navigation("Server"); - - b.Navigation("SourceClient"); - }); - - modelBuilder.Entity("Data.Models.Server.EFServerSnapshot", b => - { - b.HasOne("Data.Models.Client.Stats.Reference.EFMap", "Map") - .WithMany() - .HasForeignKey("MapId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Data.Models.Server.EFServer", "Server") - .WithMany() - .HasForeignKey("ServerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Map"); - - b.Navigation("Server"); - }); - - modelBuilder.Entity("Data.Models.Server.EFServerStatistics", b => - { - b.HasOne("Data.Models.Server.EFServer", "Server") - .WithMany() - .HasForeignKey("ServerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Server"); - }); - - modelBuilder.Entity("Data.Models.Zombie.ZombieClientStat", b => - { - b.HasOne("Data.Models.Client.EFClient", "Client") - .WithMany("ZombieClientStats") - .HasForeignKey("ClientId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Data.Models.Zombie.ZombieMatch", "Match") - .WithMany("ClientStats") - .HasForeignKey("MatchId"); - - b.Navigation("Client"); - - b.Navigation("Match"); - }); - - modelBuilder.Entity("Data.Models.Zombie.ZombieMatch", b => - { - b.HasOne("Data.Models.Client.EFClient", null) - .WithMany("ZombieMatches") - .HasForeignKey("EFClientClientId"); - - b.HasOne("Data.Models.Client.Stats.Reference.EFMap", "Map") - .WithMany() - .HasForeignKey("MapId"); - - b.HasOne("Data.Models.Server.EFServer", "Server") - .WithMany() - .HasForeignKey("ServerId"); - - b.Navigation("Map"); - - b.Navigation("Server"); - }); - - modelBuilder.Entity("Data.Models.Zombie.ZombieAggregateClientStat", b => - { - b.HasOne("Data.Models.Client.EFClient", null) - .WithMany("ZombieAggregateClientStats") - .HasForeignKey("EFClientClientId"); - - b.HasOne("Data.Models.Zombie.ZombieClientStat", null) - .WithOne() - .HasForeignKey("Data.Models.Zombie.ZombieAggregateClientStat", "ZombieClientStatId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Data.Models.Zombie.ZombieMatchClientStat", b => - { - b.HasOne("Data.Models.Client.EFClient", null) - .WithMany("ZombieMatchClientStats") - .HasForeignKey("EFClientClientId"); - - b.HasOne("Data.Models.Zombie.ZombieClientStat", null) - .WithOne() - .HasForeignKey("Data.Models.Zombie.ZombieMatchClientStat", "ZombieClientStatId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Data.Models.Zombie.ZombieRoundClientStat", b => - { - b.HasOne("Data.Models.Client.EFClient", null) - .WithMany("ZombieRoundClientStats") - .HasForeignKey("EFClientClientId"); - - b.HasOne("Data.Models.Zombie.ZombieClientStat", null) - .WithOne() - .HasForeignKey("Data.Models.Zombie.ZombieRoundClientStat", "ZombieClientStatId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Data.Models.Client.EFClient", b => - { - b.Navigation("AdministeredPenalties"); - - b.Navigation("Meta"); - - b.Navigation("ReceivedPenalties"); - - b.Navigation("ZombieAggregateClientStats"); - - b.Navigation("ZombieClientStats"); - - b.Navigation("ZombieMatchClientStats"); - - b.Navigation("ZombieMatches"); - - b.Navigation("ZombieRoundClientStats"); - }); - - modelBuilder.Entity("Data.Models.Client.Stats.EFACSnapshot", b => - { - b.Navigation("PredictedViewAngles"); - }); - - modelBuilder.Entity("Data.Models.Client.Stats.EFClientRatingHistory", b => - { - b.Navigation("Ratings"); - }); - - modelBuilder.Entity("Data.Models.Client.Stats.EFClientStatistics", b => - { - b.Navigation("HitLocations"); - }); - - modelBuilder.Entity("Data.Models.EFAliasLink", b => - { - b.Navigation("Children"); - - b.Navigation("ReceivedPenalties"); - }); - - modelBuilder.Entity("Data.Models.Zombie.ZombieMatch", b => - { - b.Navigation("ClientStats"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Data/Migrations/Sqlite/20230502032705_AddZombieStatsInitial.cs b/Data/Migrations/Sqlite/20230502032705_AddZombieStatsInitial.cs deleted file mode 100644 index 2bf24e29..00000000 --- a/Data/Migrations/Sqlite/20230502032705_AddZombieStatsInitial.cs +++ /dev/null @@ -1,230 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace Data.Migrations.Sqlite -{ - public partial class AddZombieStatsInitial : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "EFZombieMatch", - columns: table => new - { - ZombieMatchId = table.Column(type: "INTEGER", nullable: false) - .Annotation("Sqlite:Autoincrement", true), - MapId = table.Column(type: "INTEGER", nullable: true), - ServerId = table.Column(type: "INTEGER", nullable: true), - MatchStartDate = table.Column(type: "TEXT", nullable: false), - MatchEndDate = table.Column(type: "TEXT", nullable: true), - EFClientClientId = table.Column(type: "INTEGER", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_EFZombieMatch", x => x.ZombieMatchId); - table.ForeignKey( - name: "FK_EFZombieMatch_EFClients_EFClientClientId", - column: x => x.EFClientClientId, - principalTable: "EFClients", - principalColumn: "ClientId"); - table.ForeignKey( - name: "FK_EFZombieMatch_EFMaps_MapId", - column: x => x.MapId, - principalTable: "EFMaps", - principalColumn: "MapId"); - table.ForeignKey( - name: "FK_EFZombieMatch_EFServers_ServerId", - column: x => x.ServerId, - principalTable: "EFServers", - principalColumn: "ServerId"); - }); - - migrationBuilder.CreateTable( - name: "EFZombieClientStat", - columns: table => new - { - ZombieClientStatId = table.Column(type: "INTEGER", nullable: false) - .Annotation("Sqlite:Autoincrement", true), - MatchId = table.Column(type: "INTEGER", nullable: true), - ClientId = table.Column(type: "INTEGER", nullable: false), - Kills = table.Column(type: "INTEGER", nullable: false), - Deaths = table.Column(type: "INTEGER", nullable: false), - DamageDealt = table.Column(type: "INTEGER", nullable: false), - DamageReceived = table.Column(type: "INTEGER", nullable: false), - Headshots = table.Column(type: "INTEGER", nullable: false), - Melees = table.Column(type: "INTEGER", nullable: false), - Downs = table.Column(type: "INTEGER", nullable: false), - Revives = table.Column(type: "INTEGER", nullable: false), - PointsEarned = table.Column(type: "INTEGER", nullable: false), - PointsSpent = table.Column(type: "INTEGER", nullable: false), - PerksConsumed = table.Column(type: "INTEGER", nullable: false), - PowerupsGrabbed = table.Column(type: "INTEGER", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_EFZombieClientStat", x => x.ZombieClientStatId); - table.ForeignKey( - name: "FK_EFZombieClientStat_EFClients_ClientId", - column: x => x.ClientId, - principalTable: "EFClients", - principalColumn: "ClientId", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_EFZombieClientStat_EFZombieMatch_MatchId", - column: x => x.MatchId, - principalTable: "EFZombieMatch", - principalColumn: "ZombieMatchId"); - }); - - migrationBuilder.CreateTable( - name: "EFZombieAggregateClientStat", - columns: table => new - { - ZombieClientStatId = table.Column(type: "INTEGER", nullable: false) - .Annotation("Sqlite:Autoincrement", true), - AverageKillsPerDown = table.Column(type: "REAL", nullable: false), - AverageDowns = table.Column(type: "REAL", nullable: false), - AverageRevives = table.Column(type: "REAL", nullable: false), - HeadshotPercentage = table.Column(type: "REAL", nullable: false), - AlivePercentage = table.Column(type: "REAL", nullable: false), - AverageMelees = table.Column(type: "REAL", nullable: false), - AverageRoundReached = table.Column(type: "REAL", nullable: false), - AveragePoints = table.Column(type: "REAL", nullable: false), - HighestRound = table.Column(type: "INTEGER", nullable: false), - TotalRoundsPlayed = table.Column(type: "INTEGER", nullable: false), - TotalMatchesPlayed = table.Column(type: "INTEGER", nullable: false), - RankingMetric = table.Column(type: "REAL", nullable: false), - EFClientClientId = table.Column(type: "INTEGER", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_EFZombieAggregateClientStat", x => x.ZombieClientStatId); - table.ForeignKey( - name: "FK_EFZombieAggregateClientStat_EFClients_EFClientClientId", - column: x => x.EFClientClientId, - principalTable: "EFClients", - principalColumn: "ClientId"); - table.ForeignKey( - name: "FK_EFZombieAggregateClientStat_EFZombieClientStat_ZombieClientStatId", - column: x => x.ZombieClientStatId, - principalTable: "EFZombieClientStat", - principalColumn: "ZombieClientStatId", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "EFZombieMatchClientStat", - columns: table => new - { - ZombieClientStatId = table.Column(type: "INTEGER", nullable: false) - .Annotation("Sqlite:Autoincrement", true), - EFClientClientId = table.Column(type: "INTEGER", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_EFZombieMatchClientStat", x => x.ZombieClientStatId); - table.ForeignKey( - name: "FK_EFZombieMatchClientStat_EFClients_EFClientClientId", - column: x => x.EFClientClientId, - principalTable: "EFClients", - principalColumn: "ClientId"); - table.ForeignKey( - name: "FK_EFZombieMatchClientStat_EFZombieClientStat_ZombieClientStatId", - column: x => x.ZombieClientStatId, - principalTable: "EFZombieClientStat", - principalColumn: "ZombieClientStatId", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "EFZombieRoundClientStat", - columns: table => new - { - ZombieClientStatId = table.Column(type: "INTEGER", nullable: false) - .Annotation("Sqlite:Autoincrement", true), - StartTime = table.Column(type: "TEXT", nullable: false), - EndTime = table.Column(type: "TEXT", nullable: true), - Duration = table.Column(type: "TEXT", nullable: true), - TimeAlive = table.Column(type: "TEXT", nullable: true), - RoundNumber = table.Column(type: "INTEGER", nullable: false), - Points = table.Column(type: "INTEGER", nullable: false), - EFClientClientId = table.Column(type: "INTEGER", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_EFZombieRoundClientStat", x => x.ZombieClientStatId); - table.ForeignKey( - name: "FK_EFZombieRoundClientStat_EFClients_EFClientClientId", - column: x => x.EFClientClientId, - principalTable: "EFClients", - principalColumn: "ClientId"); - table.ForeignKey( - name: "FK_EFZombieRoundClientStat_EFZombieClientStat_ZombieClientStatId", - column: x => x.ZombieClientStatId, - principalTable: "EFZombieClientStat", - principalColumn: "ZombieClientStatId", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateIndex( - name: "IX_EFZombieAggregateClientStat_EFClientClientId", - table: "EFZombieAggregateClientStat", - column: "EFClientClientId"); - - migrationBuilder.CreateIndex( - name: "IX_EFZombieClientStat_ClientId", - table: "EFZombieClientStat", - column: "ClientId"); - - migrationBuilder.CreateIndex( - name: "IX_EFZombieClientStat_MatchId", - table: "EFZombieClientStat", - column: "MatchId"); - - migrationBuilder.CreateIndex( - name: "IX_EFZombieMatch_EFClientClientId", - table: "EFZombieMatch", - column: "EFClientClientId"); - - migrationBuilder.CreateIndex( - name: "IX_EFZombieMatch_MapId", - table: "EFZombieMatch", - column: "MapId"); - - migrationBuilder.CreateIndex( - name: "IX_EFZombieMatch_ServerId", - table: "EFZombieMatch", - column: "ServerId"); - - migrationBuilder.CreateIndex( - name: "IX_EFZombieMatchClientStat_EFClientClientId", - table: "EFZombieMatchClientStat", - column: "EFClientClientId"); - - migrationBuilder.CreateIndex( - name: "IX_EFZombieRoundClientStat_EFClientClientId", - table: "EFZombieRoundClientStat", - column: "EFClientClientId"); - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "EFZombieAggregateClientStat"); - - migrationBuilder.DropTable( - name: "EFZombieMatchClientStat"); - - migrationBuilder.DropTable( - name: "EFZombieRoundClientStat"); - - migrationBuilder.DropTable( - name: "EFZombieClientStat"); - - migrationBuilder.DropTable( - name: "EFZombieMatch"); - } - } -} diff --git a/Data/Migrations/Sqlite/SqliteDatabaseContextModelSnapshot.cs b/Data/Migrations/Sqlite/SqliteDatabaseContextModelSnapshot.cs index 867737c4..5869c6e8 100644 --- a/Data/Migrations/Sqlite/SqliteDatabaseContextModelSnapshot.cs +++ b/Data/Migrations/Sqlite/SqliteDatabaseContextModelSnapshot.cs @@ -438,6 +438,9 @@ namespace Data.Migrations.Sqlite b.Property("Newest") .HasColumnType("INTEGER"); + b.Property("PerformanceBucket") + .HasColumnType("TEXT"); + b.Property("PerformanceMetric") .HasColumnType("REAL"); @@ -1072,6 +1075,9 @@ namespace Data.Migrations.Sqlite b.Property("IsPasswordProtected") .HasColumnType("INTEGER"); + b.Property("PerformanceBucket") + .HasColumnType("TEXT"); + b.Property("Port") .HasColumnType("INTEGER"); @@ -1172,6 +1178,9 @@ namespace Data.Migrations.Sqlite b.Property("ClientId") .HasColumnType("INTEGER"); + b.Property("CreatedDateTime") + .HasColumnType("TEXT"); + b.Property("DamageDealt") .HasColumnType("INTEGER"); @@ -1199,10 +1208,10 @@ namespace Data.Migrations.Sqlite b.Property("PerksConsumed") .HasColumnType("INTEGER"); - b.Property("PointsEarned") + b.Property("PointsEarned") .HasColumnType("INTEGER"); - b.Property("PointsSpent") + b.Property("PointsSpent") .HasColumnType("INTEGER"); b.Property("PowerupsGrabbed") @@ -1211,6 +1220,9 @@ namespace Data.Migrations.Sqlite b.Property("Revives") .HasColumnType("INTEGER"); + b.Property("UpdatedDateTime") + .HasColumnType("TEXT"); + b.HasKey("ZombieClientStatId"); b.HasIndex("ClientId"); @@ -1220,12 +1232,57 @@ namespace Data.Migrations.Sqlite b.ToTable("EFZombieClientStat", (string)null); }); + modelBuilder.Entity("Data.Models.Zombie.ZombieClientStatRecord", b => + { + b.Property("ZombieClientStatRecordId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClientId") + .HasColumnType("INTEGER"); + + b.Property("CreatedDateTime") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("RoundId") + .HasColumnType("INTEGER"); + + b.Property("Type") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UpdatedDateTime") + .HasColumnType("TEXT"); + + b.Property("Value") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("ZombieClientStatRecordId"); + + b.HasIndex("ClientId"); + + b.HasIndex("RoundId"); + + b.ToTable("EFZombieClientStatRecord", (string)null); + }); + modelBuilder.Entity("Data.Models.Zombie.ZombieMatch", b => { b.Property("ZombieMatchId") .ValueGeneratedOnAdd() .HasColumnType("INTEGER"); + b.Property("ClientsCompleted") + .HasColumnType("INTEGER"); + + b.Property("CreatedDateTime") + .HasColumnType("TEXT"); + b.Property("EFClientClientId") .HasColumnType("INTEGER"); @@ -1241,6 +1298,9 @@ namespace Data.Migrations.Sqlite b.Property("ServerId") .HasColumnType("INTEGER"); + b.Property("UpdatedDateTime") + .HasColumnType("TEXT"); + b.HasKey("ZombieMatchId"); b.HasIndex("EFClientClientId"); @@ -1286,8 +1346,8 @@ namespace Data.Migrations.Sqlite b.Property("HighestRound") .HasColumnType("INTEGER"); - b.Property("RankingMetric") - .HasColumnType("REAL"); + b.Property("TotalMatchesCompleted") + .HasColumnType("INTEGER"); b.Property("TotalMatchesPlayed") .HasColumnType("INTEGER"); @@ -1800,6 +1860,21 @@ namespace Data.Migrations.Sqlite b.Navigation("Match"); }); + modelBuilder.Entity("Data.Models.Zombie.ZombieClientStatRecord", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId"); + + b.HasOne("Data.Models.Zombie.ZombieRoundClientStat", "Round") + .WithMany() + .HasForeignKey("RoundId"); + + b.Navigation("Client"); + + b.Navigation("Round"); + }); + modelBuilder.Entity("Data.Models.Zombie.ZombieMatch", b => { b.HasOne("Data.Models.Client.EFClient", null) diff --git a/Data/Models/Client/Stats/EFClientRankingHistory.cs b/Data/Models/Client/Stats/EFClientRankingHistory.cs index 6d067900..dcf16654 100644 --- a/Data/Models/Client/Stats/EFClientRankingHistory.cs +++ b/Data/Models/Client/Stats/EFClientRankingHistory.cs @@ -25,5 +25,6 @@ namespace Data.Models.Client.Stats public int? Ranking { get; set; } public double? ZScore { get; set; } public double? PerformanceMetric { get; set; } + public string PerformanceBucket { get; set; } } } diff --git a/Data/Models/DatedRecord.cs b/Data/Models/DatedRecord.cs new file mode 100644 index 00000000..559c725b --- /dev/null +++ b/Data/Models/DatedRecord.cs @@ -0,0 +1,9 @@ +using System; + +namespace Data.Models; + +public class DatedRecord +{ + public DateTimeOffset CreatedDateTime { get; set; } = DateTimeOffset.UtcNow; + public DateTimeOffset? UpdatedDateTime { get; set; } +} diff --git a/Data/Models/Server/EFServer.cs b/Data/Models/Server/EFServer.cs index 70a49cd4..eb2a2d5d 100644 --- a/Data/Models/Server/EFServer.cs +++ b/Data/Models/Server/EFServer.cs @@ -15,6 +15,7 @@ namespace Data.Models.Server public Reference.Game? GameName { get; set; } public string HostName { get; set; } public bool IsPasswordProtected { get; set; } + public string PerformanceBucket { get; set; } public long Id => ServerId; public string Value => EndPoint; } diff --git a/Data/Models/Zombie/ZombieAggregateClientStat.cs b/Data/Models/Zombie/ZombieAggregateClientStat.cs index 2410907c..d77b21e7 100644 --- a/Data/Models/Zombie/ZombieAggregateClientStat.cs +++ b/Data/Models/Zombie/ZombieAggregateClientStat.cs @@ -1,4 +1,6 @@ -namespace Data.Models.Zombie; +using System.ComponentModel.DataAnnotations.Schema; + +namespace Data.Models.Zombie; public class ZombieAggregateClientStat : ZombieClientStat { @@ -20,8 +22,23 @@ public class ZombieAggregateClientStat : ZombieClientStat public int HighestRound { get; set; } public int TotalRoundsPlayed { get; set; } public int TotalMatchesPlayed { get; set; } + public int TotalMatchesCompleted { get; set; } #endregion - - public double RankingMetric { get; set; } + + [NotMapped] + public static readonly string[] RecordsKeys = + { + nameof(AverageKillsPerDown), + nameof(AverageDowns), + nameof(AverageRevives), + nameof(HeadshotPercentage), + nameof(AlivePercentage), + nameof(AverageMelees), + nameof(AverageRoundReached), + nameof(AveragePoints), + nameof(HighestRound), + nameof(TotalRoundsPlayed), + nameof(TotalMatchesPlayed) + }; } diff --git a/Data/Models/Zombie/ZombieClientStat.cs b/Data/Models/Zombie/ZombieClientStat.cs index b055f810..97e4c749 100644 --- a/Data/Models/Zombie/ZombieClientStat.cs +++ b/Data/Models/Zombie/ZombieClientStat.cs @@ -5,7 +5,7 @@ using Data.Models.Client; namespace Data.Models.Zombie; -public abstract class ZombieClientStat +public abstract class ZombieClientStat : DatedRecord { [Key] public long ZombieClientStatId { get; set; } @@ -27,8 +27,8 @@ public abstract class ZombieClientStat public int Melees { get; set; } public int Downs { get; set; } public int Revives { get; set; } - public int PointsEarned { get; set; } - public int PointsSpent { get; set; } + public long PointsEarned { get; set; } + public long PointsSpent { get; set; } public int PerksConsumed { get; set; } public int PowerupsGrabbed { get; set; } } diff --git a/Data/Models/Zombie/ZombieClientStatRecord.cs b/Data/Models/Zombie/ZombieClientStatRecord.cs new file mode 100644 index 00000000..356eab89 --- /dev/null +++ b/Data/Models/Zombie/ZombieClientStatRecord.cs @@ -0,0 +1,29 @@ +#nullable enable +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using Data.Models.Client; + +namespace Data.Models.Zombie; + +public enum RecordType +{ + Maximum, + Minimum +} + +public class ZombieClientStatRecord : DatedRecord +{ + [Key] + public int ZombieClientStatRecordId { get; set; } + public string Name { get; set; } = string.Empty; + public string Type { get; set; } = string.Empty; + public string Value { get; set; } = string.Empty; + + public int? ClientId { get; set; } + [ForeignKey(nameof(ClientId))] + public virtual EFClient? Client { get; set; } + + public long? RoundId { get; set; } + [ForeignKey(nameof(RoundId))] + public virtual ZombieRoundClientStat? Round { get; set; } +} diff --git a/Data/Models/Zombie/ZombieMatch.cs b/Data/Models/Zombie/ZombieMatch.cs index 8c987476..c58135f2 100644 --- a/Data/Models/Zombie/ZombieMatch.cs +++ b/Data/Models/Zombie/ZombieMatch.cs @@ -8,7 +8,7 @@ using Data.Models.Server; namespace Data.Models.Zombie; -public class ZombieMatch +public class ZombieMatch : DatedRecord { [Key] public int ZombieMatchId { get; set; } @@ -21,6 +21,8 @@ public class ZombieMatch [ForeignKey(nameof(ServerId))] public virtual EFServer? Server { get; set; } + public int ClientsCompleted { get; set; } + public virtual ICollection? ClientStats { get; set; } public DateTimeOffset MatchStartDate { get; set; } = DateTimeOffset.UtcNow;