diff --git a/ProjectLighthouse.Servers.GameServer/Controllers/Login/LoginController.cs b/ProjectLighthouse.Servers.GameServer/Controllers/Login/LoginController.cs
index 077f1b00..827f9384 100644
--- a/ProjectLighthouse.Servers.GameServer/Controllers/Login/LoginController.cs
+++ b/ProjectLighthouse.Servers.GameServer/Controllers/Login/LoginController.cs
@@ -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();
diff --git a/ProjectLighthouse.Servers.GameServer/Controllers/Login/LogoutController.cs b/ProjectLighthouse.Servers.GameServer/Controllers/Login/LogoutController.cs
index 89140f71..2003dc6a 100644
--- a/ProjectLighthouse.Servers.GameServer/Controllers/Login/LogoutController.cs
+++ b/ProjectLighthouse.Servers.GameServer/Controllers/Login/LogoutController.cs
@@ -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();
}
diff --git a/ProjectLighthouse.Servers.GameServer/Controllers/MessageController.cs b/ProjectLighthouse.Servers.GameServer/Controllers/MessageController.cs
index 42b1d1b7..ec7dfaa9 100644
--- a/ProjectLighthouse.Servers.GameServer/Controllers/MessageController.cs
+++ b/ProjectLighthouse.Servers.GameServer/Controllers/MessageController.cs
@@ -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 .";
public async Task 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 .";
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" +
diff --git a/ProjectLighthouse.Servers.GameServer/Helpers/LogoutHelper.cs b/ProjectLighthouse.Servers.GameServer/Helpers/LogoutHelper.cs
new file mode 100644
index 00000000..545aef94
--- /dev/null
+++ b/ProjectLighthouse.Servers.GameServer/Helpers/LogoutHelper.cs
@@ -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);
+ }
+}
\ No newline at end of file
diff --git a/ProjectLighthouse.Servers.GameServer/Helpers/PatchworkHelper.cs b/ProjectLighthouse.Servers.GameServer/Helpers/PatchworkHelper.cs
new file mode 100644
index 00000000..3438cade
--- /dev/null
+++ b/ProjectLighthouse.Servers.GameServer/Helpers/PatchworkHelper.cs
@@ -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;
+ }
+}
\ No newline at end of file
diff --git a/ProjectLighthouse/Configuration/ServerConfiguration.cs b/ProjectLighthouse/Configuration/ServerConfiguration.cs
index ba9f7f4a..382c9d47 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; } = 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
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();
diff --git a/ProjectLighthouse/Types/Entities/Profile/UserEntity.cs b/ProjectLighthouse/Types/Entities/Profile/UserEntity.cs
index 6fb65301..c1615705 100644
--- a/ProjectLighthouse/Types/Entities/Profile/UserEntity.cs
+++ b/ProjectLighthouse/Types/Entities/Profile/UserEntity.cs
@@ -28,6 +28,8 @@ public class UserEntity
public string IconHash { get; set; }
+ public string UserAgent { get; set;}
+
///
/// 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