diff --git a/src/Ryujinx.Common/Helpers/PlayReportAnalyzer.cs b/src/Ryujinx.Common/Helpers/PlayReportAnalyzer.cs deleted file mode 100644 index b69b18f57..000000000 --- a/src/Ryujinx.Common/Helpers/PlayReportAnalyzer.cs +++ /dev/null @@ -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 _specs = []; - - public PlayReportAnalyzer AddSpec(string titleId, Func transform) - { - _specs.Add(transform(new PlayReportGameSpec { TitleIdStr = titleId })); - return this; - } - - public PlayReportAnalyzer AddSpec(string titleId, Action transform) - { - _specs.Add(new PlayReportGameSpec { TitleIdStr = titleId }.Apply(transform)); - return this; - } - - public Optional Run(string runningGameId, MessagePackObject playReport) - { - if (!playReport.IsDictionary) - return Optional.None; - - if (!_specs.TryGetFirst(s => s.TitleIdStr.EqualsIgnoreCase(runningGameId), out PlayReportGameSpec spec)) - return Optional.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.None; - } - - } - - public class PlayReportGameSpec - { - public required string TitleIdStr { get; init; } - public List Analyses { get; } = []; - - public PlayReportGameSpec AddValueFormatter(string reportKey, Func valueFormatter) - { - Analyses.Add(new PlayReportValueFormatterSpec - { - Priority = Analyses.Count, - ReportKey = reportKey, - ValueFormatter = valueFormatter - }); - return this; - } - - public PlayReportGameSpec AddValueFormatter(int priority, string reportKey, Func 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 ValueFormatter { get; init; } - } -} diff --git a/src/Ryujinx/DiscordIntegrationModule.cs b/src/Ryujinx/DiscordIntegrationModule.cs index c9fa1f732..5561c1562 100644 --- a/src/Ryujinx/DiscordIntegrationModule.cs +++ b/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 details = PlayReport.Analyzer.Run(TitleIDs.CurrentApplication.Value, playReport); + Optional details = PlayReport.Analyzer.Run(TitleIDs.CurrentApplication.Value, _currentApp, playReport); if (!details.HasValue) return; diff --git a/src/Ryujinx/Utilities/PlayReport.cs b/src/Ryujinx/Utilities/PlayReport.cs index e913ffa13..9665a1628 100644 --- a/src/Ryujinx/Utilities/PlayReport.cs +++ b/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 _specs = []; + + public PlayReportAnalyzer AddSpec(string titleId, Func transform) + { + _specs.Add(transform(new PlayReportGameSpec { TitleIdStr = titleId })); + return this; + } + + public PlayReportAnalyzer AddSpec(string titleId, Action transform) + { + _specs.Add(new PlayReportGameSpec { TitleIdStr = titleId }.Apply(transform)); + return this; + } + + public Optional Run(string runningGameId, ApplicationMetadata appMeta, MessagePackObject playReport) + { + if (!playReport.IsDictionary) + return Optional.None; + + if (!_specs.TryGetFirst(s => s.TitleIdStr.EqualsIgnoreCase(runningGameId), out PlayReportGameSpec spec)) + return Optional.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.None; + } + + } + + public class PlayReportGameSpec + { + public required string TitleIdStr { get; init; } + public List 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 }