Compare commits
59 Commits
Canary-1.2
...
8efefeaaca
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8efefeaaca | ||
|
|
4e56b1493f | ||
|
|
43f6e4a873 | ||
|
|
55f6b95d8d | ||
|
|
153d1ef06b | ||
|
|
4b84c5d240 | ||
|
|
9f22fc49c8 | ||
|
|
4f206d0e73 | ||
|
|
e1e4e5d2d5 | ||
|
|
44ee4190e6 | ||
|
|
9408452f93 | ||
|
|
38833ff60a | ||
|
|
1faa72f22f | ||
|
|
56e45ae648 | ||
|
|
07074272ca | ||
|
|
e2e8502278 | ||
|
|
9eb273a0f7 | ||
|
|
ccddaa77d1 | ||
|
|
01c2e67334 | ||
|
|
4c646721d6 | ||
|
|
d3bc3a1081 | ||
|
|
c69881a0a2 | ||
|
|
aa806b1032 | ||
|
|
aabb786016 | ||
|
|
2a38f1bbbf | ||
|
|
fdece62f88 | ||
|
|
6fb58a611e | ||
|
|
02ff76f89a | ||
|
|
d39b3a5864 | ||
|
|
f976c3c362 | ||
|
|
d9f2b813a0 | ||
|
|
8cb6767c7c | ||
|
|
80377c1553 | ||
|
|
1dbcaf1fd7 | ||
|
|
bad1f72918 | ||
|
|
a317184594 | ||
|
|
0cde245875 | ||
|
|
e3638d13b1 | ||
|
|
2fe19044cf | ||
|
|
9320decc45 | ||
|
|
35b23bcafb | ||
|
|
4add4829c7 | ||
|
|
eb46909808 | ||
|
|
c91d9d8049 | ||
|
|
21f23f0a2e | ||
|
|
9ca0926439 | ||
|
|
7b8c8776a2 | ||
|
|
b00d80c17a | ||
|
|
8c0a82bb6e | ||
|
|
1bac6ab19e | ||
|
|
dac137fd43 | ||
|
|
d83d80de73 | ||
|
|
097836bfac | ||
|
|
695f9e277d | ||
|
|
b19ee23c6b | ||
|
|
748e93ba65 | ||
|
|
732a1af863 | ||
|
|
f538cee2e8 | ||
|
|
4275a778aa |
24
.github/workflows/canary.yml
vendored
24
.github/workflows/canary.yml
vendored
@@ -21,9 +21,9 @@ env:
|
||||
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
||||
RYUJINX_BASE_VERSION: "1.2"
|
||||
RYUJINX_TARGET_RELEASE_CHANNEL_NAME: "canary"
|
||||
RYUJINX_TARGET_RELEASE_CHANNEL_OWNER: "GreemDev"
|
||||
RYUJINX_TARGET_RELEASE_CHANNEL_OWNER: "Ryubing"
|
||||
RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO: "Ryujinx"
|
||||
RYUJINX_TARGET_RELEASE_CHANNEL_REPO: "Ryujinx-Canary"
|
||||
RYUJINX_TARGET_RELEASE_CHANNEL_REPO: "Canary-Releases"
|
||||
RELEASE: 1
|
||||
|
||||
jobs:
|
||||
@@ -43,8 +43,8 @@ jobs:
|
||||
with:
|
||||
script: |
|
||||
github.rest.git.createRef({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
owner: "${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}",
|
||||
repo: "${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}",
|
||||
ref: 'refs/tags/Canary-${{ steps.version_info.outputs.build_version }}',
|
||||
sha: context.sha
|
||||
})
|
||||
@@ -64,7 +64,7 @@ jobs:
|
||||
| Windows 64-bit | [Canary Windows Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-win_x64.zip) |
|
||||
| Linux 64-bit | [Canary Linux Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz) |
|
||||
| Linux ARM 64-bit | [Canary Linux ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) |
|
||||
| macOS | [Canary macOS artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) |
|
||||
| macOS | [Canary macOS Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) |
|
||||
|
||||
**Full Changelog**: https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}/compare/Canary-${{ steps.version_info.outputs.prev_build_version }}...Canary-${{ steps.version_info.outputs.build_version }}
|
||||
omitBodyDuringUpdate: true
|
||||
@@ -196,16 +196,16 @@ jobs:
|
||||
body: |
|
||||
# Canary builds:
|
||||
|
||||
These builds are experimental and may sometimes not work, use [regular builds](https://github.com/GreemDev/Ryujinx/releases/latest) instead if that sounds like something you don't want to deal with.
|
||||
|
||||
These builds are experimental and may sometimes not work, use [regular builds](https://github.com/${{ github.repository }}/releases/latest) instead if that sounds like something you don't want to deal with.
|
||||
|
||||
| Platform | Artifact |
|
||||
|--|--|
|
||||
| Windows 64-bit | https://github.com/${{ github.repository }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-win_x64.zip |
|
||||
| Linux 64-bit | https://github.com/${{ github.repository }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz |
|
||||
| Linux ARM 64-bit | https://github.com/${{ github.repository }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz |
|
||||
| macOS | https://github.com/${{ github.repository }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz |
|
||||
| Windows 64-bit | [Canary Windows Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-win_x64.zip) |
|
||||
| Linux 64-bit | [Canary Linux Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz) |
|
||||
| Linux ARM 64-bit | [Canary Linux ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) |
|
||||
| macOS | [Canary macOS Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) |
|
||||
|
||||
"**Full Changelog**: https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}/compare/Canary-${{ steps.version_info.outputs.prev_build_version }}...Canary-${{ steps.version_info.outputs.build_version }}"
|
||||
**Full Changelog**: https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}/compare/Canary-${{ steps.version_info.outputs.prev_build_version }}...Canary-${{ steps.version_info.outputs.build_version }}
|
||||
omitBodyDuringUpdate: true
|
||||
allowUpdates: true
|
||||
replacesArtifacts: true
|
||||
|
||||
30
.github/workflows/release.yml
vendored
30
.github/workflows/release.yml
vendored
@@ -21,7 +21,7 @@ env:
|
||||
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
||||
RYUJINX_BASE_VERSION: "1.2"
|
||||
RYUJINX_TARGET_RELEASE_CHANNEL_NAME: "release"
|
||||
RYUJINX_TARGET_RELEASE_CHANNEL_OWNER: "GreemDev"
|
||||
RYUJINX_TARGET_RELEASE_CHANNEL_OWNER: "Ryubing"
|
||||
RYUJINX_TARGET_RELEASE_CHANNEL_REPO: "Ryujinx"
|
||||
RELEASE: 1
|
||||
|
||||
@@ -42,8 +42,8 @@ jobs:
|
||||
with:
|
||||
script: |
|
||||
github.rest.git.createRef({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
owner: "${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}",
|
||||
repo: "${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}",
|
||||
ref: 'refs/tags/${{ steps.version_info.outputs.build_version }}',
|
||||
sha: context.sha
|
||||
})
|
||||
@@ -54,13 +54,13 @@ jobs:
|
||||
name: ${{ steps.version_info.outputs.build_version }}
|
||||
tag: ${{ steps.version_info.outputs.build_version }}
|
||||
body: |
|
||||
# Regular builds:
|
||||
# Stable builds:
|
||||
| Platform | Artifact |
|
||||
|--|--|
|
||||
| Windows 64-bit | [Release Windows Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-win_x64.zip) |
|
||||
| Linux 64-bit | [Release Linux Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz) |
|
||||
| Linux ARM 64-bit | [Release Linux ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) |
|
||||
| macOS | [Release macOS Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) |
|
||||
| Windows 64-bit | [Stable Windows Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-win_x64.zip) |
|
||||
| Linux 64-bit | [Stable Linux Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz) |
|
||||
| Linux ARM 64-bit | [Stable Linux ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) |
|
||||
| macOS | [Stable macOS Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) |
|
||||
|
||||
**Full Changelog**: https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }}
|
||||
omitBodyDuringUpdate: true
|
||||
@@ -186,15 +186,15 @@ jobs:
|
||||
artifacts: "release_output/*.tar.gz,release_output/*.zip,release_output/*AppImage*"
|
||||
tag: ${{ steps.version_info.outputs.build_version }}
|
||||
body: |
|
||||
# Regular builds:
|
||||
# Stable builds:
|
||||
| Platform | Artifact |
|
||||
|--|--|
|
||||
| Windows 64-bit | https://github.com/${{ github.repository }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-win_x64.zip |
|
||||
| Linux 64-bit | https://github.com/${{ github.repository }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz |
|
||||
| Linux ARM 64-bit | https://github.com/${{ github.repository }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz |
|
||||
| macOS | https://github.com/${{ github.repository }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz |
|
||||
|
||||
"**Full Changelog**: https://github.com/${{ github.repository }}/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }}"
|
||||
| Windows 64-bit | [Stable Windows Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-win_x64.zip) |
|
||||
| Linux 64-bit | [Stable Linux Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz) |
|
||||
| Linux ARM 64-bit | [Stable Linux ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) |
|
||||
| macOS | [Stable macOS Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) |
|
||||
|
||||
**Full Changelog**: https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }}
|
||||
omitBodyDuringUpdate: true
|
||||
allowUpdates: true
|
||||
replacesArtifacts: true
|
||||
|
||||
@@ -261,13 +261,12 @@ Global
|
||||
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C08931FA-1191-417A-864F-3882D93E683B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C08931FA-1191-417A-864F-3882D93E683B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C08931FA-1191-417A-864F-3882D93E683B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C08931FA-1191-417A-864F-3882D93E683B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{81EA598C-DBA1-40B0-8DA4-4796B78F2037}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{81EA598C-DBA1-40B0-8DA4-4796B78F2037}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{81EA598C-DBA1-40B0-8DA4-4796B78F2037}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
using System;
|
||||
using Microsoft.Build.Utilities;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using Newtonsoft.Json;
|
||||
using Microsoft.Build.Framework;
|
||||
|
||||
namespace Ryujinx.BuildValidationTasks
|
||||
{
|
||||
public class LocaleValidationTask : Task
|
||||
{
|
||||
public override bool Execute()
|
||||
{
|
||||
string path = System.Reflection.Assembly.GetExecutingAssembly().Location;
|
||||
|
||||
if (path.Split(["src"], StringSplitOptions.None).Length == 1)
|
||||
{
|
||||
//i assume that we are in a build directory in the solution dir
|
||||
path = new FileInfo(path).Directory!.Parent!.GetDirectories("src")[0].GetDirectories("Ryujinx")[0].GetDirectories("Assets")[0].GetFiles("locales.json")[0].FullName;
|
||||
}
|
||||
else
|
||||
{
|
||||
path = path.Split(["src"], StringSplitOptions.None)[0];
|
||||
path = new FileInfo(path).Directory!.GetDirectories("src")[0].GetDirectories("Ryujinx")[0].GetDirectories("Assets")[0].GetFiles("locales.json")[0].FullName;
|
||||
}
|
||||
|
||||
string data;
|
||||
|
||||
using (StreamReader sr = new(path))
|
||||
{
|
||||
data = sr.ReadToEnd();
|
||||
}
|
||||
|
||||
LocalesJson json = JsonConvert.DeserializeObject<LocalesJson>(data);
|
||||
|
||||
for (int i = 0; i < json.Locales.Count; i++)
|
||||
{
|
||||
LocalesEntry locale = json.Locales[i];
|
||||
|
||||
foreach (string langCode in json.Languages.Where(it => !locale.Translations.ContainsKey(it)))
|
||||
{
|
||||
locale.Translations.Add(langCode, string.Empty);
|
||||
Log.LogMessage(MessageImportance.High, $"Added '{langCode}' to Locale '{locale.ID}'");
|
||||
}
|
||||
|
||||
locale.Translations = locale.Translations.OrderBy(pair => pair.Key).ToDictionary(pair => pair.Key, pair => pair.Value);
|
||||
json.Locales[i] = locale;
|
||||
}
|
||||
|
||||
string jsonString = JsonConvert.SerializeObject(json, Formatting.Indented);
|
||||
|
||||
using (StreamWriter sw = new(path))
|
||||
{
|
||||
sw.Write(jsonString);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
struct LocalesJson
|
||||
{
|
||||
public List<string> Languages { get; set; }
|
||||
public List<LocalesEntry> Locales { get; set; }
|
||||
}
|
||||
|
||||
struct LocalesEntry
|
||||
{
|
||||
public string ID { get; set; }
|
||||
public Dictionary<string, string> Translations { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
117
src/Ryujinx.BuildValidationTasks/LocalesValidationTask.cs
Normal file
117
src/Ryujinx.BuildValidationTasks/LocalesValidationTask.cs
Normal file
@@ -0,0 +1,117 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
using System.Text.Encodings.Web;
|
||||
|
||||
namespace Ryujinx.BuildValidationTasks
|
||||
{
|
||||
public class LocalesValidationTask : ValidationTask
|
||||
{
|
||||
public LocalesValidationTask() { }
|
||||
|
||||
public bool Execute(string projectPath, bool isGitRunner)
|
||||
{
|
||||
Console.WriteLine("Running Locale Validation Task...");
|
||||
|
||||
string path = projectPath + "src/Ryujinx/Assets/locales.json";
|
||||
string data;
|
||||
|
||||
using (StreamReader sr = new(path))
|
||||
{
|
||||
data = sr.ReadToEnd();
|
||||
}
|
||||
|
||||
LocalesJson json;
|
||||
|
||||
if (isGitRunner && data.Contains("\r\n"))
|
||||
throw new FormatException("locales.json is using CRLF line endings! It should be using LF line endings, build locally to fix...");
|
||||
|
||||
try
|
||||
{
|
||||
json = JsonSerializer.Deserialize<LocalesJson>(data);
|
||||
|
||||
}
|
||||
catch (JsonException e)
|
||||
{
|
||||
throw new JsonException(e.Message); //shorter and easier stacktrace
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool encounteredIssue = false;
|
||||
|
||||
for (int i = 0; i < json.Locales.Count; i++)
|
||||
{
|
||||
LocalesEntry locale = json.Locales[i];
|
||||
|
||||
foreach (string langCode in json.Languages.Where(lang => !locale.Translations.ContainsKey(lang)))
|
||||
{
|
||||
encounteredIssue = true;
|
||||
|
||||
if (!isGitRunner)
|
||||
{
|
||||
locale.Translations.Add(langCode, string.Empty);
|
||||
Console.WriteLine($"Added '{langCode}' to Locale '{locale.ID}'");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"Missing '{langCode}' in Locale '{locale.ID}'!");
|
||||
}
|
||||
}
|
||||
|
||||
foreach (string langCode in json.Languages.Where(lang => locale.Translations.ContainsKey(lang) && lang != "en_US" && locale.Translations[lang] == locale.Translations["en_US"]))
|
||||
{
|
||||
encounteredIssue = true;
|
||||
|
||||
if (!isGitRunner)
|
||||
{
|
||||
locale.Translations[langCode] = string.Empty;
|
||||
Console.WriteLine($"Lanugage '{langCode}' is a duplicate of en_US in Locale '{locale.ID}'! Resetting it...");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"Lanugage '{langCode}' is a duplicate of en_US in Locale '{locale.ID}'!");
|
||||
}
|
||||
}
|
||||
|
||||
locale.Translations = locale.Translations.OrderBy(pair => pair.Key).ToDictionary(pair => pair.Key, pair => pair.Value);
|
||||
json.Locales[i] = locale;
|
||||
}
|
||||
|
||||
if (isGitRunner && encounteredIssue)
|
||||
throw new JsonException("1 or more locales are invalid!");
|
||||
|
||||
JsonSerializerOptions jsonOptions = new JsonSerializerOptions()
|
||||
{
|
||||
WriteIndented = true,
|
||||
NewLine = "\n",
|
||||
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
|
||||
};
|
||||
|
||||
string jsonString = JsonSerializer.Serialize(json, jsonOptions);
|
||||
|
||||
using (StreamWriter sw = new(path))
|
||||
{
|
||||
sw.Write(jsonString);
|
||||
}
|
||||
|
||||
Console.WriteLine("Finished Locale Validation Task!");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
struct LocalesJson
|
||||
{
|
||||
public List<string> Languages { get; set; }
|
||||
public List<LocalesEntry> Locales { get; set; }
|
||||
}
|
||||
|
||||
struct LocalesEntry
|
||||
{
|
||||
public string ID { get; set; }
|
||||
public Dictionary<string, string> Translations { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
40
src/Ryujinx.BuildValidationTasks/Program.cs
Normal file
40
src/Ryujinx.BuildValidationTasks/Program.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ryujinx.BuildValidationTasks
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
// Display the number of command line arguments.
|
||||
if (args.Length == 0)
|
||||
throw new ArgumentException("Error: too few arguments!");
|
||||
|
||||
string path = args[0];
|
||||
|
||||
if (string.IsNullOrEmpty(path))
|
||||
throw new ArgumentException("Error: path is null or empty!");
|
||||
|
||||
if (!Path.Exists(path))
|
||||
throw new FileLoadException($"path {{{path}}} does not exist!");
|
||||
|
||||
path = Path.GetFullPath(path);
|
||||
|
||||
if (!Directory.GetDirectories(path).Contains($"{path}src"))
|
||||
throw new FileLoadException($"path {{{path}}} is not a valid ryujinx project!");
|
||||
|
||||
bool isGitRunner = path.Contains("runner") || path.Contains("D:\\a\\Ryujinx\\Ryujinx");
|
||||
if (isGitRunner)
|
||||
Console.WriteLine("Is Git Runner!");
|
||||
|
||||
// Run tasks
|
||||
// Pass extra info needed in the task constructors
|
||||
new LocalesValidationTask().Execute(path, isGitRunner);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,16 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
<OutputType>Exe</OutputType>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Build.Utilities.Core" />
|
||||
<PackageReference Include="Newtonsoft.Json" />
|
||||
</ItemGroup>
|
||||
<Target Name="PostBuildTarget" AfterTargets="AfterBuild">
|
||||
<Message Text="Running Validation Project" Importance="high" />
|
||||
|
||||
<UsingTask TaskName="Ryujinx.BuildValidationTasks.LocaleValidationTask" TaskFactory="TaskHostFactory" AssemblyFile="$(OutDir)Ryujinx.BuildValidationTasks.dll" />
|
||||
|
||||
<Target Name="LocalesJsonValidation" AfterTargets="AfterRebuild">
|
||||
<LocaleValidationTask />
|
||||
<Exec WorkingDirectory="$(ProjectDir)bin\Debug\$(TargetFramework)\"
|
||||
Command="dotnet Ryujinx.BuildValidationTasks.dll "$(ProjectDir)..\..\\""
|
||||
ConsoleToMsBuild="true"
|
||||
/>
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
</Project>
|
||||
13
src/Ryujinx.BuildValidationTasks/ValidationTask.cs
Normal file
13
src/Ryujinx.BuildValidationTasks/ValidationTask.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ryujinx.BuildValidationTasks
|
||||
{
|
||||
public interface ValidationTask
|
||||
{
|
||||
public bool Execute(string projectPath, bool isGitRunner);
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,8 @@ namespace Ryujinx.UI.App.Common
|
||||
public string Path { get; set; }
|
||||
public BlitStruct<ApplicationControlProperty> ControlHolder { get; set; }
|
||||
|
||||
public bool HasControlHolder => ControlHolder.ByteSpan.Length > 0;
|
||||
|
||||
public string TimePlayedString => ValueFormatUtils.FormatTimeSpan(TimePlayed);
|
||||
|
||||
public string LastPlayedString => ValueFormatUtils.FormatDateTime(LastPlayed)?.Replace(" ", "\n") ?? LocalizedNever();
|
||||
|
||||
@@ -789,16 +789,15 @@ namespace Ryujinx.UI.App.Common
|
||||
using HttpClient httpClient = new HttpClient();
|
||||
string ldnGameDataArrayString = await httpClient.GetStringAsync($"https://{ldnWebHost}/api/public_games");
|
||||
ldnGameDataArray = JsonHelper.Deserialize(ldnGameDataArrayString, _ldnDataSerializerContext.IEnumerableLdnGameData);
|
||||
var evt = new LdnGameDataReceivedEventArgs
|
||||
LdnGameDataReceived?.Invoke(null, new LdnGameDataReceivedEventArgs
|
||||
{
|
||||
LdnData = ldnGameDataArray
|
||||
};
|
||||
LdnGameDataReceived?.Invoke(null, evt);
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warning?.Print(LogClass.Application, $"Failed to fetch the public games JSON from the API. Player and game count in the game list will be unavailable.\n{ex.Message}");
|
||||
LdnGameDataReceived?.Invoke(null, new LdnGameDataReceivedEventArgs()
|
||||
LdnGameDataReceived?.Invoke(null, new LdnGameDataReceivedEventArgs
|
||||
{
|
||||
LdnData = Array.Empty<LdnGameData>()
|
||||
});
|
||||
@@ -806,7 +805,7 @@ namespace Ryujinx.UI.App.Common
|
||||
}
|
||||
else
|
||||
{
|
||||
LdnGameDataReceived?.Invoke(null, new LdnGameDataReceivedEventArgs()
|
||||
LdnGameDataReceived?.Invoke(null, new LdnGameDataReceivedEventArgs
|
||||
{
|
||||
LdnData = Array.Empty<LdnGameData>()
|
||||
});
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
using LibHac.Ns;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Ryujinx.UI.App.Common
|
||||
{
|
||||
@@ -12,5 +15,28 @@ namespace Ryujinx.UI.App.Common
|
||||
public string Mode { get; set; }
|
||||
public string Status { get; set; }
|
||||
public IEnumerable<string> Players { get; set; }
|
||||
|
||||
public static Array GetArrayForApp(
|
||||
IEnumerable<LdnGameData> receivedData, ref ApplicationControlProperty acp)
|
||||
{
|
||||
LibHac.Common.FixedArrays.Array8<ulong> communicationId = acp.LocalCommunicationId;
|
||||
|
||||
return new Array(receivedData.Where(game =>
|
||||
communicationId.Items.Contains(Convert.ToUInt64(game.TitleId, 16))
|
||||
));
|
||||
}
|
||||
|
||||
public class Array
|
||||
{
|
||||
private readonly LdnGameData[] _ldnDatas;
|
||||
|
||||
internal Array(IEnumerable<LdnGameData> receivedData)
|
||||
{
|
||||
_ldnDatas = receivedData.ToArray();
|
||||
}
|
||||
|
||||
public int PlayerCount => _ldnDatas.Sum(it => it.PlayerCount);
|
||||
public int GameCount => _ldnDatas.Length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -13,9 +13,13 @@
|
||||
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target Name="BuildValidationProj" BeforeTargets="BeforeRebuild">
|
||||
<MSBuild Projects="..\Ryujinx.BuildValidationTasks\Ryujinx.BuildValidationTasks.csproj" Targets="Rebuild">
|
||||
</MSBuild>
|
||||
<Target Name="BuildValidationProj" BeforeTargets="BeforeBuild">
|
||||
<Message Text="Building Validation Project for $(TargetFramework)" Importance="high" Condition="'$(RuntimeIdentifier)' == ''" />
|
||||
<Message Text="Building Validation Project for $(TargetFramework) with runtime $(RuntimeIdentifier)" Importance="high" Condition="'$(RuntimeIdentifier)' != ''" />
|
||||
<Exec WorkingDirectory="..\Ryujinx.BuildValidationTasks\" Command="dotnet restore Ryujinx.BuildValidationTasks.csproj --force --ucr true" Condition="'$(RuntimeIdentifier)' == ''" />
|
||||
<Exec WorkingDirectory="..\Ryujinx.BuildValidationTasks\" Command="dotnet restore Ryujinx.BuildValidationTasks.csproj --force --runtime $(RuntimeIdentifier)" Condition="'$(RuntimeIdentifier)' != ''" />
|
||||
<MSBuild Projects="..\Ryujinx.BuildValidationTasks\Ryujinx.BuildValidationTasks.csproj" Properties="Configuration=Debug" />
|
||||
|
||||
</Target>
|
||||
|
||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="$([MSBuild]::IsOSPlatform('OSX'))">
|
||||
|
||||
@@ -33,8 +33,11 @@ namespace Ryujinx.Ava
|
||||
.ApplicationLifetime.Cast<IClassicDesktopStyleApplicationLifetime>()
|
||||
.MainWindow.Cast<MainWindow>();
|
||||
|
||||
public static bool IsClipboardAvailable(out IClipboard clipboard)
|
||||
=> (clipboard = MainWindow.Clipboard) != null;
|
||||
public static bool IsClipboardAvailable(out IClipboard clipboard)
|
||||
{
|
||||
clipboard = MainWindow.Clipboard;
|
||||
return clipboard != null;
|
||||
}
|
||||
|
||||
public static void SetTaskbarProgress(TaskBarProgressBarState state) => MainWindow.PlatformFeatures.SetTaskBarProgressBarState(state);
|
||||
public static void SetTaskbarProgressValue(ulong current, ulong total) => MainWindow.PlatformFeatures.SetTaskBarProgressBarValue(current, total);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using Gommon;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Ncm;
|
||||
using Ryujinx.Ava.UI.ViewModels;
|
||||
@@ -47,7 +48,7 @@ namespace Ryujinx.Ava.UI.Models
|
||||
TitleId = info.ProgramId;
|
||||
UserId = info.UserId;
|
||||
|
||||
var appData = MainWindow.MainWindowViewModel.Applications.FirstOrDefault(x => x.IdString.Equals(TitleIdString, StringComparison.OrdinalIgnoreCase));
|
||||
var appData = RyujinxApp.MainWindow.ViewModel.Applications.FirstOrDefault(x => x.IdString.EqualsIgnoreCase(TitleIdString));
|
||||
|
||||
InGameList = appData != null;
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ using Avalonia.Threading;
|
||||
using DynamicData;
|
||||
using DynamicData.Binding;
|
||||
using FluentAvalonia.UI.Controls;
|
||||
using Gommon;
|
||||
using LibHac.Common;
|
||||
using LibHac.Ns;
|
||||
using Ryujinx.Ava.Common;
|
||||
@@ -109,8 +110,13 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
|
||||
private bool _areMimeTypesRegistered = FileAssociationHelper.AreMimeTypesRegistered;
|
||||
private bool _canUpdate = true;
|
||||
private Cursor _cursor;
|
||||
private string _title;
|
||||
private ApplicationData _currentApplicationData;
|
||||
private readonly AutoResetEvent _rendererWaitEvent;
|
||||
private WindowState _windowState;
|
||||
private double _windowWidth;
|
||||
private double _windowHeight;
|
||||
private int _customVSyncInterval;
|
||||
private int _customVSyncIntervalPercentageProxy;
|
||||
|
||||
@@ -119,8 +125,9 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
|
||||
public ApplicationData ListSelectedApplication;
|
||||
public ApplicationData GridSelectedApplication;
|
||||
|
||||
public IEnumerable<LdnGameData> LastLdnGameData;
|
||||
|
||||
// Key is Title ID
|
||||
public SafeDictionary<string, LdnGameData.Array> LdnData = [];
|
||||
|
||||
// The UI specifically uses a thicker bordered variant of the icon to avoid crunching out the border at lower resolutions.
|
||||
// For an example of this, download canary 1.2.95, then open the settings menu, and look at the icon in the top-left.
|
||||
@@ -211,7 +218,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
|
||||
public bool CanUpdate
|
||||
{
|
||||
get => _canUpdate && EnableNonGameRunningControls && Updater.CanUpdate();
|
||||
get => _canUpdate && EnableNonGameRunningControls && Updater.CanUpdate(false);
|
||||
set
|
||||
{
|
||||
_canUpdate = value;
|
||||
@@ -221,8 +228,12 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
|
||||
public Cursor Cursor
|
||||
{
|
||||
get => Window.Cursor;
|
||||
set => Window.Cursor = value;
|
||||
get => _cursor;
|
||||
set
|
||||
{
|
||||
_cursor = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public ReadOnlyObservableCollection<ApplicationData> AppsObservableList
|
||||
@@ -804,23 +815,35 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
|
||||
public WindowState WindowState
|
||||
{
|
||||
get => Window.WindowState;
|
||||
get => _windowState;
|
||||
internal set
|
||||
{
|
||||
Window.WindowState = value;
|
||||
_windowState = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public double WindowWidth
|
||||
{
|
||||
get => Window.Width;
|
||||
set => Window.Width = value;
|
||||
get => _windowWidth;
|
||||
set
|
||||
{
|
||||
_windowWidth = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public double WindowHeight
|
||||
{
|
||||
get => Window.Height;
|
||||
set => Window.Height = value;
|
||||
get => _windowHeight;
|
||||
set
|
||||
{
|
||||
_windowHeight = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsGrid => Glyph == Glyph.Grid;
|
||||
@@ -868,11 +891,11 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
|
||||
public string Title
|
||||
{
|
||||
get => Window.Title;
|
||||
get => _title;
|
||||
set
|
||||
{
|
||||
Window.Title = value;
|
||||
|
||||
_title = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -750,7 +750,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
config.ToFileFormat().SaveConfig(Program.ConfigurationPath);
|
||||
|
||||
MainWindow.UpdateGraphicsConfig();
|
||||
MainWindow.MainWindowViewModel.VSyncModeSettingChanged();
|
||||
RyujinxApp.MainWindow.ViewModel.VSyncModeSettingChanged();
|
||||
|
||||
SaveSettingsEvent?.Invoke();
|
||||
|
||||
|
||||
@@ -9,6 +9,11 @@
|
||||
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
|
||||
xmlns:controls="clr-namespace:Ryujinx.Ava.UI.Controls"
|
||||
xmlns:main="clr-namespace:Ryujinx.Ava.UI.Views.Main"
|
||||
Cursor="{Binding Cursor}"
|
||||
Title="{Binding Title}"
|
||||
WindowState="{Binding WindowState}"
|
||||
Width="{Binding WindowWidth}"
|
||||
Height="{Binding WindowHeight}"
|
||||
MinWidth="800"
|
||||
MinHeight="500"
|
||||
d:DesignHeight="720"
|
||||
|
||||
@@ -39,8 +39,6 @@ namespace Ryujinx.Ava.UI.Windows
|
||||
{
|
||||
public partial class MainWindow : StyleableAppWindow
|
||||
{
|
||||
internal static MainWindowViewModel MainWindowViewModel { get; private set; }
|
||||
|
||||
public MainWindowViewModel ViewModel { get; }
|
||||
|
||||
internal readonly AvaHostUIHandler UiHandler;
|
||||
@@ -76,7 +74,7 @@ namespace Ryujinx.Ava.UI.Windows
|
||||
|
||||
public MainWindow()
|
||||
{
|
||||
DataContext = ViewModel = MainWindowViewModel = new MainWindowViewModel
|
||||
DataContext = ViewModel = new MainWindowViewModel
|
||||
{
|
||||
Window = this
|
||||
};
|
||||
@@ -169,24 +167,31 @@ namespace Ryujinx.Ava.UI.Windows
|
||||
{
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
{
|
||||
var ldnGameDataArray = e.LdnData;
|
||||
ViewModel.LastLdnGameData = ldnGameDataArray;
|
||||
var ldnGameDataArray = e.LdnData.ToList();
|
||||
ViewModel.LdnData.Clear();
|
||||
foreach (var application in ViewModel.Applications)
|
||||
{
|
||||
ref var controlHolder = ref application.ControlHolder.Value;
|
||||
|
||||
ViewModel.LdnData[application.IdString] =
|
||||
LdnGameData.GetArrayForApp(
|
||||
ldnGameDataArray,
|
||||
ref controlHolder
|
||||
);
|
||||
|
||||
UpdateApplicationWithLdnData(application);
|
||||
}
|
||||
|
||||
ViewModel.RefreshView();
|
||||
});
|
||||
}
|
||||
|
||||
private void UpdateApplicationWithLdnData(ApplicationData application)
|
||||
{
|
||||
if (application.ControlHolder.ByteSpan.Length > 0 && ViewModel.LastLdnGameData != null)
|
||||
if (application.HasControlHolder && ViewModel.LdnData.TryGetValue(application.IdString, out var ldnGameDatas))
|
||||
{
|
||||
IEnumerable<LdnGameData> ldnGameData = ViewModel.LastLdnGameData.Where(game => application.ControlHolder.Value.LocalCommunicationId.Items.Contains(Convert.ToUInt64(game.TitleId, 16)));
|
||||
|
||||
application.PlayerCount = ldnGameData.Sum(game => game.PlayerCount);
|
||||
application.GameCount = ldnGameData.Count();
|
||||
application.PlayerCount = ldnGameDatas.PlayerCount;
|
||||
application.GameCount = ldnGameDatas.GameCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user