0
0
Fork 0
mirror of https://github.com/GreemDev/Ryujinx.git synced 2025-01-09 05:22:01 +00:00
Ryujinx/src/Ryujinx.UI.Common/DiscordIntegrationModule.cs

120 lines
4 KiB
C#

using DiscordRPC;
using Humanizer;
using Ryujinx.Common;
using Ryujinx.UI.App.Common;
using Ryujinx.UI.Common.Configuration;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Ryujinx.UI.Common
{
public static class DiscordIntegrationModule
{
public static Timestamps StartedAt { get; set; }
private const string Description = "A simple, experimental Nintendo Switch emulator.";
private const string ApplicationId = "1293250299716173864";
private const int ApplicationByteLimit = 128;
private const string Ellipsis = "…";
private static DiscordRpcClient _discordClient;
private static RichPresence _discordPresenceMain;
public static void Initialize()
{
_discordPresenceMain = new RichPresence
{
Assets = new Assets
{
LargeImageKey = "ryujinx",
LargeImageText = Description
},
Details = "Main Menu",
State = "Idling",
Timestamps = StartedAt
};
ConfigurationState.Instance.EnableDiscordIntegration.Event += Update;
}
private static void Update(object sender, ReactiveEventArgs<bool> evnt)
{
if (evnt.OldValue != evnt.NewValue)
{
// If the integration was active, disable it and unload everything
if (evnt.OldValue)
{
_discordClient?.Dispose();
_discordClient = null;
}
// If we need to activate it and the client isn't active, initialize it
if (evnt.NewValue && _discordClient == null)
{
_discordClient = new DiscordRpcClient(ApplicationId);
_discordClient.Initialize();
_discordClient.SetPresence(_discordPresenceMain);
}
}
}
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
{
Assets = new Assets
{
LargeImageKey = _discordGameAssets.Contains(titleId.ToLower()) ? titleId : "game",
LargeImageText = TruncateToByteLength(appMeta.Title, ApplicationByteLimit),
SmallImageKey = "ryujinx",
SmallImageText = Description
},
Details = TruncateToByteLength($"Playing {appMeta.Title}", ApplicationByteLimit),
State = $"Total play time: {appMeta.TimePlayed.Humanize(2, false)}",
Timestamps = Timestamps.Now
});
}
private static string TruncateToByteLength(string input, int byteLimit)
{
if (Encoding.UTF8.GetByteCount(input) <= byteLimit)
{
return input;
}
// Find the length to trim the string to guarantee we have space for the trailing ellipsis.
int trimLimit = byteLimit - Encoding.UTF8.GetByteCount(Ellipsis);
// Make sure the string is long enough to perform the basic trim.
// Amount of bytes != Length of the string
if (input.Length > trimLimit)
{
// Basic trim to best case scenario of 1 byte characters.
input = input[..trimLimit];
}
while (Encoding.UTF8.GetByteCount(input) > trimLimit)
{
// Remove one character from the end of the string at a time.
input = input[..^1];
}
return input.TrimEnd() + Ellipsis;
}
public static void Exit()
{
_discordClient?.Dispose();
}
}
}