From cd862f5701a219a7aca9bc419668601fcb769c52 Mon Sep 17 00:00:00 2001
From: LumaLivy <7350336+LumaLivy@users.noreply.github.com>
Date: Fri, 10 Dec 2021 23:36:36 -0500
Subject: [PATCH 1/6] Database migrations
---
...0211211043517_CacheReviewStats.Designer.cs | 828 ++++++++++++++++++
.../20211211043517_CacheReviewStats.cs | 66 ++
.../Migrations/DatabaseModelSnapshot.cs | 14 +-
3 files changed, 905 insertions(+), 3 deletions(-)
create mode 100644 ProjectLighthouse/Migrations/20211211043517_CacheReviewStats.Designer.cs
create mode 100644 ProjectLighthouse/Migrations/20211211043517_CacheReviewStats.cs
diff --git a/ProjectLighthouse/Migrations/20211211043517_CacheReviewStats.Designer.cs b/ProjectLighthouse/Migrations/20211211043517_CacheReviewStats.Designer.cs
new file mode 100644
index 00000000..ca4261c1
--- /dev/null
+++ b/ProjectLighthouse/Migrations/20211211043517_CacheReviewStats.Designer.cs
@@ -0,0 +1,828 @@
+//
+using LBPUnion.ProjectLighthouse;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+#nullable disable
+
+namespace ProjectLighthouse.Migrations
+{
+ [DbContext(typeof(Database))]
+ [Migration("20211211043517_CacheReviewStats")]
+ partial class CacheReviewStats
+ {
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "6.0.0")
+ .HasAnnotation("Relational:MaxIdentifierLength", 64);
+
+ modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.AuthenticationAttempt", b =>
+ {
+ b.Property("AuthenticationAttemptId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("GameTokenId")
+ .HasColumnType("int");
+
+ b.Property("IPAddress")
+ .HasColumnType("longtext");
+
+ b.Property("Platform")
+ .HasColumnType("int");
+
+ b.Property("Timestamp")
+ .HasColumnType("bigint");
+
+ b.HasKey("AuthenticationAttemptId");
+
+ b.HasIndex("GameTokenId");
+
+ b.ToTable("AuthenticationAttempts");
+ });
+
+ modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.GameToken", b =>
+ {
+ b.Property("TokenId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("Approved")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("GameVersion")
+ .HasColumnType("int");
+
+ b.Property("UserId")
+ .HasColumnType("int");
+
+ b.Property("UserLocation")
+ .HasColumnType("longtext");
+
+ b.Property("UserToken")
+ .HasColumnType("longtext");
+
+ b.HasKey("TokenId");
+
+ b.ToTable("GameTokens");
+ });
+
+ modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.HeartedProfile", b =>
+ {
+ b.Property("HeartedProfileId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("HeartedUserId")
+ .HasColumnType("int");
+
+ b.Property("UserId")
+ .HasColumnType("int");
+
+ b.HasKey("HeartedProfileId");
+
+ b.HasIndex("HeartedUserId");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("HeartedProfiles");
+ });
+
+ modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Levels.HeartedLevel", b =>
+ {
+ b.Property("HeartedLevelId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("SlotId")
+ .HasColumnType("int");
+
+ b.Property("UserId")
+ .HasColumnType("int");
+
+ b.HasKey("HeartedLevelId");
+
+ b.HasIndex("SlotId");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("HeartedLevels");
+ });
+
+ modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Levels.QueuedLevel", b =>
+ {
+ b.Property("QueuedLevelId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("SlotId")
+ .HasColumnType("int");
+
+ b.Property("UserId")
+ .HasColumnType("int");
+
+ b.HasKey("QueuedLevelId");
+
+ b.HasIndex("SlotId");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("QueuedLevels");
+ });
+
+ modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Levels.RatedLevel", b =>
+ {
+ b.Property("RatedLevelId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("Rating")
+ .HasColumnType("int");
+
+ b.Property("RatingLBP1")
+ .HasColumnType("double");
+
+ b.Property("SlotId")
+ .HasColumnType("int");
+
+ b.Property("UserId")
+ .HasColumnType("int");
+
+ b.HasKey("RatedLevelId");
+
+ b.HasIndex("SlotId");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("RatedLevels");
+ });
+
+ modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Levels.Slot", b =>
+ {
+ b.Property("SlotId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("AuthorLabels")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("BackgroundHash")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("CreatorId")
+ .HasColumnType("int");
+
+ b.Property("Description")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("FirstUploaded")
+ .HasColumnType("bigint");
+
+ b.Property("GameVersion")
+ .HasColumnType("int");
+
+ b.Property("IconHash")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("InitiallyLocked")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("LastUpdated")
+ .HasColumnType("bigint");
+
+ b.Property("Lbp1Only")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("LevelType")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("LocationId")
+ .HasColumnType("int");
+
+ b.Property("MaximumPlayers")
+ .HasColumnType("int");
+
+ b.Property("MinimumPlayers")
+ .HasColumnType("int");
+
+ b.Property("MoveRequired")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("PlaysLBP1")
+ .HasColumnType("int");
+
+ b.Property("PlaysLBP1Complete")
+ .HasColumnType("int");
+
+ b.Property("PlaysLBP1Unique")
+ .HasColumnType("int");
+
+ b.Property("PlaysLBP2")
+ .HasColumnType("int");
+
+ b.Property("PlaysLBP2Complete")
+ .HasColumnType("int");
+
+ b.Property("PlaysLBP2Unique")
+ .HasColumnType("int");
+
+ b.Property("PlaysLBP3")
+ .HasColumnType("int");
+
+ b.Property("PlaysLBP3Complete")
+ .HasColumnType("int");
+
+ b.Property("PlaysLBP3Unique")
+ .HasColumnType("int");
+
+ b.Property("PlaysLBPVita")
+ .HasColumnType("int");
+
+ b.Property("PlaysLBPVitaComplete")
+ .HasColumnType("int");
+
+ b.Property("PlaysLBPVitaUnique")
+ .HasColumnType("int");
+
+ b.Property("ResourceCollection")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("RootLevel")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("Shareable")
+ .HasColumnType("int");
+
+ b.Property("SubLevel")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("TeamPick")
+ .HasColumnType("tinyint(1)");
+
+ b.HasKey("SlotId");
+
+ b.HasIndex("CreatorId");
+
+ b.HasIndex("LocationId");
+
+ b.ToTable("Slots");
+ });
+
+ modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Levels.VisitedLevel", b =>
+ {
+ b.Property("VisitedLevelId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("PlaysLBP1")
+ .HasColumnType("int");
+
+ b.Property("PlaysLBP2")
+ .HasColumnType("int");
+
+ b.Property("PlaysLBP3")
+ .HasColumnType("int");
+
+ b.Property("PlaysLBPVita")
+ .HasColumnType("int");
+
+ b.Property("SlotId")
+ .HasColumnType("int");
+
+ b.Property("UserId")
+ .HasColumnType("int");
+
+ b.HasKey("VisitedLevelId");
+
+ b.HasIndex("SlotId");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("VisitedLevels");
+ });
+
+ modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Photo", b =>
+ {
+ b.Property("PhotoId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("CreatorId")
+ .HasColumnType("int");
+
+ b.Property("LargeHash")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("MediumHash")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("PhotoSubjectCollection")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("PlanHash")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("SmallHash")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("Timestamp")
+ .HasColumnType("bigint");
+
+ b.HasKey("PhotoId");
+
+ b.HasIndex("CreatorId");
+
+ b.ToTable("Photos");
+ });
+
+ modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.PhotoSubject", b =>
+ {
+ b.Property("PhotoSubjectId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("Bounds")
+ .HasColumnType("longtext");
+
+ b.Property("UserId")
+ .HasColumnType("int");
+
+ b.HasKey("PhotoSubjectId");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("PhotoSubjects");
+ });
+
+ modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Profiles.Comment", b =>
+ {
+ b.Property("CommentId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("Message")
+ .HasColumnType("longtext");
+
+ b.Property("PosterUserId")
+ .HasColumnType("int");
+
+ b.Property("TargetUserId")
+ .HasColumnType("int");
+
+ b.Property("ThumbsDown")
+ .HasColumnType("int");
+
+ b.Property("ThumbsUp")
+ .HasColumnType("int");
+
+ b.Property("Timestamp")
+ .HasColumnType("bigint");
+
+ b.HasKey("CommentId");
+
+ b.HasIndex("PosterUserId");
+
+ b.HasIndex("TargetUserId");
+
+ b.ToTable("Comments");
+ });
+
+ modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Profiles.LastMatch", b =>
+ {
+ b.Property("UserId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("GameVersion")
+ .HasColumnType("int");
+
+ b.Property("Timestamp")
+ .HasColumnType("bigint");
+
+ b.HasKey("UserId");
+
+ b.ToTable("LastMatches");
+ });
+
+ modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Profiles.Location", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("X")
+ .HasColumnType("int");
+
+ b.Property("Y")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.ToTable("Locations");
+ });
+
+ modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Reviews.RatedReview", b =>
+ {
+ b.Property("RatedReviewId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("ReviewId")
+ .HasColumnType("int");
+
+ b.Property("Thumb")
+ .HasColumnType("int");
+
+ b.Property("UserId")
+ .HasColumnType("int");
+
+ b.HasKey("RatedReviewId");
+
+ b.HasIndex("ReviewId");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("RatedReviews");
+ });
+
+ modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Reviews.Review", b =>
+ {
+ b.Property("ReviewId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("Deleted")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("DeletedBy")
+ .HasColumnType("int");
+
+ b.Property("LabelCollection")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("ReviewerId")
+ .HasColumnType("int");
+
+ b.Property("SlotId")
+ .HasColumnType("int");
+
+ b.Property("Text")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("Thumb")
+ .HasColumnType("int");
+
+ b.Property("ThumbsDown")
+ .HasColumnType("int");
+
+ b.Property("ThumbsUp")
+ .HasColumnType("int");
+
+ b.Property("Timestamp")
+ .HasColumnType("bigint");
+
+ b.HasKey("ReviewId");
+
+ b.HasIndex("ReviewerId");
+
+ b.HasIndex("SlotId");
+
+ b.ToTable("Reviews");
+ });
+
+ modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Score", b =>
+ {
+ b.Property("ScoreId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("PlayerIdCollection")
+ .HasColumnType("longtext");
+
+ b.Property("Points")
+ .HasColumnType("int");
+
+ b.Property("SlotId")
+ .HasColumnType("int");
+
+ b.Property("Type")
+ .HasColumnType("int");
+
+ b.HasKey("ScoreId");
+
+ b.HasIndex("SlotId");
+
+ b.ToTable("Scores");
+ });
+
+ modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.User", b =>
+ {
+ b.Property("UserId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("Biography")
+ .HasColumnType("longtext");
+
+ b.Property("Game")
+ .HasColumnType("int");
+
+ b.Property("IconHash")
+ .HasColumnType("longtext");
+
+ b.Property("IsAdmin")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("LocationId")
+ .HasColumnType("int");
+
+ b.Property("Password")
+ .HasColumnType("longtext");
+
+ b.Property("PasswordResetRequired")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("Pins")
+ .HasColumnType("longtext");
+
+ b.Property("PlanetHash")
+ .HasColumnType("longtext");
+
+ b.Property("Username")
+ .HasColumnType("longtext");
+
+ b.HasKey("UserId");
+
+ b.HasIndex("LocationId");
+
+ b.ToTable("Users");
+ });
+
+ modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.WebToken", b =>
+ {
+ b.Property("TokenId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("UserId")
+ .HasColumnType("int");
+
+ b.Property("UserToken")
+ .HasColumnType("longtext");
+
+ b.HasKey("TokenId");
+
+ b.ToTable("WebTokens");
+ });
+
+ modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.AuthenticationAttempt", b =>
+ {
+ b.HasOne("LBPUnion.ProjectLighthouse.Types.GameToken", "GameToken")
+ .WithMany()
+ .HasForeignKey("GameTokenId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("GameToken");
+ });
+
+ modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.HeartedProfile", b =>
+ {
+ b.HasOne("LBPUnion.ProjectLighthouse.Types.User", "HeartedUser")
+ .WithMany()
+ .HasForeignKey("HeartedUserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("LBPUnion.ProjectLighthouse.Types.User", "User")
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("HeartedUser");
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Levels.HeartedLevel", b =>
+ {
+ b.HasOne("LBPUnion.ProjectLighthouse.Types.Levels.Slot", "Slot")
+ .WithMany()
+ .HasForeignKey("SlotId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("LBPUnion.ProjectLighthouse.Types.User", "User")
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Slot");
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Levels.QueuedLevel", b =>
+ {
+ b.HasOne("LBPUnion.ProjectLighthouse.Types.Levels.Slot", "Slot")
+ .WithMany()
+ .HasForeignKey("SlotId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("LBPUnion.ProjectLighthouse.Types.User", "User")
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Slot");
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Levels.RatedLevel", b =>
+ {
+ b.HasOne("LBPUnion.ProjectLighthouse.Types.Levels.Slot", "Slot")
+ .WithMany()
+ .HasForeignKey("SlotId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("LBPUnion.ProjectLighthouse.Types.User", "User")
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Slot");
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Levels.Slot", b =>
+ {
+ b.HasOne("LBPUnion.ProjectLighthouse.Types.User", "Creator")
+ .WithMany()
+ .HasForeignKey("CreatorId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("LBPUnion.ProjectLighthouse.Types.Profiles.Location", "Location")
+ .WithMany()
+ .HasForeignKey("LocationId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Creator");
+
+ b.Navigation("Location");
+ });
+
+ modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Levels.VisitedLevel", b =>
+ {
+ b.HasOne("LBPUnion.ProjectLighthouse.Types.Levels.Slot", "Slot")
+ .WithMany()
+ .HasForeignKey("SlotId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("LBPUnion.ProjectLighthouse.Types.User", "User")
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Slot");
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Photo", b =>
+ {
+ b.HasOne("LBPUnion.ProjectLighthouse.Types.User", "Creator")
+ .WithMany()
+ .HasForeignKey("CreatorId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Creator");
+ });
+
+ modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.PhotoSubject", b =>
+ {
+ b.HasOne("LBPUnion.ProjectLighthouse.Types.User", "User")
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Profiles.Comment", b =>
+ {
+ b.HasOne("LBPUnion.ProjectLighthouse.Types.User", "Poster")
+ .WithMany()
+ .HasForeignKey("PosterUserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("LBPUnion.ProjectLighthouse.Types.User", "Target")
+ .WithMany()
+ .HasForeignKey("TargetUserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Poster");
+
+ b.Navigation("Target");
+ });
+
+ modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Reviews.RatedReview", b =>
+ {
+ b.HasOne("LBPUnion.ProjectLighthouse.Types.Reviews.Review", "Review")
+ .WithMany()
+ .HasForeignKey("ReviewId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("LBPUnion.ProjectLighthouse.Types.User", "User")
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Review");
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Reviews.Review", b =>
+ {
+ b.HasOne("LBPUnion.ProjectLighthouse.Types.User", "Reviewer")
+ .WithMany()
+ .HasForeignKey("ReviewerId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("LBPUnion.ProjectLighthouse.Types.Levels.Slot", "Slot")
+ .WithMany()
+ .HasForeignKey("SlotId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Reviewer");
+
+ b.Navigation("Slot");
+ });
+
+ modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Score", b =>
+ {
+ b.HasOne("LBPUnion.ProjectLighthouse.Types.Levels.Slot", "Slot")
+ .WithMany()
+ .HasForeignKey("SlotId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Slot");
+ });
+
+ modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.User", b =>
+ {
+ b.HasOne("LBPUnion.ProjectLighthouse.Types.Profiles.Location", "Location")
+ .WithMany()
+ .HasForeignKey("LocationId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Location");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/ProjectLighthouse/Migrations/20211211043517_CacheReviewStats.cs b/ProjectLighthouse/Migrations/20211211043517_CacheReviewStats.cs
new file mode 100644
index 00000000..43ff8248
--- /dev/null
+++ b/ProjectLighthouse/Migrations/20211211043517_CacheReviewStats.cs
@@ -0,0 +1,66 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace ProjectLighthouse.Migrations
+{
+ public partial class CacheReviewStats : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.AlterColumn(
+ name: "DeletedBy",
+ table: "Reviews",
+ type: "int",
+ nullable: false,
+ oldClrType: typeof(string),
+ oldType: "longtext")
+ .OldAnnotation("MySql:CharSet", "utf8mb4");
+
+ migrationBuilder.AddColumn(
+ name: "Thumb",
+ table: "Reviews",
+ type: "int",
+ nullable: false,
+ defaultValue: 0);
+
+ migrationBuilder.AddColumn(
+ name: "ThumbsDown",
+ table: "Reviews",
+ type: "int",
+ nullable: false,
+ defaultValue: 0);
+
+ migrationBuilder.AddColumn(
+ name: "ThumbsUp",
+ table: "Reviews",
+ type: "int",
+ nullable: false,
+ defaultValue: 0);
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropColumn(
+ name: "Thumb",
+ table: "Reviews");
+
+ migrationBuilder.DropColumn(
+ name: "ThumbsDown",
+ table: "Reviews");
+
+ migrationBuilder.DropColumn(
+ name: "ThumbsUp",
+ table: "Reviews");
+
+ migrationBuilder.AlterColumn(
+ name: "DeletedBy",
+ table: "Reviews",
+ type: "longtext",
+ nullable: false,
+ oldClrType: typeof(int),
+ oldType: "int")
+ .Annotation("MySql:CharSet", "utf8mb4");
+ }
+ }
+}
diff --git a/ProjectLighthouse/Migrations/DatabaseModelSnapshot.cs b/ProjectLighthouse/Migrations/DatabaseModelSnapshot.cs
index 0e83b95a..d4f8cfe9 100644
--- a/ProjectLighthouse/Migrations/DatabaseModelSnapshot.cs
+++ b/ProjectLighthouse/Migrations/DatabaseModelSnapshot.cs
@@ -472,9 +472,8 @@ namespace ProjectLighthouse.Migrations
b.Property("Deleted")
.HasColumnType("tinyint(1)");
- b.Property("DeletedBy")
- .IsRequired()
- .HasColumnType("longtext");
+ b.Property("DeletedBy")
+ .HasColumnType("int");
b.Property("LabelCollection")
.IsRequired()
@@ -490,6 +489,15 @@ namespace ProjectLighthouse.Migrations
.IsRequired()
.HasColumnType("longtext");
+ b.Property("Thumb")
+ .HasColumnType("int");
+
+ b.Property("ThumbsDown")
+ .HasColumnType("int");
+
+ b.Property("ThumbsUp")
+ .HasColumnType("int");
+
b.Property("Timestamp")
.HasColumnType("bigint");
From e07fd5714e5607d2e56942956d96d34afdd00783 Mon Sep 17 00:00:00 2001
From: LumaLivy <7350336+LumaLivy@users.noreply.github.com>
Date: Fri, 10 Dec 2021 23:37:55 -0500
Subject: [PATCH 2/6] Cache Review Stats; Migrate DeletedBy to enum
---
.../Controllers/ReviewController.cs | 60 +++++++++++++++----
ProjectLighthouse/Types/DeletedBy.cs | 12 +++-
ProjectLighthouse/Types/Reviews/Review.cs | 36 ++++-------
3 files changed, 69 insertions(+), 39 deletions(-)
diff --git a/ProjectLighthouse/Controllers/ReviewController.cs b/ProjectLighthouse/Controllers/ReviewController.cs
index 35948771..c6145e3e 100644
--- a/ProjectLighthouse/Controllers/ReviewController.cs
+++ b/ProjectLighthouse/Controllers/ReviewController.cs
@@ -76,6 +76,12 @@ namespace LBPUnion.ProjectLighthouse.Controllers
ratedLevel.Rating = Math.Max(Math.Min(1, rating), -1);
+ Review? review = await this.database.Reviews.FirstOrDefaultAsync(r => r.SlotId == slotId && r.ReviewerId == user.UserId);
+ if (review != null)
+ {
+ review.Thumb = ratedLevel.Rating;
+ }
+
await this.database.SaveChangesAsync();
return this.Ok();
@@ -95,15 +101,18 @@ namespace LBPUnion.ProjectLighthouse.Controllers
review = new();
review.SlotId = slotId;
review.ReviewerId = user.UserId;
- review.DeletedBy = "none";
-
+ review.DeletedBy = DeletedBy.None;
+ review.ThumbsUp = 0;
+ review.ThumbsDown = 0;
+ this.database.Reviews.Add(review);
}
+ review.Thumb = newReview.Thumb;
review.LabelCollection = newReview.LabelCollection;
review.Text = newReview.Text;
review.Deleted = false;
review.Timestamp = TimeHelper.UnixTimeMilliseconds();
- // sometimes the game posts a review without also calling dpadrate/user/etc (why??)
+ // sometimes the game posts/updates a review rating without also calling dpadrate/user/etc (why??)
RatedLevel? ratedLevel = await this.database.RatedLevels.FirstOrDefaultAsync(r => r.SlotId == slotId && r.UserId == user.UserId);
if (ratedLevel == null)
{
@@ -116,7 +125,6 @@ namespace LBPUnion.ProjectLighthouse.Controllers
ratedLevel.Rating = newReview.Thumb;
-
await this.database.SaveChangesAsync();
return this.Ok();
@@ -137,21 +145,51 @@ namespace LBPUnion.ProjectLighthouse.Controllers
Random rand = new();
- IEnumerable reviews = this.database.Reviews.Where(r => r.SlotId == slotId && r.Slot.GameVersion <= gameVersion)
+ Review? yourReview = await this.database.Reviews.FirstOrDefaultAsync(r => r.ReviewerId == user.UserId && r.SlotId == slotId && r.Slot.GameVersion <= gameVersion);
+ VisitedLevel? visitedLevel = await this.database.VisitedLevels.FirstOrDefaultAsync(v => v.UserId == user.UserId && v.SlotId == slotId && v.Slot.GameVersion <= gameVersion);
+ Slot? slot = await this.database.Slots.FirstOrDefaultAsync(s => s.SlotId == slotId);
+ if (slot == null) return this.BadRequest();
+ Boolean canNowReviewLevel = visitedLevel != null && yourReview == null;
+ if (canNowReviewLevel)
+ {
+ RatedLevel? ratedLevel = await this.database.RatedLevels.FirstOrDefaultAsync(r => r.UserId == user.UserId && r.SlotId == slotId && r.Slot.GameVersion <= gameVersion);
+
+ yourReview = new();
+ yourReview.ReviewerId = user.UserId;
+ yourReview.Reviewer = user;
+ yourReview.Thumb = ratedLevel?.Rating == null ? 0 : ratedLevel.Rating;
+ yourReview.Slot = slot;
+ yourReview.SlotId = slotId;
+ yourReview.DeletedBy = DeletedBy.None;
+ yourReview.Text = "You haven't reviewed this level yet. Edit this blank review to upload it!";
+ yourReview.LabelCollection = "";
+ yourReview.Deleted = false;
+ yourReview.Timestamp = TimeHelper.UnixTimeMilliseconds();
+ }
+
+ IQueryable reviews = this.database.Reviews.Where(r => r.SlotId == slotId && r.Slot.GameVersion <= gameVersion)
.Include(r => r.Reviewer)
.Include(r => r.Slot)
- .AsEnumerable() // performance? Needed for next line (ThumbsUp is not in DB)
.OrderByDescending(r => r.ThumbsUp)
- .ThenByDescending(_ => rand.Next())
+ .ThenByDescending(_ => EF.Functions.Random())
.Skip(pageStart - 1)
.Take(pageSize);
- string inner = Enumerable.Aggregate(reviews, string.Empty, (current, review) =>
+ IEnumerable prependedReviews;
+ if (canNowReviewLevel) // this can only be true if you have not posted a review but have visited the level
{
- RatedLevel? ratedLevel = this.database.RatedLevels.FirstOrDefault(r => r.SlotId == slotId && r.UserId == review.ReviewerId);
- RatedReview? ratedReview = this.database.RatedReviews.FirstOrDefault(r => r.ReviewId == review.ReviewId && r.UserId == user.UserId);
+ // prepend the fake review to the top of the list to be easily edited
+ prependedReviews = reviews.ToList().Prepend(yourReview);
+ }
+ else
+ {
+ prependedReviews = reviews.ToList();
+ }
- return current + review.Serialize(ratedLevel, ratedReview);
+ string inner = Enumerable.Aggregate(prependedReviews, string.Empty, (current, review) =>
+ {
+ if (review == null) return current;
+ return current + review.Serialize();
});
string response = LbpSerializer.TaggedStringElement("reviews", inner, new Dictionary
diff --git a/ProjectLighthouse/Types/DeletedBy.cs b/ProjectLighthouse/Types/DeletedBy.cs
index 02d61ec0..666e4437 100644
--- a/ProjectLighthouse/Types/DeletedBy.cs
+++ b/ProjectLighthouse/Types/DeletedBy.cs
@@ -1,9 +1,15 @@
+using System.Xml.Serialization;
+
namespace LBPUnion.ProjectLighthouse.Types
{
- public static class DeletedBy
+ public enum DeletedBy
{
- public static string Moderator { get => "moderator"; }
- public static string LevelAuthor { get => "level_author"; }
+ [XmlEnum(Name = "none")]
+ None,
+ [XmlEnum(Name = "moderator")]
+ Moderator,
+ [XmlEnum(Name = "level_author")]
+ LevelAuthor
// TODO: deletion types for comments (profile etc)
}
}
\ No newline at end of file
diff --git a/ProjectLighthouse/Types/Reviews/Review.cs b/ProjectLighthouse/Types/Reviews/Review.cs
index a2ee79d0..3a25bd06 100644
--- a/ProjectLighthouse/Types/Reviews/Review.cs
+++ b/ProjectLighthouse/Types/Reviews/Review.cs
@@ -37,7 +37,8 @@ namespace LBPUnion.ProjectLighthouse.Types.Reviews
[NotMapped]
[XmlIgnore]
- public string[] Labels {
+ public string[] Labels
+ {
get => this.LabelCollection.Split(",");
set => this.LabelCollection = string.Join(',', value);
}
@@ -46,44 +47,29 @@ namespace LBPUnion.ProjectLighthouse.Types.Reviews
public Boolean Deleted { get; set; }
[XmlElement("deleted_by")]
- public string DeletedBy { get; set; } // enum ? Needs testing e.g. Moderated/Author/Level Author? etc.
+ public DeletedBy DeletedBy { get; set; }
[XmlElement("text")]
public string Text { get; set; }
- [NotMapped]
[XmlElement("thumb")]
- public int Thumb { get; set; } // (unused) -- temp value for getting thumb from review upload body for updating level rating
-
- [NotMapped]
+ public int Thumb { get; set; }
+
[XmlElement("thumbsup")]
- public int ThumbsUp {
- get {
- using Database database = new();
-
- return database.RatedReviews.Count(r => r.ReviewId == this.ReviewId && r.Thumb == 1);
- }
- }
- [NotMapped]
+ public int ThumbsUp { get; set; }
[XmlElement("thumbsdown")]
- public int ThumbsDown {
- get {
- using Database database = new();
+ public int ThumbsDown { get; set; }
- return database.RatedReviews.Count(r => r.ReviewId == this.ReviewId && r.Thumb == -1);
- }
- }
-
- public string Serialize(RatedLevel? yourLevelRating = null, RatedReview? yourRatingStats = null) {
+ public string Serialize(RatedLevel? yourLevelRating = null, RatedReview? yourRatingStats = null)
+ {
return this.Serialize("review", yourLevelRating, yourRatingStats);
}
public string Serialize(string elementOverride, RatedLevel? yourLevelRating = null, RatedReview? yourRatingStats = null)
{
-
string reviewData = LbpSerializer.TaggedStringElement("slot_id", this.SlotId, "type", this.Slot.Type) +
LbpSerializer.StringElement("reviewer", this.Reviewer.Username) +
- LbpSerializer.StringElement("thumb", yourLevelRating?.Rating) +
+ LbpSerializer.StringElement("thumb", this.Thumb) +
LbpSerializer.StringElement("timestamp", this.Timestamp) +
LbpSerializer.StringElement("labels", this.LabelCollection) +
LbpSerializer.StringElement("deleted", this.Deleted) +
@@ -97,5 +83,5 @@ namespace LBPUnion.ProjectLighthouse.Types.Reviews
}
}
-
+
}
\ No newline at end of file
From 9ad1f6eeb155a2158f01a37334e2be3a086bdc20 Mon Sep 17 00:00:00 2001
From: LumaLivy <7350336+LumaLivy@users.noreply.github.com>
Date: Sat, 11 Dec 2021 00:01:51 -0500
Subject: [PATCH 3/6] Finalize adding review support/cleaning some warnings
---
.gitignore | 8 ++
ProjectLighthouse/Database.cs | 7 +-
.../Maintenance/Commands/CreateUserCommand.cs | 5 +-
.../Commands/WipeTokensForUserCommand.cs | 1 +
.../20211211043517_CacheReviewStats.cs | 66 -----------
...0211211045823_AddLevelReviews.Designer.cs} | 17 ++-
.../20211211045823_AddLevelReviews.cs | 107 ++++++++++++++++++
.../Migrations/DatabaseModelSnapshot.cs | 38 +++++++
.../ExternalAuth/AuthenticationPage.cshtml.cs | 2 +-
.../Types/Settings/ServerStatics.cs | 8 +-
10 files changed, 180 insertions(+), 79 deletions(-)
delete mode 100644 ProjectLighthouse/Migrations/20211211043517_CacheReviewStats.cs
rename ProjectLighthouse/Migrations/{20211211043517_CacheReviewStats.Designer.cs => 20211211045823_AddLevelReviews.Designer.cs} (98%)
create mode 100644 ProjectLighthouse/Migrations/20211211045823_AddLevelReviews.cs
diff --git a/.gitignore b/.gitignore
index bb08bcee..d0391f6a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,3 +21,11 @@ riderModule.iml
lighthouse.config.json
gitBranch.txt
gitVersion.txt
+ProjectLighthouse/.vscode/tasks.json
+ProjectLighthouse/.vscode/launch.json
+logs/Startup.log
+logs/LoggerInfo.log
+logs/all.log
+.vscode/tasks.json
+.vscode/launch.json
+.editorconfig
diff --git a/ProjectLighthouse/Database.cs b/ProjectLighthouse/Database.cs
index 3a5366cc..6e84e6ef 100644
--- a/ProjectLighthouse/Database.cs
+++ b/ProjectLighthouse/Database.cs
@@ -6,6 +6,7 @@ using LBPUnion.ProjectLighthouse.Helpers;
using LBPUnion.ProjectLighthouse.Logging;
using LBPUnion.ProjectLighthouse.Types;
using LBPUnion.ProjectLighthouse.Types.Levels;
+using LBPUnion.ProjectLighthouse.Types.Reviews;
using LBPUnion.ProjectLighthouse.Types.Profiles;
using LBPUnion.ProjectLighthouse.Types.Settings;
using Microsoft.AspNetCore.Http;
@@ -31,6 +32,8 @@ namespace LBPUnion.ProjectLighthouse
public DbSet VisitedLevels { get; set; }
public DbSet RatedLevels { get; set; }
public DbSet AuthenticationAttempts { get; set; }
+ public DbSet Reviews { get; set; }
+ public DbSet RatedReviews { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder options)
=> options.UseMySql(ServerSettings.Instance.DbConnectionString, MySqlServerVersion.LatestSupportedServerVersion);
@@ -60,7 +63,7 @@ namespace LBPUnion.ProjectLighthouse
return user;
}
- #nullable enable
+#nullable enable
public async Task AuthenticateUser(LoginData loginData, string userLocation, string titleId = "")
{
// TODO: don't use psn name to authenticate
@@ -252,6 +255,6 @@ namespace LBPUnion.ProjectLighthouse
public async Task PhotoFromSubject(PhotoSubject subject)
=> await this.Photos.FirstOrDefaultAsync(p => p.PhotoSubjectIds.Contains(subject.PhotoSubjectId.ToString()));
- #nullable disable
+#nullable disable
}
}
\ No newline at end of file
diff --git a/ProjectLighthouse/Maintenance/Commands/CreateUserCommand.cs b/ProjectLighthouse/Maintenance/Commands/CreateUserCommand.cs
index b3db6c4a..ca0379fb 100644
--- a/ProjectLighthouse/Maintenance/Commands/CreateUserCommand.cs
+++ b/ProjectLighthouse/Maintenance/Commands/CreateUserCommand.cs
@@ -1,5 +1,4 @@
-using System;
-using System.Diagnostics;
+#nullable enable
using System.Threading.Tasks;
using JetBrains.Annotations;
using Kettu;
@@ -21,7 +20,7 @@ namespace LBPUnion.ProjectLighthouse.Maintenance.Commands
string password = args[1];
password = HashHelper.Sha256Hash(password);
-
+
User? user = await this._database.Users.FirstOrDefaultAsync(u => u.Username == onlineId);
if (user == null)
{
diff --git a/ProjectLighthouse/Maintenance/Commands/WipeTokensForUserCommand.cs b/ProjectLighthouse/Maintenance/Commands/WipeTokensForUserCommand.cs
index 4e42461a..3da9514c 100644
--- a/ProjectLighthouse/Maintenance/Commands/WipeTokensForUserCommand.cs
+++ b/ProjectLighthouse/Maintenance/Commands/WipeTokensForUserCommand.cs
@@ -1,3 +1,4 @@
+#nullable enable
using System;
using System.Linq;
using System.Threading.Tasks;
diff --git a/ProjectLighthouse/Migrations/20211211043517_CacheReviewStats.cs b/ProjectLighthouse/Migrations/20211211043517_CacheReviewStats.cs
deleted file mode 100644
index 43ff8248..00000000
--- a/ProjectLighthouse/Migrations/20211211043517_CacheReviewStats.cs
+++ /dev/null
@@ -1,66 +0,0 @@
-using Microsoft.EntityFrameworkCore.Migrations;
-
-#nullable disable
-
-namespace ProjectLighthouse.Migrations
-{
- public partial class CacheReviewStats : Migration
- {
- protected override void Up(MigrationBuilder migrationBuilder)
- {
- migrationBuilder.AlterColumn(
- name: "DeletedBy",
- table: "Reviews",
- type: "int",
- nullable: false,
- oldClrType: typeof(string),
- oldType: "longtext")
- .OldAnnotation("MySql:CharSet", "utf8mb4");
-
- migrationBuilder.AddColumn(
- name: "Thumb",
- table: "Reviews",
- type: "int",
- nullable: false,
- defaultValue: 0);
-
- migrationBuilder.AddColumn(
- name: "ThumbsDown",
- table: "Reviews",
- type: "int",
- nullable: false,
- defaultValue: 0);
-
- migrationBuilder.AddColumn(
- name: "ThumbsUp",
- table: "Reviews",
- type: "int",
- nullable: false,
- defaultValue: 0);
- }
-
- protected override void Down(MigrationBuilder migrationBuilder)
- {
- migrationBuilder.DropColumn(
- name: "Thumb",
- table: "Reviews");
-
- migrationBuilder.DropColumn(
- name: "ThumbsDown",
- table: "Reviews");
-
- migrationBuilder.DropColumn(
- name: "ThumbsUp",
- table: "Reviews");
-
- migrationBuilder.AlterColumn(
- name: "DeletedBy",
- table: "Reviews",
- type: "longtext",
- nullable: false,
- oldClrType: typeof(int),
- oldType: "int")
- .Annotation("MySql:CharSet", "utf8mb4");
- }
- }
-}
diff --git a/ProjectLighthouse/Migrations/20211211043517_CacheReviewStats.Designer.cs b/ProjectLighthouse/Migrations/20211211045823_AddLevelReviews.Designer.cs
similarity index 98%
rename from ProjectLighthouse/Migrations/20211211043517_CacheReviewStats.Designer.cs
rename to ProjectLighthouse/Migrations/20211211045823_AddLevelReviews.Designer.cs
index ca4261c1..98610a6c 100644
--- a/ProjectLighthouse/Migrations/20211211043517_CacheReviewStats.Designer.cs
+++ b/ProjectLighthouse/Migrations/20211211045823_AddLevelReviews.Designer.cs
@@ -10,8 +10,8 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace ProjectLighthouse.Migrations
{
[DbContext(typeof(Database))]
- [Migration("20211211043517_CacheReviewStats")]
- partial class CacheReviewStats
+ [Migration("20211211045823_AddLevelReviews")]
+ partial class AddLevelReviews
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
@@ -407,7 +407,7 @@ namespace ProjectLighthouse.Migrations
b.ToTable("Comments");
});
- modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Profiles.LastMatch", b =>
+ modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Profiles.LastContact", b =>
{
b.Property("UserId")
.ValueGeneratedOnAdd()
@@ -421,7 +421,7 @@ namespace ProjectLighthouse.Migrations
b.HasKey("UserId");
- b.ToTable("LastMatches");
+ b.ToTable("LastContacts");
});
modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Profiles.Location", b =>
@@ -546,6 +546,9 @@ namespace ProjectLighthouse.Migrations
b.Property("Biography")
.HasColumnType("longtext");
+ b.Property("BooHash")
+ .HasColumnType("longtext");
+
b.Property("Game")
.HasColumnType("int");
@@ -558,6 +561,9 @@ namespace ProjectLighthouse.Migrations
b.Property("LocationId")
.HasColumnType("int");
+ b.Property("MehHash")
+ .HasColumnType("longtext");
+
b.Property("Password")
.HasColumnType("longtext");
@@ -573,6 +579,9 @@ namespace ProjectLighthouse.Migrations
b.Property("Username")
.HasColumnType("longtext");
+ b.Property("YayHash")
+ .HasColumnType("longtext");
+
b.HasKey("UserId");
b.HasIndex("LocationId");
diff --git a/ProjectLighthouse/Migrations/20211211045823_AddLevelReviews.cs b/ProjectLighthouse/Migrations/20211211045823_AddLevelReviews.cs
new file mode 100644
index 00000000..ccdf6c2c
--- /dev/null
+++ b/ProjectLighthouse/Migrations/20211211045823_AddLevelReviews.cs
@@ -0,0 +1,107 @@
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace ProjectLighthouse.Migrations
+{
+ public partial class AddLevelReviews : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.CreateTable(
+ name: "Reviews",
+ columns: table => new
+ {
+ ReviewId = table.Column(type: "int", nullable: false)
+ .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
+ ReviewerId = table.Column(type: "int", nullable: false),
+ SlotId = table.Column(type: "int", nullable: false),
+ Timestamp = table.Column(type: "bigint", nullable: false),
+ LabelCollection = table.Column(type: "longtext", nullable: false)
+ .Annotation("MySql:CharSet", "utf8mb4"),
+ Deleted = table.Column(type: "tinyint(1)", nullable: false),
+ DeletedBy = table.Column(type: "int", nullable: false),
+ Text = table.Column(type: "longtext", nullable: false)
+ .Annotation("MySql:CharSet", "utf8mb4"),
+ Thumb = table.Column(type: "int", nullable: false),
+ ThumbsUp = table.Column(type: "int", nullable: false),
+ ThumbsDown = table.Column(type: "int", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Reviews", x => x.ReviewId);
+ table.ForeignKey(
+ name: "FK_Reviews_Slots_SlotId",
+ column: x => x.SlotId,
+ principalTable: "Slots",
+ principalColumn: "SlotId",
+ onDelete: ReferentialAction.Cascade);
+ table.ForeignKey(
+ name: "FK_Reviews_Users_ReviewerId",
+ column: x => x.ReviewerId,
+ principalTable: "Users",
+ principalColumn: "UserId",
+ onDelete: ReferentialAction.Cascade);
+ })
+ .Annotation("MySql:CharSet", "utf8mb4");
+
+ migrationBuilder.CreateTable(
+ name: "RatedReviews",
+ columns: table => new
+ {
+ RatedReviewId = table.Column(type: "int", nullable: false)
+ .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
+ UserId = table.Column(type: "int", nullable: false),
+ ReviewId = table.Column(type: "int", nullable: false),
+ Thumb = table.Column(type: "int", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_RatedReviews", x => x.RatedReviewId);
+ table.ForeignKey(
+ name: "FK_RatedReviews_Reviews_ReviewId",
+ column: x => x.ReviewId,
+ principalTable: "Reviews",
+ principalColumn: "ReviewId",
+ onDelete: ReferentialAction.Cascade);
+ table.ForeignKey(
+ name: "FK_RatedReviews_Users_UserId",
+ column: x => x.UserId,
+ principalTable: "Users",
+ principalColumn: "UserId",
+ onDelete: ReferentialAction.Cascade);
+ })
+ .Annotation("MySql:CharSet", "utf8mb4");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_RatedReviews_ReviewId",
+ table: "RatedReviews",
+ column: "ReviewId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_RatedReviews_UserId",
+ table: "RatedReviews",
+ column: "UserId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Reviews_ReviewerId",
+ table: "Reviews",
+ column: "ReviewerId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Reviews_SlotId",
+ table: "Reviews",
+ column: "SlotId");
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropTable(
+ name: "RatedReviews");
+
+ migrationBuilder.DropTable(
+ name: "Reviews");
+ }
+ }
+}
diff --git a/ProjectLighthouse/Migrations/DatabaseModelSnapshot.cs b/ProjectLighthouse/Migrations/DatabaseModelSnapshot.cs
index 70f91a28..4afc7b51 100644
--- a/ProjectLighthouse/Migrations/DatabaseModelSnapshot.cs
+++ b/ProjectLighthouse/Migrations/DatabaseModelSnapshot.cs
@@ -770,6 +770,44 @@ namespace ProjectLighthouse.Migrations
b.Navigation("Target");
});
+ modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Reviews.RatedReview", b =>
+ {
+ b.HasOne("LBPUnion.ProjectLighthouse.Types.Reviews.Review", "Review")
+ .WithMany()
+ .HasForeignKey("ReviewId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("LBPUnion.ProjectLighthouse.Types.User", "User")
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Review");
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Reviews.Review", b =>
+ {
+ b.HasOne("LBPUnion.ProjectLighthouse.Types.User", "Reviewer")
+ .WithMany()
+ .HasForeignKey("ReviewerId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("LBPUnion.ProjectLighthouse.Types.Levels.Slot", "Slot")
+ .WithMany()
+ .HasForeignKey("SlotId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Reviewer");
+
+ b.Navigation("Slot");
+ });
+
modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Score", b =>
{
b.HasOne("LBPUnion.ProjectLighthouse.Types.Levels.Slot", "Slot")
diff --git a/ProjectLighthouse/Pages/ExternalAuth/AuthenticationPage.cshtml.cs b/ProjectLighthouse/Pages/ExternalAuth/AuthenticationPage.cshtml.cs
index f64d3102..c4bd98e3 100644
--- a/ProjectLighthouse/Pages/ExternalAuth/AuthenticationPage.cshtml.cs
+++ b/ProjectLighthouse/Pages/ExternalAuth/AuthenticationPage.cshtml.cs
@@ -12,7 +12,7 @@ namespace LBPUnion.ProjectLighthouse.Pages.ExternalAuth
public class AuthenticationPage : BaseLayout
{
public AuthenticationPage(Database database) : base(database)
- {}
+ { }
public List AuthenticationAttempts;
diff --git a/ProjectLighthouse/Types/Settings/ServerStatics.cs b/ProjectLighthouse/Types/Settings/ServerStatics.cs
index 1bb8227c..d5f94c12 100644
--- a/ProjectLighthouse/Types/Settings/ServerStatics.cs
+++ b/ProjectLighthouse/Types/Settings/ServerStatics.cs
@@ -10,13 +10,15 @@ namespace LBPUnion.ProjectLighthouse.Types.Settings
{
public const string ServerName = "ProjectLighthouse";
- public static bool DbConnected {
- get {
+ public static bool DbConnected
+ {
+ get
+ {
try
{
return new Database().Database.CanConnect();
}
- catch(Exception e)
+ catch (Exception e)
{
Logger.Log(e.ToString(), LoggerLevelDatabase.Instance);
return false;
From d596eeefc2b7ba73a4b02a7daebf661675e597f7 Mon Sep 17 00:00:00 2001
From: LumaLivy <7350336+LumaLivy@users.noreply.github.com>
Date: Sat, 11 Dec 2021 01:03:46 -0500
Subject: [PATCH 4/6] Reviews now appear ingame
---
.../Controllers/ReviewController.cs | 11 +--
ProjectLighthouse/Types/DeletedBy.cs | 1 +
ProjectLighthouse/Types/Levels/Slot.cs | 48 ++++++++++---
ProjectLighthouse/Types/Reviews/Review.cs | 17 ++++-
ProjectLighthouse/Types/User.cs | 71 +++++++++++++------
5 files changed, 108 insertions(+), 40 deletions(-)
diff --git a/ProjectLighthouse/Controllers/ReviewController.cs b/ProjectLighthouse/Controllers/ReviewController.cs
index 65e007de..55e75962 100644
--- a/ProjectLighthouse/Controllers/ReviewController.cs
+++ b/ProjectLighthouse/Controllers/ReviewController.cs
@@ -146,10 +146,13 @@ namespace LBPUnion.ProjectLighthouse.Controllers
Random rand = new();
Review? yourReview = await this.database.Reviews.FirstOrDefaultAsync(r => r.ReviewerId == user.UserId && r.SlotId == slotId && r.Slot.GameVersion <= gameVersion);
+
VisitedLevel? visitedLevel = await this.database.VisitedLevels.FirstOrDefaultAsync(v => v.UserId == user.UserId && v.SlotId == slotId && v.Slot.GameVersion <= gameVersion);
+
Slot? slot = await this.database.Slots.FirstOrDefaultAsync(s => s.SlotId == slotId);
if (slot == null) return this.BadRequest();
- Boolean canNowReviewLevel = visitedLevel != null && yourReview == null;
+
+ Boolean canNowReviewLevel = slot.CreatorId != user.UserId && visitedLevel != null && yourReview == null;
if (canNowReviewLevel)
{
RatedLevel? ratedLevel = await this.database.RatedLevels.FirstOrDefaultAsync(r => r.UserId == user.UserId && r.SlotId == slotId && r.Slot.GameVersion <= gameVersion);
@@ -160,10 +163,10 @@ namespace LBPUnion.ProjectLighthouse.Controllers
yourReview.Thumb = ratedLevel?.Rating == null ? 0 : ratedLevel.Rating;
yourReview.Slot = slot;
yourReview.SlotId = slotId;
+ yourReview.Deleted = false;
yourReview.DeletedBy = DeletedBy.None;
yourReview.Text = "You haven't reviewed this level yet. Edit this blank review to upload it!";
yourReview.LabelCollection = "";
- yourReview.Deleted = false;
yourReview.Timestamp = TimeHelper.UnixTimeMilliseconds();
}
@@ -226,9 +229,9 @@ namespace LBPUnion.ProjectLighthouse.Controllers
string inner = Enumerable.Aggregate(reviews, string.Empty, (current, review) =>
{
- RatedLevel? ratedLevel = this.database.RatedLevels.FirstOrDefault(r => r.SlotId == review.SlotId && r.UserId == user.UserId);
+ //RatedLevel? ratedLevel = this.database.RatedLevels.FirstOrDefault(r => r.SlotId == review.SlotId && r.UserId == user.UserId);
//RatedReview? ratedReview = this.database.RatedReviews.FirstOrDefault(r => r.ReviewId == review.ReviewId && r.UserId == user.UserId);
- return current + review.Serialize(ratedLevel/*, ratedReview*/);
+ return current + review.Serialize(/*, ratedReview*/);
});
string response = LbpSerializer.TaggedStringElement("reviews", inner, new Dictionary
diff --git a/ProjectLighthouse/Types/DeletedBy.cs b/ProjectLighthouse/Types/DeletedBy.cs
index 666e4437..c8beade1 100644
--- a/ProjectLighthouse/Types/DeletedBy.cs
+++ b/ProjectLighthouse/Types/DeletedBy.cs
@@ -2,6 +2,7 @@ using System.Xml.Serialization;
namespace LBPUnion.ProjectLighthouse.Types
{
+ [XmlRoot("deleted_by")]
public enum DeletedBy
{
[XmlEnum(Name = "none")]
diff --git a/ProjectLighthouse/Types/Levels/Slot.cs b/ProjectLighthouse/Types/Levels/Slot.cs
index ff0c580e..de339f29 100644
--- a/ProjectLighthouse/Types/Levels/Slot.cs
+++ b/ProjectLighthouse/Types/Levels/Slot.cs
@@ -6,6 +6,7 @@ using System.Xml.Serialization;
using LBPUnion.ProjectLighthouse.Helpers;
using LBPUnion.ProjectLighthouse.Serialization;
using LBPUnion.ProjectLighthouse.Types.Profiles;
+using LBPUnion.ProjectLighthouse.Types.Reviews;
namespace LBPUnion.ProjectLighthouse.Types.Levels
{
@@ -40,7 +41,8 @@ namespace LBPUnion.ProjectLighthouse.Types.Levels
[NotMapped]
[XmlElement("resource")]
- public string[] Resources {
+ public string[] Resources
+ {
get => this.ResourceCollection.Split(",");
set => this.ResourceCollection = string.Join(',', value);
}
@@ -102,8 +104,10 @@ namespace LBPUnion.ProjectLighthouse.Types.Levels
[XmlIgnore]
[NotMapped]
- public int Hearts {
- get {
+ public int Hearts
+ {
+ get
+ {
using Database database = new();
return database.HeartedLevels.Count(s => s.SlotId == this.SlotId);
@@ -160,8 +164,10 @@ namespace LBPUnion.ProjectLighthouse.Types.Levels
[NotMapped]
[XmlElement("thumbsup")]
- public int Thumbsup {
- get {
+ public int Thumbsup
+ {
+ get
+ {
using Database database = new();
return database.RatedLevels.Count(r => r.SlotId == this.SlotId && r.Rating == 1);
@@ -170,8 +176,10 @@ namespace LBPUnion.ProjectLighthouse.Types.Levels
[NotMapped]
[XmlElement("thumbsdown")]
- public int Thumbsdown {
- get {
+ public int Thumbsdown
+ {
+ get
+ {
using Database database = new();
return database.RatedLevels.Count(r => r.SlotId == this.SlotId && r.Rating == -1);
@@ -180,8 +188,10 @@ namespace LBPUnion.ProjectLighthouse.Types.Levels
[NotMapped]
[XmlElement("averageRating")]
- public double RatingLBP1 {
- get {
+ public double RatingLBP1
+ {
+ get
+ {
using Database database = new();
IQueryable ratedLevels = database.RatedLevels.Where(r => r.SlotId == this.SlotId && r.RatingLBP1 > 0);
@@ -191,6 +201,18 @@ namespace LBPUnion.ProjectLighthouse.Types.Levels
}
}
+ [NotMapped]
+ [XmlElement("reviewCount")]
+ public int ReviewCount
+ {
+ get
+ {
+ using Database database = new();
+
+ return database.Reviews.Count(r => r.SlotId == this.SlotId);
+ }
+ }
+
[XmlElement("leveltype")]
public string LevelType { get; set; } = "";
@@ -200,7 +222,7 @@ namespace LBPUnion.ProjectLighthouse.Types.Levels
LbpSerializer.StringElement("sizeOfResources", this.Resources.Sum(FileHelper.ResourceSize));
}
- public string Serialize(RatedLevel? yourRatingStats = null, VisitedLevel? yourVisitedStats = null)
+ public string Serialize(RatedLevel? yourRatingStats = null, VisitedLevel? yourVisitedStats = null, Review? yourReview = null)
{
string slotData = LbpSerializer.StringElement("name", this.Name) +
@@ -249,7 +271,11 @@ namespace LBPUnion.ProjectLighthouse.Types.Levels
LbpSerializer.StringElement("yourLBP2PlayCount", yourVisitedStats?.PlaysLBP2) +
LbpSerializer.StringElement("yourLBP3PlayCount", yourVisitedStats?.PlaysLBP3) +
LbpSerializer.StringElement
- ("yourLBPVitaPlayCount", yourVisitedStats?.PlaysLBPVita); // i doubt this is the right name but we'll go with it
+ ("yourLBPVitaPlayCount", yourVisitedStats?.PlaysLBPVita) + // i doubt this is the right name but we'll go with it
+ yourReview?.Serialize("yourReview") +
+ LbpSerializer.StringElement("reviewsEnabled", true) +
+ LbpSerializer.StringElement("commentsEnabled", false) +
+ LbpSerializer.StringElement("reviewCount", this.ReviewCount);
return LbpSerializer.TaggedStringElement("slot", slotData, "type", "user");
}
diff --git a/ProjectLighthouse/Types/Reviews/Review.cs b/ProjectLighthouse/Types/Reviews/Review.cs
index 3a25bd06..80ca0e80 100644
--- a/ProjectLighthouse/Types/Reviews/Review.cs
+++ b/ProjectLighthouse/Types/Reviews/Review.cs
@@ -1,10 +1,11 @@
#nullable enable
using System;
+using System.IO;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
-using System.Linq;
using LBPUnion.ProjectLighthouse.Types.Levels;
using LBPUnion.ProjectLighthouse.Serialization;
+using System.Xml;
using System.Xml.Serialization;
namespace LBPUnion.ProjectLighthouse.Types.Reviews
@@ -67,13 +68,25 @@ namespace LBPUnion.ProjectLighthouse.Types.Reviews
public string Serialize(string elementOverride, RatedLevel? yourLevelRating = null, RatedReview? yourRatingStats = null)
{
+
+ XmlWriterSettings settings = new XmlWriterSettings();
+ settings.OmitXmlDeclaration = true;
+
+ XmlSerializer serializer = new(typeof(DeletedBy));
+ StringWriter stringWriter = new StringWriter();
+ using (XmlWriter xmlWriter = XmlWriter.Create(stringWriter, settings))
+ {
+ serializer.Serialize(xmlWriter, this.DeletedBy);
+ }
+ string deletedBy = stringWriter.ToString();
+
string reviewData = LbpSerializer.TaggedStringElement("slot_id", this.SlotId, "type", this.Slot.Type) +
LbpSerializer.StringElement("reviewer", this.Reviewer.Username) +
LbpSerializer.StringElement("thumb", this.Thumb) +
LbpSerializer.StringElement("timestamp", this.Timestamp) +
LbpSerializer.StringElement("labels", this.LabelCollection) +
LbpSerializer.StringElement("deleted", this.Deleted) +
- LbpSerializer.StringElement("deleted_by", this.DeletedBy) +
+ deletedBy +
LbpSerializer.StringElement("text", this.Text) +
LbpSerializer.StringElement("thumbsup", this.ThumbsUp) +
LbpSerializer.StringElement("thumbsdown", this.ThumbsDown) +
diff --git a/ProjectLighthouse/Types/User.cs b/ProjectLighthouse/Types/User.cs
index 6f24a385..f88f0f1b 100644
--- a/ProjectLighthouse/Types/User.cs
+++ b/ProjectLighthouse/Types/User.cs
@@ -26,27 +26,40 @@ namespace LBPUnion.ProjectLighthouse.Types
public string Biography { get; set; }
[NotMapped]
- public int Reviews => 0;
+ public int Reviews
+ {
+ get
+ {
+ using Database database = new();
+ return database.Reviews.Count(r => r.ReviewerId == this.UserId);
+ }
+ }
[NotMapped]
- public int Comments {
- get {
+ public int Comments
+ {
+ get
+ {
using Database database = new();
return database.Comments.Count(c => c.TargetUserId == this.UserId);
}
}
[NotMapped]
- public int PhotosByMe {
- get {
+ public int PhotosByMe
+ {
+ get
+ {
using Database database = new();
return database.Photos.Count(p => p.CreatorId == this.UserId);
}
}
[NotMapped]
- public int PhotosWithMe {
- get {
+ public int PhotosWithMe
+ {
+ get
+ {
using Database database = new();
return Enumerable.Sum(database.Photos, photo => photo.Subjects.Count(subject => subject.User.UserId == this.UserId));
}
@@ -61,24 +74,30 @@ namespace LBPUnion.ProjectLighthouse.Types
public Location Location { get; set; }
[NotMapped]
- public int HeartedLevels {
- get {
+ public int HeartedLevels
+ {
+ get
+ {
using Database database = new();
return database.HeartedLevels.Count(p => p.UserId == this.UserId);
}
}
[NotMapped]
- public int HeartedUsers {
- get {
+ public int HeartedUsers
+ {
+ get
+ {
using Database database = new();
return database.HeartedProfiles.Count(p => p.UserId == this.UserId);
}
}
[NotMapped]
- public int QueuedLevels {
- get {
+ public int QueuedLevels
+ {
+ get
+ {
using Database database = new();
return database.QueuedLevels.Count(p => p.UserId == this.UserId);
}
@@ -88,8 +107,10 @@ namespace LBPUnion.ProjectLighthouse.Types
public string PlanetHash { get; set; } = "";
- public int Hearts {
- get {
+ public int Hearts
+ {
+ get
+ {
using Database database = new();
return database.HeartedProfiles.Count(s => s.HeartedUserId == this.UserId);
@@ -104,10 +125,12 @@ namespace LBPUnion.ProjectLighthouse.Types
public string BooHash { get; set; } = "";
public string MehHash { get; set; } = "";
- #nullable enable
+#nullable enable
[NotMapped]
- public string Status {
- get {
+ public string Status
+ {
+ get
+ {
using Database database = new();
LastContact? lastMatch = database.LastContacts.Where
(l => l.UserId == this.UserId)
@@ -118,7 +141,7 @@ namespace LBPUnion.ProjectLighthouse.Types
return "Currently online on " + lastMatch.GameVersion.ToPrettyString();
}
}
- #nullable disable
+#nullable disable
public string Serialize(GameVersion gameVersion = GameVersion.LittleBigPlanet1)
{
@@ -156,8 +179,10 @@ namespace LBPUnion.ProjectLighthouse.Types
/// The number of used slots on the earth
///
[NotMapped]
- public int UsedSlots {
- get {
+ public int UsedSlots
+ {
+ get
+ {
using Database database = new();
return database.Slots.Count(s => s.CreatorId == this.UserId);
}
@@ -218,7 +243,7 @@ namespace LBPUnion.ProjectLighthouse.Types
#endregion Slots
- #nullable enable
+#nullable enable
public override bool Equals(object? obj)
{
if (obj is User user) return user.UserId == UserId;
@@ -238,6 +263,6 @@ namespace LBPUnion.ProjectLighthouse.Types
[SuppressMessage("ReSharper", "NonReadonlyMemberInGetHashCode")]
public override int GetHashCode() => this.UserId;
- #nullable disable
+#nullable disable
}
}
\ No newline at end of file
From 16a41d4fb50e1506604664e22fe6c83ccd03eddd Mon Sep 17 00:00:00 2001
From: LumaLivy <7350336+LumaLivy@users.noreply.github.com>
Date: Sat, 11 Dec 2021 01:07:06 -0500
Subject: [PATCH 5/6] Update wording on review template
---
ProjectLighthouse/Controllers/ReviewController.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ProjectLighthouse/Controllers/ReviewController.cs b/ProjectLighthouse/Controllers/ReviewController.cs
index 55e75962..ca6549ba 100644
--- a/ProjectLighthouse/Controllers/ReviewController.cs
+++ b/ProjectLighthouse/Controllers/ReviewController.cs
@@ -165,7 +165,7 @@ namespace LBPUnion.ProjectLighthouse.Controllers
yourReview.SlotId = slotId;
yourReview.Deleted = false;
yourReview.DeletedBy = DeletedBy.None;
- yourReview.Text = "You haven't reviewed this level yet. Edit this blank review to upload it!";
+ yourReview.Text = "You haven't reviewed this level yet. Edit this blank review to upload one!";
yourReview.LabelCollection = "";
yourReview.Timestamp = TimeHelper.UnixTimeMilliseconds();
}
From aa71592a1ecc29bbcf78e348f66bbc6dbca9f305 Mon Sep 17 00:00:00 2001
From: LumaLivy <7350336+LumaLivy@users.noreply.github.com>
Date: Sat, 11 Dec 2021 01:38:23 -0500
Subject: [PATCH 6/6] Restore behaviour of cached review stats
---
ProjectLighthouse/Controllers/ReviewController.cs | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/ProjectLighthouse/Controllers/ReviewController.cs b/ProjectLighthouse/Controllers/ReviewController.cs
index ca6549ba..71befbb0 100644
--- a/ProjectLighthouse/Controllers/ReviewController.cs
+++ b/ProjectLighthouse/Controllers/ReviewController.cs
@@ -269,8 +269,18 @@ namespace LBPUnion.ProjectLighthouse.Controllers
this.database.RatedReviews.Add(ratedReview);
}
+ int oldThumb = ratedReview.Thumb;
ratedReview.Thumb = Math.Max(Math.Min(1, rating), -1);
+ if (oldThumb != ratedReview.Thumb)
+ {
+ if (oldThumb == -1) review.ThumbsDown--;
+ else if (oldThumb == 1) review.ThumbsUp--;
+
+ if (ratedReview.Thumb == -1) review.ThumbsDown++;
+ else if (ratedReview.Thumb == 1) review.ThumbsUp++;
+ }
+
await this.database.SaveChangesAsync();
return this.Ok();