From 53acfee2ed714c20082f757ad51a4efcc496805c Mon Sep 17 00:00:00 2001 From: hydronePVP45 <51852312+hydronePVP45@users.noreply.github.com> Date: Sun, 14 Nov 2021 15:15:17 +0100 Subject: [PATCH 01/10] Update README.md changed lbp vita from 'somewhat compatible with workaround' to 'compatible' because it works about as well as LBP2 and does not require any workaround other than using a different digest key (than the mainline games), but i would not call that a workaround. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 40814d97..212aca0b 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,6 @@ Some modifications may require updates to the database schema. You can automatic | LBP1 | Compatible | Incompatible, crashes on entering pod computer | N/A | | LBP2 | Compatible | Compatible with patched RPCS3 | N/A | | LBP3 | Somewhat compatible | Somewhat compatible with workaround | Incompatible | -| LBP Vita | Somewhat compatible with workaround | N/A | N/A | +| LBP Vita | Compatible | N/A | N/A | Project Lighthouse is still a heavy work in progress, so this is subject to change at any point. From 2d40cbecc4ca0021f92e3403a2fc44e399049b6f Mon Sep 17 00:00:00 2001 From: hydronePVP45 <51852312+hydronePVP45@users.noreply.github.com> Date: Sun, 14 Nov 2021 21:01:15 +0100 Subject: [PATCH 02/10] Update GameVersionHelper.cs --- ProjectLighthouse/Helpers/GameVersionHelper.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ProjectLighthouse/Helpers/GameVersionHelper.cs b/ProjectLighthouse/Helpers/GameVersionHelper.cs index f216869f..d2ca53b9 100644 --- a/ProjectLighthouse/Helpers/GameVersionHelper.cs +++ b/ProjectLighthouse/Helpers/GameVersionHelper.cs @@ -79,7 +79,7 @@ namespace LBPUnion.ProjectLighthouse.Helpers public static readonly string[] LittleBigPlanetVitaTitleIds = { - "PCSF00021", "PCSA00017", "PCSC00013", + "PCSF00021", "PCSA00017", "PCSC00013", "PCSD00006", "PCSA00549" }; public static GameVersion FromTitleId(string titleId) @@ -92,4 +92,4 @@ namespace LBPUnion.ProjectLighthouse.Helpers return GameVersion.LittleBigPlanet1; } } -} \ No newline at end of file +} From d381cbe9a6d0f8ef3e508df64605eff2fbb31860 Mon Sep 17 00:00:00 2001 From: hydronePVP45 <51852312+hydronePVP45@users.noreply.github.com> Date: Sun, 14 Nov 2021 21:09:03 +0100 Subject: [PATCH 03/10] Update GameVersionHelper.cs --- ProjectLighthouse/Helpers/GameVersionHelper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ProjectLighthouse/Helpers/GameVersionHelper.cs b/ProjectLighthouse/Helpers/GameVersionHelper.cs index d2ca53b9..ba549839 100644 --- a/ProjectLighthouse/Helpers/GameVersionHelper.cs +++ b/ProjectLighthouse/Helpers/GameVersionHelper.cs @@ -79,7 +79,7 @@ namespace LBPUnion.ProjectLighthouse.Helpers public static readonly string[] LittleBigPlanetVitaTitleIds = { - "PCSF00021", "PCSA00017", "PCSC00013", "PCSD00006", "PCSA00549" + "PCSF00021", "PCSA00017", "PCSC00013", "PCSD00006", "PCSA00549", "PCSF00516" }; public static GameVersion FromTitleId(string titleId) From 4dc48689ccf6177b52b7f3432ae2b0faa8764bed Mon Sep 17 00:00:00 2001 From: frickinfire <46013177+frickinfire@users.noreply.github.com> Date: Sun, 14 Nov 2021 14:34:51 -0600 Subject: [PATCH 04/10] Fix README table layout --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 212aca0b..e45b3290 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,6 @@ Some modifications may require updates to the database schema. You can automatic | LBP1 | Compatible | Incompatible, crashes on entering pod computer | N/A | | LBP2 | Compatible | Compatible with patched RPCS3 | N/A | | LBP3 | Somewhat compatible | Somewhat compatible with workaround | Incompatible | -| LBP Vita | Compatible | N/A | N/A | +| LBP Vita | Compatible | N/A | N/A | Project Lighthouse is still a heavy work in progress, so this is subject to change at any point. From efbd5505894732a5e4e139e8c2dbfbd919371218 Mon Sep 17 00:00:00 2001 From: jvyden Date: Sun, 14 Nov 2021 17:38:42 -0500 Subject: [PATCH 05/10] Provide logger levels to Logger.Log calls without them --- .../Controllers/MatchController.cs | 5 +++-- .../Controllers/PhotosController.cs | 5 +++-- .../Controllers/ResourcesController.cs | 10 ++++++++-- ProjectLighthouse/Logging/LoggerLevels.cs | 18 ++++++++++++++++++ ProjectLighthouse/Startup.cs | 3 ++- 5 files changed, 34 insertions(+), 7 deletions(-) diff --git a/ProjectLighthouse/Controllers/MatchController.cs b/ProjectLighthouse/Controllers/MatchController.cs index dc62e6c9..900107f8 100644 --- a/ProjectLighthouse/Controllers/MatchController.cs +++ b/ProjectLighthouse/Controllers/MatchController.cs @@ -6,6 +6,7 @@ using System.Text.Json; using System.Threading.Tasks; using Kettu; using LBPUnion.ProjectLighthouse.Helpers; +using LBPUnion.ProjectLighthouse.Logging; using LBPUnion.ProjectLighthouse.Types; using LBPUnion.ProjectLighthouse.Types.Match; using LBPUnion.ProjectLighthouse.Types.Profiles; @@ -53,8 +54,8 @@ namespace LBPUnion.ProjectLighthouse.Controllers } catch(Exception e) { - Logger.Log("Exception while parsing MatchData: " + e); - Logger.Log("Data: " + bodyString); + Logger.Log("Exception while parsing MatchData: " + e, LoggerLevelMatch.Instance); + Logger.Log("Data: " + bodyString, LoggerLevelMatch.Instance); return this.BadRequest(); } diff --git a/ProjectLighthouse/Controllers/PhotosController.cs b/ProjectLighthouse/Controllers/PhotosController.cs index d5559365..c853aedf 100644 --- a/ProjectLighthouse/Controllers/PhotosController.cs +++ b/ProjectLighthouse/Controllers/PhotosController.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Threading.Tasks; using System.Xml.Serialization; using Kettu; +using LBPUnion.ProjectLighthouse.Logging; using LBPUnion.ProjectLighthouse.Serialization; using LBPUnion.ProjectLighthouse.Types; using Microsoft.AspNetCore.Mvc; @@ -48,7 +49,7 @@ namespace LBPUnion.ProjectLighthouse.Controllers if (subject.User == null) continue; subject.UserId = subject.User.UserId; - Logger.Log($"Adding PhotoSubject (userid {subject.UserId}) to db"); + Logger.Log($"Adding PhotoSubject (userid {subject.UserId}) to db", LoggerLevelPhotos.Instance); this.database.PhotoSubjects.Add(subject); } @@ -59,7 +60,7 @@ namespace LBPUnion.ProjectLighthouse.Controllers // photo.Slot = await this.database.Slots.FirstOrDefaultAsync(s => s.SlotId == photo.SlotId); - Logger.Log($"Adding PhotoSubjectCollection ({photo.PhotoSubjectCollection}) to photo"); + Logger.Log($"Adding PhotoSubjectCollection ({photo.PhotoSubjectCollection}) to photo", LoggerLevelPhotos.Instance); this.database.Photos.Add(photo); diff --git a/ProjectLighthouse/Controllers/ResourcesController.cs b/ProjectLighthouse/Controllers/ResourcesController.cs index dcb1a4d8..3680bbfd 100644 --- a/ProjectLighthouse/Controllers/ResourcesController.cs +++ b/ProjectLighthouse/Controllers/ResourcesController.cs @@ -4,6 +4,7 @@ using System.Threading.Tasks; using System.Xml.Serialization; using Kettu; using LBPUnion.ProjectLighthouse.Helpers; +using LBPUnion.ProjectLighthouse.Logging; using LBPUnion.ProjectLighthouse.Serialization; using LBPUnion.ProjectLighthouse.Types; using LBPUnion.ProjectLighthouse.Types.Files; @@ -60,11 +61,16 @@ namespace LBPUnion.ProjectLighthouse.Controllers FileHelper.EnsureDirectoryCreated(assetsDirectory); if (FileHelper.ResourceExists(hash)) this.Ok(); // no reason to fail if it's already uploaded - Logger.Log($"Processing resource upload (hash: {hash})"); + Logger.Log($"Processing resource upload (hash: {hash})", LoggerLevelResources.Instance); LbpFile file = new(await BinaryHelper.ReadFromPipeReader(this.Request.BodyReader)); - if (!FileHelper.IsFileSafe(file)) return this.UnprocessableEntity(); + if (!FileHelper.IsFileSafe(file)) + { + Logger.Log($"File is unsafe (hash: {hash}, type: {file.FileType})", LoggerLevelResources.Instance); + return this.UnprocessableEntity(); + } + Logger.Log($"File is OK! (hash: {hash}, type: {file.FileType})", LoggerLevelResources.Instance); await IOFile.WriteAllBytesAsync(path, file.Data); return this.Ok(); } diff --git a/ProjectLighthouse/Logging/LoggerLevels.cs b/ProjectLighthouse/Logging/LoggerLevels.cs index 0b304a1a..2fb28109 100644 --- a/ProjectLighthouse/Logging/LoggerLevels.cs +++ b/ProjectLighthouse/Logging/LoggerLevels.cs @@ -33,6 +33,24 @@ namespace LBPUnion.ProjectLighthouse.Logging public override string Name => "Login"; } + public class LoggerLevelResources : LoggerLevel + { + public static readonly LoggerLevelResources Instance = new(); + public override string Name => "Resources"; + } + + public class LoggerLevelMatch : LoggerLevel + { + public static readonly LoggerLevelMatch Instance = new(); + public override string Name => "Match"; + } + + public class LoggerLevelPhotos : LoggerLevel + { + public static readonly LoggerLevelPhotos Instance = new(); + public override string Name => "Photos"; + } + public class LoggerLevelAspNet : LoggerLevel { diff --git a/ProjectLighthouse/Startup.cs b/ProjectLighthouse/Startup.cs index fe0cdd4a..106b27da 100644 --- a/ProjectLighthouse/Startup.cs +++ b/ProjectLighthouse/Startup.cs @@ -60,7 +60,8 @@ namespace LBPUnion.ProjectLighthouse Logger.Log ( "The SERVER_DIGEST_KEY environment variable wasn't set, so digest headers won't be set or verified. This will prevent LBP 1 and LBP 3 from working. " + - "To increase security, it is recommended that you find and set this variable." + "To increase security, it is recommended that you find and set this variable.", + LoggerLevelStartup.Instance ); computeDigests = false; } From 6404e1b7a2a7b7d414dbad5461ea559693b4935c Mon Sep 17 00:00:00 2001 From: jvyden Date: Sun, 14 Nov 2021 17:44:00 -0500 Subject: [PATCH 06/10] Add more logging to MatchController --- ProjectLighthouse/Controllers/MatchController.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/ProjectLighthouse/Controllers/MatchController.cs b/ProjectLighthouse/Controllers/MatchController.cs index 900107f8..4d1fa398 100644 --- a/ProjectLighthouse/Controllers/MatchController.cs +++ b/ProjectLighthouse/Controllers/MatchController.cs @@ -60,7 +60,14 @@ namespace LBPUnion.ProjectLighthouse.Controllers return this.BadRequest(); } - if (matchData == null) return this.BadRequest(); + if (matchData == null) + { + Logger.Log("Could not parse match data: matchData is null", LoggerLevelMatch.Instance); + Logger.Log("Data: " + bodyString, LoggerLevelMatch.Instance); + return this.BadRequest(); + } + + Logger.Log($"Parsed match from {user.Username} (type: {matchData.GetType()})", LoggerLevelMatch.Instance); #endregion From af09e855484ae51353a3867fd85d1ec61fabec57 Mon Sep 17 00:00:00 2001 From: jvyden Date: Sun, 14 Nov 2021 18:15:59 -0500 Subject: [PATCH 07/10] Refactor User Remove "Staff Challenge" counts, rename all counts to their plural variants --- .../20211114231343_UserRefactor.Designer.cs | 623 ++++++++++++++++++ .../Migrations/20211114231343_UserRefactor.cs | 68 ++ .../Migrations/DatabaseModelSnapshot.cs | 15 - ProjectLighthouse/Types/User.cs | 35 +- 4 files changed, 703 insertions(+), 38 deletions(-) create mode 100644 ProjectLighthouse/Migrations/20211114231343_UserRefactor.Designer.cs create mode 100644 ProjectLighthouse/Migrations/20211114231343_UserRefactor.cs diff --git a/ProjectLighthouse/Migrations/20211114231343_UserRefactor.Designer.cs b/ProjectLighthouse/Migrations/20211114231343_UserRefactor.Designer.cs new file mode 100644 index 00000000..cf70b3b0 --- /dev/null +++ b/ProjectLighthouse/Migrations/20211114231343_UserRefactor.Designer.cs @@ -0,0 +1,623 @@ +// +using LBPUnion.ProjectLighthouse; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +namespace ProjectLighthouse.Migrations +{ + [DbContext(typeof(Database))] + [Migration("20211114231343_UserRefactor")] + partial class UserRefactor + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Relational:MaxIdentifierLength", 64) + .HasAnnotation("ProductVersion", "5.0.12"); + + 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") + .HasColumnType("longtext"); + + b.Property("BackgroundHash") + .HasColumnType("longtext"); + + b.Property("CreatorId") + .HasColumnType("int"); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("FirstUploaded") + .HasColumnType("bigint"); + + b.Property("GameVersion") + .HasColumnType("int"); + + b.Property("IconHash") + .HasColumnType("longtext"); + + b.Property("InitiallyLocked") + .HasColumnType("tinyint(1)"); + + b.Property("LastUpdated") + .HasColumnType("bigint"); + + b.Property("Lbp1Only") + .HasColumnType("tinyint(1)"); + + b.Property("LevelType") + .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") + .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("ResourceCollection") + .HasColumnType("longtext"); + + b.Property("RootLevel") + .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("GameVersion") + .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("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.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.Token", b => + { + b.Property("TokenId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + 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("Tokens"); + }); + + 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("LocationId") + .HasColumnType("int"); + + 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.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.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/20211114231343_UserRefactor.cs b/ProjectLighthouse/Migrations/20211114231343_UserRefactor.cs new file mode 100644 index 00000000..2eb65a74 --- /dev/null +++ b/ProjectLighthouse/Migrations/20211114231343_UserRefactor.cs @@ -0,0 +1,68 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace ProjectLighthouse.Migrations +{ + public partial class UserRefactor : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "BooHash", + table: "Users"); + + migrationBuilder.DropColumn( + name: "StaffChallengeBronzeCount", + table: "Users"); + + migrationBuilder.DropColumn( + name: "StaffChallengeGoldCount", + table: "Users"); + + migrationBuilder.DropColumn( + name: "StaffChallengeSilverCount", + table: "Users"); + + migrationBuilder.DropColumn( + name: "YayHash", + table: "Users"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "BooHash", + table: "Users", + type: "longtext", + nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AddColumn( + name: "StaffChallengeBronzeCount", + table: "Users", + type: "int", + nullable: false, + defaultValue: 0); + + migrationBuilder.AddColumn( + name: "StaffChallengeGoldCount", + table: "Users", + type: "int", + nullable: false, + defaultValue: 0); + + migrationBuilder.AddColumn( + name: "StaffChallengeSilverCount", + table: "Users", + type: "int", + nullable: false, + defaultValue: 0); + + migrationBuilder.AddColumn( + name: "YayHash", + table: "Users", + type: "longtext", + nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"); + } + } +} diff --git a/ProjectLighthouse/Migrations/DatabaseModelSnapshot.cs b/ProjectLighthouse/Migrations/DatabaseModelSnapshot.cs index a08c6227..2359699f 100644 --- a/ProjectLighthouse/Migrations/DatabaseModelSnapshot.cs +++ b/ProjectLighthouse/Migrations/DatabaseModelSnapshot.cs @@ -414,9 +414,6 @@ namespace ProjectLighthouse.Migrations b.Property("Biography") .HasColumnType("longtext"); - b.Property("BooHash") - .HasColumnType("longtext"); - b.Property("Game") .HasColumnType("int"); @@ -432,21 +429,9 @@ namespace ProjectLighthouse.Migrations b.Property("PlanetHash") .HasColumnType("longtext"); - b.Property("StaffChallengeBronzeCount") - .HasColumnType("int"); - - b.Property("StaffChallengeGoldCount") - .HasColumnType("int"); - - b.Property("StaffChallengeSilverCount") - .HasColumnType("int"); - b.Property("Username") .HasColumnType("longtext"); - b.Property("YayHash") - .HasColumnType("longtext"); - b.HasKey("UserId"); b.HasIndex("LocationId"); diff --git a/ProjectLighthouse/Types/User.cs b/ProjectLighthouse/Types/User.cs index 84713eef..7813cc8b 100644 --- a/ProjectLighthouse/Types/User.cs +++ b/ProjectLighthouse/Types/User.cs @@ -15,10 +15,7 @@ namespace LBPUnion.ProjectLighthouse.Types public int Game { get; set; } [NotMapped] - public int Lists { get; set; } - - public string YayHash { get; set; } - public string BooHash { get; set; } + public int Lists => 0; /// /// A user-customizable biography shown on the profile card @@ -26,10 +23,10 @@ namespace LBPUnion.ProjectLighthouse.Types public string Biography { get; set; } [NotMapped] - public int ReviewCount => 0; + public int Reviews => 0; [NotMapped] - public int CommentCount { + public int Comments { get { using Database database = new(); return database.Comments.Count(c => c.PosterUserId == this.UserId); @@ -37,7 +34,7 @@ namespace LBPUnion.ProjectLighthouse.Types } [NotMapped] - public int PhotosByMeCount { + public int PhotosByMe { get { using Database database = new(); return database.Photos.Count(p => p.CreatorId == this.UserId); @@ -45,7 +42,7 @@ namespace LBPUnion.ProjectLighthouse.Types } [NotMapped] - public int PhotosWithMeCount { + public int PhotosWithMe { get { using Database database = new(); return Enumerable.Sum(database.Photos, photo => photo.Subjects.Count(subject => subject.User.UserId == this.UserId)); @@ -77,7 +74,7 @@ namespace LBPUnion.ProjectLighthouse.Types } [NotMapped] - public int QueuedLevelsCount { + public int QueuedLevels { get { using Database database = new(); return database.QueuedLevels.Count(p => p.UserId == this.UserId); @@ -85,9 +82,6 @@ namespace LBPUnion.ProjectLighthouse.Types } public string Pins { get; set; } = ""; - public int StaffChallengeGoldCount { get; set; } - public int StaffChallengeSilverCount { get; set; } - public int StaffChallengeBronzeCount { get; set; } public string PlanetHash { get; set; } = ""; @@ -106,25 +100,20 @@ namespace LBPUnion.ProjectLighthouse.Types this.SerializeSlots() + LbpSerializer.StringElement("lists", this.Lists) + LbpSerializer.StringElement("lists_quota", ServerSettings.ListsQuota) + // technically not a part of the user but LBP expects it - LbpSerializer.StringElement("yay2", this.YayHash) + - LbpSerializer.StringElement("boo2", this.BooHash) + LbpSerializer.StringElement("biography", this.Biography) + - LbpSerializer.StringElement("reviewCount", this.ReviewCount) + - LbpSerializer.StringElement("commentCount", this.CommentCount) + - LbpSerializer.StringElement("photosByMeCount", this.PhotosByMeCount) + - LbpSerializer.StringElement("photosWithMeCount", this.PhotosWithMeCount) + + LbpSerializer.StringElement("reviewCount", this.Reviews) + + LbpSerializer.StringElement("commentCount", this.Comments) + + LbpSerializer.StringElement("photosByMeCount", this.PhotosByMe) + + LbpSerializer.StringElement("photosWithMeCount", this.PhotosWithMe) + LbpSerializer.StringElement("commentsEnabled", "true") + LbpSerializer.StringElement("location", this.Location.Serialize()) + LbpSerializer.StringElement("favouriteSlotCount", this.HeartedLevels) + LbpSerializer.StringElement("favouriteUserCount", this.HeartedUsers) + - LbpSerializer.StringElement("lolcatftwCount", this.QueuedLevelsCount) + + LbpSerializer.StringElement("lolcatftwCount", this.QueuedLevels) + LbpSerializer.StringElement("pins", this.Pins) + - LbpSerializer.StringElement("staffChallengeGoldCount", this.StaffChallengeGoldCount) + - LbpSerializer.StringElement("staffChallengeSilverCount", this.StaffChallengeSilverCount) + - LbpSerializer.StringElement("staffChallengeBronzeCount", this.StaffChallengeBronzeCount) + LbpSerializer.StringElement("planets", this.PlanetHash) + LbpSerializer.BlankElement("photos") + - LbpSerializer.StringElement("heartCount", Hearts); + LbpSerializer.StringElement("heartCount", this.Hearts); this.ClientsConnected.Serialize(); return LbpSerializer.TaggedStringElement("user", user, "type", "user"); From 51679f371ae43345f9ae4c1a9522e93e6b3901ae Mon Sep 17 00:00:00 2001 From: jvyden Date: Sun, 14 Nov 2021 18:50:51 -0500 Subject: [PATCH 08/10] Dont moderate levels/poppet items --- ProjectLighthouse/Controllers/ClientConfigurationController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ProjectLighthouse/Controllers/ClientConfigurationController.cs b/ProjectLighthouse/Controllers/ClientConfigurationController.cs index d54d0c7d..f681792b 100644 --- a/ProjectLighthouse/Controllers/ClientConfigurationController.cs +++ b/ProjectLighthouse/Controllers/ClientConfigurationController.cs @@ -17,7 +17,7 @@ namespace LBPUnion.ProjectLighthouse.Controllers HostString hostname = this.Request.Host; return this.Ok ( - "ProbabilityOfPacketDelay 0.0\nMinPacketDelayFrames 0\nMaxPacketDelayFrames 3\nProbabilityOfPacketDrop 0.0\nEnableFakeConditionsForLoopback true\nNumberOfFramesPredictionAllowedForNonLocalPlayer 1000\nEnablePrediction true\nMinPredictedFrames 0\nMaxPredictedFrames 10\nAllowGameRendCameraSplit true\nFramesBeforeAgressiveCatchup 30\nPredictionPadSides 200\nPredictionPadTop 200\nPredictionPadBottom 200\nShowErrorNumbers true\nAllowModeratedLevels true\nAllowModeratedPoppetItems true\nShowLevelBoos true\nTIMEOUT_WAIT_FOR_JOIN_RESPONSE_FROM_PREV_PARTY_HOST 50.0\nTIMEOUT_WAIT_FOR_CHANGE_LEVEL_PARTY_HOST 30.0\nTIMEOUT_WAIT_FOR_CHANGE_LEVEL_PARTY_MEMBER 45.0\nTIMEOUT_WAIT_FOR_REQUEST_JOIN_FRIEND 15.0\nTIMEOUT_WAIT_FOR_CONNECTION_FROM_HOST 30.0\nTIMEOUT_WAIT_FOR_ROOM_ID_TO_JOIN 60.0\nTIMEOUT_WAIT_FOR_GET_NUM_PLAYERS_ONLINE 60.0\nTIMEOUT_WAIT_FOR_SIGNALLING_CONNECTIONS 120.0\nTIMEOUT_WAIT_FOR_PARTY_DATA 60.0\nTIME_TO_WAIT_FOR_LEAVE_MESSAGE_TO_COME_BACK 20.0\nTIME_TO_WAIT_FOR_FOLLOWING_REQUESTS_TO_ARRIVE 30.0\nTIMEOUT_WAIT_FOR_FINISHED_MIGRATING_HOST 30.0\nTIMEOUT_WAIT_FOR_PARTY_LEADER_FINISH_JOINING 45.0\nTIMEOUT_WAIT_FOR_QUICKPLAY_LEVEL 60.0\nTIMEOUT_WAIT_FOR_PLAYERS_TO_JOIN 30.0\nTIMEOUT_WAIT_FOR_DIVE_IN_PLAYERS 240.0\nTIMEOUT_WAIT_FOR_FIND_BEST_ROOM 60.0\nTIMEOUT_DIVE_IN_TOTAL 300.0\nTIMEOUT_WAIT_FOR_SOCKET_CONNECTION 120.0\nTIMEOUT_WAIT_FOR_REQUEST_RESOURCE_MESSAGE 120.0\nTIMEOUT_WAIT_FOR_LOCAL_CLIENT_TO_GET_RESOURCE_LIST 120.0\nTIMEOUT_WAIT_FOR_CLIENT_TO_LOAD_RESOURCES 120.0\nTIMEOUT_WAIT_FOR_LOCAL_CLIENT_TO_SAVE_GAME_STATE 30.0\nTIMEOUT_WAIT_FOR_ADD_PLAYERS_TO_TAKE 30.0\nTIMEOUT_WAIT_FOR_UPDATE_FROM_CLIENT 90.0\nTIMEOUT_WAIT_FOR_HOST_TO_GET_RESOURCE_LIST 60.0\nTIMEOUT_WAIT_FOR_HOST_TO_SAVE_GAME_STATE 60.0\nTIMEOUT_WAIT_FOR_HOST_TO_ADD_US 30.0\nTIMEOUT_WAIT_FOR_UPDATE 60.0\nTIMEOUT_WAIT_FOR_REQUEST_JOIN 50.0\nTIMEOUT_WAIT_FOR_AUTOJOIN_PRESENCE 60.0\nTIMEOUT_WAIT_FOR_AUTOJOIN_CONNECTION 120.0\nSECONDS_BETWEEN_PINS_AWARDED_UPLOADS 300.0\nEnableKeepAlive true\nAllowVoIPRecordingPlayback true\nCDNHostName localhost\nTelemetryServer localhost\nOverheatingThresholdDisallowMidgameJoin 0.95\nMaxCatchupFrames 3\nMaxLagBeforeShowLoading 23\nMinLagBeforeHideLoading 30\nLagImprovementInflectionPoint -1.0\nFlickerThreshold 2.0\nClosedDemo2014Version 1\nClosedDemo2014Expired false\nEnablePlayedFilter true\nEnableCommunityDecorations true\nGameStateUpdateRate 10.0\nGameStateUpdateRateWithConsumers 1.0\nDisableDLCPublishCheck false\nEnableDiveIn true\nEnableHackChecks false\n" + + "ProbabilityOfPacketDelay 0.0\nMinPacketDelayFrames 0\nMaxPacketDelayFrames 3\nProbabilityOfPacketDrop 0.0\nEnableFakeConditionsForLoopback true\nNumberOfFramesPredictionAllowedForNonLocalPlayer 1000\nEnablePrediction true\nMinPredictedFrames 0\nMaxPredictedFrames 10\nAllowGameRendCameraSplit true\nFramesBeforeAgressiveCatchup 30\nPredictionPadSides 200\nPredictionPadTop 200\nPredictionPadBottom 200\nShowErrorNumbers true\nAllowModeratedLevels false\nAllowModeratedPoppetItems false\nShowLevelBoos true\nTIMEOUT_WAIT_FOR_JOIN_RESPONSE_FROM_PREV_PARTY_HOST 50.0\nTIMEOUT_WAIT_FOR_CHANGE_LEVEL_PARTY_HOST 30.0\nTIMEOUT_WAIT_FOR_CHANGE_LEVEL_PARTY_MEMBER 45.0\nTIMEOUT_WAIT_FOR_REQUEST_JOIN_FRIEND 15.0\nTIMEOUT_WAIT_FOR_CONNECTION_FROM_HOST 30.0\nTIMEOUT_WAIT_FOR_ROOM_ID_TO_JOIN 60.0\nTIMEOUT_WAIT_FOR_GET_NUM_PLAYERS_ONLINE 60.0\nTIMEOUT_WAIT_FOR_SIGNALLING_CONNECTIONS 120.0\nTIMEOUT_WAIT_FOR_PARTY_DATA 60.0\nTIME_TO_WAIT_FOR_LEAVE_MESSAGE_TO_COME_BACK 20.0\nTIME_TO_WAIT_FOR_FOLLOWING_REQUESTS_TO_ARRIVE 30.0\nTIMEOUT_WAIT_FOR_FINISHED_MIGRATING_HOST 30.0\nTIMEOUT_WAIT_FOR_PARTY_LEADER_FINISH_JOINING 45.0\nTIMEOUT_WAIT_FOR_QUICKPLAY_LEVEL 60.0\nTIMEOUT_WAIT_FOR_PLAYERS_TO_JOIN 30.0\nTIMEOUT_WAIT_FOR_DIVE_IN_PLAYERS 240.0\nTIMEOUT_WAIT_FOR_FIND_BEST_ROOM 60.0\nTIMEOUT_DIVE_IN_TOTAL 300.0\nTIMEOUT_WAIT_FOR_SOCKET_CONNECTION 120.0\nTIMEOUT_WAIT_FOR_REQUEST_RESOURCE_MESSAGE 120.0\nTIMEOUT_WAIT_FOR_LOCAL_CLIENT_TO_GET_RESOURCE_LIST 120.0\nTIMEOUT_WAIT_FOR_CLIENT_TO_LOAD_RESOURCES 120.0\nTIMEOUT_WAIT_FOR_LOCAL_CLIENT_TO_SAVE_GAME_STATE 30.0\nTIMEOUT_WAIT_FOR_ADD_PLAYERS_TO_TAKE 30.0\nTIMEOUT_WAIT_FOR_UPDATE_FROM_CLIENT 90.0\nTIMEOUT_WAIT_FOR_HOST_TO_GET_RESOURCE_LIST 60.0\nTIMEOUT_WAIT_FOR_HOST_TO_SAVE_GAME_STATE 60.0\nTIMEOUT_WAIT_FOR_HOST_TO_ADD_US 30.0\nTIMEOUT_WAIT_FOR_UPDATE 60.0\nTIMEOUT_WAIT_FOR_REQUEST_JOIN 50.0\nTIMEOUT_WAIT_FOR_AUTOJOIN_PRESENCE 60.0\nTIMEOUT_WAIT_FOR_AUTOJOIN_CONNECTION 120.0\nSECONDS_BETWEEN_PINS_AWARDED_UPLOADS 300.0\nEnableKeepAlive true\nAllowVoIPRecordingPlayback true\nCDNHostName localhost\nTelemetryServer localhost\nOverheatingThresholdDisallowMidgameJoin 0.95\nMaxCatchupFrames 3\nMaxLagBeforeShowLoading 23\nMinLagBeforeHideLoading 30\nLagImprovementInflectionPoint -1.0\nFlickerThreshold 2.0\nClosedDemo2014Version 1\nClosedDemo2014Expired false\nEnablePlayedFilter true\nEnableCommunityDecorations true\nGameStateUpdateRate 10.0\nGameStateUpdateRateWithConsumers 1.0\nDisableDLCPublishCheck false\nEnableDiveIn true\nEnableHackChecks false\n" + $"TelemetryServer {hostname}\nCDNHostName {hostname}" ); } From b641a6be81b16a46be0e98b34478ecbd4299039e Mon Sep 17 00:00:00 2001 From: jvyden Date: Sun, 14 Nov 2021 18:53:53 -0500 Subject: [PATCH 09/10] Implement pages for slots/by endpoint --- .../Controllers/SlotsController.cs | 27 ++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/ProjectLighthouse/Controllers/SlotsController.cs b/ProjectLighthouse/Controllers/SlotsController.cs index 2a01f5fc..85138ff9 100644 --- a/ProjectLighthouse/Controllers/SlotsController.cs +++ b/ProjectLighthouse/Controllers/SlotsController.cs @@ -6,6 +6,7 @@ using System.Threading.Tasks; using LBPUnion.ProjectLighthouse.Serialization; using LBPUnion.ProjectLighthouse.Types; using LBPUnion.ProjectLighthouse.Types.Levels; +using LBPUnion.ProjectLighthouse.Types.Settings; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; @@ -23,24 +24,44 @@ namespace LBPUnion.ProjectLighthouse.Controllers } [HttpGet("slots/by")] - public async Task SlotsBy([FromQuery] string u) + public async Task SlotsBy([FromQuery] string u, [FromQuery] int pageStart, [FromQuery] int pageSize) { Token? token = await this.database.TokenFromRequest(this.Request); if (token == null) return this.BadRequest(); GameVersion gameVersion = token.GameVersion; + User user = await this.database.Users.FirstOrDefaultAsync(dbUser => dbUser.Username == u); + string response = Enumerable.Aggregate ( this.database.Slots.Where(s => s.GameVersion <= gameVersion) .Include(s => s.Creator) .Include(s => s.Location) - .Where(s => s.Creator.Username == u), + .Where(s => s.Creator.Username == user.Username) + .Skip(pageStart - 1) + .Take(Math.Min(pageSize, ServerSettings.EntitledSlots)), string.Empty, (current, slot) => current + slot.Serialize() ); - return this.Ok(LbpSerializer.TaggedStringElement("slots", response, "total", 1)); + return this.Ok + ( + LbpSerializer.TaggedStringElement + ( + "slots", + response, + new Dictionary + { + { + "hint_start", pageStart + Math.Min(pageSize, ServerSettings.EntitledSlots) + }, + { + "total", user.UsedSlots + }, + } + ) + ); } [HttpGet("s/user/{id:int}")] From 278113f72933fb7b866432f02bf5e5652a11054c Mon Sep 17 00:00:00 2001 From: jvyden Date: Sun, 14 Nov 2021 21:25:30 -0500 Subject: [PATCH 10/10] Show used slots per-game --- ProjectLighthouse/Types/User.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/ProjectLighthouse/Types/User.cs b/ProjectLighthouse/Types/User.cs index 7813cc8b..8cdfef8d 100644 --- a/ProjectLighthouse/Types/User.cs +++ b/ProjectLighthouse/Types/User.cs @@ -132,6 +132,12 @@ namespace LBPUnion.ProjectLighthouse.Types } } + public int GetUsedSlotsForGame(GameVersion version) + { + using Database database = new(); + return database.Slots.Count(s => s.CreatorId == this.UserId && s.GameVersion == version); + } + /// /// The number of slots remaining on the earth /// @@ -147,13 +153,15 @@ namespace LBPUnion.ProjectLighthouse.Types { string slots = string.Empty; - slots += LbpSerializer.StringElement("lbp1UsedSlots", this.UsedSlots); + slots += LbpSerializer.StringElement("lbp1UsedSlots", this.GetUsedSlotsForGame(GameVersion.LittleBigPlanet1)); + slots += LbpSerializer.StringElement("lbp2UsedSlots", this.GetUsedSlotsForGame(GameVersion.LittleBigPlanet2)); + slots += LbpSerializer.StringElement("lbp3UsedSlots", this.GetUsedSlotsForGame(GameVersion.LittleBigPlanet3)); + slots += LbpSerializer.StringElement("entitledSlots", ServerSettings.EntitledSlots); slots += LbpSerializer.StringElement("freeSlots", this.FreeSlots); foreach (string slotType in slotTypes) { - slots += LbpSerializer.StringElement(slotType + "UsedSlots", 0); slots += LbpSerializer.StringElement(slotType + "EntitledSlots", ServerSettings.EntitledSlots); // ReSharper disable once StringLiteralTypo slots += LbpSerializer.StringElement(slotType + slotType == "crossControl" ? "PurchsedSlots" : "PurchasedSlots", 0);