diff --git a/.gitignore b/.gitignore
index 5d65988d..1c626784 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
+r/ # cdn resources folder
bin/
obj/
/packages/
@@ -10,4 +11,4 @@ riderModule.iml
/ProjectLighthouse/r/*
/ProjectLighthouse/logs/*
/ProjectLighthouse/ProjectLighthouse.csproj.user
-.vs/
\ No newline at end of file
+.vs/
diff --git a/ProjectLighthouse.Tests/Tests/AuthenticationTests.cs b/ProjectLighthouse.Tests/Tests/AuthenticationTests.cs
index a996612b..893648e0 100644
--- a/ProjectLighthouse.Tests/Tests/AuthenticationTests.cs
+++ b/ProjectLighthouse.Tests/Tests/AuthenticationTests.cs
@@ -12,7 +12,7 @@ namespace LBPUnion.ProjectLighthouse.Tests
[Fact]
public async Task ShouldReturnErrorOnNoPostData()
{
- HttpResponseMessage response = await this.Client.PostAsync($"/LITTLEBIGPLANETPS3_XML/login", null!);
+ HttpResponseMessage response = await this.Client.PostAsync("/LITTLEBIGPLANETPS3_XML/login", null!);
Assert.False(response.IsSuccessStatusCode);
#if NET6_0_OR_GREATER
Assert.True(response.StatusCode == HttpStatusCode.BadRequest);
diff --git a/ProjectLighthouse.sln.DotSettings b/ProjectLighthouse.sln.DotSettings
index 9035b5a5..f914df07 100644
--- a/ProjectLighthouse.sln.DotSettings
+++ b/ProjectLighthouse.sln.DotSettings
@@ -89,6 +89,7 @@
True
True
True
+ True
True
True
True
@@ -103,6 +104,7 @@
True
True
True
+ True
True
True
True
diff --git a/ProjectLighthouse/Controllers/LoginController.cs b/ProjectLighthouse/Controllers/LoginController.cs
index d1c61fab..c0e88d38 100644
--- a/ProjectLighthouse/Controllers/LoginController.cs
+++ b/ProjectLighthouse/Controllers/LoginController.cs
@@ -22,8 +22,10 @@ namespace LBPUnion.ProjectLighthouse.Controllers
}
[HttpPost]
- public async Task Login([FromQuery] string titleId)
+ public async Task Login([FromQuery] string? titleId)
{
+ titleId ??= "";
+
string body = await new StreamReader(this.Request.Body).ReadToEndAsync();
LoginData? loginData;
diff --git a/ProjectLighthouse/Controllers/PhotosController.cs b/ProjectLighthouse/Controllers/PhotosController.cs
new file mode 100644
index 00000000..9ce5c655
--- /dev/null
+++ b/ProjectLighthouse/Controllers/PhotosController.cs
@@ -0,0 +1,85 @@
+#nullable enable
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Xml.Serialization;
+using LBPUnion.ProjectLighthouse.Serialization;
+using LBPUnion.ProjectLighthouse.Types;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.EntityFrameworkCore;
+
+namespace LBPUnion.ProjectLighthouse.Controllers
+{
+ [ApiController]
+ [Route("LITTLEBIGPLANETPS3_XML/")]
+ [Produces("text/xml")]
+ public class PhotosController : ControllerBase
+ {
+ private readonly Database database;
+
+ public PhotosController(Database database)
+ {
+ this.database = database;
+ }
+
+ [HttpPost("uploadPhoto")]
+ public async Task UploadPhoto()
+ {
+ 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(Photo));
+ Photo? photo = (Photo?)serializer.Deserialize(new StringReader(bodyString));
+ if (photo == null) return this.BadRequest();
+
+ photo.CreatorId = user.UserId;
+ photo.Creator = user;
+
+ foreach (PhotoSubject subject in photo.Subjects)
+ {
+ subject.User = await this.database.Users.FirstOrDefaultAsync(u => u.Username == subject.Username);
+
+ if (subject.User == null) return this.BadRequest();
+
+ subject.UserId = subject.User.UserId;
+
+ this.database.PhotoSubjects.Add(subject);
+ }
+
+ await this.database.SaveChangesAsync();
+
+ photo.PhotoSubjectCollection = photo.Subjects.Aggregate(string.Empty, (s, subject) => s + subject.PhotoSubjectId);
+// photo.Slot = await this.database.Slots.FirstOrDefaultAsync(s => s.SlotId == photo.SlotId);
+
+ this.database.Photos.Add(photo);
+
+ await this.database.SaveChangesAsync();
+
+ return this.Ok();
+ }
+
+ [HttpGet("photos/user/{id:int}")]
+ public async Task SlotPhotos(int id)
+ {
+ List photos = await this.database.Photos.Take(10).ToListAsync();
+ string response = photos.Aggregate(string.Empty, (s, photo) => s + photo.Serialize(id));
+ return this.Ok(LbpSerializer.StringElement("photos", response));
+ }
+
+ [HttpGet("photos/by")]
+ public async Task UserPhotos([FromQuery] string user)
+ {
+ User? userFromQuery = await this.database.Users.FirstOrDefaultAsync(u => u.Username == user);
+ // ReSharper disable once ConditionIsAlwaysTrueOrFalse
+ if (user == null) return this.NotFound();
+
+ List photos = await this.database.Photos.Where(p => p.CreatorId == userFromQuery.UserId).Take(10).ToListAsync();
+ string response = photos.Aggregate(string.Empty, (s, photo) => s + photo.Serialize(0));
+ return this.Ok(LbpSerializer.StringElement("photos", response));
+ }
+ }
+}
\ No newline at end of file
diff --git a/ProjectLighthouse/Controllers/PublishController.cs b/ProjectLighthouse/Controllers/PublishController.cs
index bf59ef15..b52a02c7 100644
--- a/ProjectLighthouse/Controllers/PublishController.cs
+++ b/ProjectLighthouse/Controllers/PublishController.cs
@@ -60,7 +60,7 @@ namespace LBPUnion.ProjectLighthouse.Controllers
// User user = await this.database.UserFromRequest(this.Request);
(User, Token)? userAndToken = await this.database.UserAndTokenFromRequest(this.Request);
- if (userAndToken != null) return this.StatusCode(403, "");
+ if (userAndToken == null) return this.StatusCode(403, "");
// ReSharper disable once PossibleInvalidOperationException
User user = userAndToken.Value.Item1;
diff --git a/ProjectLighthouse/Controllers/ScoreController.cs b/ProjectLighthouse/Controllers/ScoreController.cs
index 53f70375..7715218a 100644
--- a/ProjectLighthouse/Controllers/ScoreController.cs
+++ b/ProjectLighthouse/Controllers/ScoreController.cs
@@ -1,11 +1,13 @@
+#nullable enable
using System;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
-using System.Collections.Generic;
using System.Threading.Tasks;
using System.Xml.Serialization;
-using LBPUnion.ProjectLighthouse.Types;
using LBPUnion.ProjectLighthouse.Serialization;
+using LBPUnion.ProjectLighthouse.Types;
using Microsoft.AspNetCore.Mvc;
namespace LBPUnion.ProjectLighthouse.Controllers
@@ -29,7 +31,7 @@ namespace LBPUnion.ProjectLighthouse.Controllers
string bodyString = await new StreamReader(this.Request.Body).ReadToEndAsync();
XmlSerializer serializer = new(typeof(Score));
- Score score = (Score)serializer.Deserialize(new StringReader(bodyString));
+ Score? score = (Score?)serializer.Deserialize(new StringReader(bodyString));
if (score == null) return this.BadRequest();
score.SlotId = id;
@@ -38,7 +40,7 @@ namespace LBPUnion.ProjectLighthouse.Controllers
if (existingScore.Any())
{
- Score first = existingScore.FirstOrDefault(s => s.SlotId == score.SlotId);
+ Score first = existingScore.First(s => s.SlotId == score.SlotId);
score.ScoreId = first.ScoreId;
score.Points = Math.Max(first.Points, score.Points);
this.database.Entry(first).CurrentValues.SetValues(score);
@@ -57,22 +59,31 @@ namespace LBPUnion.ProjectLighthouse.Controllers
=> await TopScores(slotId, type);
[HttpGet("topscores/user/{slotId:int}/{type:int}")]
- public async Task TopScores(int slotId, int type, [FromQuery] int pageStart=-1, [FromQuery] int pageSize=5)
+ [SuppressMessage("ReSharper", "PossibleMultipleEnumeration")]
+ 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);
+ User? user = await this.database.UserFromRequest(this.Request);
+
+ if (user == null) return this.StatusCode(403, "");
// 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)
+ var rankedScores = this.database.Scores.Where(s => s.SlotId == slotId && s.Type == type)
.OrderByDescending(s => s.Points)
.ToList()
- .Select((Score s, int rank) => new { Score = s, Rank = rank + 1 });
+ .Select
+ (
+ (s, rank) => new
+ {
+ Score = s,
+ Rank = rank + 1,
+ }
+ );
// Find your score, since even if you aren't in the top list your score is pinned
- var myScore = rankedScores
- .Where(rs => rs.Score.PlayerIdCollection.Contains(user.Username))
+ var myScore = rankedScores.Where
+ (rs => rs.Score.PlayerIdCollection.Contains(user.Username))
.OrderByDescending(rs => rs.Score.Points)
.FirstOrDefault();
@@ -81,23 +92,40 @@ namespace LBPUnion.ProjectLighthouse.Controllers
.Skip(pageStart != -1 ? pageStart - 1 : myScore.Rank - 3)
.Take(Math.Min(pageSize, 30));
- string serializedScores = Enumerable.Aggregate(pagedScores, string.Empty, (current, rs) => {
- rs.Score.Rank = rs.Rank;
- return current + rs.Score.Serialize();
- });
+ string serializedScores = pagedScores.Aggregate
+ (
+ string.Empty,
+ (current, rs) =>
+ {
+ rs.Score.Rank = rs.Rank;
+ return current + rs.Score.Serialize();
+ }
+ );
string res;
if (myScore == null)
{
res = LbpSerializer.StringElement("scores", serializedScores);
- }
+ }
else
{
- res = LbpSerializer.TaggedStringElement("scores", serializedScores, new Dictionary() {
- {"yourScore", myScore.Score.Points},
- {"yourRank", myScore.Rank }, //This is the numerator of your position globally in the side menu.
- {"totalNumScores", rankedScores.Count() } // This is the denominator of your position globally in the side menu.
- });
+ res = LbpSerializer.TaggedStringElement
+ (
+ "scores",
+ serializedScores,
+ new Dictionary()
+ {
+ {
+ "yourScore", myScore.Score.Points
+ },
+ {
+ "yourRank", myScore.Rank
+ }, //This is the numerator of your position globally in the side menu.
+ {
+ "totalNumScores", rankedScores.Count()
+ }, // This is the denominator of your position globally in the side menu.
+ }
+ );
}
return this.Ok(res);
diff --git a/ProjectLighthouse/Controllers/SlotsController.cs b/ProjectLighthouse/Controllers/SlotsController.cs
index b74800c5..231967d7 100644
--- a/ProjectLighthouse/Controllers/SlotsController.cs
+++ b/ProjectLighthouse/Controllers/SlotsController.cs
@@ -42,6 +42,9 @@ namespace LBPUnion.ProjectLighthouse.Controllers
return this.Ok(slot.Serialize());
}
+ [HttpGet("slots/cool")]
+ public IActionResult CoolSlots([FromQuery] int page) => NewestSlots(30 * page, 30);
+
[HttpGet("slots")]
public IActionResult NewestSlots([FromQuery] int pageStart, [FromQuery] int pageSize)
{
diff --git a/ProjectLighthouse/Database.cs b/ProjectLighthouse/Database.cs
index d4c90b7e..9d9e880a 100644
--- a/ProjectLighthouse/Database.cs
+++ b/ProjectLighthouse/Database.cs
@@ -23,7 +23,8 @@ namespace LBPUnion.ProjectLighthouse
public DbSet Comments { get; set; }
public DbSet Tokens { get; set; }
public DbSet Scores { get; set; }
-
+ public DbSet PhotoSubjects { get; set; }
+ public DbSet Photos { get; set; }
public DbSet LastMatches { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder options)
@@ -106,6 +107,9 @@ namespace LBPUnion.ProjectLighthouse
return (user, token);
}
+
+ public async Task PhotoFromSubject(PhotoSubject subject)
+ => await this.Photos.FirstOrDefaultAsync(p => p.PhotoSubjectIds.Contains(subject.PhotoSubjectId.ToString()));
#nullable disable
}
}
\ No newline at end of file
diff --git a/ProjectLighthouse/Helpers/EulaHelper.cs b/ProjectLighthouse/Helpers/EulaHelper.cs
index 8bc167e7..195963c5 100644
--- a/ProjectLighthouse/Helpers/EulaHelper.cs
+++ b/ProjectLighthouse/Helpers/EulaHelper.cs
@@ -22,6 +22,6 @@ Please do not make anything public for now, and keep in mind security isn't as t
// ReSharper disable once UnreachableCode
public const string PrivateInstanceNoticeOrBlank = ShowPrivateInstanceNotice ? PrivateInstanceNotice : "";
- public const bool ShowPrivateInstanceNotice = true;
+ public const bool ShowPrivateInstanceNotice = false;
}
}
\ No newline at end of file
diff --git a/ProjectLighthouse/Helpers/Extensions/StringExtensions.cs b/ProjectLighthouse/Helpers/Extensions/StringExtensions.cs
index 4ed898e9..177027de 100644
--- a/ProjectLighthouse/Helpers/Extensions/StringExtensions.cs
+++ b/ProjectLighthouse/Helpers/Extensions/StringExtensions.cs
@@ -8,11 +8,8 @@ namespace LBPUnion.ProjectLighthouse.Helpers.Extensions
{
char[] invalidPathChars = Path.GetInvalidFileNameChars();
string path = text;
-
- foreach (char c in invalidPathChars)
- {
- path = path.Replace(c.ToString(), "");
- }
+
+ foreach (char c in invalidPathChars) path = path.Replace(c.ToString(), "");
return path;
}
diff --git a/ProjectLighthouse/Helpers/GameVersionHelper.cs b/ProjectLighthouse/Helpers/GameVersionHelper.cs
index 12ec15b0..a44721d4 100644
--- a/ProjectLighthouse/Helpers/GameVersionHelper.cs
+++ b/ProjectLighthouse/Helpers/GameVersionHelper.cs
@@ -82,7 +82,7 @@ namespace LBPUnion.ProjectLighthouse.Helpers
if (LittleBigPlanet2TitleIds.Contains(titleId)) return GameVersion.LittleBigPlanet2;
if (LittleBigPlanet3TitleIds.Contains(titleId)) return GameVersion.LittleBigPlanet3;
- return GameVersion.Unknown;
+ return GameVersion.LittleBigPlanet1;
}
}
}
\ No newline at end of file
diff --git a/ProjectLighthouse/Logging/LighthouseFileLogger.cs b/ProjectLighthouse/Logging/LighthouseFileLogger.cs
index 31879a69..4b0e08a4 100644
--- a/ProjectLighthouse/Logging/LighthouseFileLogger.cs
+++ b/ProjectLighthouse/Logging/LighthouseFileLogger.cs
@@ -9,6 +9,7 @@ namespace LBPUnion.ProjectLighthouse.Logging
public class LighthouseFileLogger : LoggerBase
{
private static readonly string logsDirectory = Path.Combine(Environment.CurrentDirectory, "logs");
+ public override bool AllowMultiple => false;
public override void Send(LoggerLine line)
{
@@ -22,6 +23,5 @@ namespace LBPUnion.ProjectLighthouse.Logging
File.AppendAllText(Path.Combine(logsDirectory, line.LoggerLevel.Name.ToFileName() + ".log"), contentFile);
File.AppendAllText(Path.Combine(logsDirectory, "all.log"), contentAll);
}
- public override bool AllowMultiple => false;
}
}
\ No newline at end of file
diff --git a/ProjectLighthouse/Migrations/20211104195812_AddPhotoSupport.Designer.cs b/ProjectLighthouse/Migrations/20211104195812_AddPhotoSupport.Designer.cs
new file mode 100644
index 00000000..b848597f
--- /dev/null
+++ b/ProjectLighthouse/Migrations/20211104195812_AddPhotoSupport.Designer.cs
@@ -0,0 +1,537 @@
+//
+using System;
+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("20211104195812_AddPhotoSupport")]
+ partial class AddPhotoSupport
+ {
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("Relational:MaxIdentifierLength", 64)
+ .HasAnnotation("ProductVersion", "5.0.11");
+
+ 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("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("LargeHash")
+ .HasColumnType("longtext");
+
+ b.Property("MediumHash")
+ .HasColumnType("longtext");
+
+ b.Property("PlanHash")
+ .HasColumnType("longtext");
+
+ b.Property("SlotId")
+ .HasColumnType("int");
+
+ b.Property("SmallHash")
+ .HasColumnType("longtext");
+
+ b.Property("Timestamp")
+ .HasColumnType("bigint");
+
+ b.HasKey("PhotoId");
+
+ b.HasIndex("SlotId");
+
+ b.ToTable("Photos");
+ });
+
+ modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.PhotoSubject", b =>
+ {
+ b.Property("PhotoSubjectId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("PhotoId")
+ .HasColumnType("int");
+
+ b.HasKey("PhotoSubjectId");
+
+ b.HasIndex("PhotoId");
+
+ 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("CommentCount")
+ .HasColumnType("int");
+
+ b.Property("CommentsEnabled")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("FavouriteSlotCount")
+ .HasColumnType("int");
+
+ b.Property("FavouriteUserCount")
+ .HasColumnType("int");
+
+ b.Property("Game")
+ .HasColumnType("int");
+
+ b.Property("HeartCount")
+ .HasColumnType("int");
+
+ b.Property("IconHash")
+ .HasColumnType("longtext");
+
+ b.Property("Lists")
+ .HasColumnType("int");
+
+ b.Property("LocationId")
+ .HasColumnType("int");
+
+ b.Property("LolCatFtwCount")
+ .HasColumnType("int");
+
+ b.Property("PhotosByMeCount")
+ .HasColumnType("int");
+
+ b.Property("PhotosWithMeCount")
+ .HasColumnType("int");
+
+ b.Property("Pins")
+ .HasColumnType("longtext");
+
+ b.Property("PlanetHash")
+ .HasColumnType("longtext");
+
+ b.Property("ReviewCount")
+ .HasColumnType("int");
+
+ 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.Levels.Slot", "Slot")
+ .WithMany()
+ .HasForeignKey("SlotId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Slot");
+ });
+
+ modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.PhotoSubject", b =>
+ {
+ b.HasOne("LBPUnion.ProjectLighthouse.Types.Photo", null)
+ .WithMany("Subjects")
+ .HasForeignKey("PhotoId");
+ });
+
+ 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");
+ });
+
+ modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Photo", b =>
+ {
+ b.Navigation("Subjects");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/ProjectLighthouse/Migrations/20211104195812_AddPhotoSupport.cs b/ProjectLighthouse/Migrations/20211104195812_AddPhotoSupport.cs
new file mode 100644
index 00000000..3bb78906
--- /dev/null
+++ b/ProjectLighthouse/Migrations/20211104195812_AddPhotoSupport.cs
@@ -0,0 +1,79 @@
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+namespace ProjectLighthouse.Migrations
+{
+ public partial class AddPhotoSupport : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.CreateTable(
+ name: "Photos",
+ columns: table => new
+ {
+ PhotoId = table.Column(type: "int", nullable: false)
+ .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
+ Timestamp = table.Column(type: "bigint", nullable: false),
+ SmallHash = table.Column(type: "longtext", nullable: true)
+ .Annotation("MySql:CharSet", "utf8mb4"),
+ MediumHash = table.Column(type: "longtext", nullable: true)
+ .Annotation("MySql:CharSet", "utf8mb4"),
+ LargeHash = table.Column(type: "longtext", nullable: true)
+ .Annotation("MySql:CharSet", "utf8mb4"),
+ PlanHash = table.Column(type: "longtext", nullable: true)
+ .Annotation("MySql:CharSet", "utf8mb4"),
+ SlotId = table.Column(type: "int", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Photos", x => x.PhotoId);
+ table.ForeignKey(
+ name: "FK_Photos_Slots_SlotId",
+ column: x => x.SlotId,
+ principalTable: "Slots",
+ principalColumn: "SlotId",
+ onDelete: ReferentialAction.Cascade);
+ })
+ .Annotation("MySql:CharSet", "utf8mb4");
+
+ migrationBuilder.CreateTable(
+ name: "PhotoSubjects",
+ columns: table => new
+ {
+ PhotoSubjectId = table.Column(type: "int", nullable: false)
+ .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
+ PhotoId = table.Column(type: "int", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_PhotoSubjects", x => x.PhotoSubjectId);
+ table.ForeignKey(
+ name: "FK_PhotoSubjects_Photos_PhotoId",
+ column: x => x.PhotoId,
+ principalTable: "Photos",
+ principalColumn: "PhotoId",
+ onDelete: ReferentialAction.Restrict);
+ })
+ .Annotation("MySql:CharSet", "utf8mb4");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Photos_SlotId",
+ table: "Photos",
+ column: "SlotId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_PhotoSubjects_PhotoId",
+ table: "PhotoSubjects",
+ column: "PhotoId");
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropTable(
+ name: "PhotoSubjects");
+
+ migrationBuilder.DropTable(
+ name: "Photos");
+ }
+ }
+}
diff --git a/ProjectLighthouse/Migrations/20211105205010_UpdatePhotoAndPhotoSubjectToDoStuffWeirdName.Designer.cs b/ProjectLighthouse/Migrations/20211105205010_UpdatePhotoAndPhotoSubjectToDoStuffWeirdName.Designer.cs
new file mode 100644
index 00000000..9dee3007
--- /dev/null
+++ b/ProjectLighthouse/Migrations/20211105205010_UpdatePhotoAndPhotoSubjectToDoStuffWeirdName.Designer.cs
@@ -0,0 +1,554 @@
+//
+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("20211105205010_UpdatePhotoAndPhotoSubjectToDoStuffWeirdName")]
+ partial class UpdatePhotoAndPhotoSubjectToDoStuffWeirdName
+ {
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("Relational:MaxIdentifierLength", 64)
+ .HasAnnotation("ProductVersion", "5.0.11");
+
+ 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("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("LargeHash")
+ .HasColumnType("longtext");
+
+ b.Property("MediumHash")
+ .HasColumnType("longtext");
+
+ b.Property("PhotoSubjectCollection")
+ .HasColumnType("longtext");
+
+ b.Property("PlanHash")
+ .HasColumnType("longtext");
+
+ b.Property("SlotId")
+ .HasColumnType("int");
+
+ b.Property("SmallHash")
+ .HasColumnType("longtext");
+
+ b.Property("Timestamp")
+ .HasColumnType("bigint");
+
+ b.HasKey("PhotoId");
+
+ b.HasIndex("SlotId");
+
+ b.ToTable("Photos");
+ });
+
+ modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.PhotoSubject", b =>
+ {
+ b.Property("PhotoSubjectId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("Bounds")
+ .HasColumnType("longtext");
+
+ b.Property("ParentPhotoId")
+ .HasColumnType("int");
+
+ b.Property("UserId")
+ .HasColumnType("int");
+
+ b.HasKey("PhotoSubjectId");
+
+ b.HasIndex("ParentPhotoId");
+
+ 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("CommentCount")
+ .HasColumnType("int");
+
+ b.Property("CommentsEnabled")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("FavouriteSlotCount")
+ .HasColumnType("int");
+
+ b.Property("FavouriteUserCount")
+ .HasColumnType("int");
+
+ b.Property("Game")
+ .HasColumnType("int");
+
+ b.Property("HeartCount")
+ .HasColumnType("int");
+
+ b.Property("IconHash")
+ .HasColumnType("longtext");
+
+ b.Property("Lists")
+ .HasColumnType("int");
+
+ b.Property("LocationId")
+ .HasColumnType("int");
+
+ b.Property("LolCatFtwCount")
+ .HasColumnType("int");
+
+ b.Property("PhotosByMeCount")
+ .HasColumnType("int");
+
+ b.Property("PhotosWithMeCount")
+ .HasColumnType("int");
+
+ b.Property("Pins")
+ .HasColumnType("longtext");
+
+ b.Property("PlanetHash")
+ .HasColumnType("longtext");
+
+ b.Property("ReviewCount")
+ .HasColumnType("int");
+
+ 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.Levels.Slot", "Slot")
+ .WithMany()
+ .HasForeignKey("SlotId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Slot");
+ });
+
+ modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.PhotoSubject", b =>
+ {
+ b.HasOne("LBPUnion.ProjectLighthouse.Types.Photo", "ParentPhoto")
+ .WithMany()
+ .HasForeignKey("ParentPhotoId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("LBPUnion.ProjectLighthouse.Types.User", "User")
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("ParentPhoto");
+
+ 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/20211105205010_UpdatePhotoAndPhotoSubjectToDoStuffWeirdName.cs b/ProjectLighthouse/Migrations/20211105205010_UpdatePhotoAndPhotoSubjectToDoStuffWeirdName.cs
new file mode 100644
index 00000000..080be211
--- /dev/null
+++ b/ProjectLighthouse/Migrations/20211105205010_UpdatePhotoAndPhotoSubjectToDoStuffWeirdName.cs
@@ -0,0 +1,130 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+
+namespace ProjectLighthouse.Migrations
+{
+ public partial class UpdatePhotoAndPhotoSubjectToDoStuffWeirdName : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropForeignKey(
+ name: "FK_PhotoSubjects_Photos_PhotoId",
+ table: "PhotoSubjects");
+
+ migrationBuilder.DropIndex(
+ name: "IX_PhotoSubjects_PhotoId",
+ table: "PhotoSubjects");
+
+ migrationBuilder.DropColumn(
+ name: "PhotoId",
+ table: "PhotoSubjects");
+
+ migrationBuilder.AddColumn(
+ name: "Bounds",
+ table: "PhotoSubjects",
+ type: "longtext",
+ nullable: true)
+ .Annotation("MySql:CharSet", "utf8mb4");
+
+ migrationBuilder.AddColumn(
+ name: "ParentPhotoId",
+ table: "PhotoSubjects",
+ type: "int",
+ nullable: false,
+ defaultValue: 0);
+
+ migrationBuilder.AddColumn(
+ name: "UserId",
+ table: "PhotoSubjects",
+ type: "int",
+ nullable: false,
+ defaultValue: 0);
+
+ migrationBuilder.AddColumn(
+ name: "PhotoSubjectCollection",
+ table: "Photos",
+ type: "longtext",
+ nullable: true)
+ .Annotation("MySql:CharSet", "utf8mb4");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_PhotoSubjects_ParentPhotoId",
+ table: "PhotoSubjects",
+ column: "ParentPhotoId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_PhotoSubjects_UserId",
+ table: "PhotoSubjects",
+ column: "UserId");
+
+ migrationBuilder.AddForeignKey(
+ name: "FK_PhotoSubjects_Photos_ParentPhotoId",
+ table: "PhotoSubjects",
+ column: "ParentPhotoId",
+ principalTable: "Photos",
+ principalColumn: "PhotoId",
+ onDelete: ReferentialAction.Cascade);
+
+ migrationBuilder.AddForeignKey(
+ name: "FK_PhotoSubjects_Users_UserId",
+ table: "PhotoSubjects",
+ column: "UserId",
+ principalTable: "Users",
+ principalColumn: "UserId",
+ onDelete: ReferentialAction.Cascade);
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropForeignKey(
+ name: "FK_PhotoSubjects_Photos_ParentPhotoId",
+ table: "PhotoSubjects");
+
+ migrationBuilder.DropForeignKey(
+ name: "FK_PhotoSubjects_Users_UserId",
+ table: "PhotoSubjects");
+
+ migrationBuilder.DropIndex(
+ name: "IX_PhotoSubjects_ParentPhotoId",
+ table: "PhotoSubjects");
+
+ migrationBuilder.DropIndex(
+ name: "IX_PhotoSubjects_UserId",
+ table: "PhotoSubjects");
+
+ migrationBuilder.DropColumn(
+ name: "Bounds",
+ table: "PhotoSubjects");
+
+ migrationBuilder.DropColumn(
+ name: "ParentPhotoId",
+ table: "PhotoSubjects");
+
+ migrationBuilder.DropColumn(
+ name: "UserId",
+ table: "PhotoSubjects");
+
+ migrationBuilder.DropColumn(
+ name: "PhotoSubjectCollection",
+ table: "Photos");
+
+ migrationBuilder.AddColumn(
+ name: "PhotoId",
+ table: "PhotoSubjects",
+ type: "int",
+ nullable: true);
+
+ migrationBuilder.CreateIndex(
+ name: "IX_PhotoSubjects_PhotoId",
+ table: "PhotoSubjects",
+ column: "PhotoId");
+
+ migrationBuilder.AddForeignKey(
+ name: "FK_PhotoSubjects_Photos_PhotoId",
+ table: "PhotoSubjects",
+ column: "PhotoId",
+ principalTable: "Photos",
+ principalColumn: "PhotoId",
+ onDelete: ReferentialAction.Restrict);
+ }
+ }
+}
diff --git a/ProjectLighthouse/Migrations/20211105205239_DropPhotoSubjectParentPhoto.Designer.cs b/ProjectLighthouse/Migrations/20211105205239_DropPhotoSubjectParentPhoto.Designer.cs
new file mode 100644
index 00000000..5f463653
--- /dev/null
+++ b/ProjectLighthouse/Migrations/20211105205239_DropPhotoSubjectParentPhoto.Designer.cs
@@ -0,0 +1,541 @@
+//
+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("20211105205239_DropPhotoSubjectParentPhoto")]
+ partial class DropPhotoSubjectParentPhoto
+ {
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("Relational:MaxIdentifierLength", 64)
+ .HasAnnotation("ProductVersion", "5.0.11");
+
+ 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("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("LargeHash")
+ .HasColumnType("longtext");
+
+ b.Property("MediumHash")
+ .HasColumnType("longtext");
+
+ b.Property("PhotoSubjectCollection")
+ .HasColumnType("longtext");
+
+ b.Property("PlanHash")
+ .HasColumnType("longtext");
+
+ b.Property("SlotId")
+ .HasColumnType("int");
+
+ b.Property("SmallHash")
+ .HasColumnType("longtext");
+
+ b.Property("Timestamp")
+ .HasColumnType("bigint");
+
+ b.HasKey("PhotoId");
+
+ b.HasIndex("SlotId");
+
+ 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