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