diff --git a/ProjectLighthouse.sln.DotSettings b/ProjectLighthouse.sln.DotSettings index 698d69e9..ab04bcc9 100644 --- a/ProjectLighthouse.sln.DotSettings +++ b/ProjectLighthouse.sln.DotSettings @@ -71,7 +71,9 @@ UseExplicitType UseExplicitType UseExplicitType + LBP 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" /> @@ -93,10 +95,12 @@ True True True + True True 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/Controllers/ReviewController.cs b/ProjectLighthouse/Controllers/ReviewController.cs new file mode 100644 index 00000000..cece8a3e --- /dev/null +++ b/ProjectLighthouse/Controllers/ReviewController.cs @@ -0,0 +1,78 @@ +#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; + } + + // 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.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.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/Controllers/SlotsController.cs b/ProjectLighthouse/Controllers/SlotsController.cs index 953ea027..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; @@ -45,19 +46,24 @@ 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(); - return this.Ok(slot.Serialize()); + RatedLevel? ratedLevel = await this.database.RatedLevels.FirstOrDefaultAsync(r => r.SlotId == id && r.UserId == user.UserId); + string res = ratedLevel != null ? slot.Serialize(ratedLevel.RatingLBP1, ratedLevel.Rating) : slot.Serialize(); + return this.Ok(res); } [HttpGet("slots/lbp2cool")] @@ -110,15 +116,20 @@ 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? - IQueryable slots = this.database.Slots.Where(s => s.GameVersion <= gameVersion) - .OrderBy(_ => Guid.NewGuid()) + 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)); - string response = Enumerable.Aggregate(slots, string.Empty, (current, slot) => current + slot.Serialize()); + .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))); } 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 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/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/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/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 96f61582..80cbef7e 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") @@ -115,6 +142,9 @@ namespace ProjectLighthouse.Migrations b.Property("Lbp1Only") .HasColumnType("tinyint(1)"); + b.Property("LevelType") + .HasColumnType("longtext"); + b.Property("LocationId") .HasColumnType("int"); @@ -478,6 +508,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..95e8bdd7 100644 --- a/ProjectLighthouse/Types/Levels/Slot.cs +++ b/ProjectLighthouse/Types/Levels/Slot.cs @@ -110,42 +110,93 @@ 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 { + using Database database = new(); + + return database.RatedLevels.Count(r => r.SlotId == this.SlotId && r.Rating == 1); + } + } + + [NotMapped] + [XmlElement("thumbsdown")] + public int Thumbsdown { + get { + using Database database = new(); + + return database.RatedLevels.Count(r => r.SlotId == this.SlotId && r.Rating == -1); + } + } + + [NotMapped] + [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); + + ; + } + } + + [XmlElement("leveltype")] + public string LevelType { 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) + @@ -179,7 +230,15 @@ 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) + + (yourRating != null ? LbpSerializer.StringElement("yourRating", yourRating) : "") + + (yourDPadRating != null ? LbpSerializer.StringElement("yourDPadRating", yourDPadRating) : "") + + (yourLBP1PlayCount != null ? LbpSerializer.StringElement("yourLBP1PlayCount", yourLBP1PlayCount) : "") + + (yourLBP2PlayCount != null ? LbpSerializer.StringElement("yourLBP2PlayCount", yourLBP2PlayCount) : "") + + LbpSerializer.StringElement("leveltype", this.LevelType); return LbpSerializer.TaggedStringElement("slot", slotData, "type", "user"); } 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