UI: Improve Discord RPC for select games & show play time in place of title ID.

This commit is contained in:
Evan Husted 2024-10-10 18:15:38 -05:00
parent 289e6dbbf6
commit 6da83688b2
3 changed files with 27 additions and 37 deletions

View file

@ -1,14 +1,20 @@
using DiscordRPC; using DiscordRPC;
using Humanizer;
using Ryujinx.Common; using Ryujinx.Common;
using Ryujinx.UI.App.Common;
using Ryujinx.UI.Common.Configuration; using Ryujinx.UI.Common.Configuration;
using System.Collections.Generic;
using System.Linq;
using System.Text; using System.Text;
namespace Ryujinx.UI.Common namespace Ryujinx.UI.Common
{ {
public static class DiscordIntegrationModule public static class DiscordIntegrationModule
{ {
public static Timestamps StartedAt { get; set; }
private const string Description = "A simple, experimental Nintendo Switch emulator."; private const string Description = "A simple, experimental Nintendo Switch emulator.";
private const string ApplicationId = "1216775165866807456"; private const string ApplicationId = "1293250299716173864";
private const int ApplicationByteLimit = 128; private const int ApplicationByteLimit = 128;
private const string Ellipsis = "…"; private const string Ellipsis = "…";
@ -23,19 +29,11 @@ namespace Ryujinx.UI.Common
Assets = new Assets Assets = new Assets
{ {
LargeImageKey = "ryujinx", LargeImageKey = "ryujinx",
LargeImageText = Description, LargeImageText = Description
}, },
Details = "Main Menu", Details = "Main Menu",
State = "Idling", State = "Idling",
Timestamps = Timestamps.Now, Timestamps = StartedAt
Buttons =
[
new Button
{
Label = "Website",
Url = "https://ryujinx.org/",
},
],
}; };
ConfigurationState.Instance.EnableDiscordIntegration.Event += Update; ConfigurationState.Instance.EnableDiscordIntegration.Event += Update;
@ -64,36 +62,29 @@ namespace Ryujinx.UI.Common
} }
} }
public static void SwitchToPlayingState(string titleId, string applicationName) private static readonly string[] _discordGameAssets = [
"0100f2c0115b6000", // Tears of the Kingdom
"0100744001588000", // Cars 3: Driven to Win
];
public static void SwitchToPlayingState(string titleId, ApplicationMetadata appMeta)
{ {
_discordClient?.SetPresence(new RichPresence _discordClient?.SetPresence(new RichPresence
{ {
Assets = new Assets Assets = new Assets
{ {
LargeImageKey = "game", LargeImageKey = _discordGameAssets.Contains(titleId.ToLower()) ? titleId : "game",
LargeImageText = TruncateToByteLength(applicationName, ApplicationByteLimit), LargeImageText = TruncateToByteLength(appMeta.Title, ApplicationByteLimit),
SmallImageKey = "ryujinx", SmallImageKey = "ryujinx",
SmallImageText = Description, SmallImageText = Description
}, },
Details = TruncateToByteLength($"Playing {applicationName}", ApplicationByteLimit), Details = TruncateToByteLength($"Playing {appMeta.Title}", ApplicationByteLimit),
State = (titleId == "0000000000000000") ? "Homebrew" : titleId.ToUpper(), State = $"Total play time: {appMeta.TimePlayed.Humanize(2, false)}",
Timestamps = Timestamps.Now, Timestamps = Timestamps.Now
Buttons =
[
new Button
{
Label = "Website",
Url = "https://ryujinx.org/",
},
],
}); });
} }
public static void SwitchToMainMenu()
{
_discordClient?.SetPresence(_discordPresenceMain);
}
private static string TruncateToByteLength(string input, int byteLimit) private static string TruncateToByteLength(string input, int byteLimit)
{ {
if (Encoding.UTF8.GetByteCount(input) <= byteLimit) if (Encoding.UTF8.GetByteCount(input) <= byteLimit)

View file

@ -57,6 +57,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="DiscordRichPresence" /> <PackageReference Include="DiscordRichPresence" />
<PackageReference Include="DynamicData" /> <PackageReference Include="DynamicData" />
<PackageReference Include="Humanizer" />
<PackageReference Include="securifybv.ShellLink" /> <PackageReference Include="securifybv.ShellLink" />
</ItemGroup> </ItemGroup>

View file

@ -785,13 +785,13 @@ namespace Ryujinx.Ava
return false; return false;
} }
DiscordIntegrationModule.SwitchToPlayingState(Device.Processes.ActiveApplication.ProgramIdText, Device.Processes.ActiveApplication.Name); ApplicationMetadata appMeta = ApplicationLibrary.LoadAndSaveMetaData(Device.Processes.ActiveApplication.ProgramIdText, appMetadata =>
ApplicationLibrary.LoadAndSaveMetaData(Device.Processes.ActiveApplication.ProgramIdText, appMetadata =>
{ {
appMetadata.UpdatePreGame(); appMetadata.UpdatePreGame();
}); });
DiscordIntegrationModule.SwitchToPlayingState(Device.Processes.ActiveApplication.ProgramIdText, appMeta);
return true; return true;
} }
@ -948,10 +948,8 @@ namespace Ryujinx.Ava
private void MainLoop() private void MainLoop()
{ {
while (_isActive) while (UpdateFrame())
{ {
UpdateFrame();
// Polling becomes expensive if it's not slept. // Polling becomes expensive if it's not slept.
Thread.Sleep(1); Thread.Sleep(1);
} }