diff --git a/ProjectLighthouse.Localization/BaseLayout.resx b/ProjectLighthouse.Localization/BaseLayout.resx index 6cd9c681a..65d1229f7 100644 --- a/ProjectLighthouse.Localization/BaseLayout.resx +++ b/ProjectLighthouse.Localization/BaseLayout.resx @@ -87,4 +87,10 @@ If not, please publish the source code somewhere accessible to your users. + + Read-Only Mode + + + This instance is currently in read-only mode. Level and photo uploads, comments, reviews, and certain profile changes will be restricted until read-only mode is disabled. + \ No newline at end of file diff --git a/ProjectLighthouse.Localization/StringLists/BaseLayoutStrings.cs b/ProjectLighthouse.Localization/StringLists/BaseLayoutStrings.cs index 64f390219..f46cb4e60 100644 --- a/ProjectLighthouse.Localization/StringLists/BaseLayoutStrings.cs +++ b/ProjectLighthouse.Localization/StringLists/BaseLayoutStrings.cs @@ -23,5 +23,8 @@ public static class BaseLayoutStrings public static readonly TranslatableString LicenseWarn2 = create("license_warn_2"); public static readonly TranslatableString LicenseWarn3 = create("license_warn_3"); + public static readonly TranslatableString ReadOnlyWarnTitle = create("read_only_warn_title"); + public static readonly TranslatableString ReadOnlyWarn = create("read_only_warn"); + private static TranslatableString create(string key) => new(TranslationAreas.BaseLayout, key); } \ No newline at end of file diff --git a/ProjectLighthouse.Servers.GameServer/Controllers/CommentController.cs b/ProjectLighthouse.Servers.GameServer/Controllers/CommentController.cs index 76f2b715b..a906b170b 100644 --- a/ProjectLighthouse.Servers.GameServer/Controllers/CommentController.cs +++ b/ProjectLighthouse.Servers.GameServer/Controllers/CommentController.cs @@ -119,6 +119,9 @@ public async Task PostComment(string? username, string? slotType, { GameTokenEntity token = this.GetToken(); + // Deny request if in read-only mode + if (ServerConfiguration.Instance.UserGeneratedContentLimits.ReadOnlyMode) return this.BadRequest(); + GameComment? comment = await this.DeserializeBody(); if (comment?.Message == null) return this.BadRequest(); @@ -159,6 +162,9 @@ public async Task DeleteComment([FromQuery] int commentId, string { GameTokenEntity token = this.GetToken(); + // Deny request if in read-only mode + if (ServerConfiguration.Instance.UserGeneratedContentLimits.ReadOnlyMode) return this.BadRequest(); + if ((slotId == 0 || SlotHelper.IsTypeInvalid(slotType)) == (username == null)) return this.BadRequest(); CommentEntity? comment = await this.database.Comments.FirstOrDefaultAsync(c => c.CommentId == commentId); diff --git a/ProjectLighthouse.Servers.GameServer/Controllers/MessageController.cs b/ProjectLighthouse.Servers.GameServer/Controllers/MessageController.cs index 3d3f16be9..4666366f6 100644 --- a/ProjectLighthouse.Servers.GameServer/Controllers/MessageController.cs +++ b/ProjectLighthouse.Servers.GameServer/Controllers/MessageController.cs @@ -3,6 +3,8 @@ using LBPUnion.ProjectLighthouse.Database; using LBPUnion.ProjectLighthouse.Extensions; using LBPUnion.ProjectLighthouse.Helpers; +using LBPUnion.ProjectLighthouse.Localization; +using LBPUnion.ProjectLighthouse.Localization.StringLists; using LBPUnion.ProjectLighthouse.Logging; using LBPUnion.ProjectLighthouse.Serialization; using LBPUnion.ProjectLighthouse.Types.Entities.Notifications; @@ -59,6 +61,11 @@ public async Task Announce() announceText.Replace("%user", username); announceText.Replace("%id", token.UserId.ToString()); + if (ServerConfiguration.Instance.UserGeneratedContentLimits.ReadOnlyMode) + { + announceText.Insert(0, BaseLayoutStrings.ReadOnlyWarn.Translate(LocalizationManager.DefaultLang)); + } + #if DEBUG announceText.Append("\n\n---DEBUG INFO---\n" + $"user.UserId: {token.UserId}\n" + diff --git a/ProjectLighthouse.Servers.GameServer/Controllers/Resources/PhotosController.cs b/ProjectLighthouse.Servers.GameServer/Controllers/Resources/PhotosController.cs index e79626439..4c73d0a04 100644 --- a/ProjectLighthouse.Servers.GameServer/Controllers/Resources/PhotosController.cs +++ b/ProjectLighthouse.Servers.GameServer/Controllers/Resources/PhotosController.cs @@ -37,6 +37,9 @@ public async Task UploadPhoto() { GameTokenEntity token = this.GetToken(); + // Deny request if in read-only mode + if (ServerConfiguration.Instance.UserGeneratedContentLimits.ReadOnlyMode) return this.BadRequest(); + int photoCount = await this.database.Photos.CountAsync(p => p.CreatorId == token.UserId); if (photoCount >= ServerConfiguration.Instance.UserGeneratedContentLimits.PhotosQuota) return this.BadRequest(); @@ -90,7 +93,7 @@ public async Task UploadPhoto() case SlotType.Developer: { SlotEntity? slot = await this.database.Slots.FirstOrDefaultAsync(s => s.Type == photoSlot.SlotType && s.InternalSlotId == photoSlot.SlotId); - if (slot != null) + if (slot != null) photoSlot.SlotId = slot.SlotId; else photoSlot.SlotId = await SlotHelper.GetPlaceholderSlotId(this.database, photoSlot.SlotId, photoSlot.SlotType); diff --git a/ProjectLighthouse.Servers.GameServer/Controllers/Resources/ResourcesController.cs b/ProjectLighthouse.Servers.GameServer/Controllers/Resources/ResourcesController.cs index 3c1c2f822..7231ccafb 100644 --- a/ProjectLighthouse.Servers.GameServer/Controllers/Resources/ResourcesController.cs +++ b/ProjectLighthouse.Servers.GameServer/Controllers/Resources/ResourcesController.cs @@ -1,5 +1,6 @@ #nullable enable using System.Text; +using LBPUnion.ProjectLighthouse.Configuration; using LBPUnion.ProjectLighthouse.Extensions; using LBPUnion.ProjectLighthouse.Files; using LBPUnion.ProjectLighthouse.Logging; @@ -58,10 +59,14 @@ public async Task UploadResource(string hash) string fullPath = Path.GetFullPath(path); FileHelper.EnsureDirectoryCreated(assetsDirectory); - // lbp treats code 409 as success and as an indicator that the file is already present + + // Deny request if in read-only mode + if (ServerConfiguration.Instance.UserGeneratedContentLimits.ReadOnlyMode) return this.BadRequest(); + + // LBP treats code 409 as success and as an indicator that the file is already present if (FileHelper.ResourceExists(hash)) return this.Conflict(); - // theoretically shouldn't be possible because of hash check but handle anyways + // Theoretically shouldn't be possible because of hash check but handle anyways if (!fullPath.StartsWith(FileHelper.FullResourcePath)) return this.BadRequest(); Logger.Info($"Processing resource upload (hash: {hash})", LogArea.Resources); diff --git a/ProjectLighthouse.Servers.GameServer/Controllers/Slots/PublishController.cs b/ProjectLighthouse.Servers.GameServer/Controllers/Slots/PublishController.cs index e09a06e65..7bedc01dc 100644 --- a/ProjectLighthouse.Servers.GameServer/Controllers/Slots/PublishController.cs +++ b/ProjectLighthouse.Servers.GameServer/Controllers/Slots/PublishController.cs @@ -43,6 +43,9 @@ public async Task StartPublish() UserEntity? user = await this.database.UserFromGameToken(token); if (user == null) return this.Forbid(); + // Deny request if in read-only mode + if (ServerConfiguration.Instance.UserGeneratedContentLimits.ReadOnlyMode) return this.BadRequest(); + GameUserSlot? slot = await this.DeserializeBody(); if (slot == null) { @@ -116,6 +119,9 @@ public async Task Publish([FromQuery] string? game) UserEntity? user = await this.database.UserFromGameToken(token); if (user == null) return this.Forbid(); + // Deny request if in read-only mode + if (ServerConfiguration.Instance.UserGeneratedContentLimits.ReadOnlyMode) return this.BadRequest(); + GameUserSlot? slot = await this.DeserializeBody(); if (slot == null) @@ -335,6 +341,9 @@ public async Task Unpublish(int id) { GameTokenEntity token = this.GetToken(); + // Deny request if in read-only mode + if (ServerConfiguration.Instance.UserGeneratedContentLimits.ReadOnlyMode) return this.BadRequest(); + SlotEntity? slot = await this.database.Slots.FirstOrDefaultAsync(s => s.SlotId == id); if (slot == null) return this.NotFound(); diff --git a/ProjectLighthouse.Servers.GameServer/Controllers/Slots/ReviewController.cs b/ProjectLighthouse.Servers.GameServer/Controllers/Slots/ReviewController.cs index aa4e1c5b9..7feae4bf4 100644 --- a/ProjectLighthouse.Servers.GameServer/Controllers/Slots/ReviewController.cs +++ b/ProjectLighthouse.Servers.GameServer/Controllers/Slots/ReviewController.cs @@ -1,4 +1,5 @@ #nullable enable +using LBPUnion.ProjectLighthouse.Configuration; using LBPUnion.ProjectLighthouse.Database; using LBPUnion.ProjectLighthouse.Extensions; using LBPUnion.ProjectLighthouse.Helpers; @@ -92,6 +93,9 @@ public async Task PostReview(int slotId) { GameTokenEntity token = this.GetToken(); + // Deny request if in read-only mode + if (ServerConfiguration.Instance.UserGeneratedContentLimits.ReadOnlyMode) return this.BadRequest(); + GameReview? newReview = await this.DeserializeBody(); if (newReview == null) return this.BadRequest(); @@ -115,7 +119,7 @@ public async Task PostReview(int slotId) } review.Thumb = Math.Clamp(newReview.Thumb, -1, 1); review.LabelCollection = LabelHelper.RemoveInvalidLabels(newReview.LabelCollection); - + review.Text = newReview.Text; review.Deleted = false; review.Timestamp = TimeHelper.TimestampMillis; @@ -239,6 +243,9 @@ public async Task DeleteReview(int slotId, string username) { GameTokenEntity token = this.GetToken(); + // Deny request if in read-only mode + if (ServerConfiguration.Instance.UserGeneratedContentLimits.ReadOnlyMode) return this.BadRequest(); + int creatorId = await this.database.Slots.Where(s => s.SlotId == slotId).Select(s => s.CreatorId).FirstOrDefaultAsync(); if (creatorId == 0) return this.BadRequest(); diff --git a/ProjectLighthouse.Servers.GameServer/Controllers/UserController.cs b/ProjectLighthouse.Servers.GameServer/Controllers/UserController.cs index fb5b6128f..cbed989be 100644 --- a/ProjectLighthouse.Servers.GameServer/Controllers/UserController.cs +++ b/ProjectLighthouse.Servers.GameServer/Controllers/UserController.cs @@ -1,4 +1,5 @@ using System.Text.Json; +using LBPUnion.ProjectLighthouse.Configuration; using LBPUnion.ProjectLighthouse.Database; using LBPUnion.ProjectLighthouse.Extensions; using LBPUnion.ProjectLighthouse.Files; @@ -73,6 +74,9 @@ public async Task UpdateUser() if (update.Biography != null) { + // Deny request if in read-only mode + if (ServerConfiguration.Instance.UserGeneratedContentLimits.ReadOnlyMode) return this.BadRequest(); + if (update.Biography.Length > 512) return this.BadRequest(); user.Biography = update.Biography; @@ -85,6 +89,9 @@ public async Task UpdateUser() { if (string.IsNullOrWhiteSpace(resource)) continue; + // Deny request if in read-only mode + if (ServerConfiguration.Instance.UserGeneratedContentLimits.ReadOnlyMode) return this.BadRequest(); + if (!FileHelper.ResourceExists(resource) && !resource.StartsWith('g')) return this.BadRequest(); if (!GameResourceHelper.IsValidTexture(resource)) return this.BadRequest(); diff --git a/ProjectLighthouse.Servers.Website/Controllers/SlotPageController.cs b/ProjectLighthouse.Servers.Website/Controllers/SlotPageController.cs index 66eafbc08..7f22b0b6b 100644 --- a/ProjectLighthouse.Servers.Website/Controllers/SlotPageController.cs +++ b/ProjectLighthouse.Servers.Website/Controllers/SlotPageController.cs @@ -10,7 +10,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; -// I would like to apologize in advance for anyone dealing with this file. +// I would like to apologize in advance for anyone dealing with this file. // Theres probably a better way to do this with delegates but I'm tired. // TODO: Clean up this file // - jvyden @@ -63,6 +63,9 @@ public async Task PostComment([FromRoute] int id, [FromForm] stri WebTokenEntity? token = this.database.WebTokenFromRequest(this.Request); if (token == null) return this.Redirect("~/login"); + // Deny request if in read-only mode + if (ServerConfiguration.Instance.UserGeneratedContentLimits.ReadOnlyMode) return this.Redirect("~/slot/" + id); + if (msg == null) { Logger.Error($"Refusing to post comment from {token.UserId} on level {id}, {nameof(msg)} is null", LogArea.Comments); diff --git a/ProjectLighthouse.Servers.Website/Controllers/UserPageController.cs b/ProjectLighthouse.Servers.Website/Controllers/UserPageController.cs index 161bb1a87..afd23458d 100644 --- a/ProjectLighthouse.Servers.Website/Controllers/UserPageController.cs +++ b/ProjectLighthouse.Servers.Website/Controllers/UserPageController.cs @@ -39,6 +39,9 @@ public async Task PostComment([FromRoute] int id, [FromForm] stri WebTokenEntity? token = this.database.WebTokenFromRequest(this.Request); if (token == null) return this.Redirect("~/login"); + // Deny request if in read-only mode + if (ServerConfiguration.Instance.UserGeneratedContentLimits.ReadOnlyMode) return this.Redirect("~/user/" + id); + if (msg == null) { Logger.Error($"Refusing to post comment from {token.UserId} on user {id}, {nameof(msg)} is null", LogArea.Comments); diff --git a/ProjectLighthouse.Servers.Website/Pages/LandingPage.cshtml b/ProjectLighthouse.Servers.Website/Pages/LandingPage.cshtml index 903dbf0cb..9f9ba991e 100644 --- a/ProjectLighthouse.Servers.Website/Pages/LandingPage.cshtml +++ b/ProjectLighthouse.Servers.Website/Pages/LandingPage.cshtml @@ -60,7 +60,42 @@ } } -

+@if (Model.LatestAnnouncement != null) +{ +
+
+

@Model.LatestAnnouncement.Title

+
+ @if (Model.LatestAnnouncement.Content.Length > 250) + { + + @Model.LatestAnnouncement.Content[..250]... + read more + + } + else + { + + @Model.LatestAnnouncement.Content + + } +
+ @if (Model.LatestAnnouncement.Publisher != null) + { + + } +
+
+} +else +{ +

+}
diff --git a/ProjectLighthouse.Servers.Website/Pages/LandingPage.cshtml.cs b/ProjectLighthouse.Servers.Website/Pages/LandingPage.cshtml.cs index f866557b3..37edf44bd 100644 --- a/ProjectLighthouse.Servers.Website/Pages/LandingPage.cshtml.cs +++ b/ProjectLighthouse.Servers.Website/Pages/LandingPage.cshtml.cs @@ -5,6 +5,7 @@ using LBPUnion.ProjectLighthouse.Servers.Website.Pages.Layouts; using LBPUnion.ProjectLighthouse.Types.Entities.Level; using LBPUnion.ProjectLighthouse.Types.Entities.Profile; +using LBPUnion.ProjectLighthouse.Types.Entities.Website; using LBPUnion.ProjectLighthouse.Types.Levels; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; @@ -19,6 +20,8 @@ public class LandingPage : BaseLayout public int PendingAuthAttempts; public List PlayersOnline = new(); + public WebsiteAnnouncementEntity? LatestAnnouncement; + public LandingPage(DatabaseContext database) : base(database) { } @@ -54,6 +57,10 @@ public async Task OnGet() .Include(s => s.Creator) .ToListAsync(); + this.LatestAnnouncement = await this.Database.WebsiteAnnouncements.Include(a => a.Publisher) + .OrderByDescending(a => a.AnnouncementId) + .FirstOrDefaultAsync(); + return this.Page(); } } \ No newline at end of file diff --git a/ProjectLighthouse.Servers.Website/Pages/Layouts/BaseLayout.cshtml b/ProjectLighthouse.Servers.Website/Pages/Layouts/BaseLayout.cshtml index 5de98aa34..14f147822 100644 --- a/ProjectLighthouse.Servers.Website/Pages/Layouts/BaseLayout.cshtml +++ b/ProjectLighthouse.Servers.Website/Pages/Layouts/BaseLayout.cshtml @@ -178,6 +178,18 @@
} + @if (ServerConfiguration.Instance.UserGeneratedContentLimits.ReadOnlyMode) + { +
+
+ + @Model.Translate(BaseLayoutStrings.ReadOnlyWarnTitle) +

+ @Html.Raw(Model.Translate(BaseLayoutStrings.ReadOnlyWarn)) +

+
+
+ }
diff --git a/ProjectLighthouse.Servers.Website/Pages/Partials/CommentsPartial.cshtml b/ProjectLighthouse.Servers.Website/Pages/Partials/CommentsPartial.cshtml index 4a2a98691..cbab2fdbb 100644 --- a/ProjectLighthouse.Servers.Website/Pages/Partials/CommentsPartial.cshtml +++ b/ProjectLighthouse.Servers.Website/Pages/Partials/CommentsPartial.cshtml @@ -1,4 +1,5 @@ @using System.Web +@using LBPUnion.ProjectLighthouse.Configuration @using LBPUnion.ProjectLighthouse.Database @using LBPUnion.ProjectLighthouse.Localization @using LBPUnion.ProjectLighthouse.Servers.Website.Extensions @@ -31,18 +32,32 @@ @if (Model.CommentsEnabled && Model.User != null) {
-
-
- + @if (ServerConfiguration.Instance.UserGeneratedContentLimits.ReadOnlyMode) + { +
+

+ + @ServerConfiguration.Instance.Customization.ServerName is currently in read-only mode. + You will not be able to post comments until read-only mode is disabled. + +

- - + } + else + { +
+
+ +
+ +
+ } @if (Model.Comments.Count > 0) {
} } - + @{ int i = 0; foreach (KeyValuePair commentAndReaction in Model.Comments) diff --git a/ProjectLighthouse.Servers.Website/Pages/Partials/ReviewPartial.cshtml b/ProjectLighthouse.Servers.Website/Pages/Partials/ReviewPartial.cshtml index 610342658..f8c16a5ff 100644 --- a/ProjectLighthouse.Servers.Website/Pages/Partials/ReviewPartial.cshtml +++ b/ProjectLighthouse.Servers.Website/Pages/Partials/ReviewPartial.cshtml @@ -4,7 +4,6 @@ @using LBPUnion.ProjectLighthouse.Helpers @using LBPUnion.ProjectLighthouse.Types.Entities.Level @using LBPUnion.ProjectLighthouse.Types.Serialization - @{ bool isMobile = (bool?)ViewData["IsMobile"] ?? false; bool canDelete = (bool?)ViewData["CanDelete"] ?? false; @@ -29,6 +28,18 @@
} + @if (ServerConfiguration.Instance.UserGeneratedContentLimits.ReadOnlyMode) + { +
+

+ + @ServerConfiguration.Instance.Customization.ServerName is currently in read-only mode. + You will not be able to post reviews in-game until read-only mode is disabled. + +

+
+ } + @for(int i = 0; i < Model.Reviews.Count; i++) { ReviewEntity review = Model.Reviews[i]; @@ -36,7 +47,7 @@ -1 => review.Reviewer?.BooHash, 0 => review.Reviewer?.MehHash, 1 => review.Reviewer?.YayHash, - + _ => throw new ArgumentOutOfRangeException(), }) ?? ""; @@ -49,7 +60,7 @@ -1 => "Boo!", 0 => "Meh.", 1 => "Yay!", - + _ => throw new ArgumentOutOfRangeException(), }; @@ -114,7 +125,7 @@ if (window.confirm("Are you sure you want to delete this?\nThis action cannot be undone.")){ window.location.hash = "reviews"; window.location.href = "/moderation/deleteReview/" + reviewId + "?callbackUrl=" + this.window.location; - } + } }
diff --git a/ProjectLighthouse.Servers.Website/Pages/SlotSettingsPage.cshtml.cs b/ProjectLighthouse.Servers.Website/Pages/SlotSettingsPage.cshtml.cs index 310386e76..b461d9825 100644 --- a/ProjectLighthouse.Servers.Website/Pages/SlotSettingsPage.cshtml.cs +++ b/ProjectLighthouse.Servers.Website/Pages/SlotSettingsPage.cshtml.cs @@ -1,4 +1,5 @@ #nullable enable +using LBPUnion.ProjectLighthouse.Configuration; using LBPUnion.ProjectLighthouse.Database; using LBPUnion.ProjectLighthouse.Files; using LBPUnion.ProjectLighthouse.Helpers; @@ -25,6 +26,10 @@ public async Task OnPost([FromRoute] int slotId, [FromForm] strin if (!this.User.IsModerator && this.User != this.Slot.Creator) return this.Redirect("~/slot/" + slotId); + // Deny request if in read-only mode + if (ServerConfiguration.Instance.UserGeneratedContentLimits.ReadOnlyMode) + return this.Redirect($"~/slot/{slotId}"); + string? avatarHash = await FileHelper.ParseBase64Image(avatar); if (avatarHash != null) this.Slot.IconHash = avatarHash; @@ -46,7 +51,7 @@ public async Task OnPost([FromRoute] int slotId, [FromForm] strin if (labels != null) { labels = LabelHelper.RemoveInvalidLabels(labels); - if (this.Slot.AuthorLabels != labels) + if (this.Slot.AuthorLabels != labels) this.Slot.AuthorLabels = labels; } diff --git a/ProjectLighthouse.Servers.Website/Pages/UserSettingsPage.cshtml.cs b/ProjectLighthouse.Servers.Website/Pages/UserSettingsPage.cshtml.cs index 066ca973b..85b0c242f 100644 --- a/ProjectLighthouse.Servers.Website/Pages/UserSettingsPage.cshtml.cs +++ b/ProjectLighthouse.Servers.Website/Pages/UserSettingsPage.cshtml.cs @@ -39,6 +39,10 @@ [FromForm] string? language if (!this.User.IsModerator && this.User != this.ProfileUser) return this.Redirect("~/user/" + userId); + // Deny request if in read-only mode + if (avatar != null && ServerConfiguration.Instance.UserGeneratedContentLimits.ReadOnlyMode) + return this.Redirect($"~/user/{userId}"); + string? avatarHash = await FileHelper.ParseBase64Image(avatar); if (avatarHash != null) this.ProfileUser.IconHash = avatarHash; @@ -47,6 +51,10 @@ [FromForm] string? language if (biography != null) { + // Deny request if in read-only mode + if (ServerConfiguration.Instance.UserGeneratedContentLimits.ReadOnlyMode) + return this.Redirect($"~/user/{userId}"); + biography = CensorHelper.FilterMessage(biography); if (this.ProfileUser.Biography != biography && biography.Length <= 512) this.ProfileUser.Biography = biography; diff --git a/ProjectLighthouse/Configuration/ConfigurationCategories/UserGeneratedContentLimitConfiguration.cs b/ProjectLighthouse/Configuration/ConfigurationCategories/UserGeneratedContentLimitConfiguration.cs index 6430b7541..f725c2788 100644 --- a/ProjectLighthouse/Configuration/ConfigurationCategories/UserGeneratedContentLimitConfiguration.cs +++ b/ProjectLighthouse/Configuration/ConfigurationCategories/UserGeneratedContentLimitConfiguration.cs @@ -11,6 +11,12 @@ public class UserGeneratedContentLimitConfiguration public int PhotosQuota { get; set; } = 500; + /// + /// When enabled, all UGC uploads are disabled. This includes levels, photos, reviews, + /// comments, and certain profile settings. + /// + public bool ReadOnlyMode { get; set; } = false; + public bool ProfileCommentsEnabled { get; set; } = true; public bool LevelCommentsEnabled { get; set; } = true; diff --git a/ProjectLighthouse/Configuration/ServerConfiguration.cs b/ProjectLighthouse/Configuration/ServerConfiguration.cs index 7258804e0..30c7c89be 100644 --- a/ProjectLighthouse/Configuration/ServerConfiguration.cs +++ b/ProjectLighthouse/Configuration/ServerConfiguration.cs @@ -11,7 +11,7 @@ public class ServerConfiguration : ConfigurationBase // This is so Lighthouse can properly identify outdated configurations and update them with newer settings accordingly. // If you are modifying anything here, this value MUST be incremented. // Thanks for listening~ - public override int ConfigVersion { get; set; } = 25; + public override int ConfigVersion { get; set; } = 26; public override string ConfigName { get; set; } = "lighthouse.yml"; public string WebsiteListenUrl { get; set; } = "http://localhost:10060";