From 213db4f2d84d13ba170e439a80ed0b591d87ac08 Mon Sep 17 00:00:00 2001 From: jvyden Date: Sun, 3 Apr 2022 19:07:36 -0400 Subject: [PATCH 01/24] Add teampicks and trending levels on landing page Rough implementation for https://github.com/LBPUnion/ProjectLighthouse/issues/241 --- ProjectLighthouse/Pages/LandingPage.cshtml | 38 ++++++++++++++- ProjectLighthouse/Pages/LandingPage.cshtml.cs | 46 ++++++++++++++++++- .../Pages/Partials/SlotCardPartial.cshtml | 40 ++++++++++++---- 3 files changed, 112 insertions(+), 12 deletions(-) diff --git a/ProjectLighthouse/Pages/LandingPage.cshtml b/ProjectLighthouse/Pages/LandingPage.cshtml index 47735d4c..d48da0f5 100644 --- a/ProjectLighthouse/Pages/LandingPage.cshtml +++ b/ProjectLighthouse/Pages/LandingPage.cshtml @@ -1,11 +1,14 @@ @page "/" +@using LBPUnion.ProjectLighthouse.Helpers.Extensions @using LBPUnion.ProjectLighthouse.Types +@using LBPUnion.ProjectLighthouse.Types.Levels @using LBPUnion.ProjectLighthouse.Types.Settings @model LBPUnion.ProjectLighthouse.Pages.LandingPage @{ Layout = "Layouts/BaseLayout"; Model.ShowTitleInPage = false; + bool isMobile = this.Request.IsMobile(); }

Welcome to Project Lighthouse!

@@ -40,4 +43,37 @@ else { @user.Username } -} \ No newline at end of file +} + +
+
+
+

Latest Team Picks

+
+
+ @foreach (Slot slot in Model.LatestTeamPicks) + { + @await Html.PartialAsync("Partials/SlotCardPartial", slot, Model.GetSlotViewData(slot.SlotId, isMobile)) +
+ } +
+
+
+ @if (isMobile) + { +
+ } +
+
+

Trending Levels

+
+
+ @foreach (Slot slot in Model.TrendingLevels) + { + @await Html.PartialAsync("Partials/SlotCardPartial", slot, Model.GetSlotViewData(slot.SlotId, isMobile)) +
+ } +
+
+
+
\ No newline at end of file diff --git a/ProjectLighthouse/Pages/LandingPage.cshtml.cs b/ProjectLighthouse/Pages/LandingPage.cshtml.cs index 0d23a58e..8cd35a1d 100644 --- a/ProjectLighthouse/Pages/LandingPage.cshtml.cs +++ b/ProjectLighthouse/Pages/LandingPage.cshtml.cs @@ -6,20 +6,25 @@ using JetBrains.Annotations; using LBPUnion.ProjectLighthouse.Helpers; using LBPUnion.ProjectLighthouse.Pages.Layouts; using LBPUnion.ProjectLighthouse.Types; +using LBPUnion.ProjectLighthouse.Types.Levels; using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.ViewFeatures; using Microsoft.EntityFrameworkCore; namespace LBPUnion.ProjectLighthouse.Pages; public class LandingPage : BaseLayout { + public LandingPage(Database database) : base(database) + {} public int AuthenticationAttemptsCount; public List PlayersOnline; public int PlayersOnlineCount; - public LandingPage(Database database) : base(database) - {} + + public List LatestTeamPicks; + public List TrendingLevels; [UsedImplicitly] public async Task OnGet() @@ -37,6 +42,43 @@ public class LandingPage : BaseLayout List userIds = await this.Database.LastContacts.Where(l => TimestampHelper.Timestamp - l.Timestamp < 300).Select(l => l.UserId).ToListAsync(); this.PlayersOnline = await this.Database.Users.Where(u => userIds.Contains(u.UserId)).ToListAsync(); + + const int maxShownLevels = 5; + + this.LatestTeamPicks = await this.Database.Slots.Where + (s => s.TeamPick) + .OrderBy(s => s.FirstUploaded) + .Take(maxShownLevels) + .Include(s => s.Creator) + .ToListAsync(); + + this.TrendingLevels = await this.Database.Slots.OrderByDescending + (s => s.PlaysLBP1Unique + s.PlaysLBP2Unique + s.PlaysLBP3Unique + s.PlaysLBPVitaUnique) + .ThenBy(s => s.FirstUploaded) + .Take(maxShownLevels) + .Include(s => s.Creator) + .ToListAsync(); + return this.Page(); } + + public ViewDataDictionary GetSlotViewData(int slotId, bool isMobile = false) + => new(ViewData) + { + { + "User", this.User + }, + { + "CallbackUrl", $"~/slot/{slotId}" + }, + { + "ShowLink", true + }, + { + "IsMini", true + }, + { + "IsMobile", isMobile + }, + }; } \ No newline at end of file diff --git a/ProjectLighthouse/Pages/Partials/SlotCardPartial.cshtml b/ProjectLighthouse/Pages/Partials/SlotCardPartial.cshtml index 36318404..c6891995 100644 --- a/ProjectLighthouse/Pages/Partials/SlotCardPartial.cshtml +++ b/ProjectLighthouse/Pages/Partials/SlotCardPartial.cshtml @@ -12,6 +12,8 @@ string slotName = string.IsNullOrEmpty(Model.Name) ? "Unnamed Level" : Model.Name; bool isMobile = (bool?)ViewData["IsMobile"] ?? false; + bool mini = (bool?)ViewData["IsMini"] ?? false; + bool isQueued = false; bool isHearted = false; @@ -30,25 +32,44 @@ }
@{ - int size = isMobile ? 50 : 100; + int size = isMobile || mini ? 50 : 100; }
- @if (showLink) + @if (!mini) { -

- @slotName -

+ @if (showLink) + { +

+ @slotName +

+ } + else + { +

+ @slotName +

+ } } else { -

- @slotName -

+ @if (showLink) + { +

+ @slotName +

+ } + else + { +

+ @slotName +

+ } } +
@Model.Hearts @Model.Plays @@ -61,13 +82,14 @@ @Model.RatingLBP1 }
+

Created by @Model.Creator?.Username for @Model.GameVersion.ToPrettyString()


- @if (user != null) + @if (user != null && !mini) { if (isHearted) { From 75254ad6ebbad884f28632c38be66a86c994206e Mon Sep 17 00:00:00 2001 From: jvyden Date: Fri, 8 Apr 2022 14:55:57 -0400 Subject: [PATCH 02/24] Proper ordering, change trending levels to newest levels --- ProjectLighthouse/Pages/LandingPage.cshtml | 10 ++++++---- ProjectLighthouse/Pages/LandingPage.cshtml.cs | 11 +++-------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/ProjectLighthouse/Pages/LandingPage.cshtml b/ProjectLighthouse/Pages/LandingPage.cshtml index d48da0f5..bc09fccb 100644 --- a/ProjectLighthouse/Pages/LandingPage.cshtml +++ b/ProjectLighthouse/Pages/LandingPage.cshtml @@ -45,10 +45,12 @@ else } } +
+
-

Latest Team Picks

+

Latest Team Picks

@foreach (Slot slot in Model.LatestTeamPicks) @@ -64,11 +66,11 @@ else
}
-
-

Trending Levels

+
+

Newest Levels

- @foreach (Slot slot in Model.TrendingLevels) + @foreach (Slot slot in Model.NewestLevels) { @await Html.PartialAsync("Partials/SlotCardPartial", slot, Model.GetSlotViewData(slot.SlotId, isMobile))
diff --git a/ProjectLighthouse/Pages/LandingPage.cshtml.cs b/ProjectLighthouse/Pages/LandingPage.cshtml.cs index 8cd35a1d..dab09ea4 100644 --- a/ProjectLighthouse/Pages/LandingPage.cshtml.cs +++ b/ProjectLighthouse/Pages/LandingPage.cshtml.cs @@ -24,7 +24,7 @@ public class LandingPage : BaseLayout public int PlayersOnlineCount; public List LatestTeamPicks; - public List TrendingLevels; + public List NewestLevels; [UsedImplicitly] public async Task OnGet() @@ -47,17 +47,12 @@ public class LandingPage : BaseLayout this.LatestTeamPicks = await this.Database.Slots.Where (s => s.TeamPick) - .OrderBy(s => s.FirstUploaded) + .OrderByDescending(s => s.FirstUploaded) .Take(maxShownLevels) .Include(s => s.Creator) .ToListAsync(); - this.TrendingLevels = await this.Database.Slots.OrderByDescending - (s => s.PlaysLBP1Unique + s.PlaysLBP2Unique + s.PlaysLBP3Unique + s.PlaysLBPVitaUnique) - .ThenBy(s => s.FirstUploaded) - .Take(maxShownLevels) - .Include(s => s.Creator) - .ToListAsync(); + this.NewestLevels = await this.Database.Slots.OrderByDescending(s => s.FirstUploaded).Take(maxShownLevels).Include(s => s.Creator).ToListAsync(); return this.Page(); } From e8a10245c8d09d2412a9ab81f6183d96eb786124 Mon Sep 17 00:00:00 2001 From: jvyden Date: Sun, 22 May 2022 15:22:26 -0400 Subject: [PATCH 03/24] Update dotnet-ef tools command to 6.0.5 --- .config/dotnet-tools.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 5060fd65..e80b80ff 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "dotnet-ef": { - "version": "6.0.4", + "version": "6.0.5", "commands": [ "dotnet-ef" ] From 09994769da4d29b6ad029c3b289dca07ee41523b Mon Sep 17 00:00:00 2001 From: jvyden Date: Sun, 22 May 2022 16:16:57 -0400 Subject: [PATCH 04/24] Only cleanup rooms on gameserver --- ProjectLighthouse/StartupTasks.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/ProjectLighthouse/StartupTasks.cs b/ProjectLighthouse/StartupTasks.cs index 100c3fc1..9df051c0 100644 --- a/ProjectLighthouse/StartupTasks.cs +++ b/ProjectLighthouse/StartupTasks.cs @@ -83,13 +83,16 @@ public static class StartupTasks { FileHelper.ConvertAllTexturesToPng(); } - - Logger.Info("Starting room cleanup thread...", LogArea.Startup); - RoomHelper.StartCleanupThread(); - + Logger.Info("Initializing Redis...", LogArea.Startup); RedisDatabase.Initialize().Wait(); + if (serverType == ServerType.GameServer) + { + Logger.Info("Starting room cleanup thread...", LogArea.Startup); + RoomHelper.StartCleanupThread(); + } + stopwatch.Stop(); Logger.Success($"Ready! Startup took {stopwatch.ElapsedMilliseconds}ms. Passing off control to ASP.NET...", LogArea.Startup); } From 7ff2d3f1a26b295b384de9ac9ba05eb7265c74f4 Mon Sep 17 00:00:00 2001 From: jvyden Date: Sun, 22 May 2022 16:23:07 -0400 Subject: [PATCH 05/24] Add ServerType to file logs --- ProjectLighthouse/Configuration/ServerStatics.cs | 8 ++++++++ ProjectLighthouse/Logging/Loggers/ConsoleLogger.cs | 3 ++- .../Loggers/{LighthouseFileLogger.cs => FileLogger.cs} | 8 ++++---- ProjectLighthouse/Startup/DebugWarmupLifetime.cs | 3 +-- ProjectLighthouse/StartupTasks.cs | 6 ++---- 5 files changed, 17 insertions(+), 11 deletions(-) rename ProjectLighthouse/Logging/Loggers/{LighthouseFileLogger.cs => FileLogger.cs} (62%) diff --git a/ProjectLighthouse/Configuration/ServerStatics.cs b/ProjectLighthouse/Configuration/ServerStatics.cs index 233d0eba..787967b9 100644 --- a/ProjectLighthouse/Configuration/ServerStatics.cs +++ b/ProjectLighthouse/Configuration/ServerStatics.cs @@ -2,6 +2,7 @@ using System; using System.Linq; using LBPUnion.ProjectLighthouse.Logging; +using LBPUnion.ProjectLighthouse.Types; namespace LBPUnion.ProjectLighthouse.Configuration; @@ -25,6 +26,7 @@ public static class ServerStatics } } + // FIXME: This needs to go at some point. public static bool IsUnitTesting => AppDomain.CurrentDomain.GetAssemblies().Any(assembly => assembly.FullName!.StartsWith("xunit")); #if DEBUG @@ -32,4 +34,10 @@ public static class ServerStatics #else public static readonly bool IsDebug = false; #endif + + /// + /// The servertype, determined on startup. Shouldn't be null unless very very early in startup. + /// + // The way of doing this is kinda weird, but it works. + public static ServerType ServerType; } \ No newline at end of file diff --git a/ProjectLighthouse/Logging/Loggers/ConsoleLogger.cs b/ProjectLighthouse/Logging/Loggers/ConsoleLogger.cs index 4cc2351a..3ebc3343 100644 --- a/ProjectLighthouse/Logging/Loggers/ConsoleLogger.cs +++ b/ProjectLighthouse/Logging/Loggers/ConsoleLogger.cs @@ -11,7 +11,8 @@ public class ConsoleLogger : ILogger foreach (string line in logLine.Message.Split('\n')) { - // The following is scuffed. Beware~ + // The following is scuffed. + // Beware~ // Write the level! [Success] Console.ForegroundColor = ConsoleColor.White; diff --git a/ProjectLighthouse/Logging/Loggers/LighthouseFileLogger.cs b/ProjectLighthouse/Logging/Loggers/FileLogger.cs similarity index 62% rename from ProjectLighthouse/Logging/Loggers/LighthouseFileLogger.cs rename to ProjectLighthouse/Logging/Loggers/FileLogger.cs index 405e31a1..802263e5 100644 --- a/ProjectLighthouse/Logging/Loggers/LighthouseFileLogger.cs +++ b/ProjectLighthouse/Logging/Loggers/FileLogger.cs @@ -1,11 +1,11 @@ using System; using System.IO; +using LBPUnion.ProjectLighthouse.Configuration; using LBPUnion.ProjectLighthouse.Files; -using LBPUnion.ProjectLighthouse.Helpers; namespace LBPUnion.ProjectLighthouse.Logging.Loggers; -public class LighthouseFileLogger : ILogger +public class FileLogger : ILogger { private static readonly string logsDirectory = Path.Combine(Environment.CurrentDirectory, "logs"); @@ -13,8 +13,8 @@ public class LighthouseFileLogger : ILogger { FileHelper.EnsureDirectoryCreated(logsDirectory); - string contentFile = $"[{line.Level}] <{line.Trace.Name}:{line.Trace.Section}> {line.Message}\n"; - string contentAll = $"[{line.Area}:{line.Level}] <{line.Trace.Name}:{line.Trace.Section}> {line.Message}\n"; + string contentFile = $"[{ServerStatics.ServerType}] [{line.Level}] <{line.Trace.Name}:{line.Trace.Section}> {line.Message}\n"; + string contentAll = $"[{ServerStatics.ServerType}] [{line.Area}:{line.Level}] <{line.Trace.Name}:{line.Trace.Section}> {line.Message}\n"; try { diff --git a/ProjectLighthouse/Startup/DebugWarmupLifetime.cs b/ProjectLighthouse/Startup/DebugWarmupLifetime.cs index 0af030c3..2161dbf4 100644 --- a/ProjectLighthouse/Startup/DebugWarmupLifetime.cs +++ b/ProjectLighthouse/Startup/DebugWarmupLifetime.cs @@ -20,7 +20,6 @@ public class DebugWarmupLifetime : IHostLifetime private CancellationTokenRegistration applicationStartedRegistration; private readonly ConsoleLifetime consoleLifetime; - public static ServerType ServerType; public DebugWarmupLifetime ( @@ -39,7 +38,7 @@ public class DebugWarmupLifetime : IHostLifetime { using HttpClient client = new(); - string url = ServerType switch + string url = ServerStatics.ServerType switch { ServerType.GameServer => ServerConfiguration.Instance.GameApiListenUrl, ServerType.Website => ServerConfiguration.Instance.WebsiteListenUrl, diff --git a/ProjectLighthouse/StartupTasks.cs b/ProjectLighthouse/StartupTasks.cs index 9df051c0..51656fd1 100644 --- a/ProjectLighthouse/StartupTasks.cs +++ b/ProjectLighthouse/StartupTasks.cs @@ -24,13 +24,11 @@ public static class StartupTasks Stopwatch stopwatch = new(); stopwatch.Start(); - #if DEBUG - DebugWarmupLifetime.ServerType = serverType; - #endif + ServerStatics.ServerType = serverType; // Setup logging Logger.Instance.AddLogger(new ConsoleLogger()); - Logger.Instance.AddLogger(new LighthouseFileLogger()); + Logger.Instance.AddLogger(new FileLogger()); Logger.Info($"Welcome to the Project Lighthouse {serverType.ToString()}!", LogArea.Startup); Logger.Info($"You are running version {VersionHelper.FullVersion}", LogArea.Startup); From 95a8c8eabe10a4515752850f37cc1bf1a8c4324d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 May 2022 21:34:36 -0400 Subject: [PATCH 06/24] Bump Discord.Net.Webhook from 3.6.1 to 3.7.0 (#312) Bumps [Discord.Net.Webhook](https://github.com/Discord-Net/Discord.Net) from 3.6.1 to 3.7.0. - [Release notes](https://github.com/Discord-Net/Discord.Net/releases) - [Changelog](https://github.com/discord-net/Discord.Net/blob/dev/CHANGELOG.md) - [Commits](https://github.com/Discord-Net/Discord.Net/compare/3.6.1...3.7.0) --- updated-dependencies: - dependency-name: Discord.Net.Webhook dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ProjectLighthouse/ProjectLighthouse.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ProjectLighthouse/ProjectLighthouse.csproj b/ProjectLighthouse/ProjectLighthouse.csproj index 903e3e3b..3523c45d 100644 --- a/ProjectLighthouse/ProjectLighthouse.csproj +++ b/ProjectLighthouse/ProjectLighthouse.csproj @@ -11,7 +11,7 @@ - + From c567e0c1ddea1971d1c37554bf763efd92abce32 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 May 2022 13:53:18 -0400 Subject: [PATCH 07/24] Bump Discord.Net.Webhook from 3.7.0 to 3.7.1 (#314) Bumps [Discord.Net.Webhook](https://github.com/Discord-Net/Discord.Net) from 3.7.0 to 3.7.1. - [Release notes](https://github.com/Discord-Net/Discord.Net/releases) - [Changelog](https://github.com/discord-net/Discord.Net/blob/dev/CHANGELOG.md) - [Commits](https://github.com/Discord-Net/Discord.Net/compare/3.7.0...3.7.1) --- updated-dependencies: - dependency-name: Discord.Net.Webhook dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ProjectLighthouse/ProjectLighthouse.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ProjectLighthouse/ProjectLighthouse.csproj b/ProjectLighthouse/ProjectLighthouse.csproj index 3523c45d..7184b1b7 100644 --- a/ProjectLighthouse/ProjectLighthouse.csproj +++ b/ProjectLighthouse/ProjectLighthouse.csproj @@ -11,7 +11,7 @@ - + From 238894c2beeb80852249cab149bcd70f25e55537 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Jun 2022 00:13:33 -0400 Subject: [PATCH 08/24] Bump Selenium.WebDriver from 4.1.1 to 4.2.0 (#316) Bumps Selenium.WebDriver from 4.1.1 to 4.2.0. --- updated-dependencies: - dependency-name: Selenium.WebDriver dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../ProjectLighthouse.Tests.WebsiteTests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ProjectLighthouse.Tests.WebsiteTests/ProjectLighthouse.Tests.WebsiteTests.csproj b/ProjectLighthouse.Tests.WebsiteTests/ProjectLighthouse.Tests.WebsiteTests.csproj index 68bb134c..4483c810 100644 --- a/ProjectLighthouse.Tests.WebsiteTests/ProjectLighthouse.Tests.WebsiteTests.csproj +++ b/ProjectLighthouse.Tests.WebsiteTests/ProjectLighthouse.Tests.WebsiteTests.csproj @@ -15,7 +15,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + From ee541dbfae129e359635f0a80917dce2c9972b93 Mon Sep 17 00:00:00 2001 From: jvyden Date: Wed, 1 Jun 2022 00:34:38 -0400 Subject: [PATCH 09/24] Allow instance owners to provide custom name, Include server version in LbpEnvVer This is the first step towards instance customization. Just a name for now ;) --- .../Controllers/LoginController.cs | 2 +- .../Pages/LandingPage.cshtml | 2 +- .../Tests/AuthenticationTests.cs | 7 ++++--- .../ConfigurationCategories/CustomizationConfiguration.cs | 6 ++++++ ProjectLighthouse/Configuration/ServerConfiguration.cs | 5 ++++- ProjectLighthouse/Configuration/ServerStatics.cs | 2 -- ProjectLighthouse/Helpers/VersionHelper.cs | 8 ++++---- ProjectLighthouse/PlayerData/LoginResult.cs | 7 +++++-- 8 files changed, 25 insertions(+), 14 deletions(-) create mode 100644 ProjectLighthouse/Configuration/ConfigurationCategories/CustomizationConfiguration.cs diff --git a/ProjectLighthouse.Servers.GameServer/Controllers/LoginController.cs b/ProjectLighthouse.Servers.GameServer/Controllers/LoginController.cs index 270aa145..7b7ba8f4 100644 --- a/ProjectLighthouse.Servers.GameServer/Controllers/LoginController.cs +++ b/ProjectLighthouse.Servers.GameServer/Controllers/LoginController.cs @@ -130,7 +130,7 @@ public class LoginController : ControllerBase new LoginResult { AuthTicket = "MM_AUTH=" + token.UserToken, - LbpEnvVer = ServerStatics.ServerName, + ServerBrand = VersionHelper.FullVersion, }.Serialize() ); } diff --git a/ProjectLighthouse.Servers.Website/Pages/LandingPage.cshtml b/ProjectLighthouse.Servers.Website/Pages/LandingPage.cshtml index 5c6e49c3..df663f1a 100644 --- a/ProjectLighthouse.Servers.Website/Pages/LandingPage.cshtml +++ b/ProjectLighthouse.Servers.Website/Pages/LandingPage.cshtml @@ -8,7 +8,7 @@ Layout = "Layouts/BaseLayout"; Model.ShowTitleInPage = false; } -

Welcome to Project Lighthouse!

+

Welcome to @ServerConfiguration.Instance.Customization.ServerName!

@if (Model.User != null) { diff --git a/ProjectLighthouse.Tests.GameApiTests/Tests/AuthenticationTests.cs b/ProjectLighthouse.Tests.GameApiTests/Tests/AuthenticationTests.cs index 1fe89c3e..acfbfb6b 100644 --- a/ProjectLighthouse.Tests.GameApiTests/Tests/AuthenticationTests.cs +++ b/ProjectLighthouse.Tests.GameApiTests/Tests/AuthenticationTests.cs @@ -2,6 +2,7 @@ using System.Net; using System.Net.Http; using System.Threading.Tasks; using LBPUnion.ProjectLighthouse.Configuration; +using LBPUnion.ProjectLighthouse.Helpers; using LBPUnion.ProjectLighthouse.PlayerData; using LBPUnion.ProjectLighthouse.Tests; using Xunit; @@ -25,7 +26,7 @@ public class AuthenticationTests : LighthouseServerTest Assert.True(response.IsSuccessStatusCode); string responseContent = await response.Content.ReadAsStringAsync(); Assert.Contains("MM_AUTH=", responseContent); - Assert.Contains(ServerStatics.ServerName, responseContent); + Assert.Contains(VersionHelper.FullVersion, responseContent); } [DatabaseFact] @@ -35,10 +36,10 @@ public class AuthenticationTests : LighthouseServerTest Assert.NotNull(loginResult); Assert.NotNull(loginResult.AuthTicket); - Assert.NotNull(loginResult.LbpEnvVer); + Assert.NotNull(loginResult.ServerBrand); Assert.Contains("MM_AUTH=", loginResult.AuthTicket); - Assert.Equal(ServerStatics.ServerName, loginResult.LbpEnvVer); + Assert.Equal(VersionHelper.FullVersion, loginResult.ServerBrand); } [DatabaseFact] diff --git a/ProjectLighthouse/Configuration/ConfigurationCategories/CustomizationConfiguration.cs b/ProjectLighthouse/Configuration/ConfigurationCategories/CustomizationConfiguration.cs new file mode 100644 index 00000000..027c1753 --- /dev/null +++ b/ProjectLighthouse/Configuration/ConfigurationCategories/CustomizationConfiguration.cs @@ -0,0 +1,6 @@ +namespace LBPUnion.ProjectLighthouse.Configuration.ConfigurationCategories; + +public class CustomizationConfiguration +{ + public string ServerName { get; set; } = "Project Lighthouse"; +} \ No newline at end of file diff --git a/ProjectLighthouse/Configuration/ServerConfiguration.cs b/ProjectLighthouse/Configuration/ServerConfiguration.cs index ddf8113b..53cb1c3a 100644 --- a/ProjectLighthouse/Configuration/ServerConfiguration.cs +++ b/ProjectLighthouse/Configuration/ServerConfiguration.cs @@ -163,6 +163,9 @@ public class ServerConfiguration #endregion + // TODO: Find a way to properly remove config options + // YamlDotNet hates that and it's fucking annoying. + // This seriously sucks. /rant [Obsolete("Obsolete. Use the Website/GameApi/Api listen URLS instead.")] public string ListenUrl { get; set; } = "http://localhost:10060"; @@ -193,5 +196,5 @@ public class ServerConfiguration public MailConfiguration Mail { get; set; } = new(); public UserGeneratedContentLimitConfiguration UserGeneratedContentLimits { get; set; } = new(); public WebsiteConfiguration WebsiteConfiguration { get; set; } = new(); - + public CustomizationConfiguration Customization { get; set; } = new(); } \ No newline at end of file diff --git a/ProjectLighthouse/Configuration/ServerStatics.cs b/ProjectLighthouse/Configuration/ServerStatics.cs index 787967b9..f432b5ce 100644 --- a/ProjectLighthouse/Configuration/ServerStatics.cs +++ b/ProjectLighthouse/Configuration/ServerStatics.cs @@ -8,8 +8,6 @@ namespace LBPUnion.ProjectLighthouse.Configuration; public static class ServerStatics { - public const string ServerName = "ProjectLighthouse"; - public const int PageSize = 20; public static bool DbConnected { diff --git a/ProjectLighthouse/Helpers/VersionHelper.cs b/ProjectLighthouse/Helpers/VersionHelper.cs index 3642c5fe..1c926104 100644 --- a/ProjectLighthouse/Helpers/VersionHelper.cs +++ b/ProjectLighthouse/Helpers/VersionHelper.cs @@ -31,8 +31,8 @@ public static class VersionHelper { Logger.Error ( - "Project Lighthouse was built incorrectly. Please make sure git is available when building. " + - "Because of this, you will not be notified of updates.", + "Project Lighthouse was built incorrectly. Please make sure git is available when building.", +// "Because of this, you will not be notified of updates.", LogArea.Startup ); CommitHash = "invalid"; @@ -54,14 +54,14 @@ public static class VersionHelper public static string CommitHash { get; set; } public static string Branch { get; set; } - public static string FullVersion => $"{ServerStatics.ServerName} {Branch}@{CommitHash} {Build}"; + public static string FullVersion => $"{ServerConfiguration.Instance.Customization.ServerName} {Branch}@{CommitHash} {Build}"; public static bool IsDirty => CommitHash.EndsWith("-dirty") || CommitsOutOfDate != 1 || CommitHash == "invalid" || Branch == "invalid"; public static int CommitsOutOfDate { get; set; } public static bool CanCheckForUpdates { get; set; } public static string[] Remotes { get; set; } public const string Build = - #if DEBUG + #if DEBUG "Debug"; #elif RELEASE "Release"; diff --git a/ProjectLighthouse/PlayerData/LoginResult.cs b/ProjectLighthouse/PlayerData/LoginResult.cs index f577f175..09842ac3 100644 --- a/ProjectLighthouse/PlayerData/LoginResult.cs +++ b/ProjectLighthouse/PlayerData/LoginResult.cs @@ -15,9 +15,12 @@ public class LoginResult public string AuthTicket { get; set; } [XmlElement("lbpEnvVer")] - public string LbpEnvVer { get; set; } + public string ServerBrand { get; set; } public string Serialize() => LbpSerializer.Elements - (new KeyValuePair("authTicket", this.AuthTicket), new KeyValuePair("lbpEnvVer", this.LbpEnvVer)); + ( + new KeyValuePair("authTicket", this.AuthTicket), + new KeyValuePair("lbpEnvVer", this.ServerBrand) + ); } \ No newline at end of file From 8ead63943f1a4db7d06d98b4a5ee8a77eb866bf4 Mon Sep 17 00:00:00 2001 From: jvyden Date: Wed, 1 Jun 2022 00:35:24 -0400 Subject: [PATCH 10/24] Bump config version to 5 --- ProjectLighthouse/Configuration/ServerConfiguration.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ProjectLighthouse/Configuration/ServerConfiguration.cs b/ProjectLighthouse/Configuration/ServerConfiguration.cs index 53cb1c3a..bd3ce250 100644 --- a/ProjectLighthouse/Configuration/ServerConfiguration.cs +++ b/ProjectLighthouse/Configuration/ServerConfiguration.cs @@ -23,7 +23,7 @@ public class ServerConfiguration // You can use an ObsoleteAttribute instead. Make sure you set it to error, though. // // Thanks for listening~ - public const int CurrentConfigVersion = 4; + public const int CurrentConfigVersion = 5; #region Meta From 48d8cb1a028b7ebe6ef29abc225e8bc973e4b524 Mon Sep 17 00:00:00 2001 From: jvyden Date: Wed, 1 Jun 2022 00:46:22 -0400 Subject: [PATCH 11/24] Show instance custom name in tab title --- .../Pages/Layouts/BaseLayout.cshtml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ProjectLighthouse.Servers.Website/Pages/Layouts/BaseLayout.cshtml b/ProjectLighthouse.Servers.Website/Pages/Layouts/BaseLayout.cshtml index 2ca305e2..f19c67e2 100644 --- a/ProjectLighthouse.Servers.Website/Pages/Layouts/BaseLayout.cshtml +++ b/ProjectLighthouse.Servers.Website/Pages/Layouts/BaseLayout.cshtml @@ -33,11 +33,11 @@ @if (Model.Title == string.Empty) { - Project Lighthouse + @ServerConfiguration.Instance.Customization.ServerName } else { - Project Lighthouse - @Model.Title + @ServerConfiguration.Instance.Customization.ServerName - @Model.Title } @@ -52,7 +52,7 @@ @* Embed Stuff *@ - + @if (!string.IsNullOrEmpty(Model.Description)) { From 422b1268ca05cbff5cf60215c7f9298f77afdfcb Mon Sep 17 00:00:00 2001 From: jvyden Date: Wed, 1 Jun 2022 16:45:31 -0400 Subject: [PATCH 12/24] Dont store the room list in RoomHelper --- ProjectLighthouse/Configuration/ServerStatics.cs | 4 ++-- ProjectLighthouse/Match/Rooms/RoomHelper.cs | 2 +- ProjectLighthouse/StartupTasks.cs | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ProjectLighthouse/Configuration/ServerStatics.cs b/ProjectLighthouse/Configuration/ServerStatics.cs index f432b5ce..8e87417d 100644 --- a/ProjectLighthouse/Configuration/ServerStatics.cs +++ b/ProjectLighthouse/Configuration/ServerStatics.cs @@ -28,9 +28,9 @@ public static class ServerStatics public static bool IsUnitTesting => AppDomain.CurrentDomain.GetAssemblies().Any(assembly => assembly.FullName!.StartsWith("xunit")); #if DEBUG - public static readonly bool IsDebug = true; + public const bool IsDebug = true; #else - public static readonly bool IsDebug = false; + public const bool IsDebug = false; #endif /// diff --git a/ProjectLighthouse/Match/Rooms/RoomHelper.cs b/ProjectLighthouse/Match/Rooms/RoomHelper.cs index 9d4f18e4..4e09d5ea 100644 --- a/ProjectLighthouse/Match/Rooms/RoomHelper.cs +++ b/ProjectLighthouse/Match/Rooms/RoomHelper.cs @@ -16,7 +16,7 @@ namespace LBPUnion.ProjectLighthouse.Match.Rooms; public class RoomHelper { - public static readonly StorableList Rooms = RoomStore.GetRooms(); + public static StorableList Rooms => RoomStore.GetRooms(); public static void StartCleanupThread() { diff --git a/ProjectLighthouse/StartupTasks.cs b/ProjectLighthouse/StartupTasks.cs index 51656fd1..4e439aa6 100644 --- a/ProjectLighthouse/StartupTasks.cs +++ b/ProjectLighthouse/StartupTasks.cs @@ -33,7 +33,7 @@ public static class StartupTasks Logger.Info($"Welcome to the Project Lighthouse {serverType.ToString()}!", LogArea.Startup); Logger.Info($"You are running version {VersionHelper.FullVersion}", LogArea.Startup); - // Referencing ServerSettings.Instance here loads the config, see ServerSettings.cs for more information + // Referencing ServerConfiguration.Instance here loads the config, see ServerConfiguration.cs for more information Logger.Success("Loaded config file version " + ServerConfiguration.Instance.ConfigVersion, LogArea.Startup); Logger.Info("Connecting to the database...", LogArea.Startup); @@ -44,7 +44,7 @@ public static class StartupTasks } else { - Logger.Success("Connected!", LogArea.Startup); + Logger.Success("Connected to the database!", LogArea.Startup); } if (!dbConnected) Environment.Exit(1); @@ -95,7 +95,7 @@ public static class StartupTasks Logger.Success($"Ready! Startup took {stopwatch.ElapsedMilliseconds}ms. Passing off control to ASP.NET...", LogArea.Startup); } - private static void migrateDatabase(Database database) + private static void migrateDatabase(DbContext database) { Stopwatch stopwatch = new(); stopwatch.Start(); From 27d92001c317c30297701300bfca002bd0ad3f1a Mon Sep 17 00:00:00 2001 From: jvyden Date: Wed, 1 Jun 2022 17:06:27 -0400 Subject: [PATCH 13/24] Create admin user on first startup --- ProjectLighthouse/StartupTasks.cs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/ProjectLighthouse/StartupTasks.cs b/ProjectLighthouse/StartupTasks.cs index 4e439aa6..caff91bc 100644 --- a/ProjectLighthouse/StartupTasks.cs +++ b/ProjectLighthouse/StartupTasks.cs @@ -9,6 +9,7 @@ using LBPUnion.ProjectLighthouse.Helpers; using LBPUnion.ProjectLighthouse.Logging; using LBPUnion.ProjectLighthouse.Logging.Loggers; using LBPUnion.ProjectLighthouse.Match.Rooms; +using LBPUnion.ProjectLighthouse.PlayerData.Profiles; using LBPUnion.ProjectLighthouse.Startup; using LBPUnion.ProjectLighthouse.StorableLists; using LBPUnion.ProjectLighthouse.Types; @@ -91,6 +92,22 @@ public static class StartupTasks RoomHelper.StartCleanupThread(); } + // Create admin user if no users exist + if (serverType == ServerType.Website && database.Users.CountAsync().Result == 0) + { + const string passwordClear = "lighthouse"; + string password = CryptoHelper.BCryptHash(CryptoHelper.Sha256Hash(passwordClear)); + + User admin = database.CreateUser("admin", password).Result; + admin.IsAdmin = true; + admin.PasswordResetRequired = true; + + database.SaveChanges(); + + Logger.Success("No users were found, so an admin user was created. " + + $"The username is 'admin' and the password is '{passwordClear}'.", LogArea.Startup); + } + stopwatch.Stop(); Logger.Success($"Ready! Startup took {stopwatch.ElapsedMilliseconds}ms. Passing off control to ASP.NET...", LogArea.Startup); } From b2c73ccfc469c9faf109160c0e8aff40a78f96ca Mon Sep 17 00:00:00 2001 From: jvyden Date: Wed, 1 Jun 2022 17:06:59 -0400 Subject: [PATCH 14/24] Only redirect users to email verification if mail is enabled when resetting password --- .../Pages/PasswordResetPage.cshtml.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ProjectLighthouse.Servers.Website/Pages/PasswordResetPage.cshtml.cs b/ProjectLighthouse.Servers.Website/Pages/PasswordResetPage.cshtml.cs index 5a767460..6f744979 100644 --- a/ProjectLighthouse.Servers.Website/Pages/PasswordResetPage.cshtml.cs +++ b/ProjectLighthouse.Servers.Website/Pages/PasswordResetPage.cshtml.cs @@ -1,5 +1,6 @@ #nullable enable using JetBrains.Annotations; +using LBPUnion.ProjectLighthouse.Configuration; using LBPUnion.ProjectLighthouse.Helpers; using LBPUnion.ProjectLighthouse.PlayerData.Profiles; using LBPUnion.ProjectLighthouse.Servers.Website.Pages.Layouts; @@ -38,7 +39,8 @@ public class PasswordResetPage : BaseLayout await this.Database.SaveChangesAsync(); - if (!user.EmailAddressVerified) return this.Redirect("~/login/sendVerificationEmail"); + if (!user.EmailAddressVerified && ServerConfiguration.Instance.Mail.MailEnabled) + return this.Redirect("~/login/sendVerificationEmail"); return this.Redirect("~/"); } From 7a2f99291d301aabd5eaa8d29e6f6c48f8e62056 Mon Sep 17 00:00:00 2001 From: jvyden Date: Wed, 1 Jun 2022 17:07:20 -0400 Subject: [PATCH 15/24] Rename ServerConfiguration.WebsiteConfiguration to Website --- .../Pages/Partials/SlotCardPartial.cshtml | 2 +- ProjectLighthouse.Servers.Website/Pages/SlotPage.cshtml | 2 +- ProjectLighthouse/Configuration/Legacy/LegacyServerSettings.cs | 2 +- ProjectLighthouse/Configuration/ServerConfiguration.cs | 2 +- ProjectLighthouse/PlayerData/Profiles/User.cs | 2 +- ProjectLighthouse/StartupTasks.cs | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ProjectLighthouse.Servers.Website/Pages/Partials/SlotCardPartial.cshtml b/ProjectLighthouse.Servers.Website/Pages/Partials/SlotCardPartial.cshtml index 6e469d63..cd633eb2 100644 --- a/ProjectLighthouse.Servers.Website/Pages/Partials/SlotCardPartial.cshtml +++ b/ProjectLighthouse.Servers.Website/Pages/Partials/SlotCardPartial.cshtml @@ -27,7 +27,7 @@ bool showLink = (bool?)ViewData["ShowLink"] ?? false; string iconHash = Model.IconHash; - if (string.IsNullOrWhiteSpace(iconHash) || iconHash.StartsWith('g')) iconHash = ServerConfiguration.Instance.WebsiteConfiguration.MissingIconHash; + if (string.IsNullOrWhiteSpace(iconHash) || iconHash.StartsWith('g')) iconHash = ServerConfiguration.Instance.Website.MissingIconHash; }
@{ diff --git a/ProjectLighthouse.Servers.Website/Pages/SlotPage.cshtml b/ProjectLighthouse.Servers.Website/Pages/SlotPage.cshtml index 0722a616..43f59b33 100644 --- a/ProjectLighthouse.Servers.Website/Pages/SlotPage.cshtml +++ b/ProjectLighthouse.Servers.Website/Pages/SlotPage.cshtml @@ -98,7 +98,7 @@ if (string.IsNullOrWhiteSpace(faceHash)) { - faceHash = ServerConfiguration.Instance.WebsiteConfiguration.MissingIconHash; + faceHash = ServerConfiguration.Instance.Website.MissingIconHash; } string faceAlt = review.Thumb switch { diff --git a/ProjectLighthouse/Configuration/Legacy/LegacyServerSettings.cs b/ProjectLighthouse/Configuration/Legacy/LegacyServerSettings.cs index 123fcf63..ea08ed67 100644 --- a/ProjectLighthouse/Configuration/Legacy/LegacyServerSettings.cs +++ b/ProjectLighthouse/Configuration/Legacy/LegacyServerSettings.cs @@ -203,7 +203,7 @@ internal class LegacyServerSettings ProfileCommentsEnabled = this.ProfileCommentsEnabled, }; - configuration.WebsiteConfiguration = new WebsiteConfiguration + configuration.Website = new WebsiteConfiguration { MissingIconHash = this.MissingIconHash, ConvertAssetsOnStartup = this.ConvertAssetsOnStartup, diff --git a/ProjectLighthouse/Configuration/ServerConfiguration.cs b/ProjectLighthouse/Configuration/ServerConfiguration.cs index bd3ce250..0cd17c4a 100644 --- a/ProjectLighthouse/Configuration/ServerConfiguration.cs +++ b/ProjectLighthouse/Configuration/ServerConfiguration.cs @@ -195,6 +195,6 @@ public class ServerConfiguration public InfluxDBConfiguration InfluxDB { get; set; } = new(); public MailConfiguration Mail { get; set; } = new(); public UserGeneratedContentLimitConfiguration UserGeneratedContentLimits { get; set; } = new(); - public WebsiteConfiguration WebsiteConfiguration { get; set; } = new(); + public WebsiteConfiguration Website { get; set; } = new(); public CustomizationConfiguration Customization { get; set; } = new(); } \ No newline at end of file diff --git a/ProjectLighthouse/PlayerData/Profiles/User.cs b/ProjectLighthouse/PlayerData/Profiles/User.cs index 300345d2..451c3f18 100644 --- a/ProjectLighthouse/PlayerData/Profiles/User.cs +++ b/ProjectLighthouse/PlayerData/Profiles/User.cs @@ -64,7 +64,7 @@ public class User if (string.IsNullOrWhiteSpace(avatarHash) || this.IconHash.StartsWith('g')) avatarHash = this.YayHash; if (string.IsNullOrWhiteSpace(avatarHash)) avatarHash = this.MehHash; if (string.IsNullOrWhiteSpace(avatarHash)) avatarHash = this.BooHash; - if (string.IsNullOrWhiteSpace(avatarHash)) avatarHash = ServerConfiguration.Instance.WebsiteConfiguration.MissingIconHash; + if (string.IsNullOrWhiteSpace(avatarHash)) avatarHash = ServerConfiguration.Instance.Website.MissingIconHash; return avatarHash; } diff --git a/ProjectLighthouse/StartupTasks.cs b/ProjectLighthouse/StartupTasks.cs index caff91bc..69c72829 100644 --- a/ProjectLighthouse/StartupTasks.cs +++ b/ProjectLighthouse/StartupTasks.cs @@ -77,7 +77,7 @@ public static class StartupTasks return; } - if (ServerConfiguration.Instance.WebsiteConfiguration.ConvertAssetsOnStartup + if (ServerConfiguration.Instance.Website.ConvertAssetsOnStartup && serverType == ServerType.Website) { FileHelper.ConvertAllTexturesToPng(); From 96ed3cfad2ba2400834932990749ef5e3d3ec567 Mon Sep 17 00:00:00 2001 From: jvyden Date: Wed, 1 Jun 2022 17:10:13 -0400 Subject: [PATCH 16/24] Revert "Rename ServerConfiguration.WebsiteConfiguration to Website" This reverts commit 7a2f99291d301aabd5eaa8d29e6f6c48f8e62056. --- .../Pages/Partials/SlotCardPartial.cshtml | 2 +- ProjectLighthouse.Servers.Website/Pages/SlotPage.cshtml | 2 +- ProjectLighthouse/Configuration/Legacy/LegacyServerSettings.cs | 2 +- ProjectLighthouse/Configuration/ServerConfiguration.cs | 2 +- ProjectLighthouse/PlayerData/Profiles/User.cs | 2 +- ProjectLighthouse/StartupTasks.cs | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ProjectLighthouse.Servers.Website/Pages/Partials/SlotCardPartial.cshtml b/ProjectLighthouse.Servers.Website/Pages/Partials/SlotCardPartial.cshtml index cd633eb2..6e469d63 100644 --- a/ProjectLighthouse.Servers.Website/Pages/Partials/SlotCardPartial.cshtml +++ b/ProjectLighthouse.Servers.Website/Pages/Partials/SlotCardPartial.cshtml @@ -27,7 +27,7 @@ bool showLink = (bool?)ViewData["ShowLink"] ?? false; string iconHash = Model.IconHash; - if (string.IsNullOrWhiteSpace(iconHash) || iconHash.StartsWith('g')) iconHash = ServerConfiguration.Instance.Website.MissingIconHash; + if (string.IsNullOrWhiteSpace(iconHash) || iconHash.StartsWith('g')) iconHash = ServerConfiguration.Instance.WebsiteConfiguration.MissingIconHash; }
@{ diff --git a/ProjectLighthouse.Servers.Website/Pages/SlotPage.cshtml b/ProjectLighthouse.Servers.Website/Pages/SlotPage.cshtml index 43f59b33..0722a616 100644 --- a/ProjectLighthouse.Servers.Website/Pages/SlotPage.cshtml +++ b/ProjectLighthouse.Servers.Website/Pages/SlotPage.cshtml @@ -98,7 +98,7 @@ if (string.IsNullOrWhiteSpace(faceHash)) { - faceHash = ServerConfiguration.Instance.Website.MissingIconHash; + faceHash = ServerConfiguration.Instance.WebsiteConfiguration.MissingIconHash; } string faceAlt = review.Thumb switch { diff --git a/ProjectLighthouse/Configuration/Legacy/LegacyServerSettings.cs b/ProjectLighthouse/Configuration/Legacy/LegacyServerSettings.cs index ea08ed67..123fcf63 100644 --- a/ProjectLighthouse/Configuration/Legacy/LegacyServerSettings.cs +++ b/ProjectLighthouse/Configuration/Legacy/LegacyServerSettings.cs @@ -203,7 +203,7 @@ internal class LegacyServerSettings ProfileCommentsEnabled = this.ProfileCommentsEnabled, }; - configuration.Website = new WebsiteConfiguration + configuration.WebsiteConfiguration = new WebsiteConfiguration { MissingIconHash = this.MissingIconHash, ConvertAssetsOnStartup = this.ConvertAssetsOnStartup, diff --git a/ProjectLighthouse/Configuration/ServerConfiguration.cs b/ProjectLighthouse/Configuration/ServerConfiguration.cs index 0cd17c4a..bd3ce250 100644 --- a/ProjectLighthouse/Configuration/ServerConfiguration.cs +++ b/ProjectLighthouse/Configuration/ServerConfiguration.cs @@ -195,6 +195,6 @@ public class ServerConfiguration public InfluxDBConfiguration InfluxDB { get; set; } = new(); public MailConfiguration Mail { get; set; } = new(); public UserGeneratedContentLimitConfiguration UserGeneratedContentLimits { get; set; } = new(); - public WebsiteConfiguration Website { get; set; } = new(); + public WebsiteConfiguration WebsiteConfiguration { get; set; } = new(); public CustomizationConfiguration Customization { get; set; } = new(); } \ No newline at end of file diff --git a/ProjectLighthouse/PlayerData/Profiles/User.cs b/ProjectLighthouse/PlayerData/Profiles/User.cs index 451c3f18..300345d2 100644 --- a/ProjectLighthouse/PlayerData/Profiles/User.cs +++ b/ProjectLighthouse/PlayerData/Profiles/User.cs @@ -64,7 +64,7 @@ public class User if (string.IsNullOrWhiteSpace(avatarHash) || this.IconHash.StartsWith('g')) avatarHash = this.YayHash; if (string.IsNullOrWhiteSpace(avatarHash)) avatarHash = this.MehHash; if (string.IsNullOrWhiteSpace(avatarHash)) avatarHash = this.BooHash; - if (string.IsNullOrWhiteSpace(avatarHash)) avatarHash = ServerConfiguration.Instance.Website.MissingIconHash; + if (string.IsNullOrWhiteSpace(avatarHash)) avatarHash = ServerConfiguration.Instance.WebsiteConfiguration.MissingIconHash; return avatarHash; } diff --git a/ProjectLighthouse/StartupTasks.cs b/ProjectLighthouse/StartupTasks.cs index 69c72829..caff91bc 100644 --- a/ProjectLighthouse/StartupTasks.cs +++ b/ProjectLighthouse/StartupTasks.cs @@ -77,7 +77,7 @@ public static class StartupTasks return; } - if (ServerConfiguration.Instance.Website.ConvertAssetsOnStartup + if (ServerConfiguration.Instance.WebsiteConfiguration.ConvertAssetsOnStartup && serverType == ServerType.Website) { FileHelper.ConvertAllTexturesToPng(); From d0f5d07194c3c0ef488976c628e18f54a7f04e91 Mon Sep 17 00:00:00 2001 From: Josh Date: Sat, 4 Jun 2022 16:55:20 -0500 Subject: [PATCH 17/24] Fix level text limits (#318) --- .../Controllers/Slots/PublishController.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ProjectLighthouse.Servers.GameServer/Controllers/Slots/PublishController.cs b/ProjectLighthouse.Servers.GameServer/Controllers/Slots/PublishController.cs index a0eed01f..8c7a2eb7 100644 --- a/ProjectLighthouse.Servers.GameServer/Controllers/Slots/PublishController.cs +++ b/ProjectLighthouse.Servers.GameServer/Controllers/Slots/PublishController.cs @@ -86,9 +86,9 @@ public class PublishController : ControllerBase if (slot.Location == null) return this.BadRequest(); - if (slot.Description.Length > 200) return this.BadRequest(); + if (slot.Description.Length > 500) return this.BadRequest(); - if (slot.Name.Length > 100) return this.BadRequest(); + if (slot.Name.Length > 64) return this.BadRequest(); if (slot.Resources.Any(resource => !FileHelper.ResourceExists(resource))) { From 31f6aff49b3754e87ec8a9c3bc5d84d887102cea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 4 Jun 2022 17:56:58 -0400 Subject: [PATCH 18/24] Bump Discord.Net.Webhook from 3.7.1 to 3.7.2 (#317) Bumps [Discord.Net.Webhook](https://github.com/Discord-Net/Discord.Net) from 3.7.1 to 3.7.2. - [Release notes](https://github.com/Discord-Net/Discord.Net/releases) - [Changelog](https://github.com/discord-net/Discord.Net/blob/dev/CHANGELOG.md) - [Commits](https://github.com/Discord-Net/Discord.Net/compare/3.7.1...3.7.2) --- updated-dependencies: - dependency-name: Discord.Net.Webhook dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jayden --- ProjectLighthouse/ProjectLighthouse.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ProjectLighthouse/ProjectLighthouse.csproj b/ProjectLighthouse/ProjectLighthouse.csproj index 7184b1b7..f38c51ff 100644 --- a/ProjectLighthouse/ProjectLighthouse.csproj +++ b/ProjectLighthouse/ProjectLighthouse.csproj @@ -11,7 +11,7 @@ - + From 6d0673fcb8f49de949f3962d0686915f99d5c7cf Mon Sep 17 00:00:00 2001 From: jvyden Date: Fri, 10 Jun 2022 02:20:28 -0400 Subject: [PATCH 19/24] Adjust naming of customized versions --- ProjectLighthouse/Helpers/VersionHelper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ProjectLighthouse/Helpers/VersionHelper.cs b/ProjectLighthouse/Helpers/VersionHelper.cs index 1c926104..212eb091 100644 --- a/ProjectLighthouse/Helpers/VersionHelper.cs +++ b/ProjectLighthouse/Helpers/VersionHelper.cs @@ -54,7 +54,7 @@ public static class VersionHelper public static string CommitHash { get; set; } public static string Branch { get; set; } - public static string FullVersion => $"{ServerConfiguration.Instance.Customization.ServerName} {Branch}@{CommitHash} {Build}"; + public static string FullVersion => $"Project Lighthouse {Branch}@{CommitHash} {Build} ({ServerConfiguration.Instance.Customization.ServerName})"; public static bool IsDirty => CommitHash.EndsWith("-dirty") || CommitsOutOfDate != 1 || CommitHash == "invalid" || Branch == "invalid"; public static int CommitsOutOfDate { get; set; } public static bool CanCheckForUpdates { get; set; } From 64f65ba57482a6a1cea0fc4b1538c1efb7fa0b70 Mon Sep 17 00:00:00 2001 From: jvyden Date: Fri, 10 Jun 2022 02:21:01 -0400 Subject: [PATCH 20/24] Add support for migrations that need the database context --- .../.idea/indexLayout.xml | 2 + .../Administration/CompletedMigration.cs | 25 + .../Maintenance/IMaintenanceJob.cs | 2 + .../Maintenance/IMigrationTask.cs | 20 + .../Maintenance/MaintenanceHelper.cs | 72 +- .../CleanupBrokenPhotosMaintenanceJob.cs | 2 +- .../MaintenanceJobs/CleanupXMLInjection.cs | 36 - .../CleanupXMLInjectionMigration.cs | 31 + ProjectLighthouse/Database.cs | 2 + .../Extensions/DatabaseExtensions.cs | 6 + .../20220610061641_AddCompletedMigrations.cs | 37 + .../Migrations/DatabaseModelSnapshot.cs | 866 +++++++++--------- ProjectLighthouse/ProjectLighthouse.csproj | 4 + ProjectLighthouse/StartupTasks.cs | 27 +- scripts-and-tools/create-migration.sh | 5 + 15 files changed, 656 insertions(+), 481 deletions(-) create mode 100644 ProjectLighthouse/Administration/CompletedMigration.cs create mode 100644 ProjectLighthouse/Administration/Maintenance/IMigrationTask.cs delete mode 100644 ProjectLighthouse/Administration/Maintenance/MaintenanceJobs/CleanupXMLInjection.cs create mode 100644 ProjectLighthouse/Administration/Maintenance/MigrationTasks/CleanupXMLInjectionMigration.cs create mode 100644 ProjectLighthouse/Migrations/20220610061641_AddCompletedMigrations.cs diff --git a/.idea/.idea.ProjectLighthouse/.idea/indexLayout.xml b/.idea/.idea.ProjectLighthouse/.idea/indexLayout.xml index 46037895..e9bcd75e 100644 --- a/.idea/.idea.ProjectLighthouse/.idea/indexLayout.xml +++ b/.idea/.idea.ProjectLighthouse/.idea/indexLayout.xml @@ -3,11 +3,13 @@ + .config/dotnet-tools.json .github .gitignore .idea CONTRIBUTING.md DatabaseMigrations + LICENSE ProjectLighthouse.sln.DotSettings ProjectLighthouse.sln.DotSettings.user README.md diff --git a/ProjectLighthouse/Administration/CompletedMigration.cs b/ProjectLighthouse/Administration/CompletedMigration.cs new file mode 100644 index 00000000..3ddd3b25 --- /dev/null +++ b/ProjectLighthouse/Administration/CompletedMigration.cs @@ -0,0 +1,25 @@ +using System; +using System.ComponentModel.DataAnnotations; +using LBPUnion.ProjectLighthouse.Administration.Maintenance; + +namespace LBPUnion.ProjectLighthouse.Administration; + +/// +/// A record of the completion of a . +/// +public class CompletedMigration +{ + /// + /// The name of the migration. + /// + /// + /// Do not use the user-friendly name when setting this. + /// + [Key] + public string MigrationName { get; set; } + + /// + /// The moment the migration was ran. + /// + public DateTime RanAt { get; set; } +} \ No newline at end of file diff --git a/ProjectLighthouse/Administration/Maintenance/IMaintenanceJob.cs b/ProjectLighthouse/Administration/Maintenance/IMaintenanceJob.cs index cf9b82da..15229ed1 100644 --- a/ProjectLighthouse/Administration/Maintenance/IMaintenanceJob.cs +++ b/ProjectLighthouse/Administration/Maintenance/IMaintenanceJob.cs @@ -1,7 +1,9 @@ using System.Threading.Tasks; +using JetBrains.Annotations; namespace LBPUnion.ProjectLighthouse.Administration.Maintenance; +[UsedImplicitly(ImplicitUseTargetFlags.WithInheritors)] public interface IMaintenanceJob { public Task Run(); diff --git a/ProjectLighthouse/Administration/Maintenance/IMigrationTask.cs b/ProjectLighthouse/Administration/Maintenance/IMigrationTask.cs new file mode 100644 index 00000000..cba570a3 --- /dev/null +++ b/ProjectLighthouse/Administration/Maintenance/IMigrationTask.cs @@ -0,0 +1,20 @@ +using System.Threading.Tasks; +using JetBrains.Annotations; + +namespace LBPUnion.ProjectLighthouse.Administration.Maintenance; + +[UsedImplicitly(ImplicitUseTargetFlags.WithInheritors)] +public interface IMigrationTask +{ + /// + /// The user-friendly name of a migration. + /// + public string Name(); + + /// + /// Performs the migration. + /// + /// The Lighthouse database. + /// True if successful, false if not. + internal Task Run(Database database); +} \ No newline at end of file diff --git a/ProjectLighthouse/Administration/Maintenance/MaintenanceHelper.cs b/ProjectLighthouse/Administration/Maintenance/MaintenanceHelper.cs index 3d86ad38..7d7490d8 100644 --- a/ProjectLighthouse/Administration/Maintenance/MaintenanceHelper.cs +++ b/ProjectLighthouse/Administration/Maintenance/MaintenanceHelper.cs @@ -1,9 +1,11 @@ #nullable enable using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Reflection; using System.Threading.Tasks; +using LBPUnion.ProjectLighthouse.Extensions; using LBPUnion.ProjectLighthouse.Logging; using LBPUnion.ProjectLighthouse.Logging.Loggers; @@ -11,24 +13,16 @@ namespace LBPUnion.ProjectLighthouse.Administration.Maintenance; public static class MaintenanceHelper { - static MaintenanceHelper() { Commands = getListOfInterfaceObjects(); MaintenanceJobs = getListOfInterfaceObjects(); + MigrationTasks = getListOfInterfaceObjects(); } + public static List Commands { get; } - public static List MaintenanceJobs { get; } - - private static List getListOfInterfaceObjects() where T : class - { - return Assembly.GetExecutingAssembly() - .GetTypes() - .Where(t => t.GetInterfaces().Contains(typeof(T)) && t.GetConstructor(Type.EmptyTypes) != null) - .Select(t => Activator.CreateInstance(t) as T) - .ToList()!; - } + public static List MigrationTasks { get; } public static async Task> RunCommand(string[] args) { @@ -66,11 +60,57 @@ public static class MaintenanceHelper IMaintenanceJob? job = MaintenanceJobs.FirstOrDefault(j => j.GetType().Name == jobName); if (job == null) throw new ArgumentNullException(); - await RunMaintenanceJob(job); - } - - public static async Task RunMaintenanceJob(IMaintenanceJob job) - { await job.Run(); } + + public static async Task RunMigration(IMigrationTask migrationTask, Database? database = null) + { + database ??= new Database(); + + // Migrations should never be run twice. + Debug.Assert(!await database.CompletedMigrations.Has(m => m.MigrationName == migrationTask.GetType().Name)); + + Logger.Info($"Running migration task {migrationTask.Name()}", LogArea.Database); + + bool success; + Exception? exception = null; + + try + { + success = await migrationTask.Run(database); + } + catch(Exception e) + { + success = false; + exception = e; + } + + if(!success) + { + Logger.Error($"Could not run migration {migrationTask.Name()}", LogArea.Database); + if (exception != null) Logger.Error(exception.ToDetailedException(), LogArea.Database); + + return; + } + + Logger.Success($"Successfully completed migration {migrationTask.Name()}", LogArea.Database); + + CompletedMigration completedMigration = new() + { + MigrationName = migrationTask.GetType().Name, + RanAt = DateTime.Now, + }; + + database.CompletedMigrations.Add(completedMigration); + await database.SaveChangesAsync(); + } + + private static List getListOfInterfaceObjects() where T : class + { + return Assembly.GetExecutingAssembly() + .GetTypes() + .Where(t => t.GetInterfaces().Contains(typeof(T)) && t.GetConstructor(Type.EmptyTypes) != null) + .Select(t => Activator.CreateInstance(t) as T) + .ToList()!; + } } \ No newline at end of file diff --git a/ProjectLighthouse/Administration/Maintenance/MaintenanceJobs/CleanupBrokenPhotosMaintenanceJob.cs b/ProjectLighthouse/Administration/Maintenance/MaintenanceJobs/CleanupBrokenPhotosMaintenanceJob.cs index fdd6f523..b8074025 100644 --- a/ProjectLighthouse/Administration/Maintenance/MaintenanceJobs/CleanupBrokenPhotosMaintenanceJob.cs +++ b/ProjectLighthouse/Administration/Maintenance/MaintenanceJobs/CleanupBrokenPhotosMaintenanceJob.cs @@ -25,7 +25,7 @@ public class CleanupBrokenPhotosMaintenanceJob : IMaintenanceJob bool largeHashIsInvalidFile = false; bool tooManyPhotoSubjects = false; bool duplicatePhotoSubjects = false; - bool takenInTheFuture = true; + bool takenInTheFuture = false; // Checks should generally be ordered in least computationally expensive to most. diff --git a/ProjectLighthouse/Administration/Maintenance/MaintenanceJobs/CleanupXMLInjection.cs b/ProjectLighthouse/Administration/Maintenance/MaintenanceJobs/CleanupXMLInjection.cs deleted file mode 100644 index 91dd40d3..00000000 --- a/ProjectLighthouse/Administration/Maintenance/MaintenanceJobs/CleanupXMLInjection.cs +++ /dev/null @@ -1,36 +0,0 @@ -#nullable enable -using System.Threading.Tasks; -using LBPUnion.ProjectLighthouse.Administration.Reports; -using LBPUnion.ProjectLighthouse.Helpers; -using LBPUnion.ProjectLighthouse.Levels; -using LBPUnion.ProjectLighthouse.PlayerData; -using LBPUnion.ProjectLighthouse.PlayerData.Profiles; -using LBPUnion.ProjectLighthouse.PlayerData.Reviews; - -namespace LBPUnion.ProjectLighthouse.Administration.Maintenance.MaintenanceJobs; - -public class CleanupXmlInjection : IMaintenanceJob -{ - private readonly Database database = new(); - public string Name() => "Sanitize user content"; - public string Description() => "Sanitizes all user-generated strings in levels, reviews, comments, users, and scores to prevent XML injection. Only needs to be run once."; - - public async Task Run() - { - foreach (Slot slot in this.database.Slots) SanitizationHelper.SanitizeStringsInClass(slot); - - foreach (Review review in this.database.Reviews) SanitizationHelper.SanitizeStringsInClass(review); - - foreach (Comment comment in this.database.Comments) SanitizationHelper.SanitizeStringsInClass(comment); - - foreach (Score score in this.database.Scores) SanitizationHelper.SanitizeStringsInClass(score); - - foreach (User user in this.database.Users) SanitizationHelper.SanitizeStringsInClass(user); - - foreach (Photo photo in this.database.Photos) SanitizationHelper.SanitizeStringsInClass(photo); - - foreach (GriefReport report in this.database.Reports) SanitizationHelper.SanitizeStringsInClass(report); - - await this.database.SaveChangesAsync(); - } -} \ No newline at end of file diff --git a/ProjectLighthouse/Administration/Maintenance/MigrationTasks/CleanupXMLInjectionMigration.cs b/ProjectLighthouse/Administration/Maintenance/MigrationTasks/CleanupXMLInjectionMigration.cs new file mode 100644 index 00000000..bb1b71e9 --- /dev/null +++ b/ProjectLighthouse/Administration/Maintenance/MigrationTasks/CleanupXMLInjectionMigration.cs @@ -0,0 +1,31 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using LBPUnion.ProjectLighthouse.Helpers; + +namespace LBPUnion.ProjectLighthouse.Administration.Maintenance.MigrationTasks; + +public class CleanupXmlInjectionMigration : IMigrationTask +{ + public string Name() => "Cleanup XML injections"; + + // Weird, but required. Thanks, hejlsberg. + async Task IMigrationTask.Run(Database database) + { + List objsToBeSanitized = new(); + + // Store all the objects we need to sanitize in a list. + // The alternative here is to loop through every table, but thats a ton of code... + objsToBeSanitized.AddRange(database.Slots); + objsToBeSanitized.AddRange(database.Reviews); + objsToBeSanitized.AddRange(database.Comments); + objsToBeSanitized.AddRange(database.Scores); + objsToBeSanitized.AddRange(database.Users); + objsToBeSanitized.AddRange(database.Photos); + objsToBeSanitized.AddRange(database.Reports); + + foreach (object obj in objsToBeSanitized) SanitizationHelper.SanitizeStringsInClass(obj); + + await database.SaveChangesAsync(); + return true; + } +} \ No newline at end of file diff --git a/ProjectLighthouse/Database.cs b/ProjectLighthouse/Database.cs index 7430e070..eca4a621 100644 --- a/ProjectLighthouse/Database.cs +++ b/ProjectLighthouse/Database.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; using System.Threading.Tasks; +using LBPUnion.ProjectLighthouse.Administration; using LBPUnion.ProjectLighthouse.Administration.Reports; using LBPUnion.ProjectLighthouse.Configuration; using LBPUnion.ProjectLighthouse.Helpers; @@ -21,6 +22,7 @@ namespace LBPUnion.ProjectLighthouse; public class Database : DbContext { + public DbSet CompletedMigrations { get; set; } public DbSet Users { get; set; } public DbSet Locations { get; set; } public DbSet Slots { get; set; } diff --git a/ProjectLighthouse/Extensions/DatabaseExtensions.cs b/ProjectLighthouse/Extensions/DatabaseExtensions.cs index eb8af6c7..a7e27782 100644 --- a/ProjectLighthouse/Extensions/DatabaseExtensions.cs +++ b/ProjectLighthouse/Extensions/DatabaseExtensions.cs @@ -1,4 +1,7 @@ +using System; using System.Linq; +using System.Linq.Expressions; +using System.Threading.Tasks; using LBPUnion.ProjectLighthouse.Levels; using LBPUnion.ProjectLighthouse.PlayerData; using LBPUnion.ProjectLighthouse.PlayerData.Reviews; @@ -52,4 +55,7 @@ public static class DatabaseExtensions return query; } + + public static async Task Has(this IQueryable queryable, Expression> predicate) => + await queryable.FirstOrDefaultAsync(predicate) != null; } \ No newline at end of file diff --git a/ProjectLighthouse/Migrations/20220610061641_AddCompletedMigrations.cs b/ProjectLighthouse/Migrations/20220610061641_AddCompletedMigrations.cs new file mode 100644 index 00000000..5c33f89a --- /dev/null +++ b/ProjectLighthouse/Migrations/20220610061641_AddCompletedMigrations.cs @@ -0,0 +1,37 @@ +using System; +using LBPUnion.ProjectLighthouse; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace ProjectLighthouse.Migrations +{ + [DbContext(typeof(Database))] + [Migration("20220610061641_AddCompletedMigrations")] + public class AddCompletedMigrations : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "CompletedMigrations", + columns: table => new + { + MigrationName = table.Column(type: "varchar(255)", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + RanAt = table.Column(type: "datetime(6)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_CompletedMigrations", x => x.MigrationName); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "CompletedMigrations"); + } + } +} diff --git a/ProjectLighthouse/Migrations/DatabaseModelSnapshot.cs b/ProjectLighthouse/Migrations/DatabaseModelSnapshot.cs index 6acb3ff5..147d7e03 100644 --- a/ProjectLighthouse/Migrations/DatabaseModelSnapshot.cs +++ b/ProjectLighthouse/Migrations/DatabaseModelSnapshot.cs @@ -1,4 +1,5 @@ // +using System; using LBPUnion.ProjectLighthouse; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; @@ -15,35 +16,69 @@ namespace ProjectLighthouse.Migrations { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "6.0.4") + .HasAnnotation("ProductVersion", "6.0.5") .HasAnnotation("Relational:MaxIdentifierLength", 64); - modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.AuthenticationAttempt", b => + modelBuilder.Entity("LBPUnion.ProjectLighthouse.Administration.CompletedMigration", b => { - b.Property("AuthenticationAttemptId") + b.Property("MigrationName") + .HasColumnType("varchar(255)"); + + b.Property("RanAt") + .HasColumnType("datetime(6)"); + + b.HasKey("MigrationName"); + + b.ToTable("CompletedMigrations"); + }); + + modelBuilder.Entity("LBPUnion.ProjectLighthouse.Administration.Reports.GriefReport", b => + { + b.Property("ReportId") .ValueGeneratedOnAdd() .HasColumnType("int"); - b.Property("GameTokenId") - .HasColumnType("int"); - - b.Property("IPAddress") + b.Property("Bounds") .HasColumnType("longtext"); - b.Property("Platform") + b.Property("GriefStateHash") + .HasColumnType("longtext"); + + b.Property("InitialStateHash") + .HasColumnType("longtext"); + + b.Property("JpegHash") + .HasColumnType("longtext"); + + b.Property("LevelId") + .HasColumnType("int"); + + b.Property("LevelOwner") + .HasColumnType("longtext"); + + b.Property("LevelType") + .HasColumnType("longtext"); + + b.Property("Players") + .HasColumnType("longtext"); + + b.Property("ReportingPlayerId") .HasColumnType("int"); b.Property("Timestamp") .HasColumnType("bigint"); - b.HasKey("AuthenticationAttemptId"); + b.Property("Type") + .HasColumnType("int"); - b.HasIndex("GameTokenId"); + b.HasKey("ReportId"); - b.ToTable("AuthenticationAttempts"); + b.HasIndex("ReportingPlayerId"); + + b.ToTable("Reports"); }); - modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Categories.DatabaseCategory", b => + modelBuilder.Entity("LBPUnion.ProjectLighthouse.Levels.Categories.DatabaseCategory", b => { b.Property("CategoryId") .ValueGeneratedOnAdd() @@ -69,62 +104,7 @@ namespace ProjectLighthouse.Migrations b.ToTable("CustomCategories"); }); - modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.GameToken", b => - { - b.Property("TokenId") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - b.Property("Approved") - .HasColumnType("tinyint(1)"); - - b.Property("GameVersion") - .HasColumnType("int"); - - b.Property("Platform") - .HasColumnType("int"); - - b.Property("Used") - .HasColumnType("tinyint(1)"); - - b.Property("UserId") - .HasColumnType("int"); - - b.Property("UserLocation") - .HasColumnType("longtext"); - - b.Property("UserToken") - .HasColumnType("longtext"); - - b.HasKey("TokenId"); - - b.HasIndex("UserId"); - - b.ToTable("GameTokens"); - }); - - 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 => + modelBuilder.Entity("LBPUnion.ProjectLighthouse.Levels.HeartedLevel", b => { b.Property("HeartedLevelId") .ValueGeneratedOnAdd() @@ -145,7 +125,7 @@ namespace ProjectLighthouse.Migrations b.ToTable("HeartedLevels"); }); - modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Levels.QueuedLevel", b => + modelBuilder.Entity("LBPUnion.ProjectLighthouse.Levels.QueuedLevel", b => { b.Property("QueuedLevelId") .ValueGeneratedOnAdd() @@ -166,7 +146,7 @@ namespace ProjectLighthouse.Migrations b.ToTable("QueuedLevels"); }); - modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Levels.RatedLevel", b => + modelBuilder.Entity("LBPUnion.ProjectLighthouse.Levels.RatedLevel", b => { b.Property("RatedLevelId") .ValueGeneratedOnAdd() @@ -193,7 +173,7 @@ namespace ProjectLighthouse.Migrations b.ToTable("RatedLevels"); }); - modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Levels.Slot", b => + modelBuilder.Entity("LBPUnion.ProjectLighthouse.Levels.Slot", b => { b.Property("SlotId") .ValueGeneratedOnAdd() @@ -318,7 +298,7 @@ namespace ProjectLighthouse.Migrations b.ToTable("Slots"); }); - modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Levels.VisitedLevel", b => + modelBuilder.Entity("LBPUnion.ProjectLighthouse.Levels.VisitedLevel", b => { b.Property("VisitedLevelId") .ValueGeneratedOnAdd() @@ -351,7 +331,66 @@ namespace ProjectLighthouse.Migrations b.ToTable("VisitedLevels"); }); - modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Photo", b => + modelBuilder.Entity("LBPUnion.ProjectLighthouse.PlayerData.AuthenticationAttempt", b => + { + b.Property("AuthenticationAttemptId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("GameTokenId") + .HasColumnType("int"); + + b.Property("IPAddress") + .HasColumnType("longtext"); + + b.Property("Platform") + .HasColumnType("int"); + + b.Property("Timestamp") + .HasColumnType("bigint"); + + b.HasKey("AuthenticationAttemptId"); + + b.HasIndex("GameTokenId"); + + b.ToTable("AuthenticationAttempts"); + }); + + modelBuilder.Entity("LBPUnion.ProjectLighthouse.PlayerData.GameToken", b => + { + b.Property("TokenId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Approved") + .HasColumnType("tinyint(1)"); + + b.Property("GameVersion") + .HasColumnType("int"); + + b.Property("Platform") + .HasColumnType("int"); + + b.Property("Used") + .HasColumnType("tinyint(1)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.Property("UserLocation") + .HasColumnType("longtext"); + + b.Property("UserToken") + .HasColumnType("longtext"); + + b.HasKey("TokenId"); + + b.HasIndex("UserId"); + + b.ToTable("GameTokens"); + }); + + modelBuilder.Entity("LBPUnion.ProjectLighthouse.PlayerData.Photo", b => { b.Property("PhotoId") .ValueGeneratedOnAdd() @@ -390,7 +429,7 @@ namespace ProjectLighthouse.Migrations b.ToTable("Photos"); }); - modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.PhotoSubject", b => + modelBuilder.Entity("LBPUnion.ProjectLighthouse.PlayerData.PhotoSubject", b => { b.Property("PhotoSubjectId") .ValueGeneratedOnAdd() @@ -409,7 +448,7 @@ namespace ProjectLighthouse.Migrations b.ToTable("PhotoSubjects"); }); - modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Profiles.Comment", b => + modelBuilder.Entity("LBPUnion.ProjectLighthouse.PlayerData.Profiles.Comment", b => { b.Property("CommentId") .ValueGeneratedOnAdd() @@ -452,7 +491,7 @@ namespace ProjectLighthouse.Migrations b.ToTable("Comments"); }); - modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Profiles.Email.EmailSetToken", b => + modelBuilder.Entity("LBPUnion.ProjectLighthouse.PlayerData.Profiles.Email.EmailSetToken", b => { b.Property("EmailSetTokenId") .ValueGeneratedOnAdd() @@ -471,7 +510,7 @@ namespace ProjectLighthouse.Migrations b.ToTable("EmailSetTokens"); }); - modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Profiles.Email.EmailVerificationToken", b => + modelBuilder.Entity("LBPUnion.ProjectLighthouse.PlayerData.Profiles.Email.EmailVerificationToken", b => { b.Property("EmailVerificationTokenId") .ValueGeneratedOnAdd() @@ -490,7 +529,28 @@ namespace ProjectLighthouse.Migrations b.ToTable("EmailVerificationTokens"); }); - modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Profiles.LastContact", b => + modelBuilder.Entity("LBPUnion.ProjectLighthouse.PlayerData.Profiles.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.PlayerData.Profiles.LastContact", b => { b.Property("UserId") .HasColumnType("int"); @@ -509,7 +569,7 @@ namespace ProjectLighthouse.Migrations b.ToTable("LastContacts"); }); - modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Profiles.Location", b => + modelBuilder.Entity("LBPUnion.ProjectLighthouse.PlayerData.Profiles.Location", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -526,169 +586,7 @@ namespace ProjectLighthouse.Migrations b.ToTable("Locations"); }); - modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Reaction", b => - { - b.Property("RatingId") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - b.Property("Rating") - .HasColumnType("int"); - - b.Property("TargetId") - .HasColumnType("int"); - - b.Property("UserId") - .HasColumnType("int"); - - b.HasKey("RatingId"); - - b.ToTable("Reactions"); - }); - - modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Reports.GriefReport", b => - { - b.Property("ReportId") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - b.Property("Bounds") - .HasColumnType("longtext"); - - b.Property("GriefStateHash") - .HasColumnType("longtext"); - - b.Property("InitialStateHash") - .HasColumnType("longtext"); - - b.Property("JpegHash") - .HasColumnType("longtext"); - - b.Property("LevelId") - .HasColumnType("int"); - - b.Property("LevelOwner") - .HasColumnType("longtext"); - - b.Property("LevelType") - .HasColumnType("longtext"); - - b.Property("Players") - .HasColumnType("longtext"); - - b.Property("ReportingPlayerId") - .HasColumnType("int"); - - b.Property("Timestamp") - .HasColumnType("bigint"); - - b.Property("Type") - .HasColumnType("int"); - - b.HasKey("ReportId"); - - b.HasIndex("ReportingPlayerId"); - - b.ToTable("Reports"); - }); - - modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Reviews.RatedReview", b => - { - b.Property("RatedReviewId") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - b.Property("ReviewId") - .HasColumnType("int"); - - b.Property("Thumb") - .HasColumnType("int"); - - b.Property("UserId") - .HasColumnType("int"); - - b.HasKey("RatedReviewId"); - - b.HasIndex("ReviewId"); - - b.HasIndex("UserId"); - - b.ToTable("RatedReviews"); - }); - - modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Reviews.Review", b => - { - b.Property("ReviewId") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - b.Property("Deleted") - .HasColumnType("tinyint(1)"); - - b.Property("DeletedBy") - .HasColumnType("int"); - - b.Property("LabelCollection") - .IsRequired() - .HasColumnType("longtext"); - - b.Property("ReviewerId") - .HasColumnType("int"); - - b.Property("SlotId") - .HasColumnType("int"); - - b.Property("Text") - .IsRequired() - .HasColumnType("longtext"); - - b.Property("Thumb") - .HasColumnType("int"); - - b.Property("ThumbsDown") - .HasColumnType("int"); - - b.Property("ThumbsUp") - .HasColumnType("int"); - - b.Property("Timestamp") - .HasColumnType("bigint"); - - b.HasKey("ReviewId"); - - b.HasIndex("ReviewerId"); - - b.HasIndex("SlotId"); - - b.ToTable("Reviews"); - }); - - 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.User", b => + modelBuilder.Entity("LBPUnion.ProjectLighthouse.PlayerData.Profiles.User", b => { b.Property("UserId") .ValueGeneratedOnAdd() @@ -761,7 +659,7 @@ namespace ProjectLighthouse.Migrations b.ToTable("Users"); }); - modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.UserApprovedIpAddress", b => + modelBuilder.Entity("LBPUnion.ProjectLighthouse.PlayerData.Profiles.UserApprovedIpAddress", b => { b.Property("UserApprovedIpAddressId") .ValueGeneratedOnAdd() @@ -780,7 +678,123 @@ namespace ProjectLighthouse.Migrations b.ToTable("UserApprovedIpAddresses"); }); - modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.WebToken", b => + modelBuilder.Entity("LBPUnion.ProjectLighthouse.PlayerData.Reaction", b => + { + b.Property("RatingId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Rating") + .HasColumnType("int"); + + b.Property("TargetId") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("RatingId"); + + b.ToTable("Reactions"); + }); + + modelBuilder.Entity("LBPUnion.ProjectLighthouse.PlayerData.Reviews.RatedReview", b => + { + b.Property("RatedReviewId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ReviewId") + .HasColumnType("int"); + + b.Property("Thumb") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("RatedReviewId"); + + b.HasIndex("ReviewId"); + + b.HasIndex("UserId"); + + b.ToTable("RatedReviews"); + }); + + modelBuilder.Entity("LBPUnion.ProjectLighthouse.PlayerData.Reviews.Review", b => + { + b.Property("ReviewId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Deleted") + .HasColumnType("tinyint(1)"); + + b.Property("DeletedBy") + .HasColumnType("int"); + + b.Property("LabelCollection") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ReviewerId") + .HasColumnType("int"); + + b.Property("SlotId") + .HasColumnType("int"); + + b.Property("Text") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Thumb") + .HasColumnType("int"); + + b.Property("ThumbsDown") + .HasColumnType("int"); + + b.Property("ThumbsUp") + .HasColumnType("int"); + + b.Property("Timestamp") + .HasColumnType("bigint"); + + b.HasKey("ReviewId"); + + b.HasIndex("ReviewerId"); + + b.HasIndex("SlotId"); + + b.ToTable("Reviews"); + }); + + modelBuilder.Entity("LBPUnion.ProjectLighthouse.PlayerData.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.PlayerData.WebToken", b => { b.Property("TokenId") .ValueGeneratedOnAdd() @@ -797,9 +811,115 @@ namespace ProjectLighthouse.Migrations b.ToTable("WebTokens"); }); - modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.AuthenticationAttempt", b => + modelBuilder.Entity("LBPUnion.ProjectLighthouse.Administration.Reports.GriefReport", b => { - b.HasOne("LBPUnion.ProjectLighthouse.Types.GameToken", "GameToken") + b.HasOne("LBPUnion.ProjectLighthouse.PlayerData.Profiles.User", "ReportingPlayer") + .WithMany() + .HasForeignKey("ReportingPlayerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ReportingPlayer"); + }); + + modelBuilder.Entity("LBPUnion.ProjectLighthouse.Levels.HeartedLevel", b => + { + b.HasOne("LBPUnion.ProjectLighthouse.Levels.Slot", "Slot") + .WithMany() + .HasForeignKey("SlotId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("LBPUnion.ProjectLighthouse.PlayerData.Profiles.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Slot"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("LBPUnion.ProjectLighthouse.Levels.QueuedLevel", b => + { + b.HasOne("LBPUnion.ProjectLighthouse.Levels.Slot", "Slot") + .WithMany() + .HasForeignKey("SlotId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("LBPUnion.ProjectLighthouse.PlayerData.Profiles.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Slot"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("LBPUnion.ProjectLighthouse.Levels.RatedLevel", b => + { + b.HasOne("LBPUnion.ProjectLighthouse.Levels.Slot", "Slot") + .WithMany() + .HasForeignKey("SlotId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("LBPUnion.ProjectLighthouse.PlayerData.Profiles.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Slot"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("LBPUnion.ProjectLighthouse.Levels.Slot", b => + { + b.HasOne("LBPUnion.ProjectLighthouse.PlayerData.Profiles.User", "Creator") + .WithMany() + .HasForeignKey("CreatorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("LBPUnion.ProjectLighthouse.PlayerData.Profiles.Location", "Location") + .WithMany() + .HasForeignKey("LocationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Creator"); + + b.Navigation("Location"); + }); + + modelBuilder.Entity("LBPUnion.ProjectLighthouse.Levels.VisitedLevel", b => + { + b.HasOne("LBPUnion.ProjectLighthouse.Levels.Slot", "Slot") + .WithMany() + .HasForeignKey("SlotId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("LBPUnion.ProjectLighthouse.PlayerData.Profiles.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Slot"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("LBPUnion.ProjectLighthouse.PlayerData.AuthenticationAttempt", b => + { + b.HasOne("LBPUnion.ProjectLighthouse.PlayerData.GameToken", "GameToken") .WithMany() .HasForeignKey("GameTokenId") .OnDelete(DeleteBehavior.Cascade) @@ -808,9 +928,9 @@ namespace ProjectLighthouse.Migrations b.Navigation("GameToken"); }); - modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.GameToken", b => + modelBuilder.Entity("LBPUnion.ProjectLighthouse.PlayerData.GameToken", b => { - b.HasOne("LBPUnion.ProjectLighthouse.Types.User", "User") + b.HasOne("LBPUnion.ProjectLighthouse.PlayerData.Profiles.User", "User") .WithMany() .HasForeignKey("UserId") .OnDelete(DeleteBehavior.Cascade) @@ -819,15 +939,70 @@ namespace ProjectLighthouse.Migrations b.Navigation("User"); }); - modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.HeartedProfile", b => + modelBuilder.Entity("LBPUnion.ProjectLighthouse.PlayerData.Photo", b => { - b.HasOne("LBPUnion.ProjectLighthouse.Types.User", "HeartedUser") + b.HasOne("LBPUnion.ProjectLighthouse.PlayerData.Profiles.User", "Creator") + .WithMany() + .HasForeignKey("CreatorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Creator"); + }); + + modelBuilder.Entity("LBPUnion.ProjectLighthouse.PlayerData.PhotoSubject", b => + { + b.HasOne("LBPUnion.ProjectLighthouse.PlayerData.Profiles.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("LBPUnion.ProjectLighthouse.PlayerData.Profiles.Comment", b => + { + b.HasOne("LBPUnion.ProjectLighthouse.PlayerData.Profiles.User", "Poster") + .WithMany() + .HasForeignKey("PosterUserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Poster"); + }); + + modelBuilder.Entity("LBPUnion.ProjectLighthouse.PlayerData.Profiles.Email.EmailSetToken", b => + { + b.HasOne("LBPUnion.ProjectLighthouse.PlayerData.Profiles.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("LBPUnion.ProjectLighthouse.PlayerData.Profiles.Email.EmailVerificationToken", b => + { + b.HasOne("LBPUnion.ProjectLighthouse.PlayerData.Profiles.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("LBPUnion.ProjectLighthouse.PlayerData.Profiles.HeartedProfile", b => + { + b.HasOne("LBPUnion.ProjectLighthouse.PlayerData.Profiles.User", "HeartedUser") .WithMany() .HasForeignKey("HeartedUserId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); - b.HasOne("LBPUnion.ProjectLighthouse.Types.User", "User") + b.HasOne("LBPUnion.ProjectLighthouse.PlayerData.Profiles.User", "User") .WithMany() .HasForeignKey("UserId") .OnDelete(DeleteBehavior.Cascade) @@ -838,115 +1013,31 @@ namespace ProjectLighthouse.Migrations b.Navigation("User"); }); - modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Levels.HeartedLevel", b => + modelBuilder.Entity("LBPUnion.ProjectLighthouse.PlayerData.Profiles.LastContact", b => { - b.HasOne("LBPUnion.ProjectLighthouse.Types.Levels.Slot", "Slot") - .WithMany() - .HasForeignKey("SlotId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("LBPUnion.ProjectLighthouse.Types.User", "User") + b.HasOne("LBPUnion.ProjectLighthouse.PlayerData.Profiles.User", "User") .WithMany() .HasForeignKey("UserId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); - b.Navigation("Slot"); - b.Navigation("User"); }); - modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Levels.QueuedLevel", b => + modelBuilder.Entity("LBPUnion.ProjectLighthouse.PlayerData.Profiles.User", b => { - b.HasOne("LBPUnion.ProjectLighthouse.Types.Levels.Slot", "Slot") - .WithMany() - .HasForeignKey("SlotId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("LBPUnion.ProjectLighthouse.Types.User", "User") - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Slot"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Levels.RatedLevel", b => - { - b.HasOne("LBPUnion.ProjectLighthouse.Types.Levels.Slot", "Slot") - .WithMany() - .HasForeignKey("SlotId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("LBPUnion.ProjectLighthouse.Types.User", "User") - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Slot"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Levels.Slot", b => - { - b.HasOne("LBPUnion.ProjectLighthouse.Types.User", "Creator") - .WithMany() - .HasForeignKey("CreatorId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("LBPUnion.ProjectLighthouse.Types.Profiles.Location", "Location") + b.HasOne("LBPUnion.ProjectLighthouse.PlayerData.Profiles.Location", "Location") .WithMany() .HasForeignKey("LocationId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); - b.Navigation("Creator"); - b.Navigation("Location"); }); - modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Levels.VisitedLevel", b => + modelBuilder.Entity("LBPUnion.ProjectLighthouse.PlayerData.Profiles.UserApprovedIpAddress", 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") + b.HasOne("LBPUnion.ProjectLighthouse.PlayerData.Profiles.User", "User") .WithMany() .HasForeignKey("UserId") .OnDelete(DeleteBehavior.Cascade) @@ -955,70 +1046,15 @@ namespace ProjectLighthouse.Migrations b.Navigation("User"); }); - modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Profiles.Comment", b => + modelBuilder.Entity("LBPUnion.ProjectLighthouse.PlayerData.Reviews.RatedReview", b => { - b.HasOne("LBPUnion.ProjectLighthouse.Types.User", "Poster") - .WithMany() - .HasForeignKey("PosterUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Poster"); - }); - - modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Profiles.Email.EmailSetToken", b => - { - b.HasOne("LBPUnion.ProjectLighthouse.Types.User", "User") - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Profiles.Email.EmailVerificationToken", b => - { - b.HasOne("LBPUnion.ProjectLighthouse.Types.User", "User") - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Profiles.LastContact", b => - { - b.HasOne("LBPUnion.ProjectLighthouse.Types.User", "User") - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Reports.GriefReport", b => - { - b.HasOne("LBPUnion.ProjectLighthouse.Types.User", "ReportingPlayer") - .WithMany() - .HasForeignKey("ReportingPlayerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("ReportingPlayer"); - }); - - modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Reviews.RatedReview", b => - { - b.HasOne("LBPUnion.ProjectLighthouse.Types.Reviews.Review", "Review") + b.HasOne("LBPUnion.ProjectLighthouse.PlayerData.Reviews.Review", "Review") .WithMany() .HasForeignKey("ReviewId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); - b.HasOne("LBPUnion.ProjectLighthouse.Types.User", "User") + b.HasOne("LBPUnion.ProjectLighthouse.PlayerData.Profiles.User", "User") .WithMany() .HasForeignKey("UserId") .OnDelete(DeleteBehavior.Cascade) @@ -1029,15 +1065,15 @@ namespace ProjectLighthouse.Migrations b.Navigation("User"); }); - modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Reviews.Review", b => + modelBuilder.Entity("LBPUnion.ProjectLighthouse.PlayerData.Reviews.Review", b => { - b.HasOne("LBPUnion.ProjectLighthouse.Types.User", "Reviewer") + b.HasOne("LBPUnion.ProjectLighthouse.PlayerData.Profiles.User", "Reviewer") .WithMany() .HasForeignKey("ReviewerId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); - b.HasOne("LBPUnion.ProjectLighthouse.Types.Levels.Slot", "Slot") + b.HasOne("LBPUnion.ProjectLighthouse.Levels.Slot", "Slot") .WithMany() .HasForeignKey("SlotId") .OnDelete(DeleteBehavior.Cascade) @@ -1048,9 +1084,9 @@ namespace ProjectLighthouse.Migrations b.Navigation("Slot"); }); - modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Score", b => + modelBuilder.Entity("LBPUnion.ProjectLighthouse.PlayerData.Score", b => { - b.HasOne("LBPUnion.ProjectLighthouse.Types.Levels.Slot", "Slot") + b.HasOne("LBPUnion.ProjectLighthouse.Levels.Slot", "Slot") .WithMany() .HasForeignKey("SlotId") .OnDelete(DeleteBehavior.Cascade) @@ -1058,28 +1094,6 @@ namespace ProjectLighthouse.Migrations 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.UserApprovedIpAddress", b => - { - b.HasOne("LBPUnion.ProjectLighthouse.Types.User", "User") - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); #pragma warning restore 612, 618 } } diff --git a/ProjectLighthouse/ProjectLighthouse.csproj b/ProjectLighthouse/ProjectLighthouse.csproj index f38c51ff..be8a30f9 100644 --- a/ProjectLighthouse/ProjectLighthouse.csproj +++ b/ProjectLighthouse/ProjectLighthouse.csproj @@ -50,6 +50,10 @@ + + + + diff --git a/ProjectLighthouse/StartupTasks.cs b/ProjectLighthouse/StartupTasks.cs index caff91bc..234cf75e 100644 --- a/ProjectLighthouse/StartupTasks.cs +++ b/ProjectLighthouse/StartupTasks.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Linq; +using LBPUnion.ProjectLighthouse.Administration; using LBPUnion.ProjectLighthouse.Administration.Maintenance; using LBPUnion.ProjectLighthouse.Configuration; using LBPUnion.ProjectLighthouse.Extensions; @@ -112,14 +114,35 @@ public static class StartupTasks Logger.Success($"Ready! Startup took {stopwatch.ElapsedMilliseconds}ms. Passing off control to ASP.NET...", LogArea.Startup); } - private static void migrateDatabase(DbContext database) + private static void migrateDatabase(Database database) { + Stopwatch totalStopwatch = new(); Stopwatch stopwatch = new(); + totalStopwatch.Start(); stopwatch.Start(); database.Database.MigrateAsync().Wait(); + stopwatch.Stop(); + Logger.Success($"Structure migration took {stopwatch.ElapsedMilliseconds}ms.", LogArea.Database); + + stopwatch.Reset(); + stopwatch.Start(); + + List completedMigrations = database.CompletedMigrations.ToList(); + List migrationsToRun = MaintenanceHelper.MigrationTasks + .Where(migrationTask => !completedMigrations + .Select(m => m.MigrationName) + .Contains(migrationTask.GetType().Name) + ).ToList(); + + foreach (IMigrationTask migrationTask in migrationsToRun) + { + MaintenanceHelper.RunMigration(migrationTask, database).Wait(); + } stopwatch.Stop(); - Logger.Success($"Migration took {stopwatch.ElapsedMilliseconds}ms.", LogArea.Database); + totalStopwatch.Stop(); + Logger.Success($"Extra migration tasks took {stopwatch.ElapsedMilliseconds}ms.", LogArea.Database); + Logger.Success($"Total migration took {totalStopwatch.ElapsedMilliseconds}ms.", LogArea.Database); } } \ No newline at end of file diff --git a/scripts-and-tools/create-migration.sh b/scripts-and-tools/create-migration.sh index 5ccbe0fb..43c6a3d2 100755 --- a/scripts-and-tools/create-migration.sh +++ b/scripts-and-tools/create-migration.sh @@ -1,4 +1,9 @@ #!/bin/bash +# Developer script to create EntityFramework database migrations +# +# $1: Name of the migration, e.g. SwitchToPermissionLevels +# Invoked manually + export LIGHTHOUSE_DB_CONNECTION_STRING='server=127.0.0.1;uid=root;pwd=lighthouse;database=lighthouse' dotnet ef migrations add "$1" --project ProjectLighthouse \ No newline at end of file From caa4b9bec1bd4001a7d5b712238e0af2427b56fa Mon Sep 17 00:00:00 2001 From: jvyden Date: Fri, 10 Jun 2022 02:24:26 -0400 Subject: [PATCH 21/24] Only migrate database on production gameserver --- ProjectLighthouse/StartupTasks.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ProjectLighthouse/StartupTasks.cs b/ProjectLighthouse/StartupTasks.cs index 234cf75e..95497e90 100644 --- a/ProjectLighthouse/StartupTasks.cs +++ b/ProjectLighthouse/StartupTasks.cs @@ -52,8 +52,10 @@ public static class StartupTasks if (!dbConnected) Environment.Exit(1); using Database database = new(); - - Logger.Info("Migrating database...", LogArea.Database); + + #if !DEBUG + if(serverType == ServerType.GameServer) + #endif migrateDatabase(database); if (ServerConfiguration.Instance.InfluxDB.InfluxEnabled) @@ -116,6 +118,7 @@ public static class StartupTasks private static void migrateDatabase(Database database) { + Logger.Info("Migrating database...", LogArea.Database); Stopwatch totalStopwatch = new(); Stopwatch stopwatch = new(); totalStopwatch.Start(); From 02abb7bcabfa693f83b1a3272911ea6a53389dc8 Mon Sep 17 00:00:00 2001 From: jvyden Date: Fri, 10 Jun 2022 02:42:24 -0400 Subject: [PATCH 22/24] Add command to flush redis database --- .../Maintenance/Commands/FlushRedisCommand.cs | 20 +++++++++++++++++++ .../StorableLists/RedisDatabase.cs | 17 ++++++++++++++-- 2 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 ProjectLighthouse/Administration/Maintenance/Commands/FlushRedisCommand.cs diff --git a/ProjectLighthouse/Administration/Maintenance/Commands/FlushRedisCommand.cs b/ProjectLighthouse/Administration/Maintenance/Commands/FlushRedisCommand.cs new file mode 100644 index 00000000..85fde257 --- /dev/null +++ b/ProjectLighthouse/Administration/Maintenance/Commands/FlushRedisCommand.cs @@ -0,0 +1,20 @@ +using System.Threading.Tasks; +using LBPUnion.ProjectLighthouse.Logging; +using LBPUnion.ProjectLighthouse.StorableLists; + +namespace LBPUnion.ProjectLighthouse.Administration.Maintenance.Commands; + +public class FlushRedisCommand : ICommand +{ + public string Name() => "Flush Redis"; + public string[] Aliases() => new[] { + "flush", "flush-redis", + }; + public string Arguments() => ""; + public int RequiredArgs() => 0; + + public async Task Run(string[] args, Logger logger) + { + await RedisDatabase.FlushAll(); + } +} \ No newline at end of file diff --git a/ProjectLighthouse/StorableLists/RedisDatabase.cs b/ProjectLighthouse/StorableLists/RedisDatabase.cs index f97b127d..6910aec0 100644 --- a/ProjectLighthouse/StorableLists/RedisDatabase.cs +++ b/ProjectLighthouse/StorableLists/RedisDatabase.cs @@ -39,8 +39,7 @@ public static class RedisDatabase return; } - await connection.RecreateIndexAsync(typeof(Room)); - await connection.RecreateIndexAsync(typeof(UserFriendData)); + await createIndexes(connection); } catch(Exception e) { @@ -52,6 +51,20 @@ public static class RedisDatabase Logger.Success("Initialized Redis.", LogArea.Redis); } + public static async Task FlushAll() + { + IRedisConnection connection = getConnection(); + await connection.ExecuteAsync("FLUSHALL"); + + await createIndexes(connection); + } + + private static async Task createIndexes(IRedisConnection connection) + { + await connection.RecreateIndexAsync(typeof(Room)); + await connection.RecreateIndexAsync(typeof(UserFriendData)); + } + private static IRedisConnection getConnection() { Logger.Debug("Getting a Redis connection", LogArea.Redis); From 615b57122eccab41902c89addf248f2b60038425 Mon Sep 17 00:00:00 2001 From: jvyden Date: Fri, 10 Jun 2022 02:42:38 -0400 Subject: [PATCH 23/24] Lock RoomHelper.Rooms properly --- .../Controllers/Debug/RoomVisualizerController.cs | 2 +- ProjectLighthouse.sln.DotSettings | 1 + ProjectLighthouse/Match/Rooms/RoomHelper.cs | 5 +++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/ProjectLighthouse.Servers.Website/Controllers/Debug/RoomVisualizerController.cs b/ProjectLighthouse.Servers.Website/Controllers/Debug/RoomVisualizerController.cs index a2bff1e0..7039a9bf 100644 --- a/ProjectLighthouse.Servers.Website/Controllers/Debug/RoomVisualizerController.cs +++ b/ProjectLighthouse.Servers.Website/Controllers/Debug/RoomVisualizerController.cs @@ -42,7 +42,7 @@ public class RoomVisualizerController : ControllerBase #if !DEBUG return this.NotFound(); #else - RoomHelper.Rooms.RemoveAll(); + lock(RoomHelper.RoomLock) RoomHelper.Rooms.RemoveAll(); return this.Redirect("/debug/roomVisualizer"); #endif } diff --git a/ProjectLighthouse.sln.DotSettings b/ProjectLighthouse.sln.DotSettings index 8a9a5b94..524940d2 100644 --- a/ProjectLighthouse.sln.DotSettings +++ b/ProjectLighthouse.sln.DotSettings @@ -115,6 +115,7 @@ True True True + True True True True diff --git a/ProjectLighthouse/Match/Rooms/RoomHelper.cs b/ProjectLighthouse/Match/Rooms/RoomHelper.cs index 4e09d5ea..33f1959c 100644 --- a/ProjectLighthouse/Match/Rooms/RoomHelper.cs +++ b/ProjectLighthouse/Match/Rooms/RoomHelper.cs @@ -16,6 +16,7 @@ namespace LBPUnion.ProjectLighthouse.Match.Rooms; public class RoomHelper { + public static readonly object RoomLock = new(); public static StorableList Rooms => RoomStore.GetRooms(); public static void StartCleanupThread() @@ -162,7 +163,7 @@ public class RoomHelper }; CleanupRooms(room.HostId, room); - lock(Rooms) Rooms.Add(room); + lock(RoomLock) Rooms.Add(room); Logger.Info($"Created room (id: {room.RoomId}) for host {room.HostId}", LogArea.Match); return room; @@ -193,7 +194,7 @@ public class RoomHelper [SuppressMessage("ReSharper", "InvertIf")] public static void CleanupRooms(int? hostId = null, Room? newRoom = null, Database? database = null) { - lock(Rooms) + lock(RoomLock) { int roomCountBeforeCleanup = Rooms.Count(); From 89b6e6dff3a57b2982db59ced9cc757c32ac086a Mon Sep 17 00:00:00 2001 From: jvyden Date: Fri, 10 Jun 2022 03:48:12 -0400 Subject: [PATCH 24/24] Adjust review character limit to match LBP Vita's limit Closes #286 --- .../Controllers/Slots/ReviewController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ProjectLighthouse.Servers.GameServer/Controllers/Slots/ReviewController.cs b/ProjectLighthouse.Servers.GameServer/Controllers/Slots/ReviewController.cs index be33b216..eb6cb62d 100644 --- a/ProjectLighthouse.Servers.GameServer/Controllers/Slots/ReviewController.cs +++ b/ProjectLighthouse.Servers.GameServer/Controllers/Slots/ReviewController.cs @@ -96,7 +96,7 @@ public class ReviewController : ControllerBase Review? newReview = await this.getReviewFromBody(); if (newReview == null) return this.BadRequest(); - if (newReview.Text.Length > 100) return this.BadRequest(); + if (newReview.Text.Length > 512) return this.BadRequest(); Review? review = await this.database.Reviews.FirstOrDefaultAsync(r => r.SlotId == slotId && r.ReviewerId == user.UserId);