Implement checking for the Patchwork user agent, move logout into standalone method

This commit is contained in:
FeTetra 2025-05-25 20:10:26 -04:00
parent df7ebf977a
commit 68dbf50253
7 changed files with 72 additions and 8 deletions

View file

@ -214,7 +214,11 @@ public class LoginController : ControllerBase
Logger.Success($"Successfully logged in user {user.Username} as {token.GameVersion} client", LogArea.Login);
user.LastLogin = TimeHelper.TimestampMillis;
string userAgent = this.Request.Headers.UserAgent.ToString();
if (!String.IsNullOrWhiteSpace(userAgent))
{
user.UserAgent = userAgent;
}
await database.SaveChangesAsync();

View file

@ -1,6 +1,6 @@
using LBPUnion.ProjectLighthouse.Database;
using LBPUnion.ProjectLighthouse.Extensions;
using LBPUnion.ProjectLighthouse.Helpers;
using LBPUnion.ProjectLighthouse.Servers.GameServer.Helpers;
using LBPUnion.ProjectLighthouse.Types.Entities.Profile;
using LBPUnion.ProjectLighthouse.Types.Entities.Token;
using Microsoft.AspNetCore.Authorization;
@ -30,10 +30,7 @@ public class LogoutController : ControllerBase
UserEntity? user = await this.database.UserFromGameToken(token);
if (user == null) return this.Forbid();
user.LastLogout = TimeHelper.TimestampMillis;
await this.database.GameTokens.RemoveWhere(t => t.TokenId == token.TokenId);
await this.database.LastContacts.RemoveWhere(c => c.UserId == token.UserId);
await LogoutHelper.Logout(token, user, database);
return this.Ok();
}

View file

@ -1,4 +1,5 @@
using System.Text;
using System.Globalization;
using System.Text;
using LBPUnion.ProjectLighthouse.Configuration;
using LBPUnion.ProjectLighthouse.Database;
using LBPUnion.ProjectLighthouse.Extensions;
@ -7,6 +8,7 @@ using LBPUnion.ProjectLighthouse.Localization;
using LBPUnion.ProjectLighthouse.Localization.StringLists;
using LBPUnion.ProjectLighthouse.Logging;
using LBPUnion.ProjectLighthouse.Serialization;
using LBPUnion.ProjectLighthouse.Servers.GameServer.Helpers;
using LBPUnion.ProjectLighthouse.Types.Entities.Notifications;
using LBPUnion.ProjectLighthouse.Types.Entities.Profile;
using LBPUnion.ProjectLighthouse.Types.Entities.Token;
@ -54,6 +56,10 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.";
public async Task<IActionResult> Announce()
{
GameTokenEntity token = this.GetToken();
UserEntity? user = await this.database.UserFromGameToken(token);
if (user == null)
return this.Forbid();
string username = await this.database.UsernameFromGameToken(token);
@ -67,6 +73,18 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.";
announceText.Insert(0, BaseLayoutStrings.ReadOnlyWarn.Translate(LocalizationManager.DefaultLang) + "\n\n");
}
if (ServerConfiguration.Instance.RequirePatchworkUserAgent)
{
announceText.Append("This server instance requires the use of the Patchwork plugin for LBP.\n\n");
if (PatchworkHelper.userHasValidPatchworkUserAgent(user.UserAgent))
{
announceText.Append("It appears you do not have the Patchwork plugin installed correctly." +
"Since this server instance requires it, you will not be able to play until you so.");
}
await LogoutHelper.Logout(token, user, database);
}
#if DEBUG
announceText.Append("\n\n---DEBUG INFO---\n" +
$"user.UserId: {token.UserId}\n" +

View file

@ -0,0 +1,18 @@
using LBPUnion.ProjectLighthouse.Helpers;
using LBPUnion.ProjectLighthouse.Database;
using LBPUnion.ProjectLighthouse.Extensions;
using LBPUnion.ProjectLighthouse.Types.Entities.Token;
using LBPUnion.ProjectLighthouse.Types.Entities.Profile;
namespace LBPUnion.ProjectLighthouse.Servers.GameServer.Helpers;
public class LogoutHelper
{
public static async Task Logout(GameTokenEntity token, UserEntity user, DatabaseContext database)
{
user.LastLogout = TimeHelper.TimestampMillis;
await database.GameTokens.RemoveWhere(t => t.TokenId == token.TokenId);
await database.LastContacts.RemoveWhere(c => c.UserId == token.UserId);
}
}

View file

@ -0,0 +1,20 @@
using LBPUnion.ProjectLighthouse.Configuration;
namespace LBPUnion.ProjectLighthouse.Servers.GameServer.Helpers;
public static class PatchworkHelper
{
static int patchworkMajorVer = ServerConfiguration.Instance.PatchworkMajorVersionMinimum;
static int patchworkMinorVer = ServerConfiguration.Instance.PatchworkMinorVersionMinimum;
public static bool userHasValidPatchworkUserAgent(string userAgent)
{
if (userAgent.StartsWith("PatchworkLBP"))
return false;
string[] patchworkVer = userAgent.Split(' ')[1].Split('.');
if (int.Parse(patchworkVer[0]) >= patchworkMajorVer && int.Parse(patchworkVer[1]) >= patchworkMinorVer)
return true;
return false;
}
}

View file

@ -11,7 +11,7 @@ public class ServerConfiguration : ConfigurationBase<ServerConfiguration>
// 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; } = 27;
public override int ConfigVersion { get; set; } = 28;
public override string ConfigName { get; set; } = "lighthouse.yml";
public string WebsiteListenUrl { get; set; } = "http://localhost:10060";
@ -32,6 +32,11 @@ public class ServerConfiguration : ConfigurationBase<ServerConfiguration>
public bool LogChatFiltering { get; set; } = false;
public bool LogChatMessages { get; set; } = false;
// Require use of Zaprit's "Patchwork" prx plugin's user agent when connecting to the server
// Major and minor version minimums can be left alone if patchwork is not required
public bool RequirePatchworkUserAgent { get; set; } = false;
public int PatchworkMajorVersionMinimum { get; set; } = 0;
public int PatchworkMinorVersionMinimum { get; set; } = 0;
public AuthenticationConfiguration Authentication { get; set; } = new();
public CaptchaConfiguration Captcha { get; set; } = new();
public DigestKeyConfiguration DigestKey { get; set; } = new();

View file

@ -28,6 +28,8 @@ public class UserEntity
public string IconHash { get; set; }
public string UserAgent { get; set;}
/// <summary>
/// Markup that displays the username next to a polaroid with the user's icon.
/// This can be used everywhere markup works ingame, e.g. news or notifications