update zombie models

This commit is contained in:
RaidMax 2023-05-07 14:18:59 -05:00
parent 0d6aaa1d9d
commit 7d67a3dfc9
11 changed files with 148 additions and 2151 deletions

View File

@ -56,7 +56,8 @@ namespace Data.Context
public DbSet<ZombieMatchClientStat> ZombieMatchClientStats { get; set; } public DbSet<ZombieMatchClientStat> ZombieMatchClientStats { get; set; }
public DbSet<ZombieRoundClientStat> ZombieRoundClientStats { get; set; } public DbSet<ZombieRoundClientStat> ZombieRoundClientStats { get; set; }
public DbSet<ZombieAggregateClientStat> ZombieClientStatAggregates { get; set; } public DbSet<ZombieAggregateClientStat> ZombieClientStatAggregates { get; set; }
public DbSet<ZombieClientStatRecord> ZombieClientStatRecords { get; set; }
#endregion #endregion
private void SetAuditColumns() private void SetAuditColumns()
@ -173,6 +174,7 @@ namespace Data.Context
modelBuilder.Entity(typeof(ZombieRoundClientStat)).ToTable($"EF{nameof(ZombieRoundClientStat)}"); modelBuilder.Entity(typeof(ZombieRoundClientStat)).ToTable($"EF{nameof(ZombieRoundClientStat)}");
modelBuilder.Entity(typeof(ZombieAggregateClientStat)).ToTable($"EF{nameof(ZombieAggregateClientStat)}"); modelBuilder.Entity(typeof(ZombieAggregateClientStat)).ToTable($"EF{nameof(ZombieAggregateClientStat)}");
modelBuilder.Entity(typeof(ZombieClientStat)).ToTable($"EF{nameof(ZombieClientStat)}"); modelBuilder.Entity(typeof(ZombieClientStat)).ToTable($"EF{nameof(ZombieClientStat)}");
modelBuilder.Entity(typeof(ZombieClientStatRecord)).ToTable($"EF{nameof(ZombieClientStatRecord)}");
Models.Configuration.StatsModelConfiguration.Configure(modelBuilder); Models.Configuration.StatsModelConfiguration.Configure(modelBuilder);

File diff suppressed because it is too large Load Diff

View File

@ -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<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
MapId = table.Column<int>(type: "INTEGER", nullable: true),
ServerId = table.Column<long>(type: "INTEGER", nullable: true),
MatchStartDate = table.Column<DateTimeOffset>(type: "TEXT", nullable: false),
MatchEndDate = table.Column<DateTimeOffset>(type: "TEXT", nullable: true),
EFClientClientId = table.Column<int>(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<long>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
MatchId = table.Column<int>(type: "INTEGER", nullable: true),
ClientId = table.Column<int>(type: "INTEGER", nullable: false),
Kills = table.Column<int>(type: "INTEGER", nullable: false),
Deaths = table.Column<int>(type: "INTEGER", nullable: false),
DamageDealt = table.Column<int>(type: "INTEGER", nullable: false),
DamageReceived = table.Column<int>(type: "INTEGER", nullable: false),
Headshots = table.Column<int>(type: "INTEGER", nullable: false),
Melees = table.Column<int>(type: "INTEGER", nullable: false),
Downs = table.Column<int>(type: "INTEGER", nullable: false),
Revives = table.Column<int>(type: "INTEGER", nullable: false),
PointsEarned = table.Column<int>(type: "INTEGER", nullable: false),
PointsSpent = table.Column<int>(type: "INTEGER", nullable: false),
PerksConsumed = table.Column<int>(type: "INTEGER", nullable: false),
PowerupsGrabbed = table.Column<int>(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<long>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
AverageKillsPerDown = table.Column<double>(type: "REAL", nullable: false),
AverageDowns = table.Column<double>(type: "REAL", nullable: false),
AverageRevives = table.Column<double>(type: "REAL", nullable: false),
HeadshotPercentage = table.Column<double>(type: "REAL", nullable: false),
AlivePercentage = table.Column<double>(type: "REAL", nullable: false),
AverageMelees = table.Column<double>(type: "REAL", nullable: false),
AverageRoundReached = table.Column<double>(type: "REAL", nullable: false),
AveragePoints = table.Column<double>(type: "REAL", nullable: false),
HighestRound = table.Column<int>(type: "INTEGER", nullable: false),
TotalRoundsPlayed = table.Column<int>(type: "INTEGER", nullable: false),
TotalMatchesPlayed = table.Column<int>(type: "INTEGER", nullable: false),
RankingMetric = table.Column<double>(type: "REAL", nullable: false),
EFClientClientId = table.Column<int>(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<long>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
EFClientClientId = table.Column<int>(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<long>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
StartTime = table.Column<DateTimeOffset>(type: "TEXT", nullable: false),
EndTime = table.Column<DateTimeOffset>(type: "TEXT", nullable: true),
Duration = table.Column<TimeSpan>(type: "TEXT", nullable: true),
TimeAlive = table.Column<TimeSpan>(type: "TEXT", nullable: true),
RoundNumber = table.Column<int>(type: "INTEGER", nullable: false),
Points = table.Column<int>(type: "INTEGER", nullable: false),
EFClientClientId = table.Column<int>(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");
}
}
}

View File

@ -438,6 +438,9 @@ namespace Data.Migrations.Sqlite
b.Property<bool>("Newest") b.Property<bool>("Newest")
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
b.Property<string>("PerformanceBucket")
.HasColumnType("TEXT");
b.Property<double?>("PerformanceMetric") b.Property<double?>("PerformanceMetric")
.HasColumnType("REAL"); .HasColumnType("REAL");
@ -1072,6 +1075,9 @@ namespace Data.Migrations.Sqlite
b.Property<bool>("IsPasswordProtected") b.Property<bool>("IsPasswordProtected")
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
b.Property<string>("PerformanceBucket")
.HasColumnType("TEXT");
b.Property<int>("Port") b.Property<int>("Port")
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
@ -1170,6 +1176,9 @@ namespace Data.Migrations.Sqlite
b.Property<int>("ClientId") b.Property<int>("ClientId")
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
b.Property<DateTimeOffset>("CreatedDateTime")
.HasColumnType("TEXT");
b.Property<int>("DamageDealt") b.Property<int>("DamageDealt")
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
@ -1197,10 +1206,10 @@ namespace Data.Migrations.Sqlite
b.Property<int>("PerksConsumed") b.Property<int>("PerksConsumed")
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
b.Property<int>("PointsEarned") b.Property<long>("PointsEarned")
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
b.Property<int>("PointsSpent") b.Property<long>("PointsSpent")
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
b.Property<int>("PowerupsGrabbed") b.Property<int>("PowerupsGrabbed")
@ -1209,6 +1218,9 @@ namespace Data.Migrations.Sqlite
b.Property<int>("Revives") b.Property<int>("Revives")
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
b.Property<DateTimeOffset?>("UpdatedDateTime")
.HasColumnType("TEXT");
b.HasKey("ZombieClientStatId"); b.HasKey("ZombieClientStatId");
b.HasIndex("ClientId"); b.HasIndex("ClientId");
@ -1218,12 +1230,57 @@ namespace Data.Migrations.Sqlite
b.ToTable("EFZombieClientStat", (string)null); b.ToTable("EFZombieClientStat", (string)null);
}); });
modelBuilder.Entity("Data.Models.Zombie.ZombieClientStatRecord", b =>
{
b.Property<int>("ZombieClientStatRecordId")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int?>("ClientId")
.HasColumnType("INTEGER");
b.Property<DateTimeOffset>("CreatedDateTime")
.HasColumnType("TEXT");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("TEXT");
b.Property<long?>("RoundId")
.HasColumnType("INTEGER");
b.Property<string>("Type")
.IsRequired()
.HasColumnType("TEXT");
b.Property<DateTimeOffset?>("UpdatedDateTime")
.HasColumnType("TEXT");
b.Property<string>("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 => modelBuilder.Entity("Data.Models.Zombie.ZombieMatch", b =>
{ {
b.Property<int>("ZombieMatchId") b.Property<int>("ZombieMatchId")
.ValueGeneratedOnAdd() .ValueGeneratedOnAdd()
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
b.Property<int>("ClientsCompleted")
.HasColumnType("INTEGER");
b.Property<DateTimeOffset>("CreatedDateTime")
.HasColumnType("TEXT");
b.Property<int?>("EFClientClientId") b.Property<int?>("EFClientClientId")
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
@ -1239,6 +1296,9 @@ namespace Data.Migrations.Sqlite
b.Property<long?>("ServerId") b.Property<long?>("ServerId")
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
b.Property<DateTimeOffset?>("UpdatedDateTime")
.HasColumnType("TEXT");
b.HasKey("ZombieMatchId"); b.HasKey("ZombieMatchId");
b.HasIndex("EFClientClientId"); b.HasIndex("EFClientClientId");
@ -1284,8 +1344,8 @@ namespace Data.Migrations.Sqlite
b.Property<int>("HighestRound") b.Property<int>("HighestRound")
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
b.Property<double>("RankingMetric") b.Property<int>("TotalMatchesCompleted")
.HasColumnType("REAL"); .HasColumnType("INTEGER");
b.Property<int>("TotalMatchesPlayed") b.Property<int>("TotalMatchesPlayed")
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
@ -1798,6 +1858,21 @@ namespace Data.Migrations.Sqlite
b.Navigation("Match"); 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 => modelBuilder.Entity("Data.Models.Zombie.ZombieMatch", b =>
{ {
b.HasOne("Data.Models.Client.EFClient", null) b.HasOne("Data.Models.Client.EFClient", null)

View File

@ -25,5 +25,6 @@ namespace Data.Models.Client.Stats
public int? Ranking { get; set; } public int? Ranking { get; set; }
public double? ZScore { get; set; } public double? ZScore { get; set; }
public double? PerformanceMetric { get; set; } public double? PerformanceMetric { get; set; }
public string PerformanceBucket { get; set; }
} }
} }

View File

@ -0,0 +1,9 @@
using System;
namespace Data.Models;
public class DatedRecord
{
public DateTimeOffset CreatedDateTime { get; set; } = DateTimeOffset.UtcNow;
public DateTimeOffset? UpdatedDateTime { get; set; }
}

View File

@ -15,6 +15,7 @@ namespace Data.Models.Server
public Reference.Game? GameName { get; set; } public Reference.Game? GameName { get; set; }
public string HostName { get; set; } public string HostName { get; set; }
public bool IsPasswordProtected { get; set; } public bool IsPasswordProtected { get; set; }
public string PerformanceBucket { get; set; }
public long Id => ServerId; public long Id => ServerId;
public string Value => EndPoint; public string Value => EndPoint;
} }

View File

@ -1,4 +1,6 @@
namespace Data.Models.Zombie; using System.ComponentModel.DataAnnotations.Schema;
namespace Data.Models.Zombie;
public class ZombieAggregateClientStat : ZombieClientStat public class ZombieAggregateClientStat : ZombieClientStat
{ {
@ -20,8 +22,23 @@ public class ZombieAggregateClientStat : ZombieClientStat
public int HighestRound { get; set; } public int HighestRound { get; set; }
public int TotalRoundsPlayed { get; set; } public int TotalRoundsPlayed { get; set; }
public int TotalMatchesPlayed { get; set; } public int TotalMatchesPlayed { get; set; }
public int TotalMatchesCompleted { get; set; }
#endregion #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)
};
} }

View File

@ -5,7 +5,7 @@ using Data.Models.Client;
namespace Data.Models.Zombie; namespace Data.Models.Zombie;
public abstract class ZombieClientStat public abstract class ZombieClientStat : DatedRecord
{ {
[Key] [Key]
public long ZombieClientStatId { get; set; } public long ZombieClientStatId { get; set; }
@ -27,8 +27,8 @@ public abstract class ZombieClientStat
public int Melees { get; set; } public int Melees { get; set; }
public int Downs { get; set; } public int Downs { get; set; }
public int Revives { get; set; } public int Revives { get; set; }
public int PointsEarned { get; set; } public long PointsEarned { get; set; }
public int PointsSpent { get; set; } public long PointsSpent { get; set; }
public int PerksConsumed { get; set; } public int PerksConsumed { get; set; }
public int PowerupsGrabbed { get; set; } public int PowerupsGrabbed { get; set; }
} }

View File

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

View File

@ -8,7 +8,7 @@ using Data.Models.Server;
namespace Data.Models.Zombie; namespace Data.Models.Zombie;
public class ZombieMatch public class ZombieMatch : DatedRecord
{ {
[Key] [Key]
public int ZombieMatchId { get; set; } public int ZombieMatchId { get; set; }
@ -21,6 +21,8 @@ public class ZombieMatch
[ForeignKey(nameof(ServerId))] [ForeignKey(nameof(ServerId))]
public virtual EFServer? Server { get; set; } public virtual EFServer? Server { get; set; }
public int ClientsCompleted { get; set; }
public virtual ICollection<ZombieClientStat>? ClientStats { get; set; } public virtual ICollection<ZombieClientStat>? ClientStats { get; set; }
public DateTimeOffset MatchStartDate { get; set; } = DateTimeOffset.UtcNow; public DateTimeOffset MatchStartDate { get; set; } = DateTimeOffset.UtcNow;