From c638a7daf8c1f33daaef8e8cbf5141cafd7945b5 Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Wed, 5 Feb 2025 19:27:44 -0600 Subject: [PATCH] misc: chore: Move Play Report analyzer into a dedicated namespace and remove the PlayReport name prefix on types --- src/Ryujinx/DiscordIntegrationModule.cs | 10 +-- .../Analyzer.cs} | 74 +++++++++---------- .../PlayReports.cs} | 32 ++++---- 3 files changed, 56 insertions(+), 60 deletions(-) rename src/Ryujinx/Utilities/{PlayReportAnalyzer.cs => PlayReport/Analyzer.cs} (78%) rename src/Ryujinx/Utilities/{PlayReport.cs => PlayReport/PlayReports.cs} (76%) diff --git a/src/Ryujinx/DiscordIntegrationModule.cs b/src/Ryujinx/DiscordIntegrationModule.cs index 20b296511..d95bb80dd 100644 --- a/src/Ryujinx/DiscordIntegrationModule.cs +++ b/src/Ryujinx/DiscordIntegrationModule.cs @@ -4,16 +4,12 @@ using MsgPack; using Ryujinx.Ava.Utilities; using Ryujinx.Ava.Utilities.AppLibrary; using Ryujinx.Ava.Utilities.Configuration; +using Ryujinx.Ava.Utilities.PlayReport; using Ryujinx.Common; -using Ryujinx.Common.Helper; using Ryujinx.Common.Logging; using Ryujinx.HLE; using Ryujinx.HLE.Loaders.Processes; using Ryujinx.Horizon; -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; using System.Text; namespace Ryujinx.Ava @@ -130,8 +126,8 @@ namespace Ryujinx.Ava if (!TitleIDs.CurrentApplication.Value.HasValue) return; if (_discordPresencePlaying is null) return; - PlayReportAnalyzer.FormattedValue formattedValue = - PlayReport.Analyzer.Format(TitleIDs.CurrentApplication.Value, _currentApp, playReport); + Analyzer.FormattedValue formattedValue = + PlayReports.Analyzer.Format(TitleIDs.CurrentApplication.Value, _currentApp, playReport); if (!formattedValue.Handled) return; diff --git a/src/Ryujinx/Utilities/PlayReportAnalyzer.cs b/src/Ryujinx/Utilities/PlayReport/Analyzer.cs similarity index 78% rename from src/Ryujinx/Utilities/PlayReportAnalyzer.cs rename to src/Ryujinx/Utilities/PlayReport/Analyzer.cs index 47c36a396..ae5abbf9d 100644 --- a/src/Ryujinx/Utilities/PlayReportAnalyzer.cs +++ b/src/Ryujinx/Utilities/PlayReport/Analyzer.cs @@ -6,27 +6,27 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; -namespace Ryujinx.Ava.Utilities +namespace Ryujinx.Ava.Utilities.PlayReport { /// /// The entrypoint for the Play Report analysis system. /// - public class PlayReportAnalyzer + public class Analyzer { - private readonly List _specs = []; + private readonly List _specs = []; /// /// Add an analysis spec matching a specific game by title ID, with the provided spec configuration. /// /// The ID of the game to listen to Play Reports in. /// The configuration function for the analysis spec. - /// The current , for chaining convenience. - public PlayReportAnalyzer AddSpec(string titleId, Func transform) + /// The current , for chaining convenience. + public Analyzer AddSpec(string titleId, Func transform) { Guard.Ensure(ulong.TryParse(titleId, NumberStyles.HexNumber, null, out _), - $"Cannot use a non-hexadecimal string as the Title ID for a {nameof(PlayReportGameSpec)}."); + $"Cannot use a non-hexadecimal string as the Title ID for a {nameof(GameSpec)}."); - _specs.Add(transform(new PlayReportGameSpec { TitleIds = [titleId] })); + _specs.Add(transform(new GameSpec { TitleIds = [titleId] })); return this; } @@ -35,13 +35,13 @@ namespace Ryujinx.Ava.Utilities /// /// The ID of the game to listen to Play Reports in. /// The configuration function for the analysis spec. - /// The current , for chaining convenience. - public PlayReportAnalyzer AddSpec(string titleId, Action transform) + /// The current , for chaining convenience. + public Analyzer AddSpec(string titleId, Action transform) { Guard.Ensure(ulong.TryParse(titleId, NumberStyles.HexNumber, null, out _), - $"Cannot use a non-hexadecimal string as the Title ID for a {nameof(PlayReportGameSpec)}."); + $"Cannot use a non-hexadecimal string as the Title ID for a {nameof(GameSpec)}."); - _specs.Add(new PlayReportGameSpec { TitleIds = [titleId] }.Apply(transform)); + _specs.Add(new GameSpec { TitleIds = [titleId] }.Apply(transform)); return this; } @@ -50,15 +50,15 @@ namespace Ryujinx.Ava.Utilities /// /// The IDs of the games to listen to Play Reports in. /// The configuration function for the analysis spec. - /// The current , for chaining convenience. - public PlayReportAnalyzer AddSpec(IEnumerable titleIds, - Func transform) + /// The current , for chaining convenience. + public Analyzer AddSpec(IEnumerable titleIds, + Func transform) { string[] tids = titleIds.ToArray(); Guard.Ensure(tids.All(x => ulong.TryParse(x, NumberStyles.HexNumber, null, out _)), - $"Cannot use a non-hexadecimal string as the Title ID for a {nameof(PlayReportGameSpec)}."); + $"Cannot use a non-hexadecimal string as the Title ID for a {nameof(GameSpec)}."); - _specs.Add(transform(new PlayReportGameSpec { TitleIds = [..tids] })); + _specs.Add(transform(new GameSpec { TitleIds = [..tids] })); return this; } @@ -67,20 +67,20 @@ namespace Ryujinx.Ava.Utilities /// /// The IDs of the games to listen to Play Reports in. /// The configuration function for the analysis spec. - /// The current , for chaining convenience. - public PlayReportAnalyzer AddSpec(IEnumerable titleIds, Action transform) + /// The current , for chaining convenience. + public Analyzer AddSpec(IEnumerable titleIds, Action transform) { string[] tids = titleIds.ToArray(); Guard.Ensure(tids.All(x => ulong.TryParse(x, NumberStyles.HexNumber, null, out _)), - $"Cannot use a non-hexadecimal string as the Title ID for a {nameof(PlayReportGameSpec)}."); + $"Cannot use a non-hexadecimal string as the Title ID for a {nameof(GameSpec)}."); - _specs.Add(new PlayReportGameSpec { TitleIds = [..tids] }.Apply(transform)); + _specs.Add(new GameSpec { TitleIds = [..tids] }.Apply(transform)); return this; } /// - /// Runs the configured for the specified game title ID. + /// Runs the configured for the specified game title ID. /// /// The game currently running. /// The Application metadata information, including localized game name and play time information. @@ -95,15 +95,15 @@ namespace Ryujinx.Ava.Utilities if (!playReport.IsDictionary) return FormattedValue.Unhandled; - if (!_specs.TryGetFirst(s => runningGameId.EqualsAnyIgnoreCase(s.TitleIds), out PlayReportGameSpec spec)) + if (!_specs.TryGetFirst(s => runningGameId.EqualsAnyIgnoreCase(s.TitleIds), out GameSpec spec)) return FormattedValue.Unhandled; - foreach (PlayReportGameSpec.FormatterSpec formatSpec in spec.SimpleValueFormatters.OrderBy(x => x.Priority)) + foreach (GameSpec.FormatterSpec formatSpec in spec.SimpleValueFormatters.OrderBy(x => x.Priority)) { if (!playReport.AsDictionary().TryGetValue(formatSpec.ReportKey, out MessagePackObject valuePackObject)) continue; - return formatSpec.ValueFormatter(new PlayReportValue + return formatSpec.ValueFormatter(new Value { Application = appMeta, PackedValue = valuePackObject }); @@ -123,7 +123,7 @@ namespace Ryujinx.Ava.Utilities public bool Handled { get; private init; } /// - /// Did the handler request the caller of the to reset the existing value? + /// Did the handler request the caller of the to reset the existing value? /// public bool Reset { get; private init; } @@ -151,7 +151,7 @@ namespace Ryujinx.Ava.Utilities public static FormattedValue Unhandled => default; /// - /// Return this to suggest the caller reset the value it's using the for. + /// Return this to suggest the caller reset the value it's using the for. /// public static FormattedValue ForceReset => new() { Handled = true, Reset = true }; @@ -172,21 +172,21 @@ namespace Ryujinx.Ava.Utilities /// /// A mapping of title IDs to value formatter specs. /// - /// Generally speaking, use the .AddSpec(...) methods instead of creating this class yourself. + /// Generally speaking, use the .AddSpec(...) methods instead of creating this class yourself. /// - public class PlayReportGameSpec + public class GameSpec { public required string[] TitleIds { get; init; } public List SimpleValueFormatters { get; } = []; /// - /// Add a value formatter to the current + /// Add a value formatter to the current /// matching a specific key that could exist in a Play Report for the previously specified title IDs. /// /// The key name to match. /// The function which can return a potential formatted value. - /// The current , for chaining convenience. - public PlayReportGameSpec AddValueFormatter(string reportKey, PlayReportValueFormatter valueFormatter) + /// The current , for chaining convenience. + public GameSpec AddValueFormatter(string reportKey, PlayReportValueFormatter valueFormatter) { SimpleValueFormatters.Add(new FormatterSpec { @@ -196,14 +196,14 @@ namespace Ryujinx.Ava.Utilities } /// - /// Add a value formatter at a specific priority to the current + /// Add a value formatter at a specific priority to the current /// matching a specific key that could exist in a Play Report for the previously specified title IDs. /// /// The resolution priority of this value formatter. Higher resolves sooner. /// The key name to match. /// The function which can return a potential formatted value. - /// The current , for chaining convenience. - public PlayReportGameSpec AddValueFormatter(int priority, string reportKey, + /// The current , for chaining convenience. + public GameSpec AddValueFormatter(int priority, string reportKey, PlayReportValueFormatter valueFormatter) { SimpleValueFormatters.Add(new FormatterSpec @@ -229,7 +229,7 @@ namespace Ryujinx.Ava.Utilities /// containing the currently running application's , /// and the matched from the Play Report. /// - public class PlayReportValue + public class Value { /// /// The currently running application's . @@ -276,7 +276,7 @@ namespace Ryujinx.Ava.Utilities ///
/// a signal that nothing was available to handle it, ///
- /// OR a signal to reset the value that the caller is using the for. + /// OR a signal to reset the value that the caller is using the for. ///
- public delegate PlayReportAnalyzer.FormattedValue PlayReportValueFormatter(PlayReportValue value); + public delegate Analyzer.FormattedValue PlayReportValueFormatter(Value value); } diff --git a/src/Ryujinx/Utilities/PlayReport.cs b/src/Ryujinx/Utilities/PlayReport/PlayReports.cs similarity index 76% rename from src/Ryujinx/Utilities/PlayReport.cs rename to src/Ryujinx/Utilities/PlayReport/PlayReports.cs index 7ebf53482..ce35cae89 100644 --- a/src/Ryujinx/Utilities/PlayReport.cs +++ b/src/Ryujinx/Utilities/PlayReport/PlayReports.cs @@ -1,16 +1,16 @@ -using PlayReportFormattedValue = Ryujinx.Ava.Utilities.PlayReportAnalyzer.FormattedValue; +using static Ryujinx.Ava.Utilities.PlayReport.Analyzer; -namespace Ryujinx.Ava.Utilities +namespace Ryujinx.Ava.Utilities.PlayReport { - public static class PlayReport + public static class PlayReports { - public static PlayReportAnalyzer Analyzer { get; } = new PlayReportAnalyzer() + public static Analyzer Analyzer { get; } = new Analyzer() .AddSpec( "01007ef00011e000", spec => spec .AddValueFormatter("IsHardMode", BreathOfTheWild_MasterMode) // reset to normal status when switching between normal & master mode in title screen - .AddValueFormatter("AoCVer", PlayReportFormattedValue.AlwaysResets) + .AddValueFormatter("AoCVer", FormattedValue.AlwaysResets) ) .AddSpec( "0100f2c0115b6000", @@ -40,10 +40,10 @@ namespace Ryujinx.Ava.Utilities .AddValueFormatter("team_circle", PokemonSVUnionCircle) ); - private static PlayReportFormattedValue BreathOfTheWild_MasterMode(PlayReportValue value) - => value.BoxedValue is 1 ? "Playing Master Mode" : PlayReportFormattedValue.ForceReset; + private static FormattedValue BreathOfTheWild_MasterMode(Value value) + => value.BoxedValue is 1 ? "Playing Master Mode" : FormattedValue.ForceReset; - private static PlayReportFormattedValue TearsOfTheKingdom_CurrentField(PlayReportValue value) => + private static FormattedValue TearsOfTheKingdom_CurrentField(Value value) => value.DoubleValue switch { > 800d => "Exploring the Sky Islands", @@ -51,16 +51,16 @@ namespace Ryujinx.Ava.Utilities _ => "Roaming Hyrule" }; - private static PlayReportFormattedValue SuperMarioOdyssey_AssistMode(PlayReportValue value) + private static FormattedValue SuperMarioOdyssey_AssistMode(Value value) => value.BoxedValue is 1 ? "Playing in Assist Mode" : "Playing in Regular Mode"; - private static PlayReportFormattedValue SuperMarioOdysseyChina_AssistMode(PlayReportValue value) + private static FormattedValue SuperMarioOdysseyChina_AssistMode(Value value) => value.BoxedValue is 1 ? "Playing in 帮助模式" : "Playing in 普通模式"; - private static PlayReportFormattedValue SuperMario3DWorldOrBowsersFury(PlayReportValue value) + private static FormattedValue SuperMario3DWorldOrBowsersFury(Value value) => value.BoxedValue is 0 ? "Playing Super Mario 3D World" : "Playing Bowser's Fury"; - private static PlayReportFormattedValue MarioKart8Deluxe_Mode(PlayReportValue value) + private static FormattedValue MarioKart8Deluxe_Mode(Value value) => value.StringValue switch { // Single Player @@ -85,13 +85,13 @@ namespace Ryujinx.Ava.Utilities "Battle" => "Battle Mode", "RaceStart" => "Selecting a Course", "Race" => "Racing", - _ => PlayReportFormattedValue.ForceReset + _ => FormattedValue.ForceReset }; - private static PlayReportFormattedValue PokemonSVUnionCircle(PlayReportValue value) + private static FormattedValue PokemonSVUnionCircle(Value value) => value.BoxedValue is 0 ? "Playing Alone" : "Playing in a group"; - private static PlayReportFormattedValue PokemonSVArea(PlayReportValue value) + private static FormattedValue PokemonSVArea(Value value) => value.StringValue switch { // Base Game Locations @@ -122,7 +122,7 @@ namespace Ryujinx.Ava.Utilities "a_w26" => "East Paldean Sea", "a_w27" => "Nouth Paldean Sea", //TODO DLC Locations - _ => PlayReportFormattedValue.ForceReset + _ => FormattedValue.ForceReset }; } }