Embed compatibility list into executable

instead of downloading

Co-Authored-By: Vita Chumakova <me@ezhevita.dev>
This commit is contained in:
Evan Husted 2025-01-07 03:37:07 -06:00
parent 259526430c
commit d8265f7772
6 changed files with 4328 additions and 44 deletions

4303
docs/compatibility.csv Normal file

File diff suppressed because it is too large Load Diff

View File

@ -145,6 +145,9 @@
<EmbeddedResource Include="..\..\distribution\macos\shortcut-template.plist"> <EmbeddedResource Include="..\..\distribution\macos\shortcut-template.plist">
<Link>Assets\ShortcutFiles\shortcut-template.plist</Link> <Link>Assets\ShortcutFiles\shortcut-template.plist</Link>
</EmbeddedResource> </EmbeddedResource>
<EmbeddedResource Include="..\..\docs\compatibility.csv" LogicalName="RyujinxGameCompatibilityList">
<Link>Assets\RyujinxGameCompatibility.csv</Link>
</EmbeddedResource>
<EmbeddedResource Include="Assets\locales.json" /> <EmbeddedResource Include="Assets\locales.json" />
<EmbeddedResource Include="Assets\Styles\Styles.xaml" /> <EmbeddedResource Include="Assets\Styles\Styles.xaml" />
<EmbeddedResource Include="Assets\Icons\Controller_JoyConLeft.svg" /> <EmbeddedResource Include="Assets\Icons\Controller_JoyConLeft.svg" />

View File

@ -63,6 +63,7 @@ namespace Ryujinx.Ava.UI.Helpers
public static MiniCommand Create(Action callback) => new MiniCommand<object>(_ => callback()); public static MiniCommand Create(Action callback) => new MiniCommand<object>(_ => callback());
public static MiniCommand Create<TArg>(Action<TArg> callback) => new MiniCommand<TArg>(callback); public static MiniCommand Create<TArg>(Action<TArg> callback) => new MiniCommand<TArg>(callback);
public static MiniCommand CreateFromTask(Func<Task> callback) => new MiniCommand<object>(_ => callback()); public static MiniCommand CreateFromTask(Func<Task> callback) => new MiniCommand<object>(_ => callback());
public static MiniCommand CreateFromTask<TArg>(Func<TArg, Task> callback) => new MiniCommand<TArg>(callback);
public abstract bool CanExecute(object parameter); public abstract bool CanExecute(object parameter);
public abstract void Execute(object parameter); public abstract void Execute(object parameter);

View File

@ -66,7 +66,7 @@ namespace Ryujinx.Ava.UI.Views.Main
WindowSize2160PMenuItem.Command = new RelayCommand<string>(ChangeWindowSize); WindowSize2160PMenuItem.Command = new RelayCommand<string>(ChangeWindowSize);
} }
private CheckBox[] GenerateToggleFileTypeItems() => private IEnumerable<CheckBox> GenerateToggleFileTypeItems() =>
Enum.GetValues<FileTypes>() Enum.GetValues<FileTypes>()
.Select(it => (FileName: Enum.GetName(it)!, FileType: it)) .Select(it => (FileName: Enum.GetName(it)!, FileType: it))
.Select(it => .Select(it =>
@ -76,15 +76,13 @@ namespace Ryujinx.Ava.UI.Views.Main
IsChecked = it.FileType.GetConfigValue(ConfigurationState.Instance.UI.ShownFileTypes), IsChecked = it.FileType.GetConfigValue(ConfigurationState.Instance.UI.ShownFileTypes),
Command = MiniCommand.Create(() => Window.ToggleFileType(it.FileName)) Command = MiniCommand.Create(() => Window.ToggleFileType(it.FileName))
} }
).ToArray(); );
private static MenuItem[] GenerateLanguageMenuItems() private static IEnumerable<MenuItem> GenerateLanguageMenuItems()
{ {
List<MenuItem> menuItems = new(); const string LocalePath = "Ryujinx/Assets/locales.json";
string localePath = "Ryujinx/Assets/locales.json"; string languageJson = EmbeddedResources.ReadAllText(LocalePath);
string languageJson = EmbeddedResources.ReadAllText(localePath);
LocalesJson locales = JsonHelper.Deserialize(languageJson, LocalesJsonContext.Default.LocalesJson); LocalesJson locales = JsonHelper.Deserialize(languageJson, LocalesJsonContext.Default.LocalesJson);
@ -99,7 +97,10 @@ namespace Ryujinx.Ava.UI.Views.Main
} }
else else
{ {
languageName = locales.Locales[index].Translations[language] == "" ? language : locales.Locales[index].Translations[language]; string tr = locales.Locales[index].Translations[language];
languageName = string.IsNullOrEmpty(tr)
? language
: tr;
} }
MenuItem menuItem = new() MenuItem menuItem = new()
@ -111,10 +112,8 @@ namespace Ryujinx.Ava.UI.Views.Main
Command = MiniCommand.Create(() => MainWindowViewModel.ChangeLanguage(language)) Command = MiniCommand.Create(() => MainWindowViewModel.ChangeLanguage(language))
}; };
menuItems.Add(menuItem); yield return menuItem;
} }
return menuItems.ToArray();
} }
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)

View File

@ -1,32 +0,0 @@
using Gommon;
using nietras.SeparatedValues;
using Ryujinx.Common.Configuration;
using System.Net.Http;
using System.Threading.Tasks;
namespace Ryujinx.Ava.Utilities.Compat
{
public static class CompatibilityHelper
{
private static readonly string _downloadUrl =
"https://gist.githubusercontent.com/ezhevita/b41ed3bf64d0cc01269cab036e884f3d/raw/002b1a1c1a5f7a83276625e8c479c987a5f5b722/Ryujinx%2520Games%2520List%2520Compatibility.csv";
private static readonly FilePath _compatCsvPath = new FilePath(AppDataManager.BaseDirPath) / "system" / "compatibility.csv";
public static async Task<SepReader> DownloadAsync()
{
if (_compatCsvPath.ExistsAsFile)
return Sep.Reader().FromFile(_compatCsvPath.Path);
using var httpClient = new HttpClient();
var compatCsv = await httpClient.GetStringAsync(_downloadUrl);
_compatCsvPath.WriteAllText(compatCsv);
return Sep.Reader().FromText(compatCsv);
}
public static async Task InitAsync()
{
CompatibilityCsv.Shared = new CompatibilityCsv(await DownloadAsync());
}
}
}

View File

@ -1,6 +1,9 @@
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Styling; using Avalonia.Styling;
using nietras.SeparatedValues;
using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Helpers;
using System.IO;
using System.Reflection;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Ryujinx.Ava.Utilities.Compat namespace Ryujinx.Ava.Utilities.Compat
@ -9,7 +12,14 @@ namespace Ryujinx.Ava.Utilities.Compat
{ {
public static async Task Show() public static async Task Show()
{ {
await CompatibilityHelper.InitAsync(); if (CompatibilityCsv.Shared is null)
{
await using Stream csvStream = Assembly.GetExecutingAssembly()
.GetManifestResourceStream("RyujinxGameCompatibilityList")!;
csvStream.Position = 0;
CompatibilityCsv.Shared = new CompatibilityCsv(Sep.Reader().From(csvStream));
}
CompatibilityContentDialog contentDialog = new() CompatibilityContentDialog contentDialog = new()
{ {