Merge branch 'master' into master

This commit is contained in:
Willians 2025-02-15 22:53:46 -03:00 committed by GitHub
commit 7e3e7ac344
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 116 additions and 74 deletions

View File

@ -56,6 +56,7 @@ namespace Ryujinx.Ava
ConfigurationState.Instance.EnableDiscordIntegration.Event += Update; ConfigurationState.Instance.EnableDiscordIntegration.Event += Update;
TitleIDs.CurrentApplication.Event += (_, e) => Use(e.NewValue); TitleIDs.CurrentApplication.Event += (_, e) => Use(e.NewValue);
HorizonStatic.PlayReport += HandlePlayReport; HorizonStatic.PlayReport += HandlePlayReport;
PlayReports.Initialize();
} }
private static void Update(object sender, ReactiveEventArgs<bool> evnt) private static void Update(object sender, ReactiveEventArgs<bool> evnt)

View File

@ -1,5 +1,6 @@
using Gommon; using Gommon;
using Ryujinx.Ava.Utilities.AppLibrary; using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.Common.Logging;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
@ -27,10 +28,12 @@ namespace Ryujinx.Ava.Utilities.PlayReport
/// <returns>The current <see cref="Analyzer"/>, for chaining convenience.</returns> /// <returns>The current <see cref="Analyzer"/>, for chaining convenience.</returns>
public Analyzer AddSpec(string titleId, Func<GameSpec, GameSpec> transform) public Analyzer AddSpec(string titleId, Func<GameSpec, GameSpec> transform)
{ {
Guard.Ensure(ulong.TryParse(titleId, NumberStyles.HexNumber, null, out _), if (ulong.TryParse(titleId, NumberStyles.HexNumber, null, out _))
$"Cannot use a non-hexadecimal string as the Title ID for a {nameof(GameSpec)}."); return AddSpec(transform(GameSpec.Create(titleId)));
return AddSpec(transform(GameSpec.Create(titleId))); Logger.Notice.PrintMsg(LogClass.Application,
$"Tried to add a {nameof(GameSpec)} with a non-hexadecimal title ID value. Input: '{titleId}'");
return this;
} }
/// <summary> /// <summary>
@ -41,10 +44,12 @@ namespace Ryujinx.Ava.Utilities.PlayReport
/// <returns>The current <see cref="Analyzer"/>, for chaining convenience.</returns> /// <returns>The current <see cref="Analyzer"/>, for chaining convenience.</returns>
public Analyzer AddSpec(string titleId, Action<GameSpec> transform) public Analyzer AddSpec(string titleId, Action<GameSpec> transform)
{ {
Guard.Ensure(ulong.TryParse(titleId, NumberStyles.HexNumber, null, out _), if (ulong.TryParse(titleId, NumberStyles.HexNumber, null, out _))
$"Cannot use a non-hexadecimal string as the Title ID for a {nameof(GameSpec)}."); return AddSpec(GameSpec.Create(titleId).Apply(transform));
return AddSpec(GameSpec.Create(titleId).Apply(transform)); Logger.Notice.PrintMsg(LogClass.Application,
$"Tried to add a {nameof(GameSpec)} with a non-hexadecimal title ID value. Input: '{titleId}'");
return this;
} }
/// <summary> /// <summary>
@ -57,10 +62,19 @@ namespace Ryujinx.Ava.Utilities.PlayReport
Func<GameSpec, GameSpec> transform) Func<GameSpec, GameSpec> transform)
{ {
string[] tids = titleIds.ToArray(); string[] tids = titleIds.ToArray();
Guard.Ensure(tids.All(x => ulong.TryParse(x, NumberStyles.HexNumber, null, out _)), if (tids.All(x => ulong.TryParse(x, NumberStyles.HexNumber, null, out _) && !string.IsNullOrEmpty(x)))
$"Cannot use a non-hexadecimal string as the Title ID for a {nameof(GameSpec)}."); return AddSpec(transform(GameSpec.Create(tids)));
return AddSpec(transform(GameSpec.Create(tids))); Logger.Notice.PrintMsg(LogClass.Application,
$"Tried to add a {nameof(GameSpec)} with a non-hexadecimal title ID value. Input: '{
tids.FormatCollection(
x => x,
separator: ", ",
prefix: "[",
suffix: "]"
)
}'");
return this;
} }
/// <summary> /// <summary>
@ -72,12 +86,21 @@ namespace Ryujinx.Ava.Utilities.PlayReport
public Analyzer AddSpec(IEnumerable<string> titleIds, Action<GameSpec> transform) public Analyzer AddSpec(IEnumerable<string> titleIds, Action<GameSpec> transform)
{ {
string[] tids = titleIds.ToArray(); string[] tids = titleIds.ToArray();
Guard.Ensure(tids.All(x => ulong.TryParse(x, NumberStyles.HexNumber, null, out _)), if (tids.All(x => ulong.TryParse(x, NumberStyles.HexNumber, null, out _) && !string.IsNullOrEmpty(x)))
$"Cannot use a non-hexadecimal string as the Title ID for a {nameof(GameSpec)}."); return AddSpec(GameSpec.Create(tids).Apply(transform));
return AddSpec(GameSpec.Create(tids).Apply(transform)); Logger.Notice.PrintMsg(LogClass.Application,
$"Tried to add a {nameof(GameSpec)} with a non-hexadecimal title ID value. Input: '{
tids.FormatCollection(
x => x,
separator: ", ",
prefix: "[",
suffix: "]"
)
}'");
return this;
} }
/// <summary> /// <summary>
/// Add an analysis spec matching a specific game by title ID, with the provided pre-configured spec. /// Add an analysis spec matching a specific game by title ID, with the provided pre-configured spec.
/// </summary> /// </summary>

View File

@ -1,4 +1,5 @@
using Gommon; using Gommon;
using Humanizer;
using System; using System;
using System.Buffers.Binary; using System.Buffers.Binary;
using System.Collections.Generic; using System.Collections.Generic;
@ -18,6 +19,9 @@ namespace Ryujinx.Ava.Utilities.PlayReport
< -201d => "Exploring the Depths", < -201d => "Exploring the Depths",
_ => "Roaming Hyrule" _ => "Roaming Hyrule"
}; };
private static FormattedValue SkywardSwordHD_Rupees(SingleValue value)
=> "rupee".ToQuantity(value.Matched.IntValue);
private static FormattedValue SuperMarioOdyssey_AssistMode(SingleValue value) private static FormattedValue SuperMarioOdyssey_AssistMode(SingleValue value)
=> value.Matched.BoxedValue is 1 ? "Playing in Assist Mode" : "Playing in Regular Mode"; => value.Matched.BoxedValue is 1 ? "Playing in Assist Mode" : "Playing in Regular Mode";

View File

@ -1,67 +1,81 @@
namespace Ryujinx.Ava.Utilities.PlayReport using System;
namespace Ryujinx.Ava.Utilities.PlayReport
{ {
public static partial class PlayReports public static partial class PlayReports
{ {
public static Analyzer Analyzer { get; } = new Analyzer() public static void Initialize()
.AddSpec( {
"01007ef00011e000", // init lazy value
spec => spec _ = Analyzer;
.AddValueFormatter("IsHardMode", BreathOfTheWild_MasterMode) }
// reset to normal status when switching between normal & master mode in title screen
.AddValueFormatter("AoCVer", FormattedValue.SingleAlwaysResets) public static Analyzer Analyzer => _analyzerLazy.Value;
)
.AddSpec( private static readonly Lazy<Analyzer> _analyzerLazy = new(() =>
"0100f2c0115b6000", new Analyzer()
spec => spec .AddSpec(
.AddValueFormatter("PlayerPosY", TearsOfTheKingdom_CurrentField)) "01007ef00011e000",
.AddSpec( spec => spec
"0100000000010000", .AddValueFormatter("IsHardMode", BreathOfTheWild_MasterMode)
spec => // reset to normal status when switching between normal & master mode in title screen
spec.AddValueFormatter("is_kids_mode", SuperMarioOdyssey_AssistMode) .AddValueFormatter("AoCVer", FormattedValue.SingleAlwaysResets)
) )
.AddSpec( .AddSpec(
"010075000ecbe000", "0100f2c0115b6000",
spec => spec => spec
spec.AddValueFormatter("is_kids_mode", SuperMarioOdysseyChina_AssistMode) .AddValueFormatter("PlayerPosY", TearsOfTheKingdom_CurrentField))
) .AddSpec(
.AddSpec( "0100000000010000",
"010028600ebda000", spec =>
spec => spec.AddValueFormatter("mode", SuperMario3DWorldOrBowsersFury) spec.AddValueFormatter("is_kids_mode", SuperMarioOdyssey_AssistMode)
) )
.AddSpec( // Global & China IDs .AddSpec(
["0100152000022000", "010075100e8ec000"], "010075000ecbe000",
spec => spec.AddValueFormatter("To", MarioKart8Deluxe_Mode) spec =>
) spec.AddValueFormatter("is_kids_mode", SuperMarioOdysseyChina_AssistMode)
.AddSpec( )
["0100a3d008c5c000", "01008f6008c5e000"], .AddSpec(
spec => spec "010028600ebda000",
.AddValueFormatter("area_no", PokemonSVArea) spec => spec.AddValueFormatter("mode", SuperMario3DWorldOrBowsersFury)
.AddValueFormatter("team_circle", PokemonSVUnionCircle) )
) .AddSpec( // Global & China IDs
.AddSpec( ["0100152000022000", "010075100e8ec000"],
"01006a800016e000", spec => spec.AddValueFormatter("To", MarioKart8Deluxe_Mode)
spec => spec )
.AddSparseMultiValueFormatter( .AddSpec(
[ ["0100a3d008c5c000", "01008f6008c5e000"],
// Metadata to figure out what PlayReport we have. spec => spec
"match_mode", "match_submode", "anniversary", "fighter", "reason", "challenge_count", .AddValueFormatter("area_no", PokemonSVArea)
"adv_slot", .AddValueFormatter("team_circle", PokemonSVUnionCircle)
// List of Fighters )
"player_1_fighter", "player_2_fighter", "player_3_fighter", "player_4_fighter", .AddSpec(
"player_5_fighter", "player_6_fighter", "player_7_fighter", "player_8_fighter", "01006a800016e000",
// List of rankings/placements spec => spec
"player_1_rank", "player_2_rank", "player_3_rank", "player_4_rank", "player_5_rank", .AddSparseMultiValueFormatter(
"player_6_rank", "player_7_rank", "player_8_rank" [
], // Metadata to figure out what PlayReport we have.
SuperSmashBrosUltimate_Mode "match_mode", "match_submode", "anniversary", "fighter", "reason", "challenge_count",
) "adv_slot",
) // List of Fighters
.AddSpec( "player_1_fighter", "player_2_fighter", "player_3_fighter", "player_4_fighter",
[ "player_5_fighter", "player_6_fighter", "player_7_fighter", "player_8_fighter",
"0100c9a00ece6000", "01008d300c50c000", "0100d870045b6000", // List of rankings/placements
"010012f017576000", "0100c62011050000", "0100b3c014bda000"], "player_1_rank", "player_2_rank", "player_3_rank", "player_4_rank", "player_5_rank",
spec => spec.AddValueFormatter("launch_title_id", NsoEmulator_LaunchedGame) "player_6_rank", "player_7_rank", "player_8_rank"
); ],
SuperSmashBrosUltimate_Mode
)
)
.AddSpec(
[
"0100c9a00ece6000", "01008d300c50c000", "0100d870045b6000",
"010012f017576000", "0100c62011050000", "0100b3c014bda000"
],
spec => spec.AddValueFormatter("launch_title_id", NsoEmulator_LaunchedGame)
)
.AddSpec("01002da013484000", spec => spec.AddValueFormatter("rupees", SkywardSwordHD_Rupees))
);
private static string Playing(string game) => $"Playing {game}"; private static string Playing(string game) => $"Playing {game}";
} }