diff --git a/ProjectLighthouse/Controllers/EnterLevelController.cs b/ProjectLighthouse/Controllers/EnterLevelController.cs index 1c783cef..47378dca 100644 --- a/ProjectLighthouse/Controllers/EnterLevelController.cs +++ b/ProjectLighthouse/Controllers/EnterLevelController.cs @@ -1,5 +1,7 @@ #nullable enable +using System.Linq; using System.Threading.Tasks; +using LBPUnion.ProjectLighthouse.Types; using LBPUnion.ProjectLighthouse.Types.Levels; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; @@ -7,7 +9,7 @@ using Microsoft.EntityFrameworkCore; namespace LBPUnion.ProjectLighthouse.Controllers { [ApiController] - [Route("LITTLEBIGPLANETPS3_XML/enterLevel")] + [Route("LITTLEBIGPLANETPS3_XML/")] // [Produces("text/plain")] public class EnterLevelController : ControllerBase { @@ -18,14 +20,84 @@ namespace LBPUnion.ProjectLighthouse.Controllers this.database = database; } + + [HttpPost("play/user/{slotId}")] + public async Task PlayLevel(int slotId) + { + 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, ""); + + Token? token = await this.database.TokenFromRequest(this.Request); + if (token == null) return this.StatusCode(403, ""); + + GameVersion gameVersion = token.GameVersion; + + IQueryable visited = this.database.VisitedLevels.Where(s => s.SlotId == slotId && s.UserId == user.UserId && s.GameVersion == gameVersion); + if (!visited.Any()) + { + switch (gameVersion) + { + case GameVersion.LittleBigPlanet2: + slot.PlaysLBP2Unique++; + break; + case GameVersion.LittleBigPlanet3: + slot.PlaysLBP3Unique++; + break; + default: + return this.BadRequest(); + } + + VisitedLevel v = new(); + v.SlotId = slotId; + v.UserId = user.UserId; + v.GameVersion = gameVersion; + this.database.VisitedLevels.Add(v); + await this.database.SaveChangesAsync(); + + } + + switch (gameVersion) + { + case GameVersion.LittleBigPlanet2: + slot.PlaysLBP2++; + break; + case GameVersion.LittleBigPlanet3: + slot.PlaysLBP3++; + break; + default: + return this.BadRequest(); + } + + return this.Ok(); + } + // Only used in LBP1 [HttpGet("enterLevel/{id:int}")] public async Task EnterLevel(int id) { + 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 == id); if (slot == null) return this.NotFound(); - slot.Plays++; + IQueryable visited = this.database.VisitedLevels.Where(s => s.SlotId == id && s.UserId == user.UserId && s.GameVersion == GameVersion.LittleBigPlanet1); + if (!visited.Any()) + { + slot.PlaysLBP1Unique++; + + VisitedLevel v = new(); + v.SlotId = id; + v.UserId = user.UserId; + v.GameVersion = GameVersion.LittleBigPlanet1; + this.database.VisitedLevels.Add(v); + + } + + slot.PlaysLBP1++; await this.database.SaveChangesAsync(); diff --git a/ProjectLighthouse/Controllers/ListController.cs b/ProjectLighthouse/Controllers/ListController.cs index 0b1deefb..7ac6bf03 100644 --- a/ProjectLighthouse/Controllers/ListController.cs +++ b/ProjectLighthouse/Controllers/ListController.cs @@ -32,6 +32,7 @@ namespace LBPUnion.ProjectLighthouse.Controllers (q => q.User) .Include(q => q.Slot) .Include(q => q.Slot.Location) + .Include(q => q.Slot.Creator) .Where(q => q.User.Username == username) .AsEnumerable(); diff --git a/ProjectLighthouse/Controllers/MatchController.cs b/ProjectLighthouse/Controllers/MatchController.cs index 73ec3bbb..e69f6311 100644 --- a/ProjectLighthouse/Controllers/MatchController.cs +++ b/ProjectLighthouse/Controllers/MatchController.cs @@ -61,7 +61,7 @@ namespace LBPUnion.ProjectLighthouse.Controllers #endregion #region Process match data - + /* if (matchData is CreateRoom createRoom) { if (createRoom.Slots.Count == 0) return this.BadRequest(); @@ -79,7 +79,7 @@ namespace LBPUnion.ProjectLighthouse.Controllers await this.database.SaveChangesAsync(); } } - + */ #endregion #region Update LastMatch diff --git a/ProjectLighthouse/Controllers/ScoreController.cs b/ProjectLighthouse/Controllers/ScoreController.cs index 95445488..56d360dd 100644 --- a/ProjectLighthouse/Controllers/ScoreController.cs +++ b/ProjectLighthouse/Controllers/ScoreController.cs @@ -8,13 +8,14 @@ using System.Threading.Tasks; using System.Xml.Serialization; using LBPUnion.ProjectLighthouse.Serialization; using LBPUnion.ProjectLighthouse.Types; +using LBPUnion.ProjectLighthouse.Types.Levels; using Microsoft.AspNetCore.Mvc; namespace LBPUnion.ProjectLighthouse.Controllers { [ApiController] [Route("LITTLEBIGPLANETPS3_XML/")] - [Produces("text/plain")] + [Produces("text/xml")] public class ScoreController : ControllerBase { private readonly Database database; @@ -25,8 +26,11 @@ namespace LBPUnion.ProjectLighthouse.Controllers } [HttpPost("scoreboard/user/{id:int}")] - public async Task SubmitScore(int id) + public async Task SubmitScore(int id, [FromQuery] bool lbp1 = false, [FromQuery] bool lbp2 = false, [FromQuery] bool lbp3 = false) { + 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(); @@ -36,8 +40,14 @@ namespace LBPUnion.ProjectLighthouse.Controllers score.SlotId = id; - IQueryable existingScore = this.database.Scores.Where(s => s.SlotId == score.SlotId && s.PlayerIdCollection == score.PlayerIdCollection); + Slot? slot = this.database.Slots.FirstOrDefault(s => s.SlotId == score.SlotId); + if (slot == null) return this.BadRequest(); + if (lbp1) slot.PlaysLBP1Complete++; + if (lbp2) slot.PlaysLBP2Complete++; + if (lbp3) slot.PlaysLBP3Complete++; + IQueryable existingScore = this.database.Scores.Where(s => s.SlotId == score.SlotId && s.PlayerIdCollection == score.PlayerIdCollection); + if (existingScore.Any()) { Score first = existingScore.First(s => s.SlotId == score.SlotId); @@ -49,20 +59,31 @@ namespace LBPUnion.ProjectLighthouse.Controllers { this.database.Scores.Add(score); } + await this.database.SaveChangesAsync(); - return this.Ok(); + string myRanking = await GetScores(score.SlotId, score.Type, user); + + return this.Ok(myRanking); } + [HttpGet("friendscores/user/{slotId:int}/{type:int}")] + public IActionResult FriendScores(int slotId, int type) + //=> await TopScores(slotId, type); + => this.Ok(LbpSerializer.BlankElement("scores")); + [HttpGet("topscores/user/{slotId:int}/{type:int}")] [SuppressMessage("ReSharper", "PossibleMultipleEnumeration")] - public async Task TopScores(int slotId, int type, [FromQuery] int pageStart, [FromQuery] int pageSize) - { + public async Task TopScores(int slotId, int type, [FromQuery] int pageStart = -1, [FromQuery] int pageSize = 5) { // Get username User? user = await this.database.UserFromRequest(this.Request); if (user == null) return this.StatusCode(403, ""); + return this.Ok(await GetScores(slotId, type, user, pageStart, pageSize)); + } + public async Task GetScores(int slotId, int type, User user, int pageStart = -1, int pageSize = 5) + { // This is hella ugly but it technically assigns the proper rank to a score // var needed for Anonymous type returned from SELECT var rankedScores = this.database.Scores.Where(s => s.SlotId == slotId && s.Type == type) @@ -83,8 +104,10 @@ namespace LBPUnion.ProjectLighthouse.Controllers .OrderByDescending(rs => rs.Score.Points) .FirstOrDefault(); - // Paginated viewing - var pagedScores = rankedScores.Skip(pageStart - 1).Take(Math.Min(pageSize, 30)); + // Paginated viewing: if not requesting pageStart, get results around user + var pagedScores = rankedScores + .Skip(pageStart != -1 || myScore == null ? pageStart - 1 : myScore.Rank - 3) + .Take(Math.Min(pageSize, 30)); string serializedScores = pagedScores.Aggregate ( @@ -122,7 +145,7 @@ namespace LBPUnion.ProjectLighthouse.Controllers ); } - return this.Ok(res); + return res; } } } \ No newline at end of file diff --git a/ProjectLighthouse/Controllers/SlotsController.cs b/ProjectLighthouse/Controllers/SlotsController.cs index cda06330..953ea027 100644 --- a/ProjectLighthouse/Controllers/SlotsController.cs +++ b/ProjectLighthouse/Controllers/SlotsController.cs @@ -122,5 +122,6 @@ namespace LBPUnion.ProjectLighthouse.Controllers return this.Ok(LbpSerializer.TaggedStringElement("slots", response, "hint_start", pageStart + Math.Min(pageSize, 30))); } + } } \ No newline at end of file diff --git a/ProjectLighthouse/Controllers/UserController.cs b/ProjectLighthouse/Controllers/UserController.cs index 3f3a1e4b..32db5f5e 100644 --- a/ProjectLighthouse/Controllers/UserController.cs +++ b/ProjectLighthouse/Controllers/UserController.cs @@ -1,3 +1,4 @@ +#nullable enable using System; using System.Collections.Generic; using System.IO; @@ -5,6 +6,7 @@ using System.Linq; using System.Text.Json; using System.Threading.Tasks; using System.Xml; +using LBPUnion.ProjectLighthouse.Serialization; using LBPUnion.ProjectLighthouse.Types; using LBPUnion.ProjectLighthouse.Types.Profiles; using Microsoft.AspNetCore.Mvc; @@ -24,18 +26,32 @@ namespace LBPUnion.ProjectLighthouse.Controllers this.database = database; } - [HttpGet("user/{username}")] - public async Task GetUser(string username) + public async Task GetSerializedUser(string username) { - User user = await this.database.Users.Include(u => u.Location).FirstOrDefaultAsync(u => u.Username == username); + User? user = await this.database.Users.Include(u => u.Location).FirstOrDefaultAsync(u => u.Username == username); + return user?.Serialize(); + } + [HttpGet("user/{username}")] + public async Task GetUser(string username) { + string? user = await this.GetSerializedUser(username); if (user == null) return this.NotFound(); - - return this.Ok(user.Serialize()); + return this.Ok(user); } [HttpGet("users")] - public async Task GetUserAlt([FromQuery] string u) => await this.GetUser(u); + public async Task GetUserAlt([FromQuery] string[] u) + { + List serializedUsers = new(); + foreach (string userId in u) + { + serializedUsers.Add(await this.GetSerializedUser(userId)); + } + + string serialized = serializedUsers.Aggregate(string.Empty, (current, u) => u == null ? current : current + u); + + return this.Ok(LbpSerializer.StringElement("users", serialized)); + } [HttpGet("user/{username}/playlists")] public IActionResult GetUserPlaylists(string username) => this.Ok(); diff --git a/ProjectLighthouse/Database.cs b/ProjectLighthouse/Database.cs index f26a45f1..57b18abb 100644 --- a/ProjectLighthouse/Database.cs +++ b/ProjectLighthouse/Database.cs @@ -26,6 +26,7 @@ namespace LBPUnion.ProjectLighthouse public DbSet PhotoSubjects { get; set; } public DbSet Photos { get; set; } public DbSet LastMatches { get; set; } + public DbSet VisitedLevels { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder options) => options.UseMySql(ServerSettings.DbConnectionString, MySqlServerVersion.LatestSupportedServerVersion); diff --git a/ProjectLighthouse/Helpers/MatchHelper.cs b/ProjectLighthouse/Helpers/MatchHelper.cs index 766dfd91..b60a3891 100644 --- a/ProjectLighthouse/Helpers/MatchHelper.cs +++ b/ProjectLighthouse/Helpers/MatchHelper.cs @@ -1,6 +1,8 @@ #nullable enable +using System; using System.Linq; using System.Text.Json; +using System.Text.RegularExpressions; using LBPUnion.ProjectLighthouse.Types.Match; namespace LBPUnion.ProjectLighthouse.Helpers @@ -22,6 +24,9 @@ namespace LBPUnion.ProjectLighthouse.Helpers string matchData = $"{{{string.Concat(data.Skip(matchType.Length + 3).SkipLast(2))}}}"; + // JSON does not like the hex value that location comes in (0x7f000001) so, convert it to int + matchData = Regex.Replace(matchData, @"0x[a-fA-F0-9]{8}", m => Convert.ToInt32(m.Value, 16).ToString()); + return Deserialize(matchType, matchData); } diff --git a/ProjectLighthouse/Logging/LighthouseFileLogger.cs b/ProjectLighthouse/Logging/LighthouseFileLogger.cs index 4b0e08a4..387ca881 100644 --- a/ProjectLighthouse/Logging/LighthouseFileLogger.cs +++ b/ProjectLighthouse/Logging/LighthouseFileLogger.cs @@ -20,8 +20,13 @@ namespace LBPUnion.ProjectLighthouse.Logging string contentFile = $"{channel}{line.LineData}\n"; string contentAll = $"[{$"{line.LoggerLevel.Name} {channel}".TrimEnd()}] {line.LineData}\n"; - File.AppendAllText(Path.Combine(logsDirectory, line.LoggerLevel.Name.ToFileName() + ".log"), contentFile); - File.AppendAllText(Path.Combine(logsDirectory, "all.log"), contentAll); + try + { + File.AppendAllText(Path.Combine(logsDirectory, line.LoggerLevel.Name.ToFileName() + ".log"), contentFile); + File.AppendAllText(Path.Combine(logsDirectory, "all.log"), contentAll); + } + catch (IOException) { } // windows, ya goofed + } } } \ No newline at end of file diff --git a/ProjectLighthouse/Migrations/20211108093616_GameSpecificPlayCounts.Designer.cs b/ProjectLighthouse/Migrations/20211108093616_GameSpecificPlayCounts.Designer.cs new file mode 100644 index 00000000..abf45882 --- /dev/null +++ b/ProjectLighthouse/Migrations/20211108093616_GameSpecificPlayCounts.Designer.cs @@ -0,0 +1,543 @@ +// +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("20211108093616_GameSpecificPlayCounts")] + partial class GameSpecificPlayCounts + { + 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.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.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.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.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/20211108093616_GameSpecificPlayCounts.cs b/ProjectLighthouse/Migrations/20211108093616_GameSpecificPlayCounts.cs new file mode 100644 index 00000000..8682b69e --- /dev/null +++ b/ProjectLighthouse/Migrations/20211108093616_GameSpecificPlayCounts.cs @@ -0,0 +1,116 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace ProjectLighthouse.Migrations +{ + public partial class GameSpecificPlayCounts : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "PlaysLBP1", + table: "Slots", + type: "int", + nullable: false, + defaultValue: 0); + + migrationBuilder.AddColumn( + name: "PlaysLBP1Complete", + table: "Slots", + type: "int", + nullable: false, + defaultValue: 0); + + migrationBuilder.AddColumn( + name: "PlaysLBP1Unique", + table: "Slots", + type: "int", + nullable: false, + defaultValue: 0); + + migrationBuilder.AddColumn( + name: "PlaysLBP2", + table: "Slots", + type: "int", + nullable: false, + defaultValue: 0); + + migrationBuilder.AddColumn( + name: "PlaysLBP2Complete", + table: "Slots", + type: "int", + nullable: false, + defaultValue: 0); + + migrationBuilder.AddColumn( + name: "PlaysLBP2Unique", + table: "Slots", + type: "int", + nullable: false, + defaultValue: 0); + + migrationBuilder.AddColumn( + name: "PlaysLBP3", + table: "Slots", + type: "int", + nullable: false, + defaultValue: 0); + + migrationBuilder.AddColumn( + name: "PlaysLBP3Complete", + table: "Slots", + type: "int", + nullable: false, + defaultValue: 0); + + migrationBuilder.AddColumn( + name: "PlaysLBP3Unique", + table: "Slots", + type: "int", + nullable: false, + defaultValue: 0); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "PlaysLBP1", + table: "Slots"); + + migrationBuilder.DropColumn( + name: "PlaysLBP1Complete", + table: "Slots"); + + migrationBuilder.DropColumn( + name: "PlaysLBP1Unique", + table: "Slots"); + + migrationBuilder.DropColumn( + name: "PlaysLBP2", + table: "Slots"); + + migrationBuilder.DropColumn( + name: "PlaysLBP2Complete", + table: "Slots"); + + migrationBuilder.DropColumn( + name: "PlaysLBP2Unique", + table: "Slots"); + + migrationBuilder.DropColumn( + name: "PlaysLBP3", + table: "Slots"); + + migrationBuilder.DropColumn( + name: "PlaysLBP3Complete", + table: "Slots"); + + migrationBuilder.DropColumn( + name: "PlaysLBP3Unique", + table: "Slots"); + + migrationBuilder.DropColumn( + name: "Plays", + table: "Slots"); + } + } +} diff --git a/ProjectLighthouse/Migrations/20211108114052_VisitedLevelsTable.Designer.cs b/ProjectLighthouse/Migrations/20211108114052_VisitedLevelsTable.Designer.cs new file mode 100644 index 00000000..f78f1d58 --- /dev/null +++ b/ProjectLighthouse/Migrations/20211108114052_VisitedLevelsTable.Designer.cs @@ -0,0 +1,586 @@ +// +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("20211108114052_VisitedLevelsTable")] + partial class VisitedLevelsTable + { + 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.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.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/20211108114052_VisitedLevelsTable.cs b/ProjectLighthouse/Migrations/20211108114052_VisitedLevelsTable.cs new file mode 100644 index 00000000..b4a356c3 --- /dev/null +++ b/ProjectLighthouse/Migrations/20211108114052_VisitedLevelsTable.cs @@ -0,0 +1,55 @@ +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace ProjectLighthouse.Migrations +{ + public partial class VisitedLevelsTable : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "VisitedLevels", + columns: table => new + { + VisitedLevelId = 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), + GameVersion = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_VisitedLevels", x => x.VisitedLevelId); + table.ForeignKey( + name: "FK_VisitedLevels_Slots_SlotId", + column: x => x.SlotId, + principalTable: "Slots", + principalColumn: "SlotId", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_VisitedLevels_Users_UserId", + column: x => x.UserId, + principalTable: "Users", + principalColumn: "UserId", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateIndex( + name: "IX_VisitedLevels_SlotId", + table: "VisitedLevels", + column: "SlotId"); + + migrationBuilder.CreateIndex( + name: "IX_VisitedLevels_UserId", + table: "VisitedLevels", + column: "UserId"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "VisitedLevels"); + } + } +} diff --git a/ProjectLighthouse/Migrations/DatabaseModelSnapshot.cs b/ProjectLighthouse/Migrations/DatabaseModelSnapshot.cs index 0c145dc5..96f61582 100644 --- a/ProjectLighthouse/Migrations/DatabaseModelSnapshot.cs +++ b/ProjectLighthouse/Migrations/DatabaseModelSnapshot.cs @@ -130,7 +130,31 @@ namespace ProjectLighthouse.Migrations b.Property("Name") .HasColumnType("longtext"); - b.Property("Plays") + 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") @@ -157,6 +181,30 @@ namespace ProjectLighthouse.Migrations 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") @@ -449,6 +497,25 @@ namespace ProjectLighthouse.Migrations 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") diff --git a/ProjectLighthouse/Types/Levels/Slot.cs b/ProjectLighthouse/Types/Levels/Slot.cs index 1057fa48..90bc82e0 100644 --- a/ProjectLighthouse/Types/Levels/Slot.cs +++ b/ProjectLighthouse/Types/Levels/Slot.cs @@ -109,8 +109,37 @@ namespace LBPUnion.ProjectLighthouse.Types.Levels } [XmlIgnore] - public int Plays { get; set; } + [NotMapped] + public int Plays { get => this.PlaysLBP1 + this.PlaysLBP2 + this.PlaysLBP3; } + [XmlIgnore] + [NotMapped] + public int PlaysUnique { get => this.PlaysLBP1Unique + this.PlaysLBP2Unique + this.PlaysLBP3Unique; } + [XmlIgnore] + [NotMapped] + 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; } + + public string SerializeResources() { return this.Resources.Aggregate("", (current, resource) => current + LbpSerializer.StringElement("resource", resource)); @@ -121,7 +150,7 @@ namespace LBPUnion.ProjectLighthouse.Types.Levels string slotData = LbpSerializer.StringElement("name", this.Name) + LbpSerializer.StringElement("id", this.SlotId) + LbpSerializer.StringElement("game", (int)this.GameVersion) + - LbpSerializer.StringElement("npHandle", this.Creator.Username) + + LbpSerializer.StringElement("npHandle", this.Creator?.Username) + LbpSerializer.StringElement("description", this.Description) + LbpSerializer.StringElement("icon", this.IconHash) + LbpSerializer.StringElement("rootLevel", this.RootLevel) + @@ -139,7 +168,18 @@ namespace LBPUnion.ProjectLighthouse.Types.Levels LbpSerializer.StringElement("lastUpdated", this.LastUpdated) + LbpSerializer.StringElement("mmpick", this.TeamPick) + LbpSerializer.StringElement("heartCount", this.Hearts) + - LbpSerializer.StringElement("playCount", this.Plays); + LbpSerializer.StringElement("playCount", this.Plays) + + LbpSerializer.StringElement("uniquePlayCount", this.PlaysLBP2Unique) + // ??? good naming scheme lol + LbpSerializer.StringElement("completionCount", this.PlaysComplete) + + LbpSerializer.StringElement("lbp1PlayCount", this.PlaysLBP1) + + LbpSerializer.StringElement("lbp1CompletionCount", this.PlaysLBP1Complete) + + LbpSerializer.StringElement("lbp1UniquePlayCount", this.PlaysLBP1Unique) + + LbpSerializer.StringElement("lbp2PlayCount", this.PlaysLBP2) + + LbpSerializer.StringElement("lbp2CompletionCount", this.PlaysLBP2Complete) + + 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); return LbpSerializer.TaggedStringElement("slot", slotData, "type", "user"); } diff --git a/ProjectLighthouse/Types/Levels/VisitedLevel.cs b/ProjectLighthouse/Types/Levels/VisitedLevel.cs new file mode 100644 index 00000000..101a4aaa --- /dev/null +++ b/ProjectLighthouse/Types/Levels/VisitedLevel.cs @@ -0,0 +1,24 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace LBPUnion.ProjectLighthouse.Types.Levels +{ + public class VisitedLevel + { + // ReSharper disable once UnusedMember.Global + [Key] + public int VisitedLevelId { 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 GameVersion GameVersion { get; set; } + } +} \ No newline at end of file diff --git a/ProjectLighthouse/Types/Match/CreateRoom.cs b/ProjectLighthouse/Types/Match/CreateRoom.cs index ff379e48..54c86276 100644 --- a/ProjectLighthouse/Types/Match/CreateRoom.cs +++ b/ProjectLighthouse/Types/Match/CreateRoom.cs @@ -7,16 +7,23 @@ namespace LBPUnion.ProjectLighthouse.Types.Match [SuppressMessage("ReSharper", "CollectionNeverUpdated.Global")] public class CreateRoom : IMatchData { + //[CreateRoom,["Players":["LumaLivy"],"Reservations":["0"],"NAT":[2],"Slots":[[1,3]],"RoomState":0,"HostMood":1,"PassedNoJoinPoint":0,"Location":[0x7f000001],"Language":1,"BuildVersion":289,"Search":""]] public List Players { get; set; } public List Reservations { get; set; } - // v slot type, 1 = 2974 // "Slots":[[5,0]] // ^ slot id // no idea why this is an array, but we'll work with it i suppose public List> Slots { get; set; } - [JsonIgnore] public List FirstSlot => this.Slots[0]; + public List NAT; + public int RoomState; + public int HostMood; + public int PassedNoJoinPoint; + public List Location; + public int Language; + public int BuildVersion; + public string Search; } } \ No newline at end of file