From 55b8cf6e3c80f6fd9caeef12f1be4e71e54f0e74 Mon Sep 17 00:00:00 2001 From: MutantAura Date: Sat, 30 Mar 2024 17:39:31 +0000 Subject: [PATCH 1/4] Truncate game title and details if they exceed DiscordRPC limit. --- src/Ryujinx.UI.Common/DiscordIntegrationModule.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Ryujinx.UI.Common/DiscordIntegrationModule.cs b/src/Ryujinx.UI.Common/DiscordIntegrationModule.cs index bbece1e1d..b6c1198d6 100644 --- a/src/Ryujinx.UI.Common/DiscordIntegrationModule.cs +++ b/src/Ryujinx.UI.Common/DiscordIntegrationModule.cs @@ -9,6 +9,8 @@ namespace Ryujinx.UI.Common private const string Description = "A simple, experimental Nintendo Switch emulator."; private const string ApplicationId = "1216775165866807456"; + private const int TitleCharLimit = 128; + private static DiscordRpcClient _discordClient; private static RichPresence _discordPresenceMain; @@ -62,6 +64,10 @@ namespace Ryujinx.UI.Common public static void SwitchToPlayingState(string titleId, string titleName) { + // LargeImageText and Details must be 128 characters or less. + titleName = titleName.Length > TitleCharLimit ? titleName[..TitleCharLimit] : titleName; + string details = titleName.Length > TitleCharLimit - 8 ? titleName[..(TitleCharLimit - 8)] : titleName; + _discordClient?.SetPresence(new RichPresence { Assets = new Assets @@ -71,7 +77,7 @@ namespace Ryujinx.UI.Common SmallImageKey = "ryujinx", SmallImageText = Description, }, - Details = $"Playing {titleName}", + Details = $"Playing {details}", State = (titleId == "0000000000000000") ? "Homebrew" : titleId.ToUpper(), Timestamps = Timestamps.Now, Buttons = From 36e7f56f2bb37cf71e5722bdaca145856852ab91 Mon Sep 17 00:00:00 2001 From: MutantAura Date: Sat, 30 Mar 2024 22:33:43 +0000 Subject: [PATCH 2/4] Update implementation to a byte total check. --- .../DiscordIntegrationModule.cs | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/Ryujinx.UI.Common/DiscordIntegrationModule.cs b/src/Ryujinx.UI.Common/DiscordIntegrationModule.cs index b6c1198d6..4e95356ea 100644 --- a/src/Ryujinx.UI.Common/DiscordIntegrationModule.cs +++ b/src/Ryujinx.UI.Common/DiscordIntegrationModule.cs @@ -1,6 +1,7 @@ using DiscordRPC; using Ryujinx.Common; using Ryujinx.UI.Common.Configuration; +using System.Text; namespace Ryujinx.UI.Common { @@ -9,7 +10,7 @@ namespace Ryujinx.UI.Common private const string Description = "A simple, experimental Nintendo Switch emulator."; private const string ApplicationId = "1216775165866807456"; - private const int TitleCharLimit = 128; + private const int TitleByteLimit = 128; private static DiscordRpcClient _discordClient; private static RichPresence _discordPresenceMain; @@ -64,20 +65,16 @@ namespace Ryujinx.UI.Common public static void SwitchToPlayingState(string titleId, string titleName) { - // LargeImageText and Details must be 128 characters or less. - titleName = titleName.Length > TitleCharLimit ? titleName[..TitleCharLimit] : titleName; - string details = titleName.Length > TitleCharLimit - 8 ? titleName[..(TitleCharLimit - 8)] : titleName; - _discordClient?.SetPresence(new RichPresence { Assets = new Assets { LargeImageKey = "game", - LargeImageText = titleName, + LargeImageText = TruncateToByteLength(titleName, TitleByteLimit), SmallImageKey = "ryujinx", SmallImageText = Description, }, - Details = $"Playing {details}", + Details = TruncateToByteLength($"Playing {titleName}", TitleByteLimit), State = (titleId == "0000000000000000") ? "Homebrew" : titleId.ToUpper(), Timestamps = Timestamps.Now, Buttons = @@ -96,6 +93,22 @@ namespace Ryujinx.UI.Common _discordClient?.SetPresence(_discordPresenceMain); } + private static string TruncateToByteLength(string input, int byteLimit) + { + string trimmed = input; + + while (Encoding.UTF8.GetByteCount(trimmed) > byteLimit) + { + // Remove one character from the end of the string at a time. + trimmed = trimmed[..^1]; + } + + // Remove another 3 characters to make sure we have room for "…". + trimmed = trimmed[..^3].TrimEnd() + "…"; + + return trimmed == input ? input : trimmed; + } + public static void Exit() { _discordClient?.Dispose(); From c38156732888c90abd446b7896fc6916d7c40a6c Mon Sep 17 00:00:00 2001 From: MutantAura Date: Sat, 30 Mar 2024 22:42:48 +0000 Subject: [PATCH 3/4] Track if the string has actually been modified correctly. --- src/Ryujinx.UI.Common/DiscordIntegrationModule.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Ryujinx.UI.Common/DiscordIntegrationModule.cs b/src/Ryujinx.UI.Common/DiscordIntegrationModule.cs index 4e95356ea..29a40ad6a 100644 --- a/src/Ryujinx.UI.Common/DiscordIntegrationModule.cs +++ b/src/Ryujinx.UI.Common/DiscordIntegrationModule.cs @@ -95,18 +95,21 @@ namespace Ryujinx.UI.Common private static string TruncateToByteLength(string input, int byteLimit) { + bool isModified = false; string trimmed = input; while (Encoding.UTF8.GetByteCount(trimmed) > byteLimit) { // Remove one character from the end of the string at a time. trimmed = trimmed[..^1]; + + isModified = true; } // Remove another 3 characters to make sure we have room for "…". trimmed = trimmed[..^3].TrimEnd() + "…"; - return trimmed == input ? input : trimmed; + return isModified ? trimmed : input; } public static void Exit() From a1646ff551a9d2e62cc095fe67ac73ac23bd464e Mon Sep 17 00:00:00 2001 From: MutantAura Date: Sat, 30 Mar 2024 22:47:26 +0000 Subject: [PATCH 4/4] Allow an early function return and simplify logic. --- src/Ryujinx.UI.Common/DiscordIntegrationModule.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Ryujinx.UI.Common/DiscordIntegrationModule.cs b/src/Ryujinx.UI.Common/DiscordIntegrationModule.cs index 29a40ad6a..7376f3b6d 100644 --- a/src/Ryujinx.UI.Common/DiscordIntegrationModule.cs +++ b/src/Ryujinx.UI.Common/DiscordIntegrationModule.cs @@ -95,21 +95,23 @@ namespace Ryujinx.UI.Common private static string TruncateToByteLength(string input, int byteLimit) { - bool isModified = false; + if (Encoding.UTF8.GetByteCount(input) <= byteLimit) + { + return input; + } + string trimmed = input; while (Encoding.UTF8.GetByteCount(trimmed) > byteLimit) { // Remove one character from the end of the string at a time. trimmed = trimmed[..^1]; - - isModified = true; } // Remove another 3 characters to make sure we have room for "…". trimmed = trimmed[..^3].TrimEnd() + "…"; - return isModified ? trimmed : input; + return trimmed; } public static void Exit()