From 06c8b5fc449626401d1eaaf82a6b434265b26789 Mon Sep 17 00:00:00 2001 From: jvyden Date: Mon, 8 Nov 2021 14:49:39 -0500 Subject: [PATCH 01/11] Add npData and myFriends support --- ProjectLighthouse.sln.DotSettings | 2 + .../Controllers/FriendsController.cs | 92 +++++++++++++++++++ ProjectLighthouse/Helpers/FriendHelper.cs | 12 +++ ProjectLighthouse/Types/Profiles/NPData.cs | 18 ++++ 4 files changed, 124 insertions(+) create mode 100644 ProjectLighthouse/Controllers/FriendsController.cs create mode 100644 ProjectLighthouse/Helpers/FriendHelper.cs create mode 100644 ProjectLighthouse/Types/Profiles/NPData.cs diff --git a/ProjectLighthouse.sln.DotSettings b/ProjectLighthouse.sln.DotSettings index 698d69e9..cd0a7049 100644 --- a/ProjectLighthouse.sln.DotSettings +++ b/ProjectLighthouse.sln.DotSettings @@ -72,6 +72,7 @@ UseExplicitType UseExplicitType MM + NP <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"><ExtraRule Prefix="" Suffix="" Style="aaBb" /></Policy> <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> @@ -97,6 +98,7 @@ True True True + True True True True diff --git a/ProjectLighthouse/Controllers/FriendsController.cs b/ProjectLighthouse/Controllers/FriendsController.cs new file mode 100644 index 00000000..6cd14fce --- /dev/null +++ b/ProjectLighthouse/Controllers/FriendsController.cs @@ -0,0 +1,92 @@ +#nullable enable +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; +using System.Xml.Serialization; +using LBPUnion.ProjectLighthouse.Helpers; +using LBPUnion.ProjectLighthouse.Serialization; +using LBPUnion.ProjectLighthouse.Types; +using LBPUnion.ProjectLighthouse.Types.Profiles; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; + +namespace LBPUnion.ProjectLighthouse.Controllers +{ + [ApiController] + [Route("LITTLEBIGPLANETPS3_XML/")] + public class FriendsController : ControllerBase + { + private readonly Database database; + + public FriendsController(Database database) + { + this.database = database; + } + + [HttpPost("npdata")] + public async Task NPData() + { + User? user = await this.database.UserFromRequest(this.Request); + if (user == null) return this.StatusCode(403, ""); + + this.Request.Body.Position = 0; + string bodyString = await new StreamReader(this.Request.Body).ReadToEndAsync(); + + XmlSerializer serializer = new(typeof(NPData)); + NPData? npData = (NPData?)serializer.Deserialize(new StringReader(bodyString)); + if (npData == null) return this.BadRequest(); + + List friends = new(); + foreach (string friendName in npData.Friends) + { + User? friend = await this.database.Users.FirstOrDefaultAsync(u => u.Username == friendName); + if (friend == null) continue; + + friends.Add(friend.UserId); + } + + List blockedUsers = new(); + foreach (string blockedUserName in npData.BlockedUsers) + { + User? blockedUser = await this.database.Users.FirstOrDefaultAsync(u => u.Username == blockedUserName); + if (blockedUser == null) continue; + + blockedUsers.Add(blockedUser.UserId); + } + + if (FriendHelper.FriendIdsByUserId.ContainsKey(user.UserId)) + { + FriendHelper.FriendIdsByUserId.Remove(user.UserId); + FriendHelper.BlockedIdsByUserId.Remove(user.UserId); + } + + FriendHelper.FriendIdsByUserId.Add(user.UserId, friends.ToArray()); + FriendHelper.BlockedIdsByUserId.Add(user.UserId, blockedUsers.ToArray()); + + return this.Ok(); + } + + [HttpGet("myFriends")] + public async Task MyFriends() + { + User? user = await this.database.UserFromRequest(this.Request); + if (user == null) return this.StatusCode(403, ""); + + if (!FriendHelper.FriendIdsByUserId.TryGetValue(user.UserId, out int[]? friendIds) || friendIds == null) + { + return this.NotFound(); + } + + string friends = ""; + foreach (int friendId in friendIds) + { + User? friend = await this.database.Users.Include(u => u.Location).FirstOrDefaultAsync(u => u.UserId == friendId); + if (friend == null) continue; + + friends += friend.Serialize(); + } + + return this.Ok(LbpSerializer.StringElement("myFriends", friends)); + } + } +} \ No newline at end of file diff --git a/ProjectLighthouse/Helpers/FriendHelper.cs b/ProjectLighthouse/Helpers/FriendHelper.cs new file mode 100644 index 00000000..9475e582 --- /dev/null +++ b/ProjectLighthouse/Helpers/FriendHelper.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; + +namespace LBPUnion.ProjectLighthouse.Helpers +{ + [NotMapped] + public static class FriendHelper + { + public static Dictionary FriendIdsByUserId = new(); + public static Dictionary BlockedIdsByUserId = new(); + } +} \ No newline at end of file diff --git a/ProjectLighthouse/Types/Profiles/NPData.cs b/ProjectLighthouse/Types/Profiles/NPData.cs new file mode 100644 index 00000000..a117d6bf --- /dev/null +++ b/ProjectLighthouse/Types/Profiles/NPData.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; +using System.Xml.Serialization; + +namespace LBPUnion.ProjectLighthouse.Types.Profiles +{ + [XmlRoot("npdata")] + [XmlType("npdata")] + public class NPData + { + [XmlArray("friends")] + [XmlArrayItem("npHandle")] + public List Friends { get; set; } + + [XmlArray("blocked")] + [XmlArrayItem("npHandle")] + public List BlockedUsers { get; set; } + } +} \ No newline at end of file From f765331dee6d024346496f2f517c7b96cce29948 Mon Sep 17 00:00:00 2001 From: LumaLivy Date: Mon, 8 Nov 2021 16:23:54 -0500 Subject: [PATCH 02/11] Add support for Yay/Boo on a community level --- .../Controllers/ReviewController.cs | 48 ++ ProjectLighthouse/Database.cs | 1 + ...0211108212022_BooYayRateLevels.Designer.cs | 632 ++++++++++++++++++ .../20211108212022_BooYayRateLevels.cs | 56 ++ .../Migrations/DatabaseModelSnapshot.cs | 46 ++ ProjectLighthouse/Types/Levels/RatedLevel.cs | 26 + ProjectLighthouse/Types/Levels/Slot.cs | 37 +- 7 files changed, 844 insertions(+), 2 deletions(-) create mode 100644 ProjectLighthouse/Controllers/ReviewController.cs create mode 100644 ProjectLighthouse/Migrations/20211108212022_BooYayRateLevels.Designer.cs create mode 100644 ProjectLighthouse/Migrations/20211108212022_BooYayRateLevels.cs create mode 100644 ProjectLighthouse/Types/Levels/RatedLevel.cs diff --git a/ProjectLighthouse/Controllers/ReviewController.cs b/ProjectLighthouse/Controllers/ReviewController.cs new file mode 100644 index 00000000..919e1dba --- /dev/null +++ b/ProjectLighthouse/Controllers/ReviewController.cs @@ -0,0 +1,48 @@ +#nullable enable +using System; +using System.Threading.Tasks; +using LBPUnion.ProjectLighthouse.Types; +using LBPUnion.ProjectLighthouse.Types.Levels; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; + +namespace LBPUnion.ProjectLighthouse.Controllers +{ + [ApiController] + [Route("LITTLEBIGPLANETPS3_XML/")] + [Produces("text/plain")] + public class ReviewController : ControllerBase + { + private readonly Database database; + + public ReviewController(Database database) + { + this.database = database; + } + + [HttpPost("dpadrate/user/{slotId}")] + public async Task DPadRate(int slotId, [FromQuery] int rating) + { + User? user = await this.database.UserFromRequest(this.Request); + if (user == null) return this.StatusCode(403, ""); + + Slot? slot = await this.database.Slots.FirstOrDefaultAsync(s => s.SlotId == slotId); + if (slot == null) return this.StatusCode(403, ""); + + RatedLevel? ratedLevel = await this.database.RatedLevels.FirstOrDefaultAsync(r => r.SlotId == slotId && r.UserId == user.UserId); + if (ratedLevel == null) + { + ratedLevel = new(); + this.database.RatedLevels.Add(ratedLevel); + } + ratedLevel.SlotId = slotId; + ratedLevel.UserId = user.UserId; + ratedLevel.Rating = rating; + // Unsupported: ratedLevel.LBP1Rating + + await this.database.SaveChangesAsync(); + + return this.Ok(); + } + } +} \ No newline at end of file diff --git a/ProjectLighthouse/Database.cs b/ProjectLighthouse/Database.cs index 57b18abb..fce30fd4 100644 --- a/ProjectLighthouse/Database.cs +++ b/ProjectLighthouse/Database.cs @@ -27,6 +27,7 @@ namespace LBPUnion.ProjectLighthouse public DbSet Photos { get; set; } public DbSet LastMatches { get; set; } public DbSet VisitedLevels { get; set; } + public DbSet RatedLevels { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder options) => options.UseMySql(ServerSettings.DbConnectionString, MySqlServerVersion.LatestSupportedServerVersion); diff --git a/ProjectLighthouse/Migrations/20211108212022_BooYayRateLevels.Designer.cs b/ProjectLighthouse/Migrations/20211108212022_BooYayRateLevels.Designer.cs new file mode 100644 index 00000000..4d1d9dbf --- /dev/null +++ b/ProjectLighthouse/Migrations/20211108212022_BooYayRateLevels.Designer.cs @@ -0,0 +1,632 @@ +// +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("20211108212022_BooYayRateLevels")] + partial class BooYayRateLevels + { + 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("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("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("BooHash") + .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("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"); + + 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/20211108212022_BooYayRateLevels.cs b/ProjectLighthouse/Migrations/20211108212022_BooYayRateLevels.cs new file mode 100644 index 00000000..0bb803a3 --- /dev/null +++ b/ProjectLighthouse/Migrations/20211108212022_BooYayRateLevels.cs @@ -0,0 +1,56 @@ +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace ProjectLighthouse.Migrations +{ + public partial class BooYayRateLevels : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "RatedLevels", + columns: table => new + { + RatedLevelId = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + UserId = table.Column(type: "int", nullable: false), + SlotId = table.Column(type: "int", nullable: false), + Rating = table.Column(type: "int", nullable: false), + RatingLBP1 = table.Column(type: "double", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_RatedLevels", x => x.RatedLevelId); + table.ForeignKey( + name: "FK_RatedLevels_Slots_SlotId", + column: x => x.SlotId, + principalTable: "Slots", + principalColumn: "SlotId", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_RatedLevels_Users_UserId", + column: x => x.UserId, + principalTable: "Users", + principalColumn: "UserId", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateIndex( + name: "IX_RatedLevels_SlotId", + table: "RatedLevels", + column: "SlotId"); + + migrationBuilder.CreateIndex( + name: "IX_RatedLevels_UserId", + table: "RatedLevels", + column: "UserId"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "RatedLevels"); + } + } +} diff --git a/ProjectLighthouse/Migrations/DatabaseModelSnapshot.cs b/ProjectLighthouse/Migrations/DatabaseModelSnapshot.cs index 96f61582..99b1bbf1 100644 --- a/ProjectLighthouse/Migrations/DatabaseModelSnapshot.cs +++ b/ProjectLighthouse/Migrations/DatabaseModelSnapshot.cs @@ -79,6 +79,33 @@ namespace ProjectLighthouse.Migrations 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") @@ -478,6 +505,25 @@ namespace ProjectLighthouse.Migrations 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") diff --git a/ProjectLighthouse/Types/Levels/RatedLevel.cs b/ProjectLighthouse/Types/Levels/RatedLevel.cs new file mode 100644 index 00000000..8b2228a0 --- /dev/null +++ b/ProjectLighthouse/Types/Levels/RatedLevel.cs @@ -0,0 +1,26 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace LBPUnion.ProjectLighthouse.Types.Levels +{ + public class RatedLevel + { + // ReSharper disable once UnusedMember.Global + [Key] + public int RatedLevelId { get; set; } + + public int UserId { get; set; } + + [ForeignKey(nameof(UserId))] + public User User { get; set; } + + public int SlotId { get; set; } + + [ForeignKey(nameof(SlotId))] + public Slot Slot { get; set; } + + public int Rating { get; set; } + + public double RatingLBP1 { get; set; } + } +} \ No newline at end of file diff --git a/ProjectLighthouse/Types/Levels/Slot.cs b/ProjectLighthouse/Types/Levels/Slot.cs index 90bc82e0..c48749bc 100644 --- a/ProjectLighthouse/Types/Levels/Slot.cs +++ b/ProjectLighthouse/Types/Levels/Slot.cs @@ -139,7 +139,37 @@ namespace LBPUnion.ProjectLighthouse.Types.Levels [XmlIgnore] public int PlaysLBP3Unique { get; set; } - + [XmlElement("thumbsup")] + public int Thumbsup + { + get + { + using Database database = new(); + + return database.RatedLevels.Count(r => r.SlotId == this.SlotId && r.Rating == 1); + } + } + [XmlElement("thumbsdown")] + public int Thumbsdown + { + get + { + using Database database = new(); + + return database.RatedLevels.Count(r => r.SlotId == this.SlotId && r.Rating == -1); + } + } + [XmlElement("averageRating")] + public double RatingLBP1 { get { + using Database database = new(); + + IQueryable ratedLevels = database.RatedLevels.Where(r => r.SlotId == this.SlotId && r.RatingLBP1 > 0); + if (!ratedLevels.Any()) return 3.0; + + return Enumerable.Average(ratedLevels, r => r.RatingLBP1); ; + } + } + public string SerializeResources() { return this.Resources.Aggregate("", (current, resource) => current + LbpSerializer.StringElement("resource", resource)); @@ -179,7 +209,10 @@ namespace LBPUnion.ProjectLighthouse.Types.Levels LbpSerializer.StringElement("lbp2UniquePlayCount", this.PlaysLBP2Unique) + // not actually used ingame, as per above comment LbpSerializer.StringElement("lbp3PlayCount", this.PlaysLBP3) + LbpSerializer.StringElement("lbp3CompletionCount", this.PlaysLBP3Complete) + - LbpSerializer.StringElement("lbp3UniquePlayCount", this.PlaysLBP3Unique); + LbpSerializer.StringElement("lbp3UniquePlayCount", this.PlaysLBP3Unique) + + LbpSerializer.StringElement("thumbsup", this.Thumbsup) + + LbpSerializer.StringElement("thumbsdown", this.Thumbsdown) + + LbpSerializer.StringElement("averageRating", this.RatingLBP1); return LbpSerializer.TaggedStringElement("slot", slotData, "type", "user"); } From 8c4969b14546150fe3e2bb5ab739fc870c45aad4 Mon Sep 17 00:00:00 2001 From: LumaLivy Date: Mon, 8 Nov 2021 21:13:16 -0500 Subject: [PATCH 03/11] Add support for sending/receiving LBP1 ratings --- .../Controllers/ReviewController.cs | 44 ++++++++++++++++--- ProjectLighthouse/Types/Levels/Slot.cs | 29 +++++++++++- 2 files changed, 64 insertions(+), 9 deletions(-) diff --git a/ProjectLighthouse/Controllers/ReviewController.cs b/ProjectLighthouse/Controllers/ReviewController.cs index 919e1dba..cece8a3e 100644 --- a/ProjectLighthouse/Controllers/ReviewController.cs +++ b/ProjectLighthouse/Controllers/ReviewController.cs @@ -20,29 +20,59 @@ namespace LBPUnion.ProjectLighthouse.Controllers this.database = database; } - [HttpPost("dpadrate/user/{slotId}")] - public async Task DPadRate(int slotId, [FromQuery] int rating) + // LBP1 rating + [HttpPost("rate/user/{slotId}")] + public async Task Rate(int slotId, [FromQuery] int rating) { User? user = await this.database.UserFromRequest(this.Request); if (user == null) return this.StatusCode(403, ""); - Slot? slot = await this.database.Slots.FirstOrDefaultAsync(s => s.SlotId == slotId); + Slot? slot = await this.database.Slots.Include(s => s.Creator).Include(s => s.Location).FirstOrDefaultAsync(s => s.SlotId == slotId); if (slot == null) return this.StatusCode(403, ""); RatedLevel? ratedLevel = await this.database.RatedLevels.FirstOrDefaultAsync(r => r.SlotId == slotId && r.UserId == user.UserId); if (ratedLevel == null) { ratedLevel = new(); + ratedLevel.SlotId = slotId; + ratedLevel.UserId = user.UserId; + ratedLevel.Rating = 0; this.database.RatedLevels.Add(ratedLevel); } - ratedLevel.SlotId = slotId; - ratedLevel.UserId = user.UserId; - ratedLevel.Rating = rating; - // Unsupported: ratedLevel.LBP1Rating + + ratedLevel.RatingLBP1 = Math.Max(Math.Min(5, rating), 0); await this.database.SaveChangesAsync(); return this.Ok(); } + + // LBP2 and beyond rating + [HttpPost("dpadrate/user/{slotId}")] + public async Task DPadRate(int slotId, [FromQuery] int rating) + { + User? user = await this.database.UserFromRequest(this.Request); + if (user == null) return this.StatusCode(403, ""); + + Slot? slot = await this.database.Slots.Include(s => s.Creator).Include(s => s.Location).FirstOrDefaultAsync(s => s.SlotId == slotId); + if (slot == null) return this.StatusCode(403, ""); + + RatedLevel? ratedLevel = await this.database.RatedLevels.FirstOrDefaultAsync(r => r.SlotId == slotId && r.UserId == user.UserId); + if (ratedLevel == null) + { + ratedLevel = new(); + ratedLevel.SlotId = slotId; + ratedLevel.UserId = user.UserId; + ratedLevel.RatingLBP1 = 0; + this.database.RatedLevels.Add(ratedLevel); + } + + ratedLevel.Rating = Math.Max(Math.Min(1, rating), -1); + + await this.database.SaveChangesAsync(); + + return this.Ok(); + } + } } \ No newline at end of file diff --git a/ProjectLighthouse/Types/Levels/Slot.cs b/ProjectLighthouse/Types/Levels/Slot.cs index c48749bc..d461ff5f 100644 --- a/ProjectLighthouse/Types/Levels/Slot.cs +++ b/ProjectLighthouse/Types/Levels/Slot.cs @@ -139,6 +139,7 @@ namespace LBPUnion.ProjectLighthouse.Types.Levels [XmlIgnore] public int PlaysLBP3Unique { get; set; } + [NotMapped] [XmlElement("thumbsup")] public int Thumbsup { @@ -149,6 +150,8 @@ namespace LBPUnion.ProjectLighthouse.Types.Levels return database.RatedLevels.Count(r => r.SlotId == this.SlotId && r.Rating == 1); } } + + [NotMapped] [XmlElement("thumbsdown")] public int Thumbsdown { @@ -159,6 +162,8 @@ namespace LBPUnion.ProjectLighthouse.Types.Levels return database.RatedLevels.Count(r => r.SlotId == this.SlotId && r.Rating == -1); } } + + [NotMapped] [XmlElement("averageRating")] public double RatingLBP1 { get { using Database database = new(); @@ -167,8 +172,24 @@ namespace LBPUnion.ProjectLighthouse.Types.Levels if (!ratedLevels.Any()) return 3.0; return Enumerable.Average(ratedLevels, r => r.RatingLBP1); ; - } - } + } + } + + [NotMapped] + [XmlElement("yourRating")] + public double YourRating { get; set; } + + [NotMapped] + [XmlElement("yourDPadRating")] + public int YourDPadRating { get; set; } + + [NotMapped] + [XmlElement("yourLBP1PlayCount")] + public int YourLBP1PlayCount { get; set; } + + [NotMapped] + [XmlElement("yourLBP2PlayCount")] + public int YourLBP2PlayCount { get; set; } public string SerializeResources() { @@ -212,6 +233,10 @@ namespace LBPUnion.ProjectLighthouse.Types.Levels LbpSerializer.StringElement("lbp3UniquePlayCount", this.PlaysLBP3Unique) + LbpSerializer.StringElement("thumbsup", this.Thumbsup) + LbpSerializer.StringElement("thumbsdown", this.Thumbsdown) + + LbpSerializer.StringElement("yourRating", this.YourRating) + + LbpSerializer.StringElement("yourDPadRating", this.YourDPadRating) + + LbpSerializer.StringElement("yourLBP1PlayCount", this.YourLBP1PlayCount) + + LbpSerializer.StringElement("yourLBP2PlayCount", this.YourLBP2PlayCount) + LbpSerializer.StringElement("averageRating", this.RatingLBP1); return LbpSerializer.TaggedStringElement("slot", slotData, "type", "user"); From 34448ee6f3fcaa674e245be94529848b2077b023 Mon Sep 17 00:00:00 2001 From: LumaLivy Date: Mon, 8 Nov 2021 21:14:16 -0500 Subject: [PATCH 04/11] Add rating info to s/user/ to show your current ranking in the pause menu --- ProjectLighthouse/Controllers/SlotsController.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/ProjectLighthouse/Controllers/SlotsController.cs b/ProjectLighthouse/Controllers/SlotsController.cs index 953ea027..89bdf9e8 100644 --- a/ProjectLighthouse/Controllers/SlotsController.cs +++ b/ProjectLighthouse/Controllers/SlotsController.cs @@ -45,18 +45,27 @@ namespace LBPUnion.ProjectLighthouse.Controllers [HttpGet("s/user/{id:int}")] public async Task SUser(int id) { + User? user = await this.database.UserFromRequest(this.Request); + if (user == null) return this.StatusCode(403, ""); + Token? token = await this.database.TokenFromRequest(this.Request); if (token == null) return this.BadRequest(); GameVersion gameVersion = token.GameVersion; - Slot slot = await this.database.Slots.Where(s => s.GameVersion <= gameVersion) + Slot? slot = await this.database.Slots.Where(s => s.GameVersion <= gameVersion) .Include(s => s.Creator) .Include(s => s.Location) .FirstOrDefaultAsync(s => s.SlotId == id); if (slot == null) return this.NotFound(); + RatedLevel? ratedLevel = await this.database.RatedLevels.FirstOrDefaultAsync(r => r.SlotId == id && r.UserId == user.UserId); + if (ratedLevel != null) { + slot.YourRating = ratedLevel.RatingLBP1; + slot.YourDPadRating = ratedLevel.Rating; + } + return this.Ok(slot.Serialize()); } From c0cf42a7852effd44d757d75b6f9fabcef31803e Mon Sep 17 00:00:00 2001 From: LumaLivy Date: Mon, 8 Nov 2021 21:14:16 -0500 Subject: [PATCH 05/11] Add rating info to s/user/ to show your current rating in the pause menu --- ProjectLighthouse/Controllers/SlotsController.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/ProjectLighthouse/Controllers/SlotsController.cs b/ProjectLighthouse/Controllers/SlotsController.cs index 953ea027..89bdf9e8 100644 --- a/ProjectLighthouse/Controllers/SlotsController.cs +++ b/ProjectLighthouse/Controllers/SlotsController.cs @@ -45,18 +45,27 @@ namespace LBPUnion.ProjectLighthouse.Controllers [HttpGet("s/user/{id:int}")] public async Task SUser(int id) { + User? user = await this.database.UserFromRequest(this.Request); + if (user == null) return this.StatusCode(403, ""); + Token? token = await this.database.TokenFromRequest(this.Request); if (token == null) return this.BadRequest(); GameVersion gameVersion = token.GameVersion; - Slot slot = await this.database.Slots.Where(s => s.GameVersion <= gameVersion) + Slot? slot = await this.database.Slots.Where(s => s.GameVersion <= gameVersion) .Include(s => s.Creator) .Include(s => s.Location) .FirstOrDefaultAsync(s => s.SlotId == id); if (slot == null) return this.NotFound(); + RatedLevel? ratedLevel = await this.database.RatedLevels.FirstOrDefaultAsync(r => r.SlotId == id && r.UserId == user.UserId); + if (ratedLevel != null) { + slot.YourRating = ratedLevel.RatingLBP1; + slot.YourDPadRating = ratedLevel.Rating; + } + return this.Ok(slot.Serialize()); } From f157647f689ae687bbb52a6b5b4e922e0d0083ee Mon Sep 17 00:00:00 2001 From: LumaLivy Date: Mon, 8 Nov 2021 23:44:45 -0500 Subject: [PATCH 06/11] Remove yourXXX properties from Slot and add them as arguments to serializer --- .../Controllers/SlotsController.cs | 8 ++---- ProjectLighthouse/Types/Levels/Slot.cs | 28 ++++--------------- 2 files changed, 8 insertions(+), 28 deletions(-) diff --git a/ProjectLighthouse/Controllers/SlotsController.cs b/ProjectLighthouse/Controllers/SlotsController.cs index 89bdf9e8..727a56dd 100644 --- a/ProjectLighthouse/Controllers/SlotsController.cs +++ b/ProjectLighthouse/Controllers/SlotsController.cs @@ -61,12 +61,8 @@ namespace LBPUnion.ProjectLighthouse.Controllers if (slot == null) return this.NotFound(); RatedLevel? ratedLevel = await this.database.RatedLevels.FirstOrDefaultAsync(r => r.SlotId == id && r.UserId == user.UserId); - if (ratedLevel != null) { - slot.YourRating = ratedLevel.RatingLBP1; - slot.YourDPadRating = ratedLevel.Rating; - } - - return this.Ok(slot.Serialize()); + string res = ratedLevel != null ? slot.Serialize(ratedLevel.RatingLBP1, ratedLevel.Rating) : slot.Serialize(); + return this.Ok(res); } [HttpGet("slots/lbp2cool")] diff --git a/ProjectLighthouse/Types/Levels/Slot.cs b/ProjectLighthouse/Types/Levels/Slot.cs index d461ff5f..fb0be697 100644 --- a/ProjectLighthouse/Types/Levels/Slot.cs +++ b/ProjectLighthouse/Types/Levels/Slot.cs @@ -175,28 +175,12 @@ namespace LBPUnion.ProjectLighthouse.Types.Levels } } - [NotMapped] - [XmlElement("yourRating")] - public double YourRating { get; set; } - - [NotMapped] - [XmlElement("yourDPadRating")] - public int YourDPadRating { get; set; } - - [NotMapped] - [XmlElement("yourLBP1PlayCount")] - public int YourLBP1PlayCount { get; set; } - - [NotMapped] - [XmlElement("yourLBP2PlayCount")] - public int YourLBP2PlayCount { get; set; } - public string SerializeResources() { return this.Resources.Aggregate("", (current, resource) => current + LbpSerializer.StringElement("resource", resource)); } - public string Serialize() + public string Serialize(double? yourRating = null, int? yourDPadRating = null, int? yourLBP1PlayCount = null, int? yourLBP2PlayCount = null) { string slotData = LbpSerializer.StringElement("name", this.Name) + LbpSerializer.StringElement("id", this.SlotId) + @@ -233,11 +217,11 @@ namespace LBPUnion.ProjectLighthouse.Types.Levels LbpSerializer.StringElement("lbp3UniquePlayCount", this.PlaysLBP3Unique) + LbpSerializer.StringElement("thumbsup", this.Thumbsup) + LbpSerializer.StringElement("thumbsdown", this.Thumbsdown) + - LbpSerializer.StringElement("yourRating", this.YourRating) + - LbpSerializer.StringElement("yourDPadRating", this.YourDPadRating) + - LbpSerializer.StringElement("yourLBP1PlayCount", this.YourLBP1PlayCount) + - LbpSerializer.StringElement("yourLBP2PlayCount", this.YourLBP2PlayCount) + - LbpSerializer.StringElement("averageRating", this.RatingLBP1); + LbpSerializer.StringElement("averageRating", this.RatingLBP1) + + yourRating != null ? LbpSerializer.StringElement("yourRating", yourRating) : "" + + yourDPadRating != null ? LbpSerializer.StringElement("yourDPadRating", yourDPadRating) : "" + + yourLBP1PlayCount != null ? LbpSerializer.StringElement("yourLBP1PlayCount", yourLBP1PlayCount) : "" + + yourLBP2PlayCount != null ? LbpSerializer.StringElement("yourLBP2PlayCount", yourLBP2PlayCount) : ""; return LbpSerializer.TaggedStringElement("slot", slotData, "type", "user"); } From 33f1d3fa82a64a25135ff56ec46670aaeaf2f1a0 Mon Sep 17 00:00:00 2001 From: jvyden Date: Tue, 9 Nov 2021 02:07:35 -0500 Subject: [PATCH 07/11] Fix rating ternary syntax --- ProjectLighthouse/Types/Levels/Slot.cs | 47 ++++++++++++++++---------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/ProjectLighthouse/Types/Levels/Slot.cs b/ProjectLighthouse/Types/Levels/Slot.cs index fb0be697..c2a466ee 100644 --- a/ProjectLighthouse/Types/Levels/Slot.cs +++ b/ProjectLighthouse/Types/Levels/Slot.cs @@ -110,41 +110,53 @@ namespace LBPUnion.ProjectLighthouse.Types.Levels [XmlIgnore] [NotMapped] - public int Plays { get => this.PlaysLBP1 + this.PlaysLBP2 + this.PlaysLBP3; } + public int Plays { + get => this.PlaysLBP1 + this.PlaysLBP2 + this.PlaysLBP3; + } + [XmlIgnore] [NotMapped] - public int PlaysUnique { get => this.PlaysLBP1Unique + this.PlaysLBP2Unique + this.PlaysLBP3Unique; } + public int PlaysUnique { + get => this.PlaysLBP1Unique + this.PlaysLBP2Unique + this.PlaysLBP3Unique; + } + [XmlIgnore] [NotMapped] - public int PlaysComplete { get => this.PlaysLBP1Complete + this.PlaysLBP2Complete + this.PlaysLBP3Complete; } + public int PlaysComplete { + get => this.PlaysLBP1Complete + this.PlaysLBP2Complete + this.PlaysLBP3Complete; + } [XmlIgnore] public int PlaysLBP1 { get; set; } + [XmlIgnore] public int PlaysLBP1Complete { get; set; } + [XmlIgnore] public int PlaysLBP1Unique { get; set; } [XmlIgnore] public int PlaysLBP2 { get; set; } + [XmlIgnore] public int PlaysLBP2Complete { get; set; } + [XmlIgnore] public int PlaysLBP2Unique { get; set; } [XmlIgnore] public int PlaysLBP3 { get; set; } + [XmlIgnore] public int PlaysLBP3Complete { get; set; } + [XmlIgnore] public int PlaysLBP3Unique { get; set; } [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); @@ -153,10 +165,8 @@ 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); @@ -165,13 +175,16 @@ 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); if (!ratedLevels.Any()) return 3.0; - return Enumerable.Average(ratedLevels, r => r.RatingLBP1); ; + return Enumerable.Average(ratedLevels, r => r.RatingLBP1); + + ; } } @@ -218,10 +231,10 @@ namespace LBPUnion.ProjectLighthouse.Types.Levels LbpSerializer.StringElement("thumbsup", this.Thumbsup) + LbpSerializer.StringElement("thumbsdown", this.Thumbsdown) + LbpSerializer.StringElement("averageRating", this.RatingLBP1) + - yourRating != null ? LbpSerializer.StringElement("yourRating", yourRating) : "" + - yourDPadRating != null ? LbpSerializer.StringElement("yourDPadRating", yourDPadRating) : "" + - yourLBP1PlayCount != null ? LbpSerializer.StringElement("yourLBP1PlayCount", yourLBP1PlayCount) : "" + - yourLBP2PlayCount != null ? LbpSerializer.StringElement("yourLBP2PlayCount", yourLBP2PlayCount) : ""; + (yourRating != null ? LbpSerializer.StringElement("yourRating", yourRating) : "") + + (yourDPadRating != null ? LbpSerializer.StringElement("yourDPadRating", yourDPadRating) : "") + + (yourLBP1PlayCount != null ? LbpSerializer.StringElement("yourLBP1PlayCount", yourLBP1PlayCount) : "") + + (yourLBP2PlayCount != null ? LbpSerializer.StringElement("yourLBP2PlayCount", yourLBP2PlayCount) : ""); return LbpSerializer.TaggedStringElement("slot", slotData, "type", "user"); } From 81f160780376f591fe1f29df649926fadf5b8b8e Mon Sep 17 00:00:00 2001 From: jvyden Date: Tue, 9 Nov 2021 17:40:53 -0500 Subject: [PATCH 08/11] Add LBP1 Total Level Count --- ProjectLighthouse/Controllers/StatisticsController.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ProjectLighthouse/Controllers/StatisticsController.cs b/ProjectLighthouse/Controllers/StatisticsController.cs index e27e52ea..9deb12c4 100644 --- a/ProjectLighthouse/Controllers/StatisticsController.cs +++ b/ProjectLighthouse/Controllers/StatisticsController.cs @@ -39,5 +39,8 @@ namespace LBPUnion.ProjectLighthouse.Controllers ("planetStats", LbpSerializer.StringElement("totalSlotCount", totalSlotCount) + LbpSerializer.StringElement("mmPicksCount", mmPicksCount)) ); } + + [HttpGet("planetStats/totalLevelCount")] + public async Task TotalLevelCount() => this.Ok((await this.database.Slots.CountAsync()).ToString()); } } \ No newline at end of file From ac40dd041aa52aa367b90a4150856c5db9b7d8fa Mon Sep 17 00:00:00 2001 From: jvyden Date: Tue, 9 Nov 2021 17:57:04 -0500 Subject: [PATCH 09/11] Add Level Type to Slot --- ProjectLighthouse.sln.DotSettings | 2 + ...11109225543_AddLevelTypeToSlot.Designer.cs | 635 ++++++++++++++++++ .../20211109225543_AddLevelTypeToSlot.cs | 24 + .../Migrations/DatabaseModelSnapshot.cs | 3 + ProjectLighthouse/Types/Levels/Slot.cs | 6 +- 5 files changed, 669 insertions(+), 1 deletion(-) create mode 100644 ProjectLighthouse/Migrations/20211109225543_AddLevelTypeToSlot.Designer.cs create mode 100644 ProjectLighthouse/Migrations/20211109225543_AddLevelTypeToSlot.cs diff --git a/ProjectLighthouse.sln.DotSettings b/ProjectLighthouse.sln.DotSettings index cd0a7049..ab04bcc9 100644 --- a/ProjectLighthouse.sln.DotSettings +++ b/ProjectLighthouse.sln.DotSettings @@ -71,6 +71,7 @@ UseExplicitType UseExplicitType UseExplicitType + LBP MM NP <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"><ExtraRule Prefix="" Suffix="" Style="aaBb" /></Policy> @@ -94,6 +95,7 @@ True True True + True True True True diff --git a/ProjectLighthouse/Migrations/20211109225543_AddLevelTypeToSlot.Designer.cs b/ProjectLighthouse/Migrations/20211109225543_AddLevelTypeToSlot.Designer.cs new file mode 100644 index 00000000..cc243392 --- /dev/null +++ b/ProjectLighthouse/Migrations/20211109225543_AddLevelTypeToSlot.Designer.cs @@ -0,0 +1,635 @@ +// +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("20211109225543_AddLevelTypeToSlot")] + partial class AddLevelTypeToSlot + { + 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("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("BooHash") + .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("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"); + + 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/20211109225543_AddLevelTypeToSlot.cs b/ProjectLighthouse/Migrations/20211109225543_AddLevelTypeToSlot.cs new file mode 100644 index 00000000..791151c5 --- /dev/null +++ b/ProjectLighthouse/Migrations/20211109225543_AddLevelTypeToSlot.cs @@ -0,0 +1,24 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace ProjectLighthouse.Migrations +{ + public partial class AddLevelTypeToSlot : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "LevelType", + table: "Slots", + type: "longtext", + nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "LevelType", + table: "Slots"); + } + } +} diff --git a/ProjectLighthouse/Migrations/DatabaseModelSnapshot.cs b/ProjectLighthouse/Migrations/DatabaseModelSnapshot.cs index 99b1bbf1..80cbef7e 100644 --- a/ProjectLighthouse/Migrations/DatabaseModelSnapshot.cs +++ b/ProjectLighthouse/Migrations/DatabaseModelSnapshot.cs @@ -142,6 +142,9 @@ namespace ProjectLighthouse.Migrations b.Property("Lbp1Only") .HasColumnType("tinyint(1)"); + b.Property("LevelType") + .HasColumnType("longtext"); + b.Property("LocationId") .HasColumnType("int"); diff --git a/ProjectLighthouse/Types/Levels/Slot.cs b/ProjectLighthouse/Types/Levels/Slot.cs index c2a466ee..95e8bdd7 100644 --- a/ProjectLighthouse/Types/Levels/Slot.cs +++ b/ProjectLighthouse/Types/Levels/Slot.cs @@ -188,6 +188,9 @@ namespace LBPUnion.ProjectLighthouse.Types.Levels } } + [XmlElement("leveltype")] + public string LevelType { get; set; } + public string SerializeResources() { return this.Resources.Aggregate("", (current, resource) => current + LbpSerializer.StringElement("resource", resource)); @@ -234,7 +237,8 @@ namespace LBPUnion.ProjectLighthouse.Types.Levels (yourRating != null ? LbpSerializer.StringElement("yourRating", yourRating) : "") + (yourDPadRating != null ? LbpSerializer.StringElement("yourDPadRating", yourDPadRating) : "") + (yourLBP1PlayCount != null ? LbpSerializer.StringElement("yourLBP1PlayCount", yourLBP1PlayCount) : "") + - (yourLBP2PlayCount != null ? LbpSerializer.StringElement("yourLBP2PlayCount", yourLBP2PlayCount) : ""); + (yourLBP2PlayCount != null ? LbpSerializer.StringElement("yourLBP2PlayCount", yourLBP2PlayCount) : "") + + LbpSerializer.StringElement("leveltype", this.LevelType); return LbpSerializer.TaggedStringElement("slot", slotData, "type", "user"); } From 4b2db485501683dfc29fdc83e923ed01931d744c Mon Sep 17 00:00:00 2001 From: jvyden Date: Tue, 9 Nov 2021 21:25:39 -0500 Subject: [PATCH 10/11] Make lucky dip actually random --- ProjectLighthouse/Controllers/SlotsController.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ProjectLighthouse/Controllers/SlotsController.cs b/ProjectLighthouse/Controllers/SlotsController.cs index 727a56dd..b8591722 100644 --- a/ProjectLighthouse/Controllers/SlotsController.cs +++ b/ProjectLighthouse/Controllers/SlotsController.cs @@ -117,13 +117,14 @@ namespace LBPUnion.ProjectLighthouse.Controllers GameVersion gameVersion = token.GameVersion; // TODO: Incorporate seed? - IQueryable slots = this.database.Slots.Where(s => s.GameVersion <= gameVersion) - .OrderBy(_ => Guid.NewGuid()) + IOrderedEnumerable slots = this.database.Slots.Where(s => s.GameVersion <= gameVersion) .Include(s => s.Creator) .Include(s => s.Location) .Skip(pageStart - 1) - .Take(Math.Min(pageSize, 30)); - string response = Enumerable.Aggregate(slots, string.Empty, (current, slot) => current + slot.Serialize()); + .Take(Math.Min(pageSize, 30)) + .AsEnumerable() + .OrderBy(_ => Guid.NewGuid()); + string response = slots.Aggregate(string.Empty, (current, slot) => current + slot.Serialize()); return this.Ok(LbpSerializer.TaggedStringElement("slots", response, "hint_start", pageStart + Math.Min(pageSize, 30))); } From 4373c23ff45aac0a7fc441d0452c6590eef09b9c Mon Sep 17 00:00:00 2001 From: jvyden Date: Wed, 10 Nov 2021 00:29:43 -0500 Subject: [PATCH 11/11] Lucky dip improvements --- ProjectLighthouse/Controllers/SlotsController.cs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/ProjectLighthouse/Controllers/SlotsController.cs b/ProjectLighthouse/Controllers/SlotsController.cs index b8591722..2a01f5fc 100644 --- a/ProjectLighthouse/Controllers/SlotsController.cs +++ b/ProjectLighthouse/Controllers/SlotsController.cs @@ -1,5 +1,6 @@ #nullable enable using System; +using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using LBPUnion.ProjectLighthouse.Serialization; @@ -115,15 +116,19 @@ namespace LBPUnion.ProjectLighthouse.Controllers if (token == null) return this.BadRequest(); GameVersion gameVersion = token.GameVersion; + int slotCount = await this.database.Slots.Where(s => s.GameVersion <= gameVersion).CountAsync(); + pageSize = Math.Min(pageSize, 30); + + int skipCount = new Random().Next(seed, slotCount) + pageStart - 1; // TODO: Incorporate seed? - IOrderedEnumerable slots = this.database.Slots.Where(s => s.GameVersion <= gameVersion) + IEnumerable slots = this.database.Slots.Where(s => s.GameVersion <= gameVersion) .Include(s => s.Creator) .Include(s => s.Location) - .Skip(pageStart - 1) - .Take(Math.Min(pageSize, 30)) - .AsEnumerable() - .OrderBy(_ => Guid.NewGuid()); + .Skip(skipCount) + .Take(pageSize) + .AsEnumerable(); + string response = slots.Aggregate(string.Empty, (current, slot) => current + slot.Serialize()); return this.Ok(LbpSerializer.TaggedStringElement("slots", response, "hint_start", pageStart + Math.Min(pageSize, 30)));