Просмотр исходного кода

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`.
MutantAura 1 год назад
Родитель
Сommit
44dbab3848
1 измененных файлов с 29 добавлено и 3 удалено
  1. 29 3
      src/Ryujinx.UI.Common/DiscordIntegrationModule.cs

+ 29 - 3
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();