From 4e8157688eb08ab651f641dc40723188cffdf820 Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Fri, 7 Feb 2025 18:34:11 -0600 Subject: [PATCH] UI: See what games do/don't have an image & dynamic RPC support in the Game Info popup --- src/Ryujinx/Assets/locales.json | 50 +++++++++++++++++++ src/Ryujinx/DiscordIntegrationModule.cs | 4 ++ .../UI/Controls/ApplicationDataView.axaml | 44 ++++++++++++++++ .../Utilities/AppLibrary/ApplicationData.cs | 3 ++ src/Ryujinx/Utilities/PlayReport/Analyzer.cs | 5 ++ 5 files changed, 106 insertions(+) diff --git a/src/Ryujinx/Assets/locales.json b/src/Ryujinx/Assets/locales.json index f30aac3bc..25a40b29e 100644 --- a/src/Ryujinx/Assets/locales.json +++ b/src/Ryujinx/Assets/locales.json @@ -23696,6 +23696,56 @@ "zh_CN": "选择一个要解压的 DLC", "zh_TW": "" } + }, + { + "ID": "GameInfoRpcImage", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Rich Presence Image", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "", + "pl_PL": "", + "pt_BR": "", + "ru_RU": "", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "", + "zh_CN": "", + "zh_TW": "" + } + }, + { + "ID": "GameInfoRpcDynamic", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Dynamic Rich Presence", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "", + "pl_PL": "", + "pt_BR": "", + "ru_RU": "", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "", + "zh_CN": "", + "zh_TW": "" + } } ] } \ No newline at end of file diff --git a/src/Ryujinx/DiscordIntegrationModule.cs b/src/Ryujinx/DiscordIntegrationModule.cs index abdd9fed1..229b6ee09 100644 --- a/src/Ryujinx/DiscordIntegrationModule.cs +++ b/src/Ryujinx/DiscordIntegrationModule.cs @@ -10,6 +10,7 @@ using Ryujinx.Common.Logging; using Ryujinx.HLE; using Ryujinx.HLE.Loaders.Processes; using Ryujinx.Horizon; +using System.Linq; using System.Text; namespace Ryujinx.Ava @@ -37,6 +38,9 @@ namespace Ryujinx.Ava private static RichPresence _discordPresencePlaying; private static ApplicationMetadata _currentApp; + public static bool HasAssetImage(string titleId) => TitleIDs.DiscordGameAssetKeys.ContainsIgnoreCase(titleId); + public static bool HasAnalyzer(string titleId) => PlayReports.Analyzer.TitleIds.ContainsIgnoreCase(titleId); + public static void Initialize() { _discordPresenceMain = new RichPresence diff --git a/src/Ryujinx/UI/Controls/ApplicationDataView.axaml b/src/Ryujinx/UI/Controls/ApplicationDataView.axaml index a0b6ad7b3..c40b6e192 100644 --- a/src/Ryujinx/UI/Controls/ApplicationDataView.axaml +++ b/src/Ryujinx/UI/Controls/ApplicationDataView.axaml @@ -4,6 +4,7 @@ xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers" xmlns:ext="using:Ryujinx.Ava.Common.Markup" xmlns:viewModels="using:Ryujinx.Ava.UI.ViewModels" + xmlns:ui="using:FluentAvalonia.UI.Controls" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="Ryujinx.Ava.UI.Controls.ApplicationDataView" @@ -85,6 +86,49 @@ + + + + + + + + + + + + + + + + + + + PlayerCount != 0 && GameCount != 0; + + public bool HasRichPresenceAsset => DiscordIntegrationModule.HasAssetImage(IdString); + public bool HasDynamicRichPresenceSupport => DiscordIntegrationModule.HasAnalyzer(IdString); public TimeSpan TimePlayed { get; set; } public DateTime? LastPlayed { get; set; } diff --git a/src/Ryujinx/Utilities/PlayReport/Analyzer.cs b/src/Ryujinx/Utilities/PlayReport/Analyzer.cs index 390e06d28..338c198a1 100644 --- a/src/Ryujinx/Utilities/PlayReport/Analyzer.cs +++ b/src/Ryujinx/Utilities/PlayReport/Analyzer.cs @@ -3,6 +3,7 @@ using MsgPack; using Ryujinx.Ava.Utilities.AppLibrary; using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Globalization; using System.Linq; @@ -15,6 +16,10 @@ namespace Ryujinx.Ava.Utilities.PlayReport { private readonly List _specs = []; + public string[] TitleIds => Specs.SelectMany(x => x.TitleIds).ToArray(); + + public IReadOnlyList Specs => new ReadOnlyCollection(_specs); + /// /// Add an analysis spec matching a specific game by title ID, with the provided spec configuration. ///