Explorar o código

UI: The argument to Play Report value formatters is now a struct containing the current ApplicationMetadata & the BoxedValue that was the only argument previously.

This allows for the title of Mario Kart to be localized when one of the value checkers doesn't match.
Evan Husted hai 1 ano
pai
achega
fe43c32e60

+ 0 - 80
src/Ryujinx.Common/Helpers/PlayReportAnalyzer.cs

@@ -1,80 +0,0 @@
-using Gommon;
-using MsgPack;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace Ryujinx.Common.Helper
-{
-    public class PlayReportAnalyzer
-    {
-        private readonly List<PlayReportGameSpec> _specs = [];
-
-        public PlayReportAnalyzer AddSpec(string titleId, Func<PlayReportGameSpec, PlayReportGameSpec> transform)
-        {
-            _specs.Add(transform(new PlayReportGameSpec { TitleIdStr = titleId }));
-            return this;
-        }
-        
-        public PlayReportAnalyzer AddSpec(string titleId, Action<PlayReportGameSpec> transform)
-        {
-            _specs.Add(new PlayReportGameSpec { TitleIdStr = titleId }.Apply(transform));
-            return this;
-        }
-
-        public Optional<string> Run(string runningGameId, MessagePackObject playReport)
-        {
-            if (!playReport.IsDictionary) 
-                return Optional<string>.None;
-
-            if (!_specs.TryGetFirst(s => s.TitleIdStr.EqualsIgnoreCase(runningGameId), out PlayReportGameSpec spec))
-                return Optional<string>.None;
-
-            foreach (PlayReportValueFormatterSpec formatSpec in spec.Analyses.OrderBy(x => x.Priority))
-            {
-                if (!playReport.AsDictionary().TryGetValue(formatSpec.ReportKey, out MessagePackObject valuePackObject))
-                    continue;
-
-                return formatSpec.ValueFormatter(valuePackObject.ToObject());
-            }
-            
-            return Optional<string>.None;
-        }
-        
-    }
-
-    public class PlayReportGameSpec
-    {
-        public required string TitleIdStr { get; init; }
-        public List<PlayReportValueFormatterSpec> Analyses { get; } = [];
-
-        public PlayReportGameSpec AddValueFormatter(string reportKey, Func<object, string> valueFormatter)
-        {
-            Analyses.Add(new PlayReportValueFormatterSpec
-            {
-                Priority = Analyses.Count,
-                ReportKey = reportKey, 
-                ValueFormatter = valueFormatter
-            });
-            return this;
-        }
-        
-        public PlayReportGameSpec AddValueFormatter(int priority, string reportKey, Func<object, string> valueFormatter)
-        {
-            Analyses.Add(new PlayReportValueFormatterSpec
-            {
-                Priority = priority,
-                ReportKey = reportKey, 
-                ValueFormatter = valueFormatter
-            });
-            return this;
-        }
-    }
-
-    public struct PlayReportValueFormatterSpec
-    {
-        public required int Priority { get; init; }
-        public required string ReportKey { get; init; }
-        public required Func<object, string> ValueFormatter { get; init; }
-    }
-}

+ 4 - 1
src/Ryujinx/DiscordIntegrationModule.cs

@@ -39,6 +39,7 @@ namespace Ryujinx.Ava
         private static DiscordRpcClient _discordClient;
         private static RichPresence _discordPresenceMain;
         private static RichPresence _discordPresencePlaying;
+        private static ApplicationMetadata _currentApp;
 
         public static void Initialize()
         {
@@ -113,6 +114,7 @@ namespace Ryujinx.Ava
         private static void SwitchToPlayingState(ApplicationMetadata appMeta, ProcessResult procRes)
         {
             _discordClient?.SetPresence(_discordPresencePlaying ??= CreatePlayingState(appMeta, procRes));
+            _currentApp = appMeta;
         }
 
         private static void UpdatePlayingState()
@@ -124,6 +126,7 @@ namespace Ryujinx.Ava
         {
             _discordClient?.SetPresence(_discordPresenceMain);
             _discordPresencePlaying = null;
+            _currentApp = null;
         }
 
         private static void HandlePlayReport(MessagePackObject playReport)
@@ -131,7 +134,7 @@ namespace Ryujinx.Ava
             if (!TitleIDs.CurrentApplication.Value.HasValue) return;
             if (_discordPresencePlaying is null) return;
 
-            Optional<string> details = PlayReport.Analyzer.Run(TitleIDs.CurrentApplication.Value, playReport);
+            Optional<string> details = PlayReport.Analyzer.Run(TitleIDs.CurrentApplication.Value, _currentApp, playReport);
 
             if (!details.HasValue) return;
             

+ 108 - 13
src/Ryujinx/Utilities/PlayReport.cs

@@ -1,4 +1,10 @@
-using Ryujinx.Common.Helper;
+using Gommon;
+using MsgPack;
+using Ryujinx.Ava.Utilities.AppLibrary;
+using Ryujinx.Common.Helper;
+using System;
+using System.Collections.Generic;
+using System.Linq;
 
 namespace Ryujinx.Ava.Utilities
 {
@@ -32,20 +38,20 @@ namespace Ryujinx.Ava.Utilities
                 spec => spec.AddValueFormatter("To", MarioKart8Deluxe_Mode)
             );
 
-        private static string BreathOfTheWild_MasterMode(object val)
-            => val is 1 ? "Playing Master Mode" : "Playing Normal Mode";
+        private static string BreathOfTheWild_MasterMode(ref PlayReportValue value)
+            => value.BoxedValue is 1 ? "Playing Master Mode" : "Playing Normal Mode";
 
-        private static string SuperMarioOdyssey_AssistMode(object val)
-            => val is 1 ? "Playing in Assist Mode" : "Playing in Regular Mode";
+        private static string SuperMarioOdyssey_AssistMode(ref PlayReportValue value)
+            => value.BoxedValue is 1 ? "Playing in Assist Mode" : "Playing in Regular Mode";
 
-        private static string SuperMarioOdysseyChina_AssistMode(object val)
-            => val is 1 ? "Playing in 帮助模式" : "Playing in 普通模式";
+        private static string SuperMarioOdysseyChina_AssistMode(ref PlayReportValue value)
+            => value.BoxedValue is 1 ? "Playing in 帮助模式" : "Playing in 普通模式";
 
-        private static string SuperMario3DWorldOrBowsersFury(object val)
-            => val is 0 ? "Playing Super Mario 3D World" : "Playing Bowser's Fury";
+        private static string SuperMario3DWorldOrBowsersFury(ref PlayReportValue value)
+            => value.BoxedValue is 0 ? "Playing Super Mario 3D World" : "Playing Bowser's Fury";
         
-        private static string MarioKart8Deluxe_Mode(object obj) 
-            => obj switch
+        private static string MarioKart8Deluxe_Mode(ref PlayReportValue value) 
+            => value.BoxedValue switch
             {
                 // Single Player
                 "Single" => "Single Player",
@@ -69,8 +75,97 @@ namespace Ryujinx.Ava.Utilities
                 "Battle" => "Battle Mode",
                 "RaceStart" => "Selecting a Course",
                 "Race" => "Racing",
-                //TODO: refactor value formatting system to pass in the name from the content archive so this can be localized properly
-                _ => "Playing Mario Kart 8 Deluxe"
+                _ => $"Playing {value.Application.Title}"
             };
     }
+
+    #region Analyzer implementation
+    
+    public class PlayReportAnalyzer
+    {
+        private readonly List<PlayReportGameSpec> _specs = [];
+
+        public PlayReportAnalyzer AddSpec(string titleId, Func<PlayReportGameSpec, PlayReportGameSpec> transform)
+        {
+            _specs.Add(transform(new PlayReportGameSpec { TitleIdStr = titleId }));
+            return this;
+        }
+        
+        public PlayReportAnalyzer AddSpec(string titleId, Action<PlayReportGameSpec> transform)
+        {
+            _specs.Add(new PlayReportGameSpec { TitleIdStr = titleId }.Apply(transform));
+            return this;
+        }
+
+        public Optional<string> Run(string runningGameId, ApplicationMetadata appMeta, MessagePackObject playReport)
+        {
+            if (!playReport.IsDictionary) 
+                return Optional<string>.None;
+
+            if (!_specs.TryGetFirst(s => s.TitleIdStr.EqualsIgnoreCase(runningGameId), out PlayReportGameSpec spec))
+                return Optional<string>.None;
+
+            foreach (PlayReportValueFormatterSpec formatSpec in spec.Analyses.OrderBy(x => x.Priority))
+            {
+                if (!playReport.AsDictionary().TryGetValue(formatSpec.ReportKey, out MessagePackObject valuePackObject))
+                    continue;
+
+                PlayReportValue value = new()
+                {
+                    Application = appMeta, 
+                    BoxedValue = valuePackObject.ToObject()
+                };
+
+                return formatSpec.ValueFormatter(ref value);
+            }
+            
+            return Optional<string>.None;
+        }
+        
+    }
+
+    public class PlayReportGameSpec
+    {
+        public required string TitleIdStr { get; init; }
+        public List<PlayReportValueFormatterSpec> Analyses { get; } = [];
+
+        public PlayReportGameSpec AddValueFormatter(string reportKey, PlayReportValueFormatter valueFormatter)
+        {
+            Analyses.Add(new PlayReportValueFormatterSpec
+            {
+                Priority = Analyses.Count,
+                ReportKey = reportKey, 
+                ValueFormatter = valueFormatter
+            });
+            return this;
+        }
+        
+        public PlayReportGameSpec AddValueFormatter(int priority, string reportKey, PlayReportValueFormatter valueFormatter)
+        {
+            Analyses.Add(new PlayReportValueFormatterSpec
+            {
+                Priority = priority,
+                ReportKey = reportKey, 
+                ValueFormatter = valueFormatter
+            });
+            return this;
+        }
+    }
+
+    public struct PlayReportValue
+    {
+        public ApplicationMetadata Application { get; init; }
+        public object BoxedValue { get; init; }
+    }
+
+    public struct PlayReportValueFormatterSpec
+    {
+        public required int Priority { get; init; }
+        public required string ReportKey { get; init; }
+        public required PlayReportValueFormatter ValueFormatter { get; init; }
+    }
+
+    public delegate string PlayReportValueFormatter(ref PlayReportValue value);
+    
+    #endregion
 }