diff --git a/src/MysqlMigrations/Migrations/20240721150411_ArcadeReplayDsPlayers.Designer.cs b/src/MysqlMigrations/Migrations/20240721150411_ArcadeReplayDsPlayers.Designer.cs new file mode 100644 index 00000000..df477ef4 --- /dev/null +++ b/src/MysqlMigrations/Migrations/20240721150411_ArcadeReplayDsPlayers.Designer.cs @@ -0,0 +1,2463 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using dsstats.db8; + +#nullable disable + +namespace MysqlMigrations.Migrations +{ + [DbContext(typeof(ReplayContext))] + [Migration("20240721150411_ArcadeReplayDsPlayers")] + partial class ArcadeReplayDsPlayers + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.7") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder); + + modelBuilder.Entity("DsAbilityDsUnit", b => + { + b.Property("AbilitiesDsAbilityId") + .HasColumnType("int"); + + b.Property("DsUnitsDsUnitId") + .HasColumnType("int"); + + b.HasKey("AbilitiesDsAbilityId", "DsUnitsDsUnitId"); + + b.HasIndex("DsUnitsDsUnitId"); + + b.ToTable("DsAbilityDsUnit"); + }); + + modelBuilder.Entity("ReplayUploader", b => + { + b.Property("ReplaysReplayId") + .HasColumnType("int"); + + b.Property("UploadersUploaderId") + .HasColumnType("int"); + + b.HasKey("ReplaysReplayId", "UploadersUploaderId"); + + b.HasIndex("UploadersUploaderId"); + + b.ToTable("UploaderReplays", (string)null); + }); + + modelBuilder.Entity("dsstats.db8.ArcadePlayer", b => + { + b.Property("ArcadePlayerId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("ArcadePlayerId")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.Property("ProfileId") + .HasColumnType("int"); + + b.Property("RealmId") + .HasColumnType("int"); + + b.Property("RegionId") + .HasColumnType("int"); + + b.HasKey("ArcadePlayerId"); + + b.HasIndex("Name"); + + b.HasIndex("RegionId", "RealmId", "ProfileId") + .IsUnique(); + + b.ToTable("ArcadePlayers"); + }); + + modelBuilder.Entity("dsstats.db8.ArcadePlayerRating", b => + { + b.Property("ArcadePlayerRatingId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("ArcadePlayerRatingId")); + + b.Property("Confidence") + .HasColumnType("double"); + + b.Property("Consistency") + .HasColumnType("double"); + + b.Property("Games") + .HasColumnType("int"); + + b.Property("IsUploader") + .HasColumnType("tinyint(1)"); + + b.Property("Main") + .HasColumnType("int"); + + b.Property("MainCount") + .HasColumnType("int"); + + b.Property("Mvp") + .HasColumnType("int"); + + b.Property("PlayerId") + .HasColumnType("int"); + + b.Property("Pos") + .HasColumnType("int"); + + b.Property("Rating") + .HasColumnType("double"); + + b.Property("RatingType") + .HasColumnType("int"); + + b.Property("TeamGames") + .HasColumnType("int"); + + b.Property("Wins") + .HasColumnType("int"); + + b.HasKey("ArcadePlayerRatingId"); + + b.HasIndex("PlayerId"); + + b.HasIndex("RatingType"); + + b.ToTable("ArcadePlayerRatings"); + }); + + modelBuilder.Entity("dsstats.db8.ArcadePlayerRatingChange", b => + { + b.Property("ArcadePlayerRatingChangeId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("ArcadePlayerRatingChangeId")); + + b.Property("ArcadePlayerRatingId") + .HasColumnType("int"); + + b.Property("Change10d") + .HasColumnType("float"); + + b.Property("Change24h") + .HasColumnType("float"); + + b.Property("Change30d") + .HasColumnType("float"); + + b.HasKey("ArcadePlayerRatingChangeId"); + + b.HasIndex("ArcadePlayerRatingId") + .IsUnique(); + + b.ToTable("ArcadePlayerRatingChanges"); + }); + + modelBuilder.Entity("dsstats.db8.ArcadeReplay", b => + { + b.Property("ArcadeReplayId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("ArcadeReplayId")); + + b.Property("BnetBucketId") + .HasColumnType("bigint"); + + b.Property("BnetRecordId") + .HasColumnType("bigint"); + + b.Property("CreatedAt") + .HasPrecision(0) + .HasColumnType("datetime(0)"); + + b.Property("Duration") + .HasColumnType("int"); + + b.Property("GameMode") + .HasColumnType("int"); + + b.Property("Imported") + .HasPrecision(0) + .HasColumnType("datetime(0)"); + + b.Property("PlayerCount") + .HasColumnType("int"); + + b.Property("RegionId") + .HasColumnType("int"); + + b.Property("ReplayHash") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("varchar(64)"); + + b.Property("TournamentEdition") + .HasColumnType("tinyint(1)"); + + b.Property("WinnerTeam") + .HasColumnType("int"); + + b.HasKey("ArcadeReplayId"); + + b.HasIndex("ReplayHash"); + + b.HasIndex("GameMode", "CreatedAt"); + + b.HasIndex("RegionId", "BnetBucketId", "BnetRecordId") + .IsUnique(); + + b.HasIndex("RegionId", "GameMode", "CreatedAt"); + + b.ToTable("ArcadeReplays"); + }); + + modelBuilder.Entity("dsstats.db8.ArcadeReplayDsPlayer", b => + { + b.Property("ArcadeReplayDsPlayerId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("ArcadeReplayDsPlayerId")); + + b.Property("ArcadeReplayId") + .HasColumnType("int"); + + b.Property("Discriminator") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.Property("PlayerId") + .HasColumnType("int"); + + b.Property("PlayerResult") + .HasColumnType("int"); + + b.Property("SlotNumber") + .HasColumnType("int"); + + b.Property("Team") + .HasColumnType("int"); + + b.HasKey("ArcadeReplayDsPlayerId"); + + b.HasIndex("ArcadeReplayId"); + + b.HasIndex("PlayerId"); + + b.ToTable("ArcadeReplayDsPlayers"); + }); + + modelBuilder.Entity("dsstats.db8.ArcadeReplayDsPlayerRating", b => + { + b.Property("ArcadeReplayDsPlayerRatingId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("ArcadeReplayDsPlayerRatingId")); + + b.Property("ArcadeReplayDsPlayerId") + .HasColumnType("int"); + + b.Property("ArcadeReplayRatingId") + .HasColumnType("int"); + + b.Property("Confidence") + .HasColumnType("float"); + + b.Property("Consistency") + .HasColumnType("float"); + + b.Property("GamePos") + .HasColumnType("int"); + + b.Property("Games") + .HasColumnType("int"); + + b.Property("Rating") + .HasColumnType("float"); + + b.Property("RatingChange") + .HasColumnType("float"); + + b.HasKey("ArcadeReplayDsPlayerRatingId"); + + b.HasIndex("ArcadeReplayDsPlayerId") + .IsUnique(); + + b.HasIndex("ArcadeReplayRatingId"); + + b.ToTable("ArcadeReplayDsPlayerRatings"); + }); + + modelBuilder.Entity("dsstats.db8.ArcadeReplayPlayer", b => + { + b.Property("ArcadeReplayPlayerId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("ArcadeReplayPlayerId")); + + b.Property("ArcadePlayerId") + .HasColumnType("int"); + + b.Property("ArcadeReplayId") + .HasColumnType("int"); + + b.Property("Discriminator") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.Property("PlayerResult") + .HasColumnType("int"); + + b.Property("SlotNumber") + .HasColumnType("int"); + + b.Property("Team") + .HasColumnType("int"); + + b.HasKey("ArcadeReplayPlayerId"); + + b.HasIndex("ArcadePlayerId"); + + b.HasIndex("ArcadeReplayId"); + + b.ToTable("ArcadeReplayPlayers"); + }); + + modelBuilder.Entity("dsstats.db8.ArcadeReplayRating", b => + { + b.Property("ArcadeReplayRatingId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("ArcadeReplayRatingId")); + + b.Property("ArcadeReplayId") + .HasColumnType("int"); + + b.Property("AvgRating") + .HasColumnType("int"); + + b.Property("ExpectationToWin") + .HasColumnType("float"); + + b.Property("LeaverType") + .HasColumnType("int"); + + b.Property("RatingType") + .HasColumnType("int"); + + b.HasKey("ArcadeReplayRatingId"); + + b.HasIndex("ArcadeReplayId") + .IsUnique(); + + b.ToTable("ArcadeReplayRatings"); + }); + + modelBuilder.Entity("dsstats.db8.BattleNetInfo", b => + { + b.Property("BattleNetInfoId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("BattleNetInfoId")); + + b.Property("BattleNetId") + .HasColumnType("int"); + + b.Property("UploaderId") + .HasColumnType("int"); + + b.HasKey("BattleNetInfoId"); + + b.HasIndex("UploaderId"); + + b.ToTable("BattleNetInfos"); + }); + + modelBuilder.Entity("dsstats.db8.BonusDamage", b => + { + b.Property("BonusDamageId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("BonusDamageId")); + + b.Property("Damage") + .HasColumnType("int"); + + b.Property("DsWeaponId") + .HasColumnType("int"); + + b.Property("PerUpgrade") + .HasColumnType("int"); + + b.Property("UnitType") + .HasColumnType("int"); + + b.HasKey("BonusDamageId"); + + b.HasIndex("DsWeaponId"); + + b.HasIndex("UnitType"); + + b.ToTable("BonusDamages"); + }); + + modelBuilder.Entity("dsstats.db8.ComboPlayerRating", b => + { + b.Property("ComboPlayerRatingId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("ComboPlayerRatingId")); + + b.Property("Confidence") + .HasColumnType("double"); + + b.Property("Consistency") + .HasColumnType("double"); + + b.Property("Games") + .HasColumnType("int"); + + b.Property("PlayerId") + .HasColumnType("int"); + + b.Property("Pos") + .HasColumnType("int"); + + b.Property("Rating") + .HasColumnType("double"); + + b.Property("RatingType") + .HasColumnType("int"); + + b.Property("Wins") + .HasColumnType("int"); + + b.HasKey("ComboPlayerRatingId"); + + b.HasIndex("PlayerId"); + + b.HasIndex("RatingType"); + + b.ToTable("ComboPlayerRatings"); + }); + + modelBuilder.Entity("dsstats.db8.ComboReplayPlayerRating", b => + { + b.Property("ComboReplayPlayerRatingId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("ComboReplayPlayerRatingId")); + + b.Property("Change") + .HasPrecision(5, 2) + .HasColumnType("double"); + + b.Property("Confidence") + .HasPrecision(5, 2) + .HasColumnType("double"); + + b.Property("Consistency") + .HasPrecision(5, 2) + .HasColumnType("double"); + + b.Property("GamePos") + .HasColumnType("int"); + + b.Property("Games") + .HasColumnType("int"); + + b.Property("Rating") + .HasColumnType("int"); + + b.Property("ReplayPlayerId") + .HasColumnType("int"); + + b.HasKey("ComboReplayPlayerRatingId"); + + b.HasIndex("ReplayPlayerId") + .IsUnique(); + + b.ToTable("ComboReplayPlayerRatings"); + }); + + modelBuilder.Entity("dsstats.db8.ComboReplayRating", b => + { + b.Property("ComboReplayRatingId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("ComboReplayRatingId")); + + b.Property("AvgRating") + .HasColumnType("int"); + + b.Property("ExpectationToWin") + .HasPrecision(5, 2) + .HasColumnType("double"); + + b.Property("IsPreRating") + .HasColumnType("tinyint(1)"); + + b.Property("LeaverType") + .HasColumnType("int"); + + b.Property("RatingType") + .HasColumnType("int"); + + b.Property("ReplayId") + .HasColumnType("int"); + + b.HasKey("ComboReplayRatingId"); + + b.HasIndex("RatingType"); + + b.HasIndex("ReplayId") + .IsUnique(); + + b.ToTable("ComboReplayRatings"); + }); + + modelBuilder.Entity("dsstats.db8.CommanderMmr", b => + { + b.Property("CommanderMmrId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("CommanderMmrId")); + + b.Property("AntiSynergyMmr") + .HasColumnType("double"); + + b.Property("OppRace") + .HasColumnType("int"); + + b.Property("Race") + .HasColumnType("int"); + + b.Property("SynergyMmr") + .HasColumnType("double"); + + b.HasKey("CommanderMmrId"); + + b.HasIndex("Race", "OppRace"); + + b.ToTable("CommanderMmrs"); + }); + + modelBuilder.Entity("dsstats.db8.DsAbility", b => + { + b.Property("DsAbilityId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("DsAbilityId")); + + b.Property("AbilityTarget") + .HasColumnType("int"); + + b.Property("AoeRadius") + .HasColumnType("float"); + + b.Property("CastRange") + .HasColumnType("int"); + + b.Property("Commander") + .HasColumnType("int"); + + b.Property("Cooldown") + .HasColumnType("int"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(310) + .HasColumnType("varchar(310)"); + + b.Property("EnergyCost") + .HasColumnType("float"); + + b.Property("GlobalTimer") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("varchar(100)"); + + b.Property("Requirements") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("varchar(100)"); + + b.HasKey("DsAbilityId"); + + b.HasIndex("Name"); + + b.ToTable("DsAbilities"); + }); + + modelBuilder.Entity("dsstats.db8.DsPickBan", b => + { + b.Property("DsPickBanId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("DsPickBanId")); + + b.Property("Bans") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("PickBanMode") + .HasColumnType("int"); + + b.Property("Picks") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Time") + .HasPrecision(0) + .HasColumnType("datetime(0)"); + + b.HasKey("DsPickBanId"); + + b.ToTable("DsPickBans"); + }); + + modelBuilder.Entity("dsstats.db8.DsUnit", b => + { + b.Property("DsUnitId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("DsUnitId")); + + b.Property("Armor") + .HasColumnType("int"); + + b.Property("Color") + .HasColumnType("int"); + + b.Property("Commander") + .HasColumnType("int"); + + b.Property("Cost") + .HasColumnType("int"); + + b.Property("EnergyRegen") + .HasColumnType("float"); + + b.Property("HealthRegen") + .HasColumnType("float"); + + b.Property("Life") + .HasColumnType("int"); + + b.Property("MaxEnergy") + .HasColumnType("int"); + + b.Property("MovementType") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("varchar(100)"); + + b.Property("ShieldArmor") + .HasColumnType("int"); + + b.Property("Shields") + .HasColumnType("int"); + + b.Property("Size") + .HasColumnType("int"); + + b.Property("Speed") + .HasColumnType("float"); + + b.Property("StartingEnergy") + .HasColumnType("int"); + + b.Property("Tier") + .HasColumnType("int"); + + b.Property("UnitId") + .HasColumnType("int"); + + b.Property("UnitType") + .HasColumnType("int"); + + b.HasKey("DsUnitId"); + + b.HasIndex("Commander"); + + b.HasIndex("Name"); + + b.HasIndex("Name", "Commander"); + + b.ToTable("DsUnits"); + }); + + modelBuilder.Entity("dsstats.db8.DsUpdate", b => + { + b.Property("DsUpdateId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("DsUpdateId")); + + b.Property("Change") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Commander") + .HasColumnType("int"); + + b.Property("DiscordId") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Time") + .HasPrecision(0) + .HasColumnType("datetime(0)"); + + b.HasKey("DsUpdateId"); + + b.HasIndex("Time"); + + b.ToTable("DsUpdates"); + }); + + modelBuilder.Entity("dsstats.db8.DsUpgrade", b => + { + b.Property("DsUpgradeId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("DsUpgradeId")); + + b.Property("Commander") + .HasColumnType("int"); + + b.Property("Cost") + .HasColumnType("int"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(300) + .HasColumnType("varchar(300)"); + + b.Property("DsUnitId") + .HasColumnType("int"); + + b.Property("RequiredTier") + .HasColumnType("int"); + + b.Property("Upgrade") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("varchar(100)"); + + b.HasKey("DsUpgradeId"); + + b.HasIndex("DsUnitId"); + + b.HasIndex("Upgrade"); + + b.ToTable("DsUpgrades"); + }); + + modelBuilder.Entity("dsstats.db8.DsWeapon", b => + { + b.Property("DsWeaponId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("DsWeaponId")); + + b.Property("AttackSpeed") + .HasColumnType("float"); + + b.Property("Attacks") + .HasColumnType("int"); + + b.Property("CanTarget") + .HasColumnType("int"); + + b.Property("Damage") + .HasColumnType("int"); + + b.Property("DamagePerUpgrade") + .HasColumnType("int"); + + b.Property("DsUnitId") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("varchar(100)"); + + b.Property("Range") + .HasColumnType("float"); + + b.HasKey("DsWeaponId"); + + b.HasIndex("DsUnitId"); + + b.ToTable("DsWeapons"); + }); + + modelBuilder.Entity("dsstats.db8.Event", b => + { + b.Property("EventId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("EventId")); + + b.Property("EventGuid") + .HasColumnType("char(36)"); + + b.Property("EventStart") + .HasPrecision(0) + .HasColumnType("datetime(0)"); + + b.Property("GameMode") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.Property("WinnerTeam") + .HasColumnType("longtext"); + + b.HasKey("EventId"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("Events"); + }); + + modelBuilder.Entity("dsstats.db8.Faq", b => + { + b.Property("FaqId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("FaqId")); + + b.Property("Answer") + .IsRequired() + .HasMaxLength(400) + .HasColumnType("varchar(400)"); + + b.Property("CreatedAt") + .HasPrecision(0) + .HasColumnType("datetime(0)"); + + b.Property("CreatedBy") + .HasMaxLength(20) + .HasColumnType("varchar(20)"); + + b.Property("Level") + .HasColumnType("int"); + + b.Property("Question") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("varchar(100)"); + + b.Property("UpdatedAt") + .HasPrecision(0) + .HasColumnType("datetime(0)"); + + b.Property("Upvotes") + .HasColumnType("int"); + + b.HasKey("FaqId"); + + b.HasIndex("Question"); + + b.ToTable("Faqs"); + }); + + modelBuilder.Entity("dsstats.db8.FaqVote", b => + { + b.Property("FaqVoteId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("FaqVoteId")); + + b.Property("FaqId") + .HasColumnType("int"); + + b.HasKey("FaqVoteId"); + + b.ToTable("FaqVotes"); + }); + + modelBuilder.Entity("dsstats.db8.FunStatsMemory", b => + { + b.Property("FunStatsMemoryId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("FunStatsMemoryId")); + + b.Property("AvgGameDuration") + .HasColumnType("int"); + + b.Property("Created") + .HasPrecision(0) + .HasColumnType("datetime(0)"); + + b.Property("FirstReplay") + .HasColumnType("longtext"); + + b.Property("GreatestArmyReplay") + .HasColumnType("longtext"); + + b.Property("GreatestComebackReplay") + .HasColumnType("longtext"); + + b.Property("MostCompetitiveReplay") + .HasColumnType("longtext"); + + b.Property("MostUpgradesReplay") + .HasColumnType("longtext"); + + b.Property("RatingType") + .HasColumnType("int"); + + b.Property("TimePeriod") + .HasColumnType("int"); + + b.Property("TotalTimePlayed") + .HasColumnType("bigint"); + + b.Property("UnitCountLeast") + .HasColumnType("int"); + + b.Property("UnitCountMost") + .HasColumnType("int"); + + b.Property("UnitNameLeast") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("UnitNameMost") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("FunStatsMemoryId"); + + b.ToTable("FunStatMemories"); + }); + + modelBuilder.Entity("dsstats.db8.GroupByHelper", b => + { + b.Property("Count") + .HasColumnType("int"); + + b.Property("Group") + .HasColumnType("tinyint(1)") + .HasColumnName("Name"); + + b.ToTable((string)null); + + b.ToView("GroupByHelper", (string)null); + }); + + modelBuilder.Entity("dsstats.db8.IhSession", b => + { + b.Property("IhSessionId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("IhSessionId")); + + b.Property("Closed") + .HasColumnType("tinyint(1)"); + + b.Property("Created") + .HasPrecision(0) + .HasColumnType("datetime(0)"); + + b.Property("Games") + .HasColumnType("int"); + + b.Property("GroupId") + .HasColumnType("char(36)"); + + b.Property("GroupState") + .HasColumnType("longtext"); + + b.Property("GroupStateV2") + .HasColumnType("longtext"); + + b.Property("Players") + .HasColumnType("int"); + + b.Property("RatingType") + .HasColumnType("int"); + + b.HasKey("IhSessionId"); + + b.HasIndex("GroupId") + .IsUnique(); + + b.ToTable("IhSessions"); + }); + + modelBuilder.Entity("dsstats.db8.IhSessionPlayer", b => + { + b.Property("IhSessionPlayerId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("IhSessionPlayerId")); + + b.Property("Games") + .HasColumnType("int"); + + b.Property("IhSessionId") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Obs") + .HasColumnType("int"); + + b.Property("Performance") + .HasColumnType("int"); + + b.Property("PlayerId") + .HasColumnType("int"); + + b.Property("RatingEnd") + .HasColumnType("int"); + + b.Property("RatingStart") + .HasColumnType("int"); + + b.Property("Wins") + .HasColumnType("int"); + + b.HasKey("IhSessionPlayerId"); + + b.HasIndex("IhSessionId"); + + b.HasIndex("PlayerId"); + + b.ToTable("IhSessionPlayers"); + }); + + modelBuilder.Entity("dsstats.db8.MaterializedArcadeReplay", b => + { + b.Property("MaterializedArcadeReplayId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("MaterializedArcadeReplayId")); + + b.Property("ArcadeReplayId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasPrecision(0) + .HasColumnType("datetime(0)"); + + b.Property("Duration") + .HasColumnType("int"); + + b.Property("GameMode") + .HasColumnType("int"); + + b.Property("WinnerTeam") + .HasColumnType("int"); + + b.HasKey("MaterializedArcadeReplayId"); + + b.HasIndex("CreatedAt"); + + b.ToTable("MaterializedArcadeReplays"); + }); + + modelBuilder.Entity("dsstats.db8.NoUploadResult", b => + { + b.Property("NoUploadResultId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("NoUploadResultId")); + + b.Property("Created") + .HasPrecision(0) + .HasColumnType("datetime(0)"); + + b.Property("LatestNoUpload") + .HasPrecision(0) + .HasColumnType("datetime(0)"); + + b.Property("LatestReplay") + .HasPrecision(0) + .HasColumnType("datetime(0)"); + + b.Property("LatestUpload") + .HasPrecision(0) + .HasColumnType("datetime(0)"); + + b.Property("NoUploadDefeats") + .HasColumnType("int"); + + b.Property("NoUploadTotal") + .HasColumnType("int"); + + b.Property("PlayerId") + .HasColumnType("int"); + + b.Property("TotalReplays") + .HasColumnType("int"); + + b.HasKey("NoUploadResultId"); + + b.HasIndex("PlayerId"); + + b.ToTable("NoUploadResults"); + }); + + modelBuilder.Entity("dsstats.db8.Player", b => + { + b.Property("PlayerId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("PlayerId")); + + b.Property("ArcadeDefeatsSinceLastUpload") + .HasColumnType("int"); + + b.Property("DisconnectCount") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.Property("NotUploadCount") + .HasColumnType("int"); + + b.Property("RageQuitCount") + .HasColumnType("int"); + + b.Property("RealmId") + .HasColumnType("int"); + + b.Property("RegionId") + .HasColumnType("int"); + + b.Property("ToonId") + .HasColumnType("int"); + + b.Property("UploaderId") + .HasColumnType("int"); + + b.HasKey("PlayerId"); + + b.HasIndex("UploaderId"); + + b.HasIndex("RegionId", "RealmId", "ToonId") + .IsUnique(); + + b.ToTable("Players"); + }); + + modelBuilder.Entity("dsstats.db8.PlayerRating", b => + { + b.Property("PlayerRatingId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("PlayerRatingId")); + + b.Property("ArcadeDefeatsSinceLastUpload") + .HasColumnType("int"); + + b.Property("Confidence") + .HasColumnType("double"); + + b.Property("Consistency") + .HasColumnType("double"); + + b.Property("Games") + .HasColumnType("int"); + + b.Property("IsUploader") + .HasColumnType("tinyint(1)"); + + b.Property("Main") + .HasColumnType("int"); + + b.Property("MainCount") + .HasColumnType("int"); + + b.Property("Mvp") + .HasColumnType("int"); + + b.Property("PlayerId") + .HasColumnType("int"); + + b.Property("Pos") + .HasColumnType("int"); + + b.Property("Rating") + .HasColumnType("double"); + + b.Property("RatingType") + .HasColumnType("int"); + + b.Property("TeamGames") + .HasColumnType("int"); + + b.Property("Wins") + .HasColumnType("int"); + + b.HasKey("PlayerRatingId"); + + b.HasIndex("PlayerId"); + + b.HasIndex("RatingType"); + + b.ToTable("PlayerRatings"); + }); + + modelBuilder.Entity("dsstats.db8.PlayerRatingChange", b => + { + b.Property("PlayerRatingChangeId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("PlayerRatingChangeId")); + + b.Property("Change10d") + .HasColumnType("float"); + + b.Property("Change24h") + .HasColumnType("float"); + + b.Property("Change30d") + .HasColumnType("float"); + + b.Property("PlayerRatingId") + .HasColumnType("int"); + + b.HasKey("PlayerRatingChangeId"); + + b.HasIndex("PlayerRatingId") + .IsUnique(); + + b.ToTable("PlayerRatingChanges"); + }); + + modelBuilder.Entity("dsstats.db8.PlayerUpgrade", b => + { + b.Property("PlayerUpgradeId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("PlayerUpgradeId")); + + b.Property("Gameloop") + .HasColumnType("int"); + + b.Property("ReplayPlayerId") + .HasColumnType("int"); + + b.Property("UpgradeId") + .HasColumnType("int"); + + b.HasKey("PlayerUpgradeId"); + + b.HasIndex("ReplayPlayerId"); + + b.HasIndex("UpgradeId"); + + b.ToTable("PlayerUpgrades"); + }); + + modelBuilder.Entity("dsstats.db8.RepPlayerRating", b => + { + b.Property("RepPlayerRatingId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("RepPlayerRatingId")); + + b.Property("Confidence") + .HasColumnType("float"); + + b.Property("Consistency") + .HasColumnType("float"); + + b.Property("GamePos") + .HasColumnType("int"); + + b.Property("Games") + .HasColumnType("int"); + + b.Property("Rating") + .HasColumnType("float"); + + b.Property("RatingChange") + .HasColumnType("float"); + + b.Property("ReplayPlayerId") + .HasColumnType("int"); + + b.Property("ReplayRatingInfoId") + .HasColumnType("int"); + + b.HasKey("RepPlayerRatingId"); + + b.HasIndex("ReplayPlayerId") + .IsUnique(); + + b.HasIndex("ReplayRatingInfoId"); + + b.ToTable("RepPlayerRatings"); + }); + + modelBuilder.Entity("dsstats.db8.Replay", b => + { + b.Property("ReplayId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("ReplayId")); + + b.Property("Bunker") + .HasColumnType("int"); + + b.Property("Cannon") + .HasColumnType("int"); + + b.Property("CommandersTeam1") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("CommandersTeam2") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("DefaultFilter") + .HasColumnType("tinyint(1)"); + + b.Property("Downloads") + .HasColumnType("int"); + + b.Property("Duration") + .HasColumnType("int"); + + b.Property("FileName") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("varchar(500)"); + + b.Property("GameMode") + .HasColumnType("int"); + + b.Property("GameTime") + .HasPrecision(0) + .HasColumnType("datetime(0)"); + + b.Property("Imported") + .HasPrecision(0) + .HasColumnType("datetime(0)"); + + b.Property("Maxkillsum") + .HasColumnType("int"); + + b.Property("Maxleaver") + .HasColumnType("int"); + + b.Property("Middle") + .IsRequired() + .HasMaxLength(4000) + .HasColumnType("varchar(4000)"); + + b.Property("Minarmy") + .HasColumnType("int"); + + b.Property("Minincome") + .HasColumnType("int"); + + b.Property("Minkillsum") + .HasColumnType("int"); + + b.Property("Objective") + .HasColumnType("int"); + + b.Property("PlayerPos") + .HasColumnType("int"); + + b.Property("PlayerResult") + .HasColumnType("int"); + + b.Property("Playercount") + .HasColumnType("tinyint unsigned"); + + b.Property("ReplayEventId") + .HasColumnType("int"); + + b.Property("ReplayHash") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("char(64)") + .IsFixedLength(); + + b.Property("ResultCorrected") + .HasColumnType("tinyint(1)"); + + b.Property("TournamentEdition") + .HasColumnType("tinyint(1)"); + + b.Property("Uploaded") + .HasColumnType("tinyint(1)"); + + b.Property("Views") + .HasColumnType("int"); + + b.Property("WinnerTeam") + .HasColumnType("int"); + + b.HasKey("ReplayId"); + + b.HasIndex("FileName"); + + b.HasIndex("GameTime"); + + b.HasIndex("Imported"); + + b.HasIndex("Maxkillsum"); + + b.HasIndex("ReplayEventId"); + + b.HasIndex("ReplayHash") + .IsUnique(); + + b.HasIndex("GameTime", "GameMode"); + + b.HasIndex("GameTime", "GameMode", "DefaultFilter"); + + b.HasIndex("GameTime", "GameMode", "Maxleaver"); + + b.HasIndex("GameTime", "GameMode", "WinnerTeam"); + + b.ToTable("Replays"); + }); + + modelBuilder.Entity("dsstats.db8.ReplayArcadeMatch", b => + { + b.Property("ReplayArcadeMatchId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("ReplayArcadeMatchId")); + + b.Property("ArcadeReplayId") + .HasColumnType("int"); + + b.Property("MatchTime") + .HasPrecision(0) + .HasColumnType("datetime(0)"); + + b.Property("ReplayId") + .HasColumnType("int"); + + b.HasKey("ReplayArcadeMatchId"); + + b.HasIndex("ArcadeReplayId") + .IsUnique(); + + b.HasIndex("MatchTime"); + + b.HasIndex("ReplayId") + .IsUnique(); + + b.ToTable("ReplayArcadeMatches"); + }); + + modelBuilder.Entity("dsstats.db8.ReplayDownloadCount", b => + { + b.Property("ReplayDownloadCountId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("ReplayDownloadCountId")); + + b.Property("ReplayHash") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("varchar(64)"); + + b.HasKey("ReplayDownloadCountId"); + + b.ToTable("ReplayDownloadCounts"); + }); + + modelBuilder.Entity("dsstats.db8.ReplayEvent", b => + { + b.Property("ReplayEventId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("ReplayEventId")); + + b.Property("Ban1") + .HasColumnType("int"); + + b.Property("Ban2") + .HasColumnType("int"); + + b.Property("Ban3") + .HasColumnType("int"); + + b.Property("Ban4") + .HasColumnType("int"); + + b.Property("Ban5") + .HasColumnType("int"); + + b.Property("EventId") + .HasColumnType("int"); + + b.Property("Round") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.Property("RunnerTeam") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("WinnerTeam") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("ReplayEventId"); + + b.HasIndex("EventId"); + + b.ToTable("ReplayEvents"); + }); + + modelBuilder.Entity("dsstats.db8.ReplayPlayer", b => + { + b.Property("ReplayPlayerId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("ReplayPlayerId")); + + b.Property("APM") + .HasColumnType("int"); + + b.Property("Army") + .HasColumnType("int"); + + b.Property("Clan") + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.Property("DidNotUpload") + .HasColumnType("tinyint(1)"); + + b.Property("Downloads") + .HasColumnType("int"); + + b.Property("Duration") + .HasColumnType("int"); + + b.Property("GamePos") + .HasColumnType("int"); + + b.Property("Income") + .HasColumnType("int"); + + b.Property("IsLeaver") + .HasColumnType("tinyint(1)"); + + b.Property("IsUploader") + .HasColumnType("tinyint(1)"); + + b.Property("Kills") + .HasColumnType("int"); + + b.Property("LastSpawnHash") + .HasMaxLength(64) + .HasColumnType("char(64)") + .IsFixedLength(); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.Property("OppRace") + .HasColumnType("int"); + + b.Property("PlayerId") + .HasColumnType("int"); + + b.Property("PlayerResult") + .HasColumnType("int"); + + b.Property("Race") + .HasColumnType("int"); + + b.Property("Refineries") + .IsRequired() + .HasMaxLength(300) + .HasColumnType("varchar(300)"); + + b.Property("ReplayId") + .HasColumnType("int"); + + b.Property("Team") + .HasColumnType("int"); + + b.Property("TierUpgrades") + .IsRequired() + .HasMaxLength(300) + .HasColumnType("varchar(300)"); + + b.Property("UpgradeId") + .HasColumnType("int"); + + b.Property("UpgradesSpent") + .HasColumnType("int"); + + b.Property("Views") + .HasColumnType("int"); + + b.HasKey("ReplayPlayerId"); + + b.HasIndex("Kills"); + + b.HasIndex("LastSpawnHash") + .IsUnique(); + + b.HasIndex("Name"); + + b.HasIndex("PlayerId"); + + b.HasIndex("Race"); + + b.HasIndex("ReplayId"); + + b.HasIndex("UpgradeId"); + + b.HasIndex("IsUploader", "Team"); + + b.HasIndex("Race", "OppRace"); + + b.ToTable("ReplayPlayers"); + }); + + modelBuilder.Entity("dsstats.db8.ReplayRating", b => + { + b.Property("ReplayRatingId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("ReplayRatingId")); + + b.Property("AvgRating") + .HasColumnType("int"); + + b.Property("ExpectationToWin") + .HasColumnType("float"); + + b.Property("IsPreRating") + .HasColumnType("tinyint(1)"); + + b.Property("LeaverType") + .HasColumnType("int"); + + b.Property("RatingType") + .HasColumnType("int"); + + b.Property("ReplayId") + .HasColumnType("int"); + + b.HasKey("ReplayRatingId"); + + b.HasIndex("RatingType"); + + b.HasIndex("ReplayId") + .IsUnique(); + + b.ToTable("ReplayRatings"); + }); + + modelBuilder.Entity("dsstats.db8.ReplayViewCount", b => + { + b.Property("ReplayViewCountId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("ReplayViewCountId")); + + b.Property("ReplayHash") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("varchar(64)"); + + b.HasKey("ReplayViewCountId"); + + b.ToTable("ReplayViewCounts"); + }); + + modelBuilder.Entity("dsstats.db8.SkipReplay", b => + { + b.Property("SkipReplayId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("SkipReplayId")); + + b.Property("Path") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("varchar(500)"); + + b.HasKey("SkipReplayId"); + + b.ToTable("SkipReplays"); + }); + + modelBuilder.Entity("dsstats.db8.Spawn", b => + { + b.Property("SpawnId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("SpawnId")); + + b.Property("ArmyValue") + .HasColumnType("int"); + + b.Property("Breakpoint") + .HasColumnType("int"); + + b.Property("Gameloop") + .HasColumnType("int"); + + b.Property("GasCount") + .HasColumnType("int"); + + b.Property("Income") + .HasColumnType("int"); + + b.Property("KilledValue") + .HasColumnType("int"); + + b.Property("ReplayPlayerId") + .HasColumnType("int"); + + b.Property("UpgradeSpent") + .HasColumnType("int"); + + b.HasKey("SpawnId"); + + b.HasIndex("ReplayPlayerId"); + + b.ToTable("Spawns"); + }); + + modelBuilder.Entity("dsstats.db8.SpawnUnit", b => + { + b.Property("SpawnUnitId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("SpawnUnitId")); + + b.Property("Count") + .HasColumnType("tinyint unsigned"); + + b.Property("Poss") + .IsRequired() + .HasMaxLength(4000) + .HasColumnType("varchar(4000)"); + + b.Property("SpawnId") + .HasColumnType("int"); + + b.Property("UnitId") + .HasColumnType("int"); + + b.HasKey("SpawnUnitId"); + + b.HasIndex("SpawnId"); + + b.HasIndex("UnitId"); + + b.ToTable("SpawnUnits"); + }); + + modelBuilder.Entity("dsstats.db8.StreakInfo", b => + { + b.Property("LongestStreak") + .HasColumnType("double"); + + b.Property("PlayerResult") + .HasColumnType("int"); + + b.ToTable("StreakInfos"); + }); + + modelBuilder.Entity("dsstats.db8.Unit", b => + { + b.Property("UnitId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("UnitId")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.HasKey("UnitId"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("Units"); + }); + + modelBuilder.Entity("dsstats.db8.Upgrade", b => + { + b.Property("UpgradeId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("UpgradeId")); + + b.Property("Cost") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.HasKey("UpgradeId"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("Upgrades"); + }); + + modelBuilder.Entity("dsstats.db8.Uploader", b => + { + b.Property("UploaderId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("UploaderId")); + + b.Property("AppGuid") + .HasColumnType("char(36)"); + + b.Property("AppVersion") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Games") + .HasColumnType("int"); + + b.Property("Identifier") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("IsDeleted") + .HasColumnType("tinyint(1)"); + + b.Property("LatestReplay") + .HasPrecision(0) + .HasColumnType("datetime(0)"); + + b.Property("LatestUpload") + .HasPrecision(0) + .HasColumnType("datetime(0)"); + + b.Property("MainCommander") + .HasColumnType("int"); + + b.Property("MainCount") + .HasColumnType("int"); + + b.Property("Mvp") + .HasColumnType("int"); + + b.Property("TeamGames") + .HasColumnType("int"); + + b.Property("UploadDisabledCount") + .HasColumnType("int"); + + b.Property("UploadIsDisabled") + .HasColumnType("tinyint(1)"); + + b.Property("UploadLastDisabled") + .HasPrecision(0) + .HasColumnType("datetime(0)"); + + b.Property("Wins") + .HasColumnType("int"); + + b.HasKey("UploaderId"); + + b.HasIndex("AppGuid") + .IsUnique(); + + b.ToTable("Uploaders"); + }); + + modelBuilder.Entity("DsAbilityDsUnit", b => + { + b.HasOne("dsstats.db8.DsAbility", null) + .WithMany() + .HasForeignKey("AbilitiesDsAbilityId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("dsstats.db8.DsUnit", null) + .WithMany() + .HasForeignKey("DsUnitsDsUnitId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ReplayUploader", b => + { + b.HasOne("dsstats.db8.Replay", null) + .WithMany() + .HasForeignKey("ReplaysReplayId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("dsstats.db8.Uploader", null) + .WithMany() + .HasForeignKey("UploadersUploaderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("dsstats.db8.ArcadePlayerRating", b => + { + b.HasOne("dsstats.db8.Player", "Player") + .WithMany("ArcadePlayerRatings") + .HasForeignKey("PlayerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Player"); + }); + + modelBuilder.Entity("dsstats.db8.ArcadePlayerRatingChange", b => + { + b.HasOne("dsstats.db8.ArcadePlayerRating", "ArcadePlayerRating") + .WithOne("ArcadePlayerRatingChange") + .HasForeignKey("dsstats.db8.ArcadePlayerRatingChange", "ArcadePlayerRatingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ArcadePlayerRating"); + }); + + modelBuilder.Entity("dsstats.db8.ArcadeReplayDsPlayer", b => + { + b.HasOne("dsstats.db8.ArcadeReplay", "ArcadeReplay") + .WithMany("ArcadeReplayDsPlayers") + .HasForeignKey("ArcadeReplayId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("dsstats.db8.Player", "Player") + .WithMany() + .HasForeignKey("PlayerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ArcadeReplay"); + + b.Navigation("Player"); + }); + + modelBuilder.Entity("dsstats.db8.ArcadeReplayDsPlayerRating", b => + { + b.HasOne("dsstats.db8.ArcadeReplayDsPlayer", "ReplayDsPlayer") + .WithOne("ArcadeReplayPlayerRating") + .HasForeignKey("dsstats.db8.ArcadeReplayDsPlayerRating", "ArcadeReplayDsPlayerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("dsstats.db8.ArcadeReplayRating", "ArcadeReplayRating") + .WithMany("ArcadeReplayDsPlayerRatings") + .HasForeignKey("ArcadeReplayRatingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ArcadeReplayRating"); + + b.Navigation("ReplayDsPlayer"); + }); + + modelBuilder.Entity("dsstats.db8.ArcadeReplayPlayer", b => + { + b.HasOne("dsstats.db8.ArcadePlayer", "ArcadePlayer") + .WithMany("ArcadeReplayPlayers") + .HasForeignKey("ArcadePlayerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("dsstats.db8.ArcadeReplay", "ArcadeReplay") + .WithMany("ArcadeReplayPlayers") + .HasForeignKey("ArcadeReplayId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ArcadePlayer"); + + b.Navigation("ArcadeReplay"); + }); + + modelBuilder.Entity("dsstats.db8.ArcadeReplayRating", b => + { + b.HasOne("dsstats.db8.ArcadeReplay", "ArcadeReplay") + .WithOne("ArcadeReplayRating") + .HasForeignKey("dsstats.db8.ArcadeReplayRating", "ArcadeReplayId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ArcadeReplay"); + }); + + modelBuilder.Entity("dsstats.db8.BattleNetInfo", b => + { + b.HasOne("dsstats.db8.Uploader", "Uploader") + .WithMany("BattleNetInfos") + .HasForeignKey("UploaderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Uploader"); + }); + + modelBuilder.Entity("dsstats.db8.BonusDamage", b => + { + b.HasOne("dsstats.db8.DsWeapon", "DsWeapon") + .WithMany("BonusDamages") + .HasForeignKey("DsWeaponId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("DsWeapon"); + }); + + modelBuilder.Entity("dsstats.db8.ComboPlayerRating", b => + { + b.HasOne("dsstats.db8.Player", "Player") + .WithMany() + .HasForeignKey("PlayerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Player"); + }); + + modelBuilder.Entity("dsstats.db8.ComboReplayPlayerRating", b => + { + b.HasOne("dsstats.db8.ReplayPlayer", "ReplayPlayer") + .WithOne("ComboReplayPlayerRating") + .HasForeignKey("dsstats.db8.ComboReplayPlayerRating", "ReplayPlayerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ReplayPlayer"); + }); + + modelBuilder.Entity("dsstats.db8.ComboReplayRating", b => + { + b.HasOne("dsstats.db8.Replay", "Replay") + .WithOne("ComboReplayRating") + .HasForeignKey("dsstats.db8.ComboReplayRating", "ReplayId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Replay"); + }); + + modelBuilder.Entity("dsstats.db8.DsUpgrade", b => + { + b.HasOne("dsstats.db8.DsUnit", null) + .WithMany("Upgrades") + .HasForeignKey("DsUnitId"); + }); + + modelBuilder.Entity("dsstats.db8.DsWeapon", b => + { + b.HasOne("dsstats.db8.DsUnit", "DsUnit") + .WithMany("Weapons") + .HasForeignKey("DsUnitId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("DsUnit"); + }); + + modelBuilder.Entity("dsstats.db8.IhSessionPlayer", b => + { + b.HasOne("dsstats.db8.IhSession", "IhSession") + .WithMany("IhSessionPlayers") + .HasForeignKey("IhSessionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("dsstats.db8.Player", "Player") + .WithMany() + .HasForeignKey("PlayerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("IhSession"); + + b.Navigation("Player"); + }); + + modelBuilder.Entity("dsstats.db8.NoUploadResult", b => + { + b.HasOne("dsstats.db8.Player", "Player") + .WithMany() + .HasForeignKey("PlayerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Player"); + }); + + modelBuilder.Entity("dsstats.db8.Player", b => + { + b.HasOne("dsstats.db8.Uploader", "Uploader") + .WithMany("Players") + .HasForeignKey("UploaderId"); + + b.Navigation("Uploader"); + }); + + modelBuilder.Entity("dsstats.db8.PlayerRating", b => + { + b.HasOne("dsstats.db8.Player", "Player") + .WithMany("PlayerRatings") + .HasForeignKey("PlayerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Player"); + }); + + modelBuilder.Entity("dsstats.db8.PlayerRatingChange", b => + { + b.HasOne("dsstats.db8.PlayerRating", "PlayerRating") + .WithOne("PlayerRatingChange") + .HasForeignKey("dsstats.db8.PlayerRatingChange", "PlayerRatingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("PlayerRating"); + }); + + modelBuilder.Entity("dsstats.db8.PlayerUpgrade", b => + { + b.HasOne("dsstats.db8.ReplayPlayer", "ReplayPlayer") + .WithMany("Upgrades") + .HasForeignKey("ReplayPlayerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("dsstats.db8.Upgrade", "Upgrade") + .WithMany() + .HasForeignKey("UpgradeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ReplayPlayer"); + + b.Navigation("Upgrade"); + }); + + modelBuilder.Entity("dsstats.db8.RepPlayerRating", b => + { + b.HasOne("dsstats.db8.ReplayPlayer", "ReplayPlayer") + .WithOne("ReplayPlayerRatingInfo") + .HasForeignKey("dsstats.db8.RepPlayerRating", "ReplayPlayerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("dsstats.db8.ReplayRating", "ReplayRatingInfo") + .WithMany("RepPlayerRatings") + .HasForeignKey("ReplayRatingInfoId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ReplayPlayer"); + + b.Navigation("ReplayRatingInfo"); + }); + + modelBuilder.Entity("dsstats.db8.Replay", b => + { + b.HasOne("dsstats.db8.ReplayEvent", "ReplayEvent") + .WithMany("Replays") + .HasForeignKey("ReplayEventId"); + + b.Navigation("ReplayEvent"); + }); + + modelBuilder.Entity("dsstats.db8.ReplayEvent", b => + { + b.HasOne("dsstats.db8.Event", "Event") + .WithMany("ReplayEvents") + .HasForeignKey("EventId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Event"); + }); + + modelBuilder.Entity("dsstats.db8.ReplayPlayer", b => + { + b.HasOne("dsstats.db8.Player", "Player") + .WithMany("ReplayPlayers") + .HasForeignKey("PlayerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("dsstats.db8.Replay", "Replay") + .WithMany("ReplayPlayers") + .HasForeignKey("ReplayId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("dsstats.db8.Upgrade", null) + .WithMany("ReplayPlayers") + .HasForeignKey("UpgradeId"); + + b.Navigation("Player"); + + b.Navigation("Replay"); + }); + + modelBuilder.Entity("dsstats.db8.ReplayRating", b => + { + b.HasOne("dsstats.db8.Replay", "Replay") + .WithOne("ReplayRatingInfo") + .HasForeignKey("dsstats.db8.ReplayRating", "ReplayId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Replay"); + }); + + modelBuilder.Entity("dsstats.db8.Spawn", b => + { + b.HasOne("dsstats.db8.ReplayPlayer", "ReplayPlayer") + .WithMany("Spawns") + .HasForeignKey("ReplayPlayerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ReplayPlayer"); + }); + + modelBuilder.Entity("dsstats.db8.SpawnUnit", b => + { + b.HasOne("dsstats.db8.Spawn", "Spawn") + .WithMany("Units") + .HasForeignKey("SpawnId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("dsstats.db8.Unit", "Unit") + .WithMany() + .HasForeignKey("UnitId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Spawn"); + + b.Navigation("Unit"); + }); + + modelBuilder.Entity("dsstats.db8.ArcadePlayer", b => + { + b.Navigation("ArcadeReplayPlayers"); + }); + + modelBuilder.Entity("dsstats.db8.ArcadePlayerRating", b => + { + b.Navigation("ArcadePlayerRatingChange"); + }); + + modelBuilder.Entity("dsstats.db8.ArcadeReplay", b => + { + b.Navigation("ArcadeReplayDsPlayers"); + + b.Navigation("ArcadeReplayPlayers"); + + b.Navigation("ArcadeReplayRating"); + }); + + modelBuilder.Entity("dsstats.db8.ArcadeReplayDsPlayer", b => + { + b.Navigation("ArcadeReplayPlayerRating"); + }); + + modelBuilder.Entity("dsstats.db8.ArcadeReplayRating", b => + { + b.Navigation("ArcadeReplayDsPlayerRatings"); + }); + + modelBuilder.Entity("dsstats.db8.DsUnit", b => + { + b.Navigation("Upgrades"); + + b.Navigation("Weapons"); + }); + + modelBuilder.Entity("dsstats.db8.DsWeapon", b => + { + b.Navigation("BonusDamages"); + }); + + modelBuilder.Entity("dsstats.db8.Event", b => + { + b.Navigation("ReplayEvents"); + }); + + modelBuilder.Entity("dsstats.db8.IhSession", b => + { + b.Navigation("IhSessionPlayers"); + }); + + modelBuilder.Entity("dsstats.db8.Player", b => + { + b.Navigation("ArcadePlayerRatings"); + + b.Navigation("PlayerRatings"); + + b.Navigation("ReplayPlayers"); + }); + + modelBuilder.Entity("dsstats.db8.PlayerRating", b => + { + b.Navigation("PlayerRatingChange"); + }); + + modelBuilder.Entity("dsstats.db8.Replay", b => + { + b.Navigation("ComboReplayRating"); + + b.Navigation("ReplayPlayers"); + + b.Navigation("ReplayRatingInfo"); + }); + + modelBuilder.Entity("dsstats.db8.ReplayEvent", b => + { + b.Navigation("Replays"); + }); + + modelBuilder.Entity("dsstats.db8.ReplayPlayer", b => + { + b.Navigation("ComboReplayPlayerRating"); + + b.Navigation("ReplayPlayerRatingInfo"); + + b.Navigation("Spawns"); + + b.Navigation("Upgrades"); + }); + + modelBuilder.Entity("dsstats.db8.ReplayRating", b => + { + b.Navigation("RepPlayerRatings"); + }); + + modelBuilder.Entity("dsstats.db8.Spawn", b => + { + b.Navigation("Units"); + }); + + modelBuilder.Entity("dsstats.db8.Upgrade", b => + { + b.Navigation("ReplayPlayers"); + }); + + modelBuilder.Entity("dsstats.db8.Uploader", b => + { + b.Navigation("BattleNetInfos"); + + b.Navigation("Players"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/MysqlMigrations/Migrations/20240721150411_ArcadeReplayDsPlayers.cs b/src/MysqlMigrations/Migrations/20240721150411_ArcadeReplayDsPlayers.cs new file mode 100644 index 00000000..afc942d8 --- /dev/null +++ b/src/MysqlMigrations/Migrations/20240721150411_ArcadeReplayDsPlayers.cs @@ -0,0 +1,234 @@ +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace MysqlMigrations.Migrations +{ + /// + public partial class ArcadeReplayDsPlayers : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + //migrationBuilder.DropForeignKey( + // name: "FK_ArcadePlayerRatings_ArcadePlayers_ArcadePlayerId", + // table: "ArcadePlayerRatings"); + + migrationBuilder.DropTable( + name: "ArcadeReplayPlayerRatings"); + + migrationBuilder.RenameColumn( + name: "ArcadePlayerId", + table: "ArcadePlayerRatings", + newName: "PlayerId"); + + migrationBuilder.RenameIndex( + name: "IX_ArcadePlayerRatings_ArcadePlayerId", + table: "ArcadePlayerRatings", + newName: "IX_ArcadePlayerRatings_PlayerId"); + + migrationBuilder.CreateTable( + name: "ArcadeReplayDsPlayers", + columns: table => new + { + ArcadeReplayDsPlayerId = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Name = table.Column(type: "varchar(50)", maxLength: 50, nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + SlotNumber = table.Column(type: "int", nullable: false), + Team = table.Column(type: "int", nullable: false), + Discriminator = table.Column(type: "int", nullable: false), + PlayerResult = table.Column(type: "int", nullable: false), + ArcadeReplayId = table.Column(type: "int", nullable: false), + PlayerId = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ArcadeReplayDsPlayers", x => x.ArcadeReplayDsPlayerId); + table.ForeignKey( + name: "FK_ArcadeReplayDsPlayers_ArcadeReplays_ArcadeReplayId", + column: x => x.ArcadeReplayId, + principalTable: "ArcadeReplays", + principalColumn: "ArcadeReplayId", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_ArcadeReplayDsPlayers_Players_PlayerId", + column: x => x.PlayerId, + principalTable: "Players", + principalColumn: "PlayerId", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "ArcadeReplayDsPlayerRatings", + columns: table => new + { + ArcadeReplayDsPlayerRatingId = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + GamePos = table.Column(type: "int", nullable: false), + Rating = table.Column(type: "float", nullable: false), + RatingChange = table.Column(type: "float", nullable: false), + Games = table.Column(type: "int", nullable: false), + Consistency = table.Column(type: "float", nullable: false), + Confidence = table.Column(type: "float", nullable: false), + ArcadeReplayDsPlayerId = table.Column(type: "int", nullable: false), + ArcadeReplayRatingId = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ArcadeReplayDsPlayerRatings", x => x.ArcadeReplayDsPlayerRatingId); + table.ForeignKey( + name: "FK_ArcadeReplayDsPlayerRatings_ArcadeReplayDsPlayers_ArcadeRepl~", + column: x => x.ArcadeReplayDsPlayerId, + principalTable: "ArcadeReplayDsPlayers", + principalColumn: "ArcadeReplayDsPlayerId", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_ArcadeReplayDsPlayerRatings_ArcadeReplayRatings_ArcadeReplay~", + column: x => x.ArcadeReplayRatingId, + principalTable: "ArcadeReplayRatings", + principalColumn: "ArcadeReplayRatingId", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateIndex( + name: "IX_ArcadeReplayDsPlayerRatings_ArcadeReplayDsPlayerId", + table: "ArcadeReplayDsPlayerRatings", + column: "ArcadeReplayDsPlayerId", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_ArcadeReplayDsPlayerRatings_ArcadeReplayRatingId", + table: "ArcadeReplayDsPlayerRatings", + column: "ArcadeReplayRatingId"); + + migrationBuilder.CreateIndex( + name: "IX_ArcadeReplayDsPlayers_ArcadeReplayId", + table: "ArcadeReplayDsPlayers", + column: "ArcadeReplayId"); + + migrationBuilder.CreateIndex( + name: "IX_ArcadeReplayDsPlayers_PlayerId", + table: "ArcadeReplayDsPlayers", + column: "PlayerId"); + + migrationBuilder.AddForeignKey( + name: "FK_ArcadePlayerRatings_Players_PlayerId", + table: "ArcadePlayerRatings", + column: "PlayerId", + principalTable: "Players", + principalColumn: "PlayerId", + onDelete: ReferentialAction.Cascade); + + var cleanup = "DROP PROCEDURE IF EXISTS `SetArcadePlayerRatingPos`;"; + migrationBuilder.Sql(cleanup); + var SetArcadePlayerRatingPos = @"CREATE PROCEDURE `SetArcadePlayerRatingPos`() +BEGIN + SET @pos = 0; + UPDATE ArcadePlayerRatings + SET Pos = (@pos:=@pos+1) + WHERE RatingType = 1 + ORDER BY Rating DESC, PlayerId; + + SET @pos = 0; + UPDATE ArcadePlayerRatings + SET Pos = (@pos:=@pos+1) + WHERE RatingType = 2 + ORDER BY Rating DESC, PlayerId; + + SET @pos = 0; + UPDATE ArcadePlayerRatings + SET Pos = (@pos:=@pos+1) + WHERE RatingType = 3 + ORDER BY Rating DESC, PlayerId; + + SET @pos = 0; + UPDATE ArcadePlayerRatings + SET Pos = (@pos:=@pos+1) + WHERE RatingType = 4 + ORDER BY Rating DESC, PlayerId; +END +"; + migrationBuilder.Sql(SetArcadePlayerRatingPos); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_ArcadePlayerRatings_Players_PlayerId", + table: "ArcadePlayerRatings"); + + migrationBuilder.DropTable( + name: "ArcadeReplayDsPlayerRatings"); + + migrationBuilder.DropTable( + name: "ArcadeReplayDsPlayers"); + + migrationBuilder.RenameColumn( + name: "PlayerId", + table: "ArcadePlayerRatings", + newName: "ArcadePlayerId"); + + migrationBuilder.RenameIndex( + name: "IX_ArcadePlayerRatings_PlayerId", + table: "ArcadePlayerRatings", + newName: "IX_ArcadePlayerRatings_ArcadePlayerId"); + + migrationBuilder.CreateTable( + name: "ArcadeReplayPlayerRatings", + columns: table => new + { + ArcadeReplayPlayerRatingId = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + ArcadeReplayPlayerId = table.Column(type: "int", nullable: false), + ArcadeReplayRatingId = table.Column(type: "int", nullable: false), + Confidence = table.Column(type: "float", nullable: false), + Consistency = table.Column(type: "float", nullable: false), + GamePos = table.Column(type: "int", nullable: false), + Games = table.Column(type: "int", nullable: false), + Rating = table.Column(type: "float", nullable: false), + RatingChange = table.Column(type: "float", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ArcadeReplayPlayerRatings", x => x.ArcadeReplayPlayerRatingId); + table.ForeignKey( + name: "FK_ArcadeReplayPlayerRatings_ArcadeReplayPlayers_ArcadeReplayPl~", + column: x => x.ArcadeReplayPlayerId, + principalTable: "ArcadeReplayPlayers", + principalColumn: "ArcadeReplayPlayerId", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_ArcadeReplayPlayerRatings_ArcadeReplayRatings_ArcadeReplayRa~", + column: x => x.ArcadeReplayRatingId, + principalTable: "ArcadeReplayRatings", + principalColumn: "ArcadeReplayRatingId", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateIndex( + name: "IX_ArcadeReplayPlayerRatings_ArcadeReplayPlayerId", + table: "ArcadeReplayPlayerRatings", + column: "ArcadeReplayPlayerId", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_ArcadeReplayPlayerRatings_ArcadeReplayRatingId", + table: "ArcadeReplayPlayerRatings", + column: "ArcadeReplayRatingId"); + + migrationBuilder.AddForeignKey( + name: "FK_ArcadePlayerRatings_ArcadePlayers_ArcadePlayerId", + table: "ArcadePlayerRatings", + column: "ArcadePlayerId", + principalTable: "ArcadePlayers", + principalColumn: "ArcadePlayerId", + onDelete: ReferentialAction.Cascade); + } + } +} diff --git a/src/MysqlMigrations/Migrations/ReplayContextModelSnapshot.cs b/src/MysqlMigrations/Migrations/ReplayContextModelSnapshot.cs index 5aaf6fbf..80551605 100644 --- a/src/MysqlMigrations/Migrations/ReplayContextModelSnapshot.cs +++ b/src/MysqlMigrations/Migrations/ReplayContextModelSnapshot.cs @@ -92,9 +92,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("ArcadePlayerRatingId")); - b.Property("ArcadePlayerId") - .HasColumnType("int"); - b.Property("Confidence") .HasColumnType("double"); @@ -116,6 +113,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("Mvp") .HasColumnType("int"); + b.Property("PlayerId") + .HasColumnType("int"); + b.Property("Pos") .HasColumnType("int"); @@ -133,7 +133,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("ArcadePlayerRatingId"); - b.HasIndex("ArcadePlayerId"); + b.HasIndex("PlayerId"); b.HasIndex("RatingType"); @@ -227,16 +227,13 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("ArcadeReplays"); }); - modelBuilder.Entity("dsstats.db8.ArcadeReplayPlayer", b => + modelBuilder.Entity("dsstats.db8.ArcadeReplayDsPlayer", b => { - b.Property("ArcadeReplayPlayerId") + b.Property("ArcadeReplayDsPlayerId") .ValueGeneratedOnAdd() .HasColumnType("int"); - MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("ArcadeReplayPlayerId")); - - b.Property("ArcadePlayerId") - .HasColumnType("int"); + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("ArcadeReplayDsPlayerId")); b.Property("ArcadeReplayId") .HasColumnType("int"); @@ -249,6 +246,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasMaxLength(50) .HasColumnType("varchar(50)"); + b.Property("PlayerId") + .HasColumnType("int"); + b.Property("PlayerResult") .HasColumnType("int"); @@ -258,24 +258,24 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("Team") .HasColumnType("int"); - b.HasKey("ArcadeReplayPlayerId"); - - b.HasIndex("ArcadePlayerId"); + b.HasKey("ArcadeReplayDsPlayerId"); b.HasIndex("ArcadeReplayId"); - b.ToTable("ArcadeReplayPlayers"); + b.HasIndex("PlayerId"); + + b.ToTable("ArcadeReplayDsPlayers"); }); - modelBuilder.Entity("dsstats.db8.ArcadeReplayPlayerRating", b => + modelBuilder.Entity("dsstats.db8.ArcadeReplayDsPlayerRating", b => { - b.Property("ArcadeReplayPlayerRatingId") + b.Property("ArcadeReplayDsPlayerRatingId") .ValueGeneratedOnAdd() .HasColumnType("int"); - MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("ArcadeReplayPlayerRatingId")); + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("ArcadeReplayDsPlayerRatingId")); - b.Property("ArcadeReplayPlayerId") + b.Property("ArcadeReplayDsPlayerId") .HasColumnType("int"); b.Property("ArcadeReplayRatingId") @@ -299,14 +299,54 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("RatingChange") .HasColumnType("float"); - b.HasKey("ArcadeReplayPlayerRatingId"); + b.HasKey("ArcadeReplayDsPlayerRatingId"); - b.HasIndex("ArcadeReplayPlayerId") + b.HasIndex("ArcadeReplayDsPlayerId") .IsUnique(); b.HasIndex("ArcadeReplayRatingId"); - b.ToTable("ArcadeReplayPlayerRatings"); + b.ToTable("ArcadeReplayDsPlayerRatings"); + }); + + modelBuilder.Entity("dsstats.db8.ArcadeReplayPlayer", b => + { + b.Property("ArcadeReplayPlayerId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("ArcadeReplayPlayerId")); + + b.Property("ArcadePlayerId") + .HasColumnType("int"); + + b.Property("ArcadeReplayId") + .HasColumnType("int"); + + b.Property("Discriminator") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.Property("PlayerResult") + .HasColumnType("int"); + + b.Property("SlotNumber") + .HasColumnType("int"); + + b.Property("Team") + .HasColumnType("int"); + + b.HasKey("ArcadeReplayPlayerId"); + + b.HasIndex("ArcadePlayerId"); + + b.HasIndex("ArcadeReplayId"); + + b.ToTable("ArcadeReplayPlayers"); }); modelBuilder.Entity("dsstats.db8.ArcadeReplayRating", b => @@ -1959,13 +1999,13 @@ protected override void BuildModel(ModelBuilder modelBuilder) modelBuilder.Entity("dsstats.db8.ArcadePlayerRating", b => { - b.HasOne("dsstats.db8.ArcadePlayer", "ArcadePlayer") + b.HasOne("dsstats.db8.Player", "Player") .WithMany("ArcadePlayerRatings") - .HasForeignKey("ArcadePlayerId") + .HasForeignKey("PlayerId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); - b.Navigation("ArcadePlayer"); + b.Navigation("Player"); }); modelBuilder.Entity("dsstats.db8.ArcadePlayerRatingChange", b => @@ -1979,42 +2019,61 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Navigation("ArcadePlayerRating"); }); - modelBuilder.Entity("dsstats.db8.ArcadeReplayPlayer", b => + modelBuilder.Entity("dsstats.db8.ArcadeReplayDsPlayer", b => { - b.HasOne("dsstats.db8.ArcadePlayer", "ArcadePlayer") - .WithMany("ArcadeReplayPlayers") - .HasForeignKey("ArcadePlayerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - b.HasOne("dsstats.db8.ArcadeReplay", "ArcadeReplay") - .WithMany("ArcadeReplayPlayers") + .WithMany("ArcadeReplayDsPlayers") .HasForeignKey("ArcadeReplayId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); - b.Navigation("ArcadePlayer"); + b.HasOne("dsstats.db8.Player", "Player") + .WithMany() + .HasForeignKey("PlayerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); b.Navigation("ArcadeReplay"); + + b.Navigation("Player"); }); - modelBuilder.Entity("dsstats.db8.ArcadeReplayPlayerRating", b => + modelBuilder.Entity("dsstats.db8.ArcadeReplayDsPlayerRating", b => { - b.HasOne("dsstats.db8.ArcadeReplayPlayer", "ReplayPlayer") + b.HasOne("dsstats.db8.ArcadeReplayDsPlayer", "ReplayDsPlayer") .WithOne("ArcadeReplayPlayerRating") - .HasForeignKey("dsstats.db8.ArcadeReplayPlayerRating", "ArcadeReplayPlayerId") + .HasForeignKey("dsstats.db8.ArcadeReplayDsPlayerRating", "ArcadeReplayDsPlayerId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); b.HasOne("dsstats.db8.ArcadeReplayRating", "ArcadeReplayRating") - .WithMany("ArcadeReplayPlayerRatings") + .WithMany("ArcadeReplayDsPlayerRatings") .HasForeignKey("ArcadeReplayRatingId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); b.Navigation("ArcadeReplayRating"); - b.Navigation("ReplayPlayer"); + b.Navigation("ReplayDsPlayer"); + }); + + modelBuilder.Entity("dsstats.db8.ArcadeReplayPlayer", b => + { + b.HasOne("dsstats.db8.ArcadePlayer", "ArcadePlayer") + .WithMany("ArcadeReplayPlayers") + .HasForeignKey("ArcadePlayerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("dsstats.db8.ArcadeReplay", "ArcadeReplay") + .WithMany("ArcadeReplayPlayers") + .HasForeignKey("ArcadeReplayId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ArcadePlayer"); + + b.Navigation("ArcadeReplay"); }); modelBuilder.Entity("dsstats.db8.ArcadeReplayRating", b => @@ -2286,8 +2345,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) modelBuilder.Entity("dsstats.db8.ArcadePlayer", b => { - b.Navigation("ArcadePlayerRatings"); - b.Navigation("ArcadeReplayPlayers"); }); @@ -2298,19 +2355,21 @@ protected override void BuildModel(ModelBuilder modelBuilder) modelBuilder.Entity("dsstats.db8.ArcadeReplay", b => { + b.Navigation("ArcadeReplayDsPlayers"); + b.Navigation("ArcadeReplayPlayers"); b.Navigation("ArcadeReplayRating"); }); - modelBuilder.Entity("dsstats.db8.ArcadeReplayPlayer", b => + modelBuilder.Entity("dsstats.db8.ArcadeReplayDsPlayer", b => { b.Navigation("ArcadeReplayPlayerRating"); }); modelBuilder.Entity("dsstats.db8.ArcadeReplayRating", b => { - b.Navigation("ArcadeReplayPlayerRatings"); + b.Navigation("ArcadeReplayDsPlayerRatings"); }); modelBuilder.Entity("dsstats.db8.DsUnit", b => @@ -2337,6 +2396,8 @@ protected override void BuildModel(ModelBuilder modelBuilder) modelBuilder.Entity("dsstats.db8.Player", b => { + b.Navigation("ArcadePlayerRatings"); + b.Navigation("PlayerRatings"); b.Navigation("ReplayPlayers"); diff --git a/src/MysqlMigrations/ReplayContextFactory.cs b/src/MysqlMigrations/ReplayContextFactory.cs index 7990d3b8..75e59e73 100644 --- a/src/MysqlMigrations/ReplayContextFactory.cs +++ b/src/MysqlMigrations/ReplayContextFactory.cs @@ -20,6 +20,7 @@ public ReplayContext CreateDbContext(string[] args) { x.EnableRetryOnFailure(); x.UseQuerySplittingBehavior(QuerySplittingBehavior.SingleQuery); + x.CommandTimeout(800); x.MigrationsAssembly("MysqlMigrations"); }); diff --git a/src/SC2ArcadeCrawler/CrawlerService.ConsistencyCheck.cs b/src/SC2ArcadeCrawler/CrawlerService.ConsistencyCheck.cs index 6349c665..ff3c1a4f 100644 --- a/src/SC2ArcadeCrawler/CrawlerService.ConsistencyCheck.cs +++ b/src/SC2ArcadeCrawler/CrawlerService.ConsistencyCheck.cs @@ -76,7 +76,7 @@ public void FixPlayerResults() while (endDate < DateTime.Today.AddDays(2)) { var replays = context.ArcadeReplays - .Include(i => i.ArcadeReplayPlayers) + .Include(i => i.ArcadeReplayDsPlayers) .OrderBy(o => o.CreatedAt) .ThenBy(o => o.ArcadeReplayId) .Where(x => x.CreatedAt >= startDate && x.CreatedAt < endDate) @@ -84,7 +84,7 @@ public void FixPlayerResults() foreach (var replay in replays) { - foreach (var rp in replay.ArcadeReplayPlayers.Where(x => x.Team != replay.WinnerTeam)) + foreach (var rp in replay.ArcadeReplayDsPlayers.Where(x => x.Team != replay.WinnerTeam)) { rp.PlayerResult = PlayerResult.Los; } diff --git a/src/SC2ArcadeCrawler/CrawlerService.Import.cs b/src/SC2ArcadeCrawler/CrawlerService.Import.cs index 8dc2b19d..bd1bb91b 100644 --- a/src/SC2ArcadeCrawler/CrawlerService.Import.cs +++ b/src/SC2ArcadeCrawler/CrawlerService.Import.cs @@ -8,12 +8,10 @@ namespace pax.dsstats.web.Server.Services.Arcade; public partial class CrawlerService { - private Dictionary arcadePlayerIds = new(); - private Dictionary arcadeReplayIds = new(); + private Dictionary arcadeReplayIds = []; private async Task ImportArcadeReplays(CrawlInfo crawlInfo, CancellationToken token) { - await SeedPlayerIds(); await SeedReplayIds(); List replays = new(); @@ -122,27 +120,31 @@ private async Task ImportArcadeReplays(CrawlInfo crawlInfo, CancellationToken to PlayerCount = 6, WinnerTeam = winnerTeam, TournamentEdition = crawlInfo.TeMap, - ArcadeReplayPlayers = result.Slots.Select(s => new ArcadeReplayPlayer() + ArcadeReplayDsPlayers = result.Slots.Select(s => new ArcadeReplayDsPlayer() { Name = s.Name, SlotNumber = s.SlotNumber ?? 0, Team = s.Team ?? 0, - ArcadePlayer = new() + Player = new() { Name = s.Name, RegionId = s.Profile?.RegionId ?? 0, RealmId = s.Profile?.RealmId ?? 0, - ProfileId = s.Profile?.ProfileId ?? 0 + ToonId = s.Profile?.ProfileId ?? 0 } - }).ToList(), + }).ToList() }; - foreach (var rp in replay.ArcadeReplayPlayers) + foreach (var rp in replay.ArcadeReplayDsPlayers) { + if (rp.Player is null) + { + continue; + } var matchPlayer = result.Match.ProfileMatches.FirstOrDefault(f => - f.Profile.RegionId == rp.ArcadePlayer.RegionId - && f.Profile.ProfileId == rp.ArcadePlayer.ProfileId - && f.Profile.RealmId == rp.ArcadePlayer.RealmId + f.Profile.RegionId == rp.Player.RegionId + && f.Profile.ProfileId == rp.Player.ToonId + && f.Profile.RealmId == rp.Player.RealmId ); if (matchPlayer == null) { @@ -204,28 +206,6 @@ private async Task SeedReplayIds() .Select(s => new { s.RegionId, s.BnetBucketId, s.BnetRecordId }).Distinct().ToListAsync()) .ToDictionary(k => new ArcadeReplayId(k.RegionId, k.BnetBucketId, k.BnetRecordId), v => true); } - - private async Task SeedPlayerIds() - { - if (arcadePlayerIds.Count != 0) - { - return; - } - - using var scope = serviceProvider.CreateScope(); - var context = scope.ServiceProvider.GetRequiredService(); - - var players = await context.ArcadePlayers - .Select(s => new - { - s.ArcadePlayerId, - s.RegionId, - s.RealmId, - s.ProfileId - }).ToListAsync(); - - arcadePlayerIds = players.ToDictionary(k => new PlayerId(k.RegionId, k.RealmId, k.ProfileId), v => v.ArcadePlayerId); - } } public record ArcadeReplayId diff --git a/src/SC2ArcadeCrawler/CrawlerService.MapPlayers.cs b/src/SC2ArcadeCrawler/CrawlerService.MapPlayers.cs index f6b26b49..39936e0a 100644 --- a/src/SC2ArcadeCrawler/CrawlerService.MapPlayers.cs +++ b/src/SC2ArcadeCrawler/CrawlerService.MapPlayers.cs @@ -1,5 +1,8 @@ using dsstats.db8; +using dsstats.shared.Interfaces; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; namespace pax.dsstats.web.Server.Services.Arcade; @@ -7,66 +10,72 @@ public partial class CrawlerService { private async Task MapPlayers(List replays, CancellationToken token) { - int newPlayers = await CreateMissingPlayers(replays, token); - MapReplayPlayerPlayers(replays); - } + using var scope = serviceProvider.CreateScope(); + var importService = scope.ServiceProvider.GetRequiredService(); - private void MapReplayPlayerPlayers(List replays) - { - for (int i = 0; i < replays.Count; i++) + foreach (var replay in replays) { - foreach (var rp in replays[i].ArcadeReplayPlayers) + foreach (var replayDsPlayer in replay.ArcadeReplayDsPlayers) { - if (rp.ArcadePlayer == null) + if (replayDsPlayer.Player is null) { continue; } - - var playerId = arcadePlayerIds[new(rp.ArcadePlayer.RegionId, rp.ArcadePlayer.RealmId, rp.ArcadePlayer.ProfileId)]; - - // todo: fix regionId !? - - rp.ArcadePlayerId = playerId; -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. - rp.ArcadePlayer = null; -#pragma warning restore CS8625 // Cannot convert null literal to non-nullable reference type. + int playerId = await importService.GetPlayerIdAsync(new(replayDsPlayer.Player.RegionId, + replayDsPlayer.Player.RealmId, + replayDsPlayer.Player.ToonId), + replayDsPlayer.Name); + replayDsPlayer.Player = null; + replayDsPlayer.PlayerId = playerId; } } } - private async Task CreateMissingPlayers(List replays, CancellationToken token) + public async Task MapArcadePlayersToPlayers(CancellationToken token = default) { using var scope = serviceProvider.CreateScope(); + var importService = scope.ServiceProvider.GetRequiredService(); var context = scope.ServiceProvider.GetRequiredService(); - List newPlayers = new(); + Dictionary ArcadePlayerIdDict = await importService.MapArcadePlayers(); + + int skip = await context.ArcadeReplayDsPlayers.CountAsync(); + int take = 100_000; + + var arcadeReplayPlayers = await context.ArcadeReplayPlayers + .OrderBy(o => o.ArcadeReplayPlayerId) + .Skip(skip) + .Take(take) + .AsNoTracking() + .ToListAsync(); - for (int i = 0; i < replays.Count; i++) + while (arcadeReplayPlayers.Count > 0) { - foreach (var rp in replays[i].ArcadeReplayPlayers) + List arcadeReplayDsPlayers = []; + foreach (var replayPlayer in arcadeReplayPlayers) { - if (!arcadePlayerIds.ContainsKey(new(rp.ArcadePlayer.RegionId, rp.ArcadePlayer.RealmId, rp.ArcadePlayer.ProfileId))) + var replayDsPlayer = new ArcadeReplayDsPlayer() { - ArcadePlayer player = new() - { - Name = rp.Name, - RegionId = rp.ArcadePlayer.RegionId, - RealmId = rp.ArcadePlayer.RealmId, - ProfileId = rp.ArcadePlayer.ProfileId - }; - context.ArcadePlayers.Add(player); - newPlayers.Add(player); - if (newPlayers.Count % 1000 == 0) - { - await context.SaveChangesAsync(token); - } - arcadePlayerIds[new(rp.ArcadePlayer.RegionId, rp.ArcadePlayer.RealmId, rp.ArcadePlayer.ProfileId)] = 0; - } + Name = replayPlayer.Name, + SlotNumber = replayPlayer.SlotNumber, + Team = replayPlayer.Team, + Discriminator = replayPlayer.Discriminator, + PlayerResult = replayPlayer.PlayerResult, + PlayerId = ArcadePlayerIdDict[replayPlayer.ArcadePlayerId], + ArcadeReplayId = replayPlayer.ArcadeReplayId + }; + arcadeReplayDsPlayers.Add(replayDsPlayer); } + context.ArcadeReplayDsPlayers.AddRange(arcadeReplayDsPlayers); + await context.SaveChangesAsync(token); + skip += take; + arcadeReplayPlayers = await context.ArcadeReplayPlayers + .OrderBy(o => o.ArcadeReplayPlayerId) + .Skip(skip) + .Take(take) + .AsNoTracking() + .ToListAsync(); + logger.LogInformation("skip: {skip}", skip); } - - await context.SaveChangesAsync(token); - newPlayers.ForEach(f => arcadePlayerIds[new(f.RegionId, f.RealmId, f.ProfileId)] = f.ArcadePlayerId); - return newPlayers.Count; } } diff --git a/src/SC2ArcadeCrawler/Program.cs b/src/SC2ArcadeCrawler/Program.cs index a630a7d5..ebda76e5 100644 --- a/src/SC2ArcadeCrawler/Program.cs +++ b/src/SC2ArcadeCrawler/Program.cs @@ -1,5 +1,8 @@ using dsstats.db8; +using dsstats.db8services; +using dsstats.db8services.Import; using dsstats.shared; +using dsstats.shared.Interfaces; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; @@ -48,12 +51,13 @@ static void Main(string[] args) }); services.AddHttpClient("sc2arcardeClient") - .ConfigureHttpClient(options => - { - options.BaseAddress = new Uri("https://api.sc2arcade.com"); - options.DefaultRequestHeaders.Add("Accept", "application/json"); - }); - + .ConfigureHttpClient(options => + { + options.BaseAddress = new Uri("https://api.sc2arcade.com"); + options.DefaultRequestHeaders.Add("Accept", "application/json"); + }); + services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); var serviceProvider = services.BuildServiceProvider(); @@ -61,13 +65,17 @@ static void Main(string[] args) var scope = serviceProvider.CreateScope(); var context = scope.ServiceProvider.GetRequiredService(); - var count = context.ArcadeReplays.Count(); - Console.WriteLine($"Count: {count}"); - var crawlerService = scope.ServiceProvider.GetRequiredService(); - crawlerService.GetLobbyHistory(DateTime.Today.AddDays(-6), default).Wait(); - // crawlerService.GetLobbyHistory(new DateTime(2021, 2, 1), default).Wait(); + if (args.Length > 0 && args[0] == "maparcadeplayers") + { + crawlerService.MapArcadePlayersToPlayers().Wait(); + } + else + { + crawlerService.GetLobbyHistory(DateTime.Today.AddDays(-2), default).Wait(); + // crawlerService.GetLobbyHistory(new DateTime(2021, 2, 1), default).Wait(); + } Console.WriteLine("done."); Console.ReadLine(); diff --git a/src/SC2ArcadeCrawler/SC2ArcadeCrawler.csproj b/src/SC2ArcadeCrawler/SC2ArcadeCrawler.csproj index 95ca2153..febc71ff 100644 --- a/src/SC2ArcadeCrawler/SC2ArcadeCrawler.csproj +++ b/src/SC2ArcadeCrawler/SC2ArcadeCrawler.csproj @@ -1,6 +1,7 @@  + diff --git a/src/dsstats.api/Program.cs b/src/dsstats.api/Program.cs index 82f2fef0..31dd0cbc 100644 --- a/src/dsstats.api/Program.cs +++ b/src/dsstats.api/Program.cs @@ -109,7 +109,7 @@ builder.Services.AddSingleton(); builder.Services.AddSingleton(); -builder.Services.AddSingleton(); +builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); @@ -180,8 +180,8 @@ } else { - //var comboRatings = scope.ServiceProvider.GetRequiredService(); - //comboRatings.CombineDsstatsSc2ArcadeReplays().Wait(); + //var crawlerService = scope.ServiceProvider.GetRequiredService(); + //crawlerService.MapArcadePlayersToPlayers().Wait(); } app.UseRateLimiter(); diff --git a/src/dsstats.api/Services/DecodeService.cs b/src/dsstats.api/Services/DecodeService.cs index 1cfa8f7b..bf08ec4c 100644 --- a/src/dsstats.api/Services/DecodeService.cs +++ b/src/dsstats.api/Services/DecodeService.cs @@ -1,5 +1,6 @@ using dsstats.db8services.Import; using dsstats.shared; +using dsstats.shared.Interfaces; namespace dsstats.api.Services; @@ -43,7 +44,7 @@ public async Task ConsumeDecodeResult(Guid guid, List replays) if (replays.Count > 0) { using var scope = scopeFactory.CreateScope(); - var importService = scope.ServiceProvider.GetRequiredService(); + var importService = scope.ServiceProvider.GetRequiredService(); replays.ForEach(f => f.Replay.FileName = string.Empty); await importService.Import(replays.Select(s => s.Replay).ToList()); } diff --git a/src/dsstats.api/Services/TimedHostedService.cs b/src/dsstats.api/Services/TimedHostedService.cs index e346002f..179541b0 100644 --- a/src/dsstats.api/Services/TimedHostedService.cs +++ b/src/dsstats.api/Services/TimedHostedService.cs @@ -65,7 +65,10 @@ private async Task DoWork(CancellationToken token) await replayRepository.FixDsstatsPlayerNames(); var crawlerService = scope.ServiceProvider.GetRequiredService(); await crawlerService.GetLobbyHistory(DateTime.Today.AddDays(-6), token); - await ratingService.ProduceRatings(shared.RatingCalcType.Arcade); + + bool arcadeRecalc = nowTime.DayOfWeek == DayOfWeek.Friday; + await ratingService.ProduceRatings(shared.RatingCalcType.Arcade, arcadeRecalc); + await replayRepository.FixArcadePlayerNames(); await ratingService.ProduceRatings(shared.RatingCalcType.Combo, true); diff --git a/src/dsstats.api/Services/UploadService.Handle.cs b/src/dsstats.api/Services/UploadService.Handle.cs index 9b91dd2c..0dcc97fe 100644 --- a/src/dsstats.api/Services/UploadService.Handle.cs +++ b/src/dsstats.api/Services/UploadService.Handle.cs @@ -1,6 +1,7 @@ using dsstats.db8; using dsstats.db8services.Import; using dsstats.shared; +using dsstats.shared.Interfaces; using Microsoft.EntityFrameworkCore; using System.Threading.Channels; @@ -44,7 +45,7 @@ private bool ProduceUploadJob(UploadDto uploadDto, string replayBlob) private async ValueTask ConsumeUploadJobs() { using var scope = scopeFactory.CreateScope(); - var importService = scope.ServiceProvider.GetRequiredService(); + var importService = scope.ServiceProvider.GetRequiredService(); while (true) { @@ -126,7 +127,7 @@ private async Task SetupUploaderPlayers(Uploader uploader, List re try { using var scope = scopeFactory.CreateScope(); - var importService = scope.ServiceProvider.GetRequiredService(); + var importService = scope.ServiceProvider.GetRequiredService(); List playerIds = new(); foreach (var rn in requestNames) diff --git a/src/dsstats.db8/ArcadeReplay.cs b/src/dsstats.db8/ArcadeReplay.cs index 772088ae..eb0f97b2 100644 --- a/src/dsstats.db8/ArcadeReplay.cs +++ b/src/dsstats.db8/ArcadeReplay.cs @@ -21,6 +21,7 @@ public class ArcadeReplay public ArcadeReplay() { ArcadeReplayPlayers = new HashSet(); + ArcadeReplayDsPlayers = new HashSet(); } [Key] @@ -41,6 +42,7 @@ public ArcadeReplay() public string ReplayHash { get; set; } = string.Empty; public ArcadeReplayRating? ArcadeReplayRating { get; set; } public ICollection ArcadeReplayPlayers { get; set; } + public ICollection ArcadeReplayDsPlayers { get; set; } } public class ArcadeReplayPlayer @@ -54,10 +56,26 @@ public class ArcadeReplayPlayer public int Discriminator { get; set; } public PlayerResult PlayerResult { get; set; } public int ArcadePlayerId { get; set; } - public ArcadeReplayPlayerRating? ArcadeReplayPlayerRating { get; set; } - public ArcadePlayer ArcadePlayer { get; set; } = null!; + public ArcadePlayer? ArcadePlayer { get; set; } public int ArcadeReplayId { get; set; } - public ArcadeReplay ArcadeReplay { get; set; } = null!; + public ArcadeReplay? ArcadeReplay { get; set; } +} + +public class ArcadeReplayDsPlayer +{ + [Key] + public int ArcadeReplayDsPlayerId { get; set; } + [MaxLength(50)] + public string Name { get; set; } = string.Empty; + public int SlotNumber { get; set; } + public int Team { get; set; } + public int Discriminator { get; set; } + public PlayerResult PlayerResult { get; set; } + public ArcadeReplayDsPlayerRating? ArcadeReplayPlayerRating { get; set; } + public int ArcadeReplayId { get; set; } + public ArcadeReplay? ArcadeReplay { get; set; } + public int PlayerId { get; set; } + public Player? Player { get; set; } } public class ArcadePlayer @@ -65,7 +83,6 @@ public class ArcadePlayer public ArcadePlayer() { ArcadeReplayPlayers = new HashSet(); - ArcadePlayerRatings = new HashSet(); } [Key] @@ -75,7 +92,6 @@ public ArcadePlayer() public int RegionId { get; set; } public int RealmId { get; set; } public int ProfileId { get; set; } - public ICollection ArcadePlayerRatings { get; set; } public ICollection ArcadeReplayPlayers { get; set; } } @@ -95,8 +111,10 @@ public class ArcadePlayerRating public double Confidence { get; set; } public bool IsUploader { get; set; } public ArcadePlayerRatingChange? ArcadePlayerRatingChange { get; set; } - public int ArcadePlayerId { get; set; } - public virtual ArcadePlayer ArcadePlayer { get; set; } = null!; + public int PlayerId { get; set; } + public Player? Player { get; set; } + //public int? PlayerId { get; set; } + //public Player? Player { get; set; } } public class ArcadePlayerRatingChange @@ -113,7 +131,7 @@ public class ArcadeReplayRating { public ArcadeReplayRating() { - ArcadeReplayPlayerRatings = new HashSet(); + ArcadeReplayDsPlayerRatings = new HashSet(); } public int ArcadeReplayRatingId { get; set; } public RatingType RatingType { get; set; } @@ -122,20 +140,20 @@ public ArcadeReplayRating() public int ArcadeReplayId { get; set; } public ArcadeReplay ArcadeReplay { get; set; } = null!; public int AvgRating { get; set; } - public virtual ICollection ArcadeReplayPlayerRatings { get; set; } + public virtual ICollection ArcadeReplayDsPlayerRatings { get; set; } } -public class ArcadeReplayPlayerRating +public class ArcadeReplayDsPlayerRating { - public int ArcadeReplayPlayerRatingId { get; set; } + public int ArcadeReplayDsPlayerRatingId { get; set; } public int GamePos { get; set; } public float Rating { get; set; } public float RatingChange { get; set; } public int Games { get; set; } public float Consistency { get; set; } public float Confidence { get; set; } - public int ArcadeReplayPlayerId { get; set; } - public ArcadeReplayPlayer ReplayPlayer { get; set; } = null!; + public int ArcadeReplayDsPlayerId { get; set; } + public ArcadeReplayDsPlayer ReplayDsPlayer { get; set; } = null!; public int ArcadeReplayRatingId { get; set; } public ArcadeReplayRating ArcadeReplayRating { get; set; } = null!; } \ No newline at end of file diff --git a/src/dsstats.db8/AutoMapper/AutoMapperProfile.cs b/src/dsstats.db8/AutoMapper/AutoMapperProfile.cs index 3aefada6..54cad00a 100644 --- a/src/dsstats.db8/AutoMapper/AutoMapperProfile.cs +++ b/src/dsstats.db8/AutoMapper/AutoMapperProfile.cs @@ -56,7 +56,7 @@ public AutoMapperProfile() CreateMap(MemberList.Destination); CreateMap(MemberList.Destination); - CreateMap(MemberList.Destination); + CreateMap(MemberList.Destination); CreateMap(MemberList.Destination); CreateMap(MemberList.Destination); CreateMap(MemberList.Destination); @@ -65,13 +65,13 @@ public AutoMapperProfile() CreateMap(MemberList.Destination) .ForMember(x => x.MmrChange, opt => opt.Ignore()); - CreateMap(MemberList.Destination); + CreateMap(MemberList.Destination); CreateMap(MemberList.Destination); CreateMap(MemberList.Destination); - CreateMap(MemberList.Destination); + CreateMap(MemberList.Destination); CreateMap(MemberList.Destination) - .ForMember(x => x.Player, opt => opt.MapFrom(m => m.ArcadePlayer)) + .ForMember(x => x.Player, opt => opt.MapFrom(m => m.Player)) .ForMember(x => x.PlayerRatingChange, opt => opt.MapFrom(m => m.ArcadePlayerRatingChange)); CreateMap(MemberList.Destination) .ForMember(x => x.ToonId, opt => opt.MapFrom(m => m.ProfileId)) @@ -79,6 +79,8 @@ public AutoMapperProfile() .ForMember(x => x.IsUploader, opt => opt.Ignore()); CreateMap(); CreateMap(MemberList.Destination); + CreateMap(MemberList.Destination); + CreateMap(MemberList.Source); CreateMap(MemberList.Destination); CreateMap(MemberList.Source); diff --git a/src/dsstats.db8/Replay.cs b/src/dsstats.db8/Replay.cs index c51dfb2b..5c5c83f7 100644 --- a/src/dsstats.db8/Replay.cs +++ b/src/dsstats.db8/Replay.cs @@ -69,6 +69,7 @@ public Player() { ReplayPlayers = new HashSet(); PlayerRatings = new HashSet(); + ArcadePlayerRatings = new HashSet(); } public int PlayerId { get; set; } [MaxLength(50)] @@ -84,6 +85,7 @@ public Player() public virtual Uploader? Uploader { get; set; } public virtual ICollection ReplayPlayers { get; set; } public virtual ICollection PlayerRatings { get; set; } + public virtual ICollection ArcadePlayerRatings { get; set; } } public class PlayerRating diff --git a/src/dsstats.db8/ReplayContext.cs b/src/dsstats.db8/ReplayContext.cs index 3d6c08de..e01926cd 100644 --- a/src/dsstats.db8/ReplayContext.cs +++ b/src/dsstats.db8/ReplayContext.cs @@ -38,10 +38,11 @@ public class ReplayContext : DbContext public virtual DbSet ArcadeReplays { get; set; } = null!; public virtual DbSet MaterializedArcadeReplays { get; set; } = null!; public virtual DbSet ArcadeReplayPlayers { get; set; } = null!; + public virtual DbSet ArcadeReplayDsPlayers { get; set; } = null!; public virtual DbSet ArcadePlayers { get; set; } = null!; public virtual DbSet ArcadeReplayRatings { get; set; } = null!; public virtual DbSet ArcadePlayerRatings { get; set; } = null!; - public virtual DbSet ArcadeReplayPlayerRatings { get; set; } = null!; + public virtual DbSet ArcadeReplayDsPlayerRatings { get; set; } = null!; public virtual DbSet ArcadePlayerRatingChanges { get; set; } = null!; public virtual DbSet DsUpdates { get; set; } = null!; public virtual DbSet DsUnits { get; set; } = null!; diff --git a/src/dsstats.db8services/Ih/IhRepository.Archive.cs b/src/dsstats.db8services/Ih/IhRepository.Archive.cs index 29c2d23b..01cedc24 100644 --- a/src/dsstats.db8services/Ih/IhRepository.Archive.cs +++ b/src/dsstats.db8services/Ih/IhRepository.Archive.cs @@ -1,6 +1,7 @@ using dsstats.db8; using dsstats.db8services.Import; using dsstats.shared; +using dsstats.shared.Interfaces; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.Extensions.DependencyInjection; @@ -28,7 +29,7 @@ public async Task ArchiveSession(Guid groupId) session.IhSessionPlayers.Clear(); using var scope = scopeFactory.CreateScope(); - var importService = scope.ServiceProvider.GetRequiredService(); + var importService = scope.ServiceProvider.GetRequiredService(); foreach (var playerState in session.GroupStateV2.PlayerStates) { @@ -70,7 +71,7 @@ public async Task ArchiveV1() .ToListAsync(); using var scope = scopeFactory.CreateScope(); - var importService = scope.ServiceProvider.GetRequiredService(); + var importService = scope.ServiceProvider.GetRequiredService(); foreach (var session in v1Sessions) { @@ -88,7 +89,7 @@ public async Task ArchiveV1() } } - private async Task> GetSessionPlayers(GroupStateV2 groupState, ImportService importService) + private async Task> GetSessionPlayers(GroupStateV2 groupState, IImportService importService) { List players = []; diff --git a/src/dsstats.db8services/Import/ImportService.Duplicates.cs b/src/dsstats.db8services/Import/ImportService.Duplicates.cs index a2d6225c..df9384b6 100644 --- a/src/dsstats.db8services/Import/ImportService.Duplicates.cs +++ b/src/dsstats.db8services/Import/ImportService.Duplicates.cs @@ -6,7 +6,7 @@ namespace dsstats.db8services.Import; public partial class ImportService { - public async Task HandleDuplicates(List replays, ReplayContext context) + private async Task HandleDuplicates(List replays, ReplayContext context) { var replayHashes = replays.Select(s => s.ReplayHash).ToList(); var dupReplays = await context.Replays diff --git a/src/dsstats.db8services/Import/ImportService.cs b/src/dsstats.db8services/Import/ImportService.cs index 6f8aa94d..462d011a 100644 --- a/src/dsstats.db8services/Import/ImportService.cs +++ b/src/dsstats.db8services/Import/ImportService.cs @@ -8,7 +8,7 @@ namespace dsstats.db8services.Import; -public partial class ImportService +public partial class ImportService : IImportService { private readonly IServiceProvider serviceProvider; private readonly ILogger logger; @@ -264,4 +264,56 @@ private int GetUpgradeId(string name) } return upgradeId; } + + public async Task> MapArcadePlayers() + { + await playersSs.WaitAsync(); + Dictionary arcadePlayerIdMap = []; + try + { + if (!IsInit) + { + await Init(); + } + List newPlayers = []; + + using var scope = serviceProvider.CreateAsyncScope(); + var context = scope.ServiceProvider.GetRequiredService(); + + var arcadePlayersDict = (await context.ArcadePlayers + .ToListAsync()).ToDictionary(k => new PlayerId(k.ProfileId, k.RealmId, k.RegionId), v => v); + + foreach (var arcadePlayer in arcadePlayersDict.Values) + { + var playerId = new PlayerId(arcadePlayer.ProfileId, arcadePlayer.RealmId, arcadePlayer.RegionId); + if (PlayerIds.TryGetValue(playerId, out var dsPlayerId)) + { + arcadePlayerIdMap[arcadePlayer.ArcadePlayerId] = dsPlayerId; + } + else + { + newPlayers.Add(new() + { + Name = arcadePlayer.Name, + ToonId = arcadePlayer.ProfileId, + RealmId = arcadePlayer.RealmId, + RegionId = arcadePlayer.RegionId, + }); + } + } + context.Players.AddRange(newPlayers); + await context.SaveChangesAsync(); + foreach (var player in newPlayers) + { + var playerId = new PlayerId(player.ToonId, player.RealmId, player.RegionId); + PlayerIds[playerId] = player.PlayerId; + arcadePlayerIdMap[arcadePlayersDict[playerId].ArcadePlayerId] = player.PlayerId; + } + } + finally + { + playersSs.Release(); + } + return arcadePlayerIdMap; + } } diff --git a/src/dsstats.db8services/MauiService.cs b/src/dsstats.db8services/MauiService.cs index 03b66dfc..806a5afd 100644 --- a/src/dsstats.db8services/MauiService.cs +++ b/src/dsstats.db8services/MauiService.cs @@ -94,12 +94,12 @@ private async Task GetArcadeMauiRatingResponse(MauiRatingReq { MauiRatingInfo? info = await context.ArcadePlayerRatings .Where(x => x.RatingType == request.RatingType - && x.ArcadePlayer.ProfileId == playerId.ToonId - && x.ArcadePlayer.RealmId == playerId.RealmId - && x.ArcadePlayer.RegionId == playerId.RegionId) + && x.Player!.ToonId == playerId.ToonId + && x.Player.RealmId == playerId.RealmId + && x.Player.RegionId == playerId.RegionId) .Select(s => new MauiRatingInfo() { - RequestNames = new(s.ArcadePlayer.Name, s.ArcadePlayer.ProfileId, s.ArcadePlayer.RegionId, s.ArcadePlayer.RealmId), + RequestNames = new(s.Player!.Name, s.Player.ToonId, s.Player.RegionId, s.Player.RealmId), Rating = Convert.ToInt32(s.Rating), Pos = s.Pos }) diff --git a/src/dsstats.db8services/PlayerService/PlayerService.Arcade.cs b/src/dsstats.db8services/PlayerService/PlayerService.Arcade.cs index a41e61db..04442a9a 100644 --- a/src/dsstats.db8services/PlayerService/PlayerService.Arcade.cs +++ b/src/dsstats.db8services/PlayerService/PlayerService.Arcade.cs @@ -30,9 +30,9 @@ private async Task> GetArcadeRatingsList(RatingsReque private IQueryable GetArcadeListQuery(RatingsRequest request) { var query = from cpr in context.ArcadePlayerRatings - from pr in context.PlayerRatings.Where(x => x.Player!.ToonId == cpr.ArcadePlayer!.ProfileId - && x.Player.RealmId == cpr.ArcadePlayer.RealmId - && x.Player.RegionId == cpr.ArcadePlayer.RegionId).DefaultIfEmpty() + from pr in context.PlayerRatings.Where(x => x.Player!.ToonId == cpr.Player!.ToonId + && x.Player.RealmId == cpr.Player.RealmId + && x.Player.RegionId == cpr.Player.RegionId).DefaultIfEmpty() where cpr.Games > 19 && cpr.RatingType == request.Type && pr.RatingType == request.Type select new ComboPlayerRatingDto() { @@ -45,10 +45,10 @@ from pr in context.PlayerRatings.Where(x => x.Player!.ToonId == cpr.ArcadePlayer }, Player = new PlayerRatingPlayerDto() { - Name = cpr.ArcadePlayer!.Name, - ToonId = cpr.ArcadePlayer.ProfileId, - RegionId = cpr.ArcadePlayer.RegionId, - RealmId = cpr.ArcadePlayer.RealmId + Name = cpr.Player!.Name, + ToonId = cpr.Player.ToonId, + RegionId = cpr.Player.RegionId, + RealmId = cpr.Player.RealmId }, PlayerRating = new PlayerRatingDto() { diff --git a/src/dsstats.db8services/PlayerService/PlayerService.PlayerIdArcade.cs b/src/dsstats.db8services/PlayerService/PlayerService.PlayerIdArcade.cs index 17bf2a32..b9856f38 100644 --- a/src/dsstats.db8services/PlayerService/PlayerService.PlayerIdArcade.cs +++ b/src/dsstats.db8services/PlayerService/PlayerService.PlayerIdArcade.cs @@ -31,9 +31,9 @@ private async Task> GetPlayerIdArcadeRatings(PlayerI { return await context.ArcadePlayerRatings .Include(i => i.ArcadePlayerRatingChange) - .Where(x => x.ArcadePlayer!.ProfileId == playerId.ToonId - && x.ArcadePlayer.RealmId == playerId.RealmId - && x.ArcadePlayer.RegionId == playerId.RegionId) + .Where(x => x.Player!.ToonId == playerId.ToonId + && x.Player.RealmId == playerId.RealmId + && x.Player.RegionId == playerId.RegionId) .Select(s => new PlayerRatingDetailDto() { RatingType = (RatingType)s.RatingType, @@ -45,10 +45,10 @@ private async Task> GetPlayerIdArcadeRatings(PlayerI Confidence = Math.Round(s.Confidence, 2), Player = new PlayerRatingPlayerDto() { - Name = s.ArcadePlayer!.Name, - ToonId = s.ArcadePlayer.ProfileId, - RegionId = s.ArcadePlayer.RegionId, - RealmId = s.ArcadePlayer.RealmId, + Name = s.Player!.Name, + ToonId = s.Player.ToonId, + RegionId = s.Player.RegionId, + RealmId = s.Player.RealmId, }, PlayerRatingChange = s.ArcadePlayerRatingChange == null ? null : new PlayerRatingChangeDto() { @@ -92,17 +92,16 @@ public async Task GetPlayerIdArcadePlayerRatingDetails(Play private async Task GetPlayerIdArcadeTeamRating(ReplayContext context, PlayerId playerId, RatingType ratingType, bool inTeam, CancellationToken token) { - var teamRatings = from p in context.ArcadePlayers - from rp in p.ArcadeReplayPlayers - from t in rp.ArcadeReplay!.ArcadeReplayPlayers - where p.ProfileId == playerId.ToonId - && p.RealmId == playerId.RealmId - && p.RegionId == playerId.RegionId + var teamRatings = from rp in context.ArcadeReplayDsPlayers + from t in rp.ArcadeReplay!.ArcadeReplayDsPlayers + where rp.Player!.ToonId == playerId.ToonId + && rp.Player.RealmId == playerId.RealmId + && rp.Player.RegionId == playerId.RegionId && rp.ArcadeReplay!.ArcadeReplayRating != null && rp.ArcadeReplay.ArcadeReplayRating.RatingType == ratingType && (!inTeam || t != rp) && (inTeam ? t.Team == rp.Team : t.Team != rp.Team) - && t.ArcadePlayer!.ProfileId > 0 + && t.Player!.ToonId > 0 select t.ArcadeReplayPlayerRating; var avgRating = await teamRatings @@ -120,7 +119,7 @@ from rp in r.ArcadeReplayPlayers from t in r.ArcadeReplayPlayers join p in context.ArcadePlayers on rp.ArcadePlayerId equals p.ArcadePlayerId join tp in context.ArcadePlayers on t.ArcadePlayerId equals tp.ArcadePlayerId - join rpr in context.ArcadeReplayPlayerRatings on rp.ArcadeReplayPlayerId equals rpr.ArcadeReplayPlayerId + join rpr in context.ArcadeReplayDsPlayerRatings on rp.ArcadeReplayPlayerId equals rpr.ArcadeReplayDsPlayerId where p.ProfileId == playerId.ToonId && p.RegionId == playerId.RegionId && p.RealmId == playerId.RealmId @@ -161,7 +160,7 @@ from rp in r.ArcadeReplayPlayers from o in r.ArcadeReplayPlayers join p in context.ArcadePlayers on rp.ArcadePlayerId equals p.ArcadePlayerId join op in context.ArcadePlayers on o.ArcadePlayerId equals op.ArcadePlayerId - join rpr in context.ArcadeReplayPlayerRatings on o.ArcadeReplayPlayerId equals rpr.ArcadeReplayPlayerId + join rpr in context.ArcadeReplayDsPlayerRatings on o.ArcadeReplayPlayerId equals rpr.ArcadeReplayDsPlayerId where p.ProfileId == playerId.ToonId && p.RegionId == playerId.RegionId && p.RealmId == playerId.RealmId diff --git a/src/dsstats.db8services/PlayerService/PlayerService.cs b/src/dsstats.db8services/PlayerService/PlayerService.cs index ab9ba1a2..234ab113 100644 --- a/src/dsstats.db8services/PlayerService/PlayerService.cs +++ b/src/dsstats.db8services/PlayerService/PlayerService.cs @@ -187,7 +187,7 @@ private async Task> GetArcadelayerRatingChartData(Pla from rp in p.ArcadeReplayPlayers join r in context.ArcadeReplays on rp.ArcadeReplayId equals r.ArcadeReplayId join rr in context.ArcadeReplayRatings on r.ArcadeReplayId equals rr.ArcadeReplayId - join rpr in context.ArcadeReplayPlayerRatings on rp.ArcadeReplayPlayerId equals rpr.ArcadeReplayPlayerId + join rpr in context.ArcadeReplayDsPlayerRatings on rp.ArcadeReplayPlayerId equals rpr.ArcadeReplayDsPlayerId where p.ProfileId == playerId.ToonId && p.RealmId == playerId.RealmId && p.RegionId == playerId.RegionId diff --git a/src/dsstats.api/Services/RemoteToggleService.cs b/src/dsstats.db8services/RemoteToggleService.cs similarity index 95% rename from src/dsstats.api/Services/RemoteToggleService.cs rename to src/dsstats.db8services/RemoteToggleService.cs index 6e086352..c44e6df1 100644 --- a/src/dsstats.api/Services/RemoteToggleService.cs +++ b/src/dsstats.db8services/RemoteToggleService.cs @@ -1,6 +1,6 @@ using dsstats.shared.Interfaces; -namespace dsstats.api.Services; +namespace dsstats.db8services; public class RemoteToggleService : IRemoteToggleService { diff --git a/src/dsstats.db8services/ReplayRepository.cs b/src/dsstats.db8services/ReplayRepository.cs index cc692e61..220c72e2 100644 --- a/src/dsstats.db8services/ReplayRepository.cs +++ b/src/dsstats.db8services/ReplayRepository.cs @@ -304,8 +304,8 @@ public async Task FixArcadePlayerNames() Stopwatch sw = Stopwatch.StartNew(); var replays = await context.ArcadeReplays - .Include(i => i.ArcadeReplayPlayers) - .ThenInclude(i => i.ArcadePlayer) + .Include(i => i.ArcadeReplayDsPlayers) + .ThenInclude(i => i.Player) .Where(x => x.CreatedAt > fromDate) .OrderByDescending(o => o.CreatedAt) .ToListAsync(); @@ -319,21 +319,21 @@ public async Task FixArcadePlayerNames() foreach (var replay in replays) { - foreach (var replayPlayer in replay.ArcadeReplayPlayers) + foreach (var replayPlayer in replay.ArcadeReplayDsPlayers) { - if (playersDone.ContainsKey(replayPlayer.ArcadePlayer.ArcadePlayerId)) + if (playersDone.ContainsKey(replayPlayer.Player!.PlayerId)) { continue; } - if (replayPlayer.Name != replayPlayer.ArcadePlayer.Name) + if (replayPlayer.Name != replayPlayer.Player.Name) { - replayPlayer.ArcadePlayer.Name = replayPlayer.Name; - playersDone[replayPlayer.ArcadePlayer.ArcadePlayerId] = replayPlayer.Name; + replayPlayer.Player.Name = replayPlayer.Name; + playersDone[replayPlayer.Player!.PlayerId] = replayPlayer.Name; } else { - playersDone[replayPlayer.ArcadePlayer.ArcadePlayerId] = replayPlayer.ArcadePlayer.Name; + playersDone[replayPlayer.Player!.PlayerId] = replayPlayer.Player.Name; } } } diff --git a/src/dsstats.db8services/ReplaysService.Arcade.cs b/src/dsstats.db8services/ReplaysService.Arcade.cs index 60bc6f45..21a42a24 100644 --- a/src/dsstats.db8services/ReplaysService.Arcade.cs +++ b/src/dsstats.db8services/ReplaysService.Arcade.cs @@ -58,7 +58,7 @@ private async Task GetArcadeReplays(ReplaysRequest request, Can GameTime = s.CreatedAt, Duration = s.Duration, WinnerTeam = s.WinnerTeam, - GameMode = (GameMode)s.GameMode, + GameMode = s.GameMode, TournamentEdition = s.TournamentEdition, ReplayHash = $"{s.RegionId}|{s.BnetBucketId}|{s.BnetRecordId}", DefaultFilter = false, @@ -99,7 +99,7 @@ private async Task GetArcadeReplaysForPlayerId(IQueryable new ReplayPlayerListDto() + ReplayPlayers = s.ArcadeReplayDsPlayers.Select(t => new ReplayPlayerListDto() { Name = t.Name, GamePos = t.SlotNumber, @@ -110,9 +110,9 @@ private async Task GetArcadeReplaysForPlayerId(IQueryable GetArcadeReplaysQueriable(ReplaysRequest reques if (request.PlayerIdVs is not null) { replays = from r in replays - from rp in r.ArcadeReplayPlayers - from rp1 in r.ArcadeReplayPlayers - where rp.ArcadePlayer.ProfileId == request.PlayerId.ToonId - && rp.ArcadePlayer.RealmId == request.PlayerId.RealmId - && rp.ArcadePlayer.RegionId == request.PlayerId.RegionId - && rp1.ArcadePlayer.ProfileId == request.PlayerIdVs.ToonId - && rp1.ArcadePlayer.RealmId == request.PlayerIdVs.RealmId - && rp1.ArcadePlayer.RegionId == request.PlayerIdVs.RegionId + from rp in r.ArcadeReplayDsPlayers + from rp1 in r.ArcadeReplayDsPlayers + where rp.Player!.ToonId == request.PlayerId.ToonId + && rp.Player.RealmId == request.PlayerId.RealmId + && rp.Player.RegionId == request.PlayerId.RegionId + && rp1.Player!.ToonId == request.PlayerIdVs.ToonId + && rp1.Player.RealmId == request.PlayerIdVs.RealmId + && rp1.Player.RegionId == request.PlayerIdVs.RegionId && rp1.Team != rp.Team select r; } else if (request.PlayerIdWith is not null) { replays = from r in replays - from rp in r.ArcadeReplayPlayers - from rp1 in r.ArcadeReplayPlayers - where rp.ArcadePlayer.ProfileId == request.PlayerId.ToonId - && rp.ArcadePlayer.RealmId == request.PlayerId.RealmId - && rp.ArcadePlayer.RegionId == request.PlayerId.RegionId - && rp1.ArcadePlayer.ProfileId == request.PlayerIdWith.ToonId - && rp1.ArcadePlayer.RealmId == request.PlayerIdWith.RealmId - && rp1.ArcadePlayer.RegionId == request.PlayerIdWith.RegionId + from rp in r.ArcadeReplayDsPlayers + from rp1 in r.ArcadeReplayDsPlayers + where rp.Player!.ToonId == request.PlayerId.ToonId + && rp.Player.RealmId == request.PlayerId.RealmId + && rp.Player.RegionId == request.PlayerId.RegionId + && rp1.Player!.ToonId == request.PlayerIdWith.ToonId + && rp1.Player.RealmId == request.PlayerIdWith.RealmId + && rp1.Player.RegionId == request.PlayerIdWith.RegionId && rp1.Team == rp.Team select r; } else { replays = from r in replays - from rp in r.ArcadeReplayPlayers - where rp.ArcadePlayer.ProfileId == request.PlayerId.ToonId - && rp.ArcadePlayer.RealmId == request.PlayerId.RealmId - && rp.ArcadePlayer.RegionId == request.PlayerId.RegionId + from rp in r.ArcadeReplayDsPlayers + where rp.Player!.ToonId == request.PlayerId.ToonId + && rp.Player.RealmId == request.PlayerId.RealmId + && rp.Player.RegionId == request.PlayerId.RegionId select r; } } @@ -260,8 +260,8 @@ private IQueryable FilterArcadePlayers(IQueryable re { var name = names[i]; replays = from r in replays - from rp in r.ArcadeReplayPlayers - where rp.ArcadePlayer.Name == name + from rp in r.ArcadeReplayDsPlayers + where rp.Player!.Name == name select r; } diff --git a/src/dsstats.db8services/Tourneys/TourneysService.New.cs b/src/dsstats.db8services/Tourneys/TourneysService.New.cs index b4cf3726..cc73d13c 100644 --- a/src/dsstats.db8services/Tourneys/TourneysService.New.cs +++ b/src/dsstats.db8services/Tourneys/TourneysService.New.cs @@ -1,6 +1,7 @@ using dsstats.db8; using dsstats.db8services.Import; using dsstats.shared; +using dsstats.shared.Interfaces; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using System.Text.Json; @@ -138,7 +139,7 @@ private async Task CreateReplayEvent(List replays, int eventId) private async Task ImportReplays(List replays) { using var scope = scopeFactory.CreateScope(); - var importService = scope.ServiceProvider.GetRequiredService(); + var importService = scope.ServiceProvider.GetRequiredService(); var result = await importService.Import(replays); Console.WriteLine($"{result.Imported} tourney replays imported."); diff --git a/src/dsstats.ratings/ComboRatings.ArcadeRep.cs b/src/dsstats.ratings/ComboRatings.ArcadeRep.cs index 0583ef99..a248973b 100644 --- a/src/dsstats.ratings/ComboRatings.ArcadeRep.cs +++ b/src/dsstats.ratings/ComboRatings.ArcadeRep.cs @@ -164,15 +164,15 @@ orderby r.MaterializedArcadeReplayId WinnerTeam = r.WinnerTeam, TournamentEdition = false, IsArcade = true, - Players = context.ArcadeReplayPlayers + Players = context.ArcadeReplayDsPlayers .Where(x => x.ArcadeReplayId == r.ArcadeReplayId) .Select(t => new PlayerCalcDto() { - ReplayPlayerId = t.ArcadeReplayPlayerId, + ReplayPlayerId = t.PlayerId, GamePos = t.SlotNumber, PlayerResult = (int)t.PlayerResult, Team = t.Team, - PlayerId = new(t.ArcadePlayer.ProfileId, t.ArcadePlayer.RealmId, t.ArcadePlayer.RegionId) + PlayerId = new(t.Player!.ToonId, t.Player.RealmId, t.Player.RegionId) }).ToList() }; diff --git a/src/dsstats.ratings/Program.cs b/src/dsstats.ratings/Program.cs index fcab23e2..933006d9 100644 --- a/src/dsstats.ratings/Program.cs +++ b/src/dsstats.ratings/Program.cs @@ -66,28 +66,29 @@ static void Main(string[] args) } Stopwatch sw = Stopwatch.StartNew(); - if (args.Length == 1) + if (args.Length > 0) { + bool recalc = true; + if (args.Length > 1 && args[1] == "continue") + { + recalc = false; + } + var ratingService = scope.ServiceProvider.GetRequiredService(); if (args[0] == "dsstats") { logger.LogInformation("producing dsstats ratings."); - ratingService.ProduceRatings(RatingCalcType.Dsstats, true).Wait(); + ratingService.ProduceRatings(RatingCalcType.Dsstats, recalc).Wait(); } - else if (args[0] == "sc2arcade") + else if (args[0] == "arcade") { logger.LogInformation("producing sc2arcade ratings."); - ratingService.ProduceRatings(RatingCalcType.Arcade, true).Wait(); + ratingService.ProduceRatings(RatingCalcType.Arcade, recalc).Wait(); } else if (args[0] == "combo") { logger.LogInformation("producing combo ratings."); - ratingService.ProduceRatings(RatingCalcType.Combo, true).Wait(); - } - else if (args[0] == "combocontinue") - { - logger.LogInformation("producing combo ratings."); - ratingService.ProduceRatings(RatingCalcType.Combo, false).Wait(); + ratingService.ProduceRatings(RatingCalcType.Combo, recalc).Wait(); } else if (args[0] == "lsdups") { diff --git a/src/dsstats.ratings/RatingService.Arcade.cs b/src/dsstats.ratings/RatingService.Arcade.cs index 4da2c01e..e348ffed 100644 --- a/src/dsstats.ratings/RatingService.Arcade.cs +++ b/src/dsstats.ratings/RatingService.Arcade.cs @@ -15,6 +15,11 @@ public partial class RatingService { private async Task ProduceArcadeRatings(bool recalc) { + if (!recalc) + { + await ContinueArcadeRatings(); + return; + } using var scope = scopeFactory.CreateAsyncScope(); var context = scope.ServiceProvider.GetRequiredService(); var ratingSaveService = scope.ServiceProvider.GetRequiredService(); @@ -111,13 +116,13 @@ private async Task> GetArcadeCalcDtos(DsstatsCalcRequest request, Duration = s.Duration, GameMode = (int)s.GameMode, TournamentEdition = s.TournamentEdition, - Players = s.ArcadeReplayPlayers.Select(t => new PlayerCalcDto() + Players = s.ArcadeReplayDsPlayers.Select(t => new PlayerCalcDto() { - ReplayPlayerId = t.ArcadeReplayPlayerId, + ReplayPlayerId = t.PlayerId, GamePos = t.SlotNumber, PlayerResult = (int)t.PlayerResult, Team = t.Team, - PlayerId = new(t.ArcadePlayer.ProfileId, t.ArcadePlayer.RealmId, t.ArcadePlayer.RegionId) + PlayerId = new(t.Player!.ToonId, t.Player.RealmId, t.Player.RegionId) }).ToList() }) .Skip(request.Skip) @@ -137,15 +142,15 @@ orderby r.MaterializedArcadeReplayId Duration = r.Duration, GameMode = (int)r.GameMode, WinnerTeam = r.WinnerTeam, - Players = context.ArcadeReplayPlayers + Players = context.ArcadeReplayDsPlayers .Where(x => x.ArcadeReplayId == r.ArcadeReplayId) .Select(t => new PlayerCalcDto() { - ReplayPlayerId = t.ArcadeReplayPlayerId, + ReplayPlayerId = t.ArcadeReplayDsPlayerId, GamePos = t.SlotNumber, PlayerResult = (int)t.PlayerResult, Team = t.Team, - PlayerId = new(t.ArcadePlayer.ProfileId, t.ArcadePlayer.RealmId, t.ArcadePlayer.RegionId) + PlayerId = new(t.Player!.ToonId, t.Player.RealmId, t.Player.RegionId) }).ToList() }; return await query diff --git a/src/dsstats.ratings/RatingService.ArcadeContinue.cs b/src/dsstats.ratings/RatingService.ArcadeContinue.cs new file mode 100644 index 00000000..83c12cb0 --- /dev/null +++ b/src/dsstats.ratings/RatingService.ArcadeContinue.cs @@ -0,0 +1,222 @@ +using dsstats.db8; +using dsstats.shared.Calc; +using dsstats.shared.Interfaces; +using dsstats.shared; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using System.Collections.Frozen; +using Microsoft.EntityFrameworkCore; + +namespace dsstats.ratings; + +public partial class RatingService +{ + public async Task ContinueArcadeRatings() + { + using var scope = scopeFactory.CreateAsyncScope(); + var context = scope.ServiceProvider.GetRequiredService(); + var ratingSaveService = scope.ServiceProvider.GetRequiredService(); + + // await DebugDeleteArcadeRatings(); + + DsstatsCalcRequest dsstatsRequest = new() + { + FromDate = DateTime.UtcNow.AddDays(-6), + GameModes = new List() { 3, 4, 7 }, + Skip = 0, + Take = 2 * 3000 * 6 + }; + + await CreateMaterializedReplays(); + var calcDtos = await GetMaterializedArcadeContinueCalcDtos(dsstatsRequest, context); + + if (calcDtos.Count == 0) + { + logger.LogInformation("arcade ratings continue: nothing to do."); + return; + } + else + { + logger.LogInformation("arcade ratings continue: {count}", calcDtos.Count); + } + + var ratingRequest = new CalcRatingRequest() + { + RatingCalcType = RatingCalcType.Dsstats, + MmrIdRatings = new() + { + { 1, new() }, + { 2, new() }, + { 3, new() }, + { 4, new() } + }, + BannedPlayers = new Dictionary().ToFrozenDictionary() + }; + + + ratingRequest.ReplayPlayerRatingAppendId = await context.ArcadeReplayDsPlayerRatings + .OrderByDescending(o => o.ArcadeReplayDsPlayerRatingId) + .Select(s => s.ArcadeReplayDsPlayerRatingId) + .FirstOrDefaultAsync(); + ratingRequest.ReplayRatingAppendId = await context.ArcadeReplayRatings + .OrderByDescending(o => o.ArcadeReplayRatingId) + .Select(s => s.ArcadeReplayRatingId) + .FirstOrDefaultAsync(); + + ratingRequest.MmrIdRatings = await GetArcadeMmrIdRatings(calcDtos); + + + List replayRatings = new(); + + for (int i = 0; i < calcDtos.Count; i++) + { + var calcDto = calcDtos[i]; + var rating = ratings.lib.Ratings.ProcessReplay(calcDto, ratingRequest); + if (rating is not null && !calcDto.IsArcade) + { + replayRatings.Add(rating); + } + } + + await ratingSaveService.SaveArcadeStepResult(replayRatings, + ratingRequest.ReplayRatingAppendId, + ratingRequest.ReplayPlayerRatingAppendId); + + logger.LogInformation("arcade replay ratings produced: {count}", replayRatings.Count); + + await ratingSaveService.SaveContinueArcadeRatings(ratingRequest.MmrIdRatings, + replayRatings); + } + + private async Task>> GetArcadeMmrIdRatings(List calcDtos) + { + var ratingTypes = calcDtos.Select(s => s.GetRatingType()) + .Distinct() + .ToList(); + + var playerIds = calcDtos.SelectMany(s => s.Players).Select(s => s.PlayerId) + .Distinct() + .ToList(); + + var toonIds = playerIds.Select(s => s.ToonId) + .Distinct() + .ToList(); + + Dictionary> mmrIdRatings = new() + { + { 1, new() }, + { 2, new() }, + { 3, new() }, + { 4, new() } + }; + + using var scope = scopeFactory.CreateAsyncScope(); + var context = scope.ServiceProvider.GetRequiredService(); + + var query = from pr in context.ArcadePlayerRatings + join p in context.Players on pr.PlayerId equals p.PlayerId + where ratingTypes.Contains((int)pr.RatingType) + && toonIds.Contains(p.ToonId) + select new + { + pr.RatingType, + PlayerId = new PlayerId(p.ToonId, p.RealmId, p.RegionId), + pr.Games, + pr.Wins, + Mmr = pr.Rating, + pr.Consistency, + pr.Confidence, + }; + + var ratings = await query.ToListAsync(); + + foreach (var playerId in playerIds) + { + var plRatings = ratings.Where(s => s.PlayerId == playerId).ToList(); + + foreach (var plRating in plRatings) + { + mmrIdRatings[(int)plRating.RatingType][playerId] = new() + { + PlayerId = playerId, + Games = plRating.Games, + Wins = plRating.Wins, + Mmr = plRating.Mmr, + Consistency = plRating.Consistency, + Confidence = plRating.Confidence, + }; + } + } + + return mmrIdRatings; + } + + private async Task> GetMaterializedArcadeContinueCalcDtos(DsstatsCalcRequest request, ReplayContext context) + { + var query = from r in context.MaterializedArcadeReplays + join rr in context.ArcadeReplayRatings on r.ArcadeReplayId equals rr.ArcadeReplayId into grouping + from g in grouping.DefaultIfEmpty() + where r.CreatedAt >= request.FromDate && g == null + orderby r.MaterializedArcadeReplayId + select new CalcDto() + { + ReplayId = r.ArcadeReplayId, + GameTime = r.CreatedAt, + Duration = r.Duration, + GameMode = (int)r.GameMode, + WinnerTeam = r.WinnerTeam, + Players = context.ArcadeReplayDsPlayers + .Where(x => x.ArcadeReplayId == r.ArcadeReplayId) + .Select(t => new PlayerCalcDto() + { + ReplayPlayerId = t.ArcadeReplayDsPlayerId, + GamePos = t.SlotNumber, + PlayerResult = (int)t.PlayerResult, + Team = t.Team, + PlayerId = new(t.Player!.ToonId, t.Player.RealmId, t.Player.RegionId) + }).ToList() + }; + return await query + .AsSplitQuery() + .Skip(request.Skip) + .Take(request.Take) + .ToListAsync(); + } + + private async Task DebugDeleteArcadeRatings() + { + using var scope = scopeFactory.CreateAsyncScope(); + var context = scope.ServiceProvider.GetRequiredService(); + + var query = from r in context.ArcadeReplays + join rr in context.ArcadeReplayRatings on r.ArcadeReplayId equals rr.ArcadeReplayId + orderby r.CreatedAt descending + select rr; + + var ratings = await query + .Take(15000) + .ToListAsync(); + + if (ratings.Count == 0) + { + return; + } + + var replayIds = ratings.Select(s => s.ArcadeReplayId).ToList(); + + var replayPlayerIds = await context.ArcadeReplays + .Where(x => replayIds.Contains(x.ArcadeReplayId)) + .SelectMany(s => s.ArcadeReplayDsPlayers) + .Select(s => s.ArcadeReplayDsPlayerId) + .ToListAsync(); + + var replayPlayerRatings = await context.ArcadeReplayDsPlayerRatings + .Where(x => replayPlayerIds.Contains(x.ArcadeReplayDsPlayerId)) + .ToListAsync(); + + context.ArcadeReplayRatings.RemoveRange(ratings); + context.ArcadeReplayDsPlayerRatings.RemoveRange(replayPlayerRatings); + + await context.SaveChangesAsync(); + } +} diff --git a/src/dsstats.ratings/RatingService.Combo.cs b/src/dsstats.ratings/RatingService.Combo.cs index 8179f77f..442e856b 100644 --- a/src/dsstats.ratings/RatingService.Combo.cs +++ b/src/dsstats.ratings/RatingService.Combo.cs @@ -144,15 +144,15 @@ orderby r.MaterializedArcadeReplayId WinnerTeam = r.WinnerTeam, TournamentEdition = false, IsArcade = true, - Players = context.ArcadeReplayPlayers + Players = context.ArcadeReplayDsPlayers .Where(x => x.ArcadeReplayId == r.ArcadeReplayId) .Select(t => new PlayerCalcDto() { - ReplayPlayerId = t.ArcadeReplayPlayerId, + ReplayPlayerId = t.PlayerId, GamePos = t.SlotNumber, PlayerResult = (int)t.PlayerResult, Team = t.Team, - PlayerId = new(t.ArcadePlayer.ProfileId, t.ArcadePlayer.RealmId, t.ArcadePlayer.RegionId) + PlayerId = new(t.Player!.ToonId, t.Player.RealmId, t.Player.RegionId) }).ToList() }; diff --git a/src/dsstats.ratings/RatingsSaveService.Arcade.Changes.cs b/src/dsstats.ratings/RatingsSaveService.Arcade.Changes.cs index 1451d295..ccded320 100644 --- a/src/dsstats.ratings/RatingsSaveService.Arcade.Changes.cs +++ b/src/dsstats.ratings/RatingsSaveService.Arcade.Changes.cs @@ -27,16 +27,15 @@ private async Task SetArcadeRatingChange(ReplayContext context, RatingType ratin DateTime bp24h = DateTime.UtcNow.AddDays(-1); DateTime bp10d = DateTime.Today.AddDays(-10); - var query = from p in context.ArcadePlayers - from rp in p.ArcadeReplayPlayers - join pr in context.ArcadePlayerRatings on p.ArcadePlayerId equals pr.ArcadePlayerId - join rpr in context.ArcadeReplayPlayerRatings on rp.ArcadeReplayPlayerId equals rpr.ArcadeReplayPlayerId + var query = from rp in context.ArcadeReplayDsPlayers + join pr in context.ArcadePlayerRatings on rp.PlayerId equals pr.PlayerId + join rpr in context.ArcadeReplayDsPlayerRatings on rp.ArcadeReplayDsPlayerId equals rpr.ArcadeReplayDsPlayerId join rr in context.ArcadeReplayRatings on rp.ArcadeReplayId equals rr.ArcadeReplayId join r in context.ArcadeReplays on rp.ArcadeReplayId equals r.ArcadeReplayId where r.CreatedAt > fromDate && pr.RatingType == ratingType && rr.RatingType == ratingType select new { - PlayerId = new PlayerId(p.ProfileId, p.RegionId, p.RealmId), + PlayerId = new PlayerId(rp.Player!.ToonId, rp.Player!.RegionId, rp.Player!.RealmId), Id = pr.ArcadePlayerRatingId, GameTime = r.CreatedAt, Change = rpr.RatingChange diff --git a/src/dsstats.ratings/RatingsSaveService.Arcade.cs b/src/dsstats.ratings/RatingsSaveService.Arcade.cs index 6bd7223a..d6872ca1 100644 --- a/src/dsstats.ratings/RatingsSaveService.Arcade.cs +++ b/src/dsstats.ratings/RatingsSaveService.Arcade.cs @@ -22,7 +22,7 @@ public partial class RatingsSaveService bool append = replayRatingId > 0; List replayRatings = new(); - List replayPlayerRatings = new(); + List replayPlayerRatings = new(); for (int i = 0; i < ratings.Count; i++) { var rating = ratings[i]; @@ -42,21 +42,21 @@ public partial class RatingsSaveService replayPlayerRatings.Add(new() { - ArcadeReplayPlayerRatingId = replayPlayerRatingId, + ArcadeReplayDsPlayerRatingId = replayPlayerRatingId, GamePos = rp.GamePos, Rating = MathF.Round(rp.Rating, 2), RatingChange = MathF.Round(rp.RatingChange, 2), Games = rp.Games, Consistency = MathF.Round(rp.Consistency, 2), Confidence = MathF.Round(rp.Confidence, 2), - ArcadeReplayPlayerId = rp.ReplayPlayerId, + ArcadeReplayDsPlayerId = rp.ReplayPlayerId, ArcadeReplayRatingId = replayRatingId }); } } var replayRatingCsv = GetFileName(RatingCalcType.Arcade, nameof(ReplayContext.ArcadeReplayRatings)); - var replayPlayerRatingCsv = GetFileName(RatingCalcType.Arcade, nameof(ReplayContext.ArcadeReplayPlayerRatings)); + var replayPlayerRatingCsv = GetFileName(RatingCalcType.Arcade, nameof(ReplayContext.ArcadeReplayDsPlayerRatings)); FileMode fileMode = append ? FileMode.Append : FileMode.Create; using var stream1 = File.Open(replayRatingCsv, fileMode); @@ -84,9 +84,9 @@ public async Task SaveArcadePlayerRatings(Dictionary(); - var playerIds = (await context.ArcadePlayers - .Select(s => new { s.ProfileId, s.RealmId, s.RegionId, s.ArcadePlayerId }).ToListAsync()) - .ToDictionary(k => new PlayerId(k.ProfileId, k.RealmId, k.RegionId), v => v.ArcadePlayerId); + var playerIds = (await context.Players + .Select(s => new { s.ToonId, s.RealmId, s.RegionId, s.PlayerId }).ToListAsync()) + .ToDictionary(k => new PlayerId(k.ToonId, k.RealmId, k.RegionId), v => v.PlayerId); var options = scope.ServiceProvider.GetRequiredService>(); var connectionString = options.Value.ImportConnectionString; @@ -98,8 +98,8 @@ await Csv2Mysql(GetFileName(RatingCalcType.Arcade, nameof(ReplayContext.ArcadePl await FixArcadeForeignKey(connectionString); await Csv2Mysql(GetFileName(RatingCalcType.Arcade, nameof(ReplayContext.ArcadeReplayRatings)), nameof(ReplayContext.ArcadeReplayRatings), connectionString); - await Csv2Mysql(GetFileName(RatingCalcType.Arcade, nameof(ReplayContext.ArcadeReplayPlayerRatings)), - nameof(ReplayContext.ArcadeReplayPlayerRatings), connectionString); + await Csv2Mysql(GetFileName(RatingCalcType.Arcade, nameof(ReplayContext.ArcadeReplayDsPlayerRatings)), + nameof(ReplayContext.ArcadeReplayDsPlayerRatings), connectionString); await SetArcadePlayerRatingsPos(connectionString); await SetArcadeRatingChange(context, connectionString); @@ -180,9 +180,136 @@ private ArcadePlayerRatingCsv GetArcadePlayerRatingCsvLine(CalcRating calcRating Mvp = calcRating.Mvps, Consistency = calcRating.Consistency, Confidence = calcRating.Confidence, - ArcadePlayerId = playerId, + PlayerId = playerId, }; } + + public async Task SaveContinueArcadeRatings(Dictionary> mmrIdRatings, + List replayRatings) + { + using var scope = scopeFactory.CreateAsyncScope(); + var context = scope.ServiceProvider.GetRequiredService(); + var options = scope.ServiceProvider.GetRequiredService>(); + var connectionString = options.Value.ImportConnectionString; + + var playerIds = (await context.Players + .Select(s => new { s.ToonId, s.RealmId, s.RegionId, s.PlayerId }).ToListAsync()) + .ToDictionary(k => new PlayerId(k.ToonId, k.RealmId, k.RegionId), v => v.PlayerId); + + await ContinueArcadePlayerRatings(mmrIdRatings, playerIds); + await ContinueCsv2Mysql(GetFileName(RatingCalcType.Arcade, nameof(ReplayContext.ArcadeReplayRatings)), + nameof(ReplayContext.ArcadeReplayRatings), + connectionString); + await ContinueCsv2Mysql(GetFileName(RatingCalcType.Arcade, nameof(ReplayContext.ArcadeReplayDsPlayerRatings)), + nameof(ReplayContext.ArcadeReplayDsPlayerRatings), + connectionString); + await SetArcadePlayerRatingsPos(connectionString); + } + + private async Task ContinueArcadePlayerRatings(Dictionary> mmrIdRatings, + Dictionary playerIdDic) + { + using var scope = scopeFactory.CreateAsyncScope(); + var options = scope.ServiceProvider.GetRequiredService>(); + var connectionString = options.Value.ImportConnectionString; + + try + { + using var connection = new MySqlConnection(connectionString); + await connection.OpenAsync(); + + using var transaction = connection.BeginTransaction(); + var command = connection.CreateCommand(); + command.Transaction = transaction; + + command.CommandText = +$@"INSERT INTO {nameof(ReplayContext.ArcadePlayerRatings)} + ({nameof(ArcadePlayerRating.ArcadePlayerRatingId)}, + {nameof(ArcadePlayerRating.RatingType)}, + {nameof(ArcadePlayerRating.Rating)}, + {nameof(ArcadePlayerRating.Pos)}, + {nameof(ArcadePlayerRating.Games)}, + {nameof(ArcadePlayerRating.Wins)}, + {nameof(ArcadePlayerRating.Mvp)}, + {nameof(ArcadePlayerRating.TeamGames)}, + {nameof(ArcadePlayerRating.MainCount)}, + {nameof(ArcadePlayerRating.Main)}, + {nameof(ArcadePlayerRating.Consistency)}, + {nameof(ArcadePlayerRating.Confidence)}, + {nameof(ArcadePlayerRating.IsUploader)}, + {nameof(ArcadePlayerRating.PlayerId)}) +VALUES ((SELECT t.{nameof(ArcadePlayerRating.ArcadePlayerRatingId)} + FROM (SELECT * from {nameof(ReplayContext.ArcadePlayerRatings)} WHERE {nameof(ArcadePlayerRating.RatingType)} = @value1 + AND {nameof(ArcadePlayerRating.PlayerId)} = @value13) as t), + @value1,@value2,@value3,@value4,@value5,@value6,@value7,@value8,@value9,@value10,@value11,@value12,@value13) +ON DUPLICATE KEY UPDATE {nameof(ArcadePlayerRating.Rating)}=@value2, + {nameof(ArcadePlayerRating.Games)}=@value4, + {nameof(ArcadePlayerRating.Wins)}=@value5, + {nameof(ArcadePlayerRating.Consistency)}=@value10, + {nameof(ArcadePlayerRating.Confidence)}=@value11 +;"; + command.Transaction = transaction; + + List parameters = new List(); + for (int i = 1; i <= 13; i++) + { + var parameter = command.CreateParameter(); + parameter.ParameterName = $"@value{i}"; + command.Parameters.Add(parameter); + parameters.Add(parameter); + } + + foreach (var ent in mmrIdRatings) + { + + foreach (var calcEnt in ent.Value.Values) + { + if (!playerIdDic.TryGetValue(calcEnt.PlayerId, out var playerId)) + { + continue; + } + var rating = new ArcadePlayerRatingCsv() + { + RatingType = ent.Key, + Rating = calcEnt.Mmr, + Pos = 0, + Games = calcEnt.Games, + Wins = calcEnt.Wins, + Mvp = 0, + TeamGames = 0, + MainCount = 0, + Main = 0, + Consistency = calcEnt.Consistency, + Confidence = calcEnt.Confidence, + IsUploader = 0, + PlayerId = playerId + }; + + parameters[0].Value = rating.RatingType; + parameters[1].Value = rating.Rating; + parameters[2].Value = rating.Pos; + parameters[3].Value = rating.Games; + parameters[4].Value = rating.Wins; + parameters[5].Value = rating.Mvp; + parameters[6].Value = rating.TeamGames; + parameters[7].Value = rating.MainCount; + parameters[8].Value = rating.Main; + parameters[9].Value = rating.Consistency; + parameters[10].Value = rating.Confidence; + parameters[11].Value = rating.IsUploader; + parameters[12].Value = rating.PlayerId; + + command.CommandTimeout = 240; + await command.ExecuteNonQueryAsync(); + } + } + await transaction.CommitAsync(); + } + catch (Exception ex) + { + logger.LogError("failed continue arcadeplayers: {error}", ex.Message); + } + } } internal record ArcadePlayerRatingCsv @@ -200,7 +327,7 @@ internal record ArcadePlayerRatingCsv public double Consistency { get; set; } public double Confidence { get; set; } public int IsUploader { get; set; } - public int ArcadePlayerId { get; set; } + public int PlayerId { get; set; } } internal record ArcadeReplayRatingCsv @@ -213,15 +340,15 @@ internal record ArcadeReplayRatingCsv public int AvgRating { get; set; } } -internal record ArcadeReplayPlayerRatingCsv +internal record ArcadeReplayDsPlayerRatingCsv { - public int ArcadeReplayPlayerRatingId { get; set; } + public int ArcadeReplayDsPlayerRatingId { get; set; } public int GamePos { get; set; } public float Rating { get; set; } public float RatingChange { get; set; } public int Games { get; set; } public float Consistency { get; set; } public float Confidence { get; set; } - public int ArcadeReplayPlayerId { get; set; } + public int ArcadeReplayDsPlayerId { get; set; } public int ArcadeReplayRatingId { get; set; } } \ No newline at end of file diff --git a/src/dsstats.razorlib/Replays/ArcadeReplayComponent.razor b/src/dsstats.razorlib/Replays/ArcadeReplayComponent.razor index 18427a04..e0076214 100644 --- a/src/dsstats.razorlib/Replays/ArcadeReplayComponent.razor +++ b/src/dsstats.razorlib/Replays/ArcadeReplayComponent.razor @@ -73,10 +73,10 @@ - @foreach (var player in Replay.ArcadeReplayPlayers.Where(x => x.Team == i).OrderBy(o => o.SlotNumber)) + @foreach (var player in Replay.ArcadeReplayDsPlayers.Where(x => x.Team == i).OrderBy(o => o.SlotNumber)) { - var plRating = Replay.ArcadeReplayRating?.ArcadeReplayPlayerRatings.FirstOrDefault(f => f.GamePos == player.SlotNumber); - + var plRating = Replay.ArcadeReplayRating?.ArcadeReplayDsPlayerRatings.FirstOrDefault(f => f.GamePos == player.SlotNumber); + @player.SlotNumber @if (plRating != null) diff --git a/src/dsstats.shared/ArcadeReplayDto.cs b/src/dsstats.shared/ArcadeReplayDto.cs index 9d341957..faa8e8da 100644 --- a/src/dsstats.shared/ArcadeReplayDto.cs +++ b/src/dsstats.shared/ArcadeReplayDto.cs @@ -11,7 +11,7 @@ public record ArcadePlayerRatingDto public int Pos { get; init; } public int Games { get; init; } public int Wins { get; init; } - public ArcadePlayerRatingPlayerDto ArcadePlayer { get; init; } = null!; + public PlayerDto Player { get; init; } = null!; public ArcadePlayerRatingChangeDto? ArcadePlayerRatingChange { get; init; } } @@ -53,7 +53,7 @@ public record ArcadeReplayDto public int WinnerTeam { get; set; } public int Duration { get; set; } public ArcadeReplayRatingDto? ArcadeReplayRating { get; set; } - public List ArcadeReplayPlayers { get; set; } = new(); + public List ArcadeReplayDsPlayers { get; set; } = new(); public string GetBnetHash() { return $"{RegionId}|{BnetBucketId}|{BnetRecordId}"; @@ -70,6 +70,16 @@ public record ArcadeReplayPlayerDto public ArcadePlayerReplayDto ArcadePlayer { get; set; } = new(); } +public record ArcadeReplayDsPlayerDto +{ + public string Name { get; set; } = string.Empty; + public int SlotNumber { get; set; } + public int Team { get; set; } + public int Discriminator { get; set; } + public PlayerResult PlayerResult { get; set; } + public PlayerDto Player { get; set; } = new(); +} + public record ArcadePlayerReplayDto { public int ProfileId { get; set; } @@ -81,7 +91,7 @@ public record ArcadeReplayRatingDto { public RatingType RatingType { get; set; } public float ExpectationToWin { get; set; } - public List ArcadeReplayPlayerRatings { get; set; } = new(); + public List ArcadeReplayDsPlayerRatings { get; set; } = new(); } public record ArcadeReplayPlayerRatingDto @@ -101,7 +111,6 @@ public record ArcadePlayerDto public int RegionId { get; set; } public int RealmId { get; set; } public int ProfileId { get; set; } - public List ArcadePlayerRatings { get; set; } = new(); } public record ArcadePlayerRatingDetailDto @@ -119,14 +128,14 @@ public record ArcadePlayerRatingDetailDto public record ArcadeReplayListRatingDto : ArcadeReplayListDto { public ArcadeReplayRatingListDto? ArcadeReplayRating { get; set; } - public List ArcadeReplayPlayers { get; set; } = new(); + public List ArcadeReplayDsPlayers { get; set; } = new(); } public record ArcadeReplayPlayerListDto { public string Name { get; set; } = string.Empty; public int SlotNumber { get; set; } - public ArcadePlayerListDto ArcadePlayer { get; set; } = null!; + public PlayerDto Player { get; set; } = null!; } public record ArcadePlayerListDto @@ -136,7 +145,7 @@ public record ArcadePlayerListDto public record ArcadeReplayRatingListDto { - public List ArcadeReplayPlayerRatings { get; set; } = new(); + public List ArcadeReplayDsPlayerRatings { get; set; } = new(); } public record ArcadeReplayPlayerRatingListDto diff --git a/src/dsstats.shared/Interfaces/IImportService.cs b/src/dsstats.shared/Interfaces/IImportService.cs new file mode 100644 index 00000000..04bbc381 --- /dev/null +++ b/src/dsstats.shared/Interfaces/IImportService.cs @@ -0,0 +1,13 @@ +namespace dsstats.shared.Interfaces; + +public interface IImportService +{ + bool IsInit { get; } + + Task GetPlayerIdAsync(PlayerId playerId, string name); + Task> GetPlayerIdDictionary(); + Task Import(List replayDtos, List? uploaderPlayerIds = null); + Task Init(); + Task SetPreRatings(); + Task> MapArcadePlayers(); +} \ No newline at end of file diff --git a/src/dsstats.shared/Interfaces/IRatingsSaveService.cs b/src/dsstats.shared/Interfaces/IRatingsSaveService.cs index 4a7cde69..89b37f1d 100644 --- a/src/dsstats.shared/Interfaces/IRatingsSaveService.cs +++ b/src/dsstats.shared/Interfaces/IRatingsSaveService.cs @@ -12,4 +12,6 @@ public interface IRatingsSaveService Task SaveDsstatsPlayerRatings(Dictionary> mmrIdRatings, FrozenDictionary softbans, bool isContinue); Task<(int, int)> SaveDsstatsStepResult(List ratings, int replayRatingId = 0, int replayPlayerRatingId = 0); Task SaveContinueComboRatings(Dictionary> mmrIdRatings, List replayRatings); + Task SaveContinueArcadeRatings(Dictionary> mmrIdRatings, + List replayRatings); } \ No newline at end of file diff --git a/src/tests/dsstats.ratings.tests/ComboRatingTests.cs b/src/tests/dsstats.ratings.tests/ComboRatingTests.cs index 85fe26d9..210ae6c9 100644 --- a/src/tests/dsstats.ratings.tests/ComboRatingTests.cs +++ b/src/tests/dsstats.ratings.tests/ComboRatingTests.cs @@ -1,5 +1,4 @@ -using dsstats.api.Services; -using dsstats.db8; +using dsstats.db8; using dsstats.db8.AutoMapper; using dsstats.db8services; using dsstats.db8services.Import; @@ -61,7 +60,7 @@ public ComboRatingsTests() services.AddScoped(); services.AddSingleton(); services.AddSingleton(); - services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); services.AddScoped(); @@ -211,7 +210,7 @@ public void T05AdvancedContinueRecalcRatingTest() { using var scope = serviceProvider.CreateScope(); var context = scope.ServiceProvider.GetRequiredService(); - var importService = scope.ServiceProvider.GetRequiredService(); + var importService = scope.ServiceProvider.GetRequiredService(); var ratingService = scope.ServiceProvider.GetRequiredService(); DateTime startTime = DateTime.UtcNow; @@ -291,21 +290,21 @@ public ArcadeReplayDto GetBasicArcadeReplayDto(GameMode gameMode = GameMode.Comm RegionId = 1, WinnerTeam = winnerTeam, Duration = 500, - ArcadeReplayPlayers = GetBasicArcadeReplayPlayerDtos(winnerTeam) + ArcadeReplayDsPlayers = GetBasicArcadeReplayPlayerDtos(winnerTeam) }; } - public List GetBasicArcadeReplayPlayerDtos(int winnerTeam) + public List GetBasicArcadeReplayPlayerDtos(int winnerTeam) { var players = GetDefaultArcadePlayers(); - return players.Select((s, i) => new ArcadeReplayPlayerDto() + return players.Select((s, i) => new ArcadeReplayDsPlayerDto() { Name = "Test", SlotNumber = i + 1, Team = i + 1 <= 3 ? 1 : 2, PlayerResult = winnerTeam == 1 ? i + 1 <= 3 ? PlayerResult.Win : PlayerResult.Los : i + 1 <= 3 ? PlayerResult.Los : PlayerResult.Win, - ArcadePlayer = s, + Player = s, }).ToList(); } @@ -371,15 +370,15 @@ public PlayerDto[] GetDefaultPlayers() .ToArray(); } - public ArcadePlayerReplayDto[] GetDefaultArcadePlayers() + public PlayerDto[] GetDefaultArcadePlayers() { var playerPool = this.playerPool.ToArray(); Random.Shared.Shuffle(playerPool); return playerPool.Take(6) - .Select(s => new ArcadePlayerReplayDto() + .Select(s => new PlayerDto() { - ProfileId = s.ToonId, + ToonId = s.ToonId, RealmId = s.RealmId, RegionId = s.RegionId, }) diff --git a/src/tests/dsstats.ratings.tests/DuplicateTests.cs b/src/tests/dsstats.ratings.tests/DuplicateTests.cs index fea26a27..a8dd3042 100644 --- a/src/tests/dsstats.ratings.tests/DuplicateTests.cs +++ b/src/tests/dsstats.ratings.tests/DuplicateTests.cs @@ -73,7 +73,7 @@ public DuplicateTests() services.AddSingleton(); services.AddSingleton(); - services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); services.AddScoped(); @@ -87,7 +87,7 @@ public void T01BasicDuplicateTest() using var scope = serviceProvider.CreateScope(); var context = scope.ServiceProvider.GetRequiredService(); var replayRepository = scope.ServiceProvider.GetRequiredService(); - var importService = scope.ServiceProvider.GetRequiredService(); + var importService = scope.ServiceProvider.GetRequiredService(); context.Database.EnsureDeleted(); context.Database.Migrate(); @@ -121,7 +121,7 @@ public void T02AdvancedDuplicateTest() using var scope = serviceProvider.CreateScope(); var context = scope.ServiceProvider.GetRequiredService(); var replayRepository = scope.ServiceProvider.GetRequiredService(); - var importService = scope.ServiceProvider.GetRequiredService(); + var importService = scope.ServiceProvider.GetRequiredService(); var replayCountBefore = context.Replays.Count(); @@ -154,7 +154,7 @@ public void T03LastSpawnDuplicateTest() using var scope = serviceProvider.CreateScope(); var context = scope.ServiceProvider.GetRequiredService(); var replayRepository = scope.ServiceProvider.GetRequiredService(); - var importService = scope.ServiceProvider.GetRequiredService(); + var importService = scope.ServiceProvider.GetRequiredService(); var replayCountBefore = context.Replays.Count(); @@ -196,7 +196,7 @@ public void T04LastSpawnDuplicateOrder1Test() using var scope = serviceProvider.CreateScope(); var context = scope.ServiceProvider.GetRequiredService(); var replayRepository = scope.ServiceProvider.GetRequiredService(); - var importService = scope.ServiceProvider.GetRequiredService(); + var importService = scope.ServiceProvider.GetRequiredService(); var replayCountBefore = context.Replays.Count(); @@ -235,7 +235,7 @@ public void T05LastSpawnDuplicateOrder2Test() using var scope = serviceProvider.CreateScope(); var context = scope.ServiceProvider.GetRequiredService(); var replayRepository = scope.ServiceProvider.GetRequiredService(); - var importService = scope.ServiceProvider.GetRequiredService(); + var importService = scope.ServiceProvider.GetRequiredService(); var replayCountBefore = context.Replays.Count(); diff --git a/src/tests/dsstats.ratings.tests/ImportSqliteTests.cs b/src/tests/dsstats.ratings.tests/ImportSqliteTests.cs index f9d7a6df..fa24d152 100644 --- a/src/tests/dsstats.ratings.tests/ImportSqliteTests.cs +++ b/src/tests/dsstats.ratings.tests/ImportSqliteTests.cs @@ -68,7 +68,7 @@ public ImportSqliteTests() services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); - services.AddSingleton(); + services.AddSingleton(); services.AddScoped(); @@ -81,7 +81,7 @@ public void T01BasicImportTest() using var scope = serviceProvider.CreateScope(); var context = scope.ServiceProvider.GetRequiredService(); var replayRepository = scope.ServiceProvider.GetRequiredService(); - var importService = scope.ServiceProvider.GetRequiredService(); + var importService = scope.ServiceProvider.GetRequiredService(); // context.Database.Migrate(); context.Database.EnsureDeleted(); @@ -122,7 +122,7 @@ public void T02AdvancedImportTest() using var scope = serviceProvider.CreateScope(); var context = scope.ServiceProvider.GetRequiredService(); var replayRepository = scope.ServiceProvider.GetRequiredService(); - var importService = scope.ServiceProvider.GetRequiredService(); + var importService = scope.ServiceProvider.GetRequiredService(); using var md5 = MD5.Create(); diff --git a/src/tests/dsstats.ratings.tests/ImportTests.cs b/src/tests/dsstats.ratings.tests/ImportTests.cs index 041355ba..9df83277 100644 --- a/src/tests/dsstats.ratings.tests/ImportTests.cs +++ b/src/tests/dsstats.ratings.tests/ImportTests.cs @@ -73,7 +73,7 @@ public ImportTests() services.AddSingleton(); services.AddSingleton(); - services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); services.AddScoped(); @@ -87,7 +87,7 @@ public void T01BasicImportTest() using var scope = serviceProvider.CreateScope(); var context = scope.ServiceProvider.GetRequiredService(); var replayRepository = scope.ServiceProvider.GetRequiredService(); - var importService = scope.ServiceProvider.GetRequiredService(); + var importService = scope.ServiceProvider.GetRequiredService(); context.Database.EnsureDeleted(); context.Database.Migrate(); @@ -127,7 +127,7 @@ public void T02AdvancedImportTest() using var scope = serviceProvider.CreateScope(); var context = scope.ServiceProvider.GetRequiredService(); var replayRepository = scope.ServiceProvider.GetRequiredService(); - var importService = scope.ServiceProvider.GetRequiredService(); + var importService = scope.ServiceProvider.GetRequiredService(); using var md5 = MD5.Create(); @@ -166,7 +166,7 @@ public void T03ImportPreRatingTest() using var scope = serviceProvider.CreateScope(); var context = scope.ServiceProvider.GetRequiredService(); var replayRepository = scope.ServiceProvider.GetRequiredService(); - var importService = scope.ServiceProvider.GetRequiredService(); + var importService = scope.ServiceProvider.GetRequiredService(); context.Database.EnsureDeleted(); context.Database.Migrate(); @@ -195,7 +195,7 @@ public void T04ImportPreRatingDoubleTest() using var scope = serviceProvider.CreateScope(); var context = scope.ServiceProvider.GetRequiredService(); var replayRepository = scope.ServiceProvider.GetRequiredService(); - var importService = scope.ServiceProvider.GetRequiredService(); + var importService = scope.ServiceProvider.GetRequiredService(); using var md5 = MD5.Create(); @@ -248,7 +248,7 @@ public void T05ImportPreRatingStdTest() using var scope = serviceProvider.CreateScope(); var context = scope.ServiceProvider.GetRequiredService(); var replayRepository = scope.ServiceProvider.GetRequiredService(); - var importService = scope.ServiceProvider.GetRequiredService(); + var importService = scope.ServiceProvider.GetRequiredService(); using var md5 = MD5.Create(); @@ -274,7 +274,7 @@ public void T06AdvancedImportPreRatingTest() using var scope = serviceProvider.CreateScope(); var context = scope.ServiceProvider.GetRequiredService(); var replayRepository = scope.ServiceProvider.GetRequiredService(); - var importService = scope.ServiceProvider.GetRequiredService(); + var importService = scope.ServiceProvider.GetRequiredService(); using var md5 = MD5.Create(); diff --git a/src/tests/dsstats.ratings.tests/PreRatingTests.cs b/src/tests/dsstats.ratings.tests/PreRatingTests.cs index 21403c33..80f7a71e 100644 --- a/src/tests/dsstats.ratings.tests/PreRatingTests.cs +++ b/src/tests/dsstats.ratings.tests/PreRatingTests.cs @@ -51,7 +51,7 @@ public PreRatingTests() services.AddSingleton(); services.AddSingleton(); - services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); services.AddScoped(); @@ -66,7 +66,7 @@ public void T01BasicPreRatingTest() using var scope = serviceProvider.CreateScope(); var context = scope.ServiceProvider.GetRequiredService(); var replayRepository = scope.ServiceProvider.GetRequiredService(); - var importService = scope.ServiceProvider.GetRequiredService(); + var importService = scope.ServiceProvider.GetRequiredService(); var ratingService = scope.ServiceProvider.GetRequiredService(); context.Database.EnsureDeleted(); @@ -109,7 +109,7 @@ public void T02AddPreRatingTest() using var scope = serviceProvider.CreateScope(); var context = scope.ServiceProvider.GetRequiredService(); var replayRepository = scope.ServiceProvider.GetRequiredService(); - var importService = scope.ServiceProvider.GetRequiredService(); + var importService = scope.ServiceProvider.GetRequiredService(); var comboPreRatingsBefore = context.ComboReplayRatings .Where(x => x.IsPreRating) @@ -142,7 +142,7 @@ public void T03SinglePreRatingTest() using var scope = serviceProvider.CreateScope(); var context = scope.ServiceProvider.GetRequiredService(); var replayRepository = scope.ServiceProvider.GetRequiredService(); - var importService = scope.ServiceProvider.GetRequiredService(); + var importService = scope.ServiceProvider.GetRequiredService(); var comboPreRatingsBefore = context.ComboReplayRatings .Where(x => x.IsPreRating) @@ -172,7 +172,7 @@ public void T04ConsConfPreRatingTest() using var scope = serviceProvider.CreateScope(); var context = scope.ServiceProvider.GetRequiredService(); var replayRepository = scope.ServiceProvider.GetRequiredService(); - var importService = scope.ServiceProvider.GetRequiredService(); + var importService = scope.ServiceProvider.GetRequiredService(); var replaysService = scope.ServiceProvider.GetRequiredService(); var comboPreRatingsBefore = context.ComboReplayRatings diff --git a/src/tests/dsstats.ratings.tests/RatingsTests.cs b/src/tests/dsstats.ratings.tests/RatingsTests.cs index dcf17731..a689c3ed 100644 --- a/src/tests/dsstats.ratings.tests/RatingsTests.cs +++ b/src/tests/dsstats.ratings.tests/RatingsTests.cs @@ -61,7 +61,7 @@ public RatingsTests() services.AddScoped(); services.AddSingleton(); services.AddSingleton(); - services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); services.AddScoped(); @@ -368,7 +368,7 @@ public void T08BasicRecalcRatingTest() using var scope = serviceProvider.CreateScope(); var context = scope.ServiceProvider.GetRequiredService(); var ratingService = scope.ServiceProvider.GetRequiredService(); - var importService = scope.ServiceProvider.GetRequiredService(); + var importService = scope.ServiceProvider.GetRequiredService(); using var md5 = MD5.Create(); var replayDto = GetBasicReplayDto(md5); diff --git a/src/tests/dsstats.ratings.tests/UploadTests.cs b/src/tests/dsstats.ratings.tests/UploadTests.cs index 2d5fb3c1..a931049c 100644 --- a/src/tests/dsstats.ratings.tests/UploadTests.cs +++ b/src/tests/dsstats.ratings.tests/UploadTests.cs @@ -73,7 +73,7 @@ public UploadTests() services.AddSingleton(); services.AddSingleton(); - services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); services.AddSingleton();