From 44dbab3848c8831d27e50f7252d759a2494ad556 Mon Sep 17 00:00:00 2001 From: MutantAura <44103205+MutantAura@users.noreply.github.com> Date: Tue, 14 May 2024 15:36:44 +0100 Subject: [PATCH] discordRPC: Truncate game title and details if they exceed discord byte limit. (#6581) * Truncate game title and details if they exceed DiscordRPC limit. * Update implementation to a byte total check. * Track if the string has actually been modified correctly. * Allow an early function return and simplify logic. * Better handling of large input strings and minimise loop opportunities. * Remove unused using. * Update to `applicationName` over `titleName`. --- .../DiscordIntegrationModule.cs | 32 +++++++++++++++++-- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/src/Ryujinx.UI.Common/DiscordIntegrationModule.cs b/src/Ryujinx.UI.Common/DiscordIntegrationModule.cs index bbece1e1d5..fb07195d08 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,6 +10,9 @@ namespace Ryujinx.UI.Common private const string Description = "A simple, experimental Nintendo Switch emulator."; private const string ApplicationId = "1216775165866807456"; + private const int ApplicationByteLimit = 128; + private const string Ellipsis = "…"; + private static DiscordRpcClient _discordClient; private static RichPresence _discordPresenceMain; @@ -60,18 +64,18 @@ namespace Ryujinx.UI.Common } } - public static void SwitchToPlayingState(string titleId, string titleName) + public static void SwitchToPlayingState(string titleId, string applicationName) { _discordClient?.SetPresence(new RichPresence { Assets = new Assets { LargeImageKey = "game", - LargeImageText = titleName, + LargeImageText = TruncateToByteLength(applicationName, ApplicationByteLimit), SmallImageKey = "ryujinx", SmallImageText = Description, }, - Details = $"Playing {titleName}", + Details = TruncateToByteLength($"Playing {applicationName}", ApplicationByteLimit), State = (titleId == "0000000000000000") ? "Homebrew" : titleId.ToUpper(), Timestamps = Timestamps.Now, Buttons = @@ -90,6 +94,28 @@ namespace Ryujinx.UI.Common _discordClient?.SetPresence(_discordPresenceMain); } + private static string TruncateToByteLength(string input, int byteLimit) + { + if (Encoding.UTF8.GetByteCount(input) <= byteLimit) + { + return input; + } + + // Find the length to trim the string to guarantee we have space for the trailing ellipsis. + int trimLimit = byteLimit - Encoding.UTF8.GetByteCount(Ellipsis); + + // Basic trim to best case scenario of 1 byte characters. + input = input[..trimLimit]; + + while (Encoding.UTF8.GetByteCount(input) > trimLimit) + { + // Remove one character from the end of the string at a time. + input = input[..^1]; + } + + return input.TrimEnd() + Ellipsis; + } + public static void Exit() { _discordClient?.Dispose();