Compare commits

...

2 Commits

Author SHA1 Message Date
Isaac Marovitz
4fbc978e73 Switch to Microsoft.IdentityModel.JsonWebTokens (#6108)
* Switch to `Microsoft.IdentityModel.JsonWebTokens`

* Formatting
2024-01-13 11:39:00 +01:00
Isaac Marovitz
1a45dc8df8 Ava UI: RTL Language Support (#5619)
* Add Hebrew locale files to ItemGroups

* Align all windows RTL for testing

This should be controlled with a binding that selects the appropriate layout based on current language

* Update FlowDirection as Locale changes

* Fix Settings NavigationViewItem FlowDirection

* Fix remaining text

* Fix input menu directionality

* Fix RTL not rendering

* Fix rebase errors
2024-01-13 01:42:42 +01:00
17 changed files with 82 additions and 52 deletions

View File

@@ -21,6 +21,7 @@
<PackageVersion Include="LibHac" Version="0.19.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.7.0" />
<PackageVersion Include="Microsoft.IdentityModel.JsonWebTokens" Version="7.2.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageVersion Include="Microsoft.IO.RecyclableMemoryStream" Version="2.3.2" />
<PackageVersion Include="MsgPack.Cli" Version="1.0.1" />
@@ -46,9 +47,8 @@
<PackageVersion Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta11" />
<PackageVersion Include="SPB" Version="0.0.4-build28" />
<PackageVersion Include="System.Drawing.Common" Version="8.0.0" />
<PackageVersion Include="System.IdentityModel.Tokens.Jwt" Version="7.0.3" />
<PackageVersion Include="System.IO.Hashing" Version="8.0.0" />
<PackageVersion Include="System.Management" Version="8.0.0" />
<PackageVersion Include="UnicornEngine.Unicorn" Version="2.0.2-rc1-fb78016" />
</ItemGroup>
</Project>
</Project>

View File

@@ -16,8 +16,10 @@ namespace Ryujinx.Ava.Common.Locale
private readonly Dictionary<LocaleKeys, string> _localeStrings;
private Dictionary<LocaleKeys, string> _localeDefaultStrings;
private readonly ConcurrentDictionary<LocaleKeys, object[]> _dynamicValues;
private string _localeLanguageCode;
public static LocaleManager Instance { get; } = new();
public event Action LocaleChanged;
public LocaleManager()
{
@@ -104,6 +106,15 @@ namespace Ryujinx.Ava.Common.Locale
}
}
public bool IsRTL()
{
return _localeLanguageCode switch
{
"he_IL" => true,
_ => false
};
}
public string UpdateAndGetDynamicValue(LocaleKeys key, params object[] values)
{
_dynamicValues[key] = values;
@@ -124,6 +135,9 @@ namespace Ryujinx.Ava.Common.Locale
{
this[item.Key] = item.Value;
}
_localeLanguageCode = languageCode;
LocaleChanged?.Invoke();
}
private static Dictionary<LocaleKeys, string> LoadJsonLanguage(string languageCode = DefaultLanguageCode)

View File

@@ -119,6 +119,7 @@
<None Remove="Assets\Locales\en_US.json" />
<None Remove="Assets\Locales\es_ES.json" />
<None Remove="Assets\Locales\fr_FR.json" />
<None Remove="Assets\Locales\he_IL.json" />
<None Remove="Assets\Locales\de_DE.json" />
<None Remove="Assets\Locales\it_IT.json" />
<None Remove="Assets\Locales\ja_JP.json" />
@@ -143,6 +144,7 @@
<EmbeddedResource Include="Assets\Locales\en_US.json" />
<EmbeddedResource Include="Assets\Locales\es_ES.json" />
<EmbeddedResource Include="Assets\Locales\fr_FR.json" />
<EmbeddedResource Include="Assets\Locales\he_IL.json" />
<EmbeddedResource Include="Assets\Locales\de_DE.json" />
<EmbeddedResource Include="Assets\Locales\it_IT.json" />
<EmbeddedResource Include="Assets\Locales\ja_JP.json" />

View File

@@ -86,17 +86,17 @@
HorizontalAlignment="Stretch"
FontWeight="Bold"
Text="{Binding TitleName}"
TextAlignment="Left"
TextAlignment="Start"
TextWrapping="Wrap" />
<TextBlock
HorizontalAlignment="Stretch"
Text="{Binding Developer}"
TextAlignment="Left"
TextAlignment="Start"
TextWrapping="Wrap" />
<TextBlock
HorizontalAlignment="Stretch"
Text="{Binding Version}"
TextAlignment="Left"
TextAlignment="Start"
TextWrapping="Wrap" />
</StackPanel>
</Border>
@@ -110,12 +110,12 @@
<TextBlock
HorizontalAlignment="Stretch"
Text="{Binding TitleId}"
TextAlignment="Left"
TextAlignment="Start"
TextWrapping="Wrap" />
<TextBlock
HorizontalAlignment="Stretch"
Text="{Binding FileExtension}"
TextAlignment="Left"
TextAlignment="Start"
TextWrapping="Wrap" />
</StackPanel>
<StackPanel
@@ -127,17 +127,17 @@
<TextBlock
HorizontalAlignment="Stretch"
Text="{Binding TimePlayedString}"
TextAlignment="Right"
TextAlignment="End"
TextWrapping="Wrap" />
<TextBlock
HorizontalAlignment="Stretch"
Text="{Binding LastPlayedString, Converter={helpers:LocalizedNeverConverter}}"
TextAlignment="Right"
TextAlignment="End"
TextWrapping="Wrap" />
<TextBlock
HorizontalAlignment="Stretch"
Text="{Binding FileSizeString}"
TextAlignment="Right"
TextAlignment="End"
TextWrapping="Wrap" />
</StackPanel>
<ui:SymbolIcon

View File

@@ -1,11 +1,12 @@
<UserControl
<UserControl
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignWidth="800"
mc:Ignorable="d"
d:DesignWidth="800"
d:DesignHeight="450"
x:Class="Ryujinx.Ava.UI.Renderer.RendererHost"
FlowDirection="LeftToRight"
Focusable="True">
</UserControl>
</UserControl>

View File

@@ -101,7 +101,7 @@
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
SelectedIndex="0"
ItemsSource="{Binding ProfilesList}"
ItemsSource="{Binding ProfilesList}"
Text="{Binding ProfileName, Mode=TwoWay}" />
<Button
Grid.Column="2"
@@ -218,6 +218,7 @@
<Grid
Name="SettingButtons"
MinHeight="450"
FlowDirection="LeftToRight"
IsVisible="{Binding ShowSettings}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />

View File

@@ -88,7 +88,7 @@
IsVisible="{Binding !ShowLoadProgress}"
PointerReleased="VsyncStatus_PointerReleased"
Text="VSync"
TextAlignment="Left" />
TextAlignment="Start" />
<Border
Width="2"
Height="12"
@@ -105,7 +105,7 @@
IsVisible="{Binding !ShowLoadProgress}"
PointerReleased="DockedStatus_PointerReleased"
Text="{Binding DockedStatusText}"
TextAlignment="Left" />
TextAlignment="Start" />
<Border
Width="2"
Height="12"
@@ -225,7 +225,7 @@
VerticalAlignment="Center"
IsVisible="{Binding !ShowLoadProgress}"
Text="{Binding GameStatusText}"
TextAlignment="Left" />
TextAlignment="Start" />
<Border
Width="2"
Height="12"
@@ -240,7 +240,7 @@
VerticalAlignment="Center"
IsVisible="{Binding !ShowLoadProgress}"
Text="{Binding FifoStatusText}"
TextAlignment="Left" />
TextAlignment="Start" />
<Border
Width="2"
Height="12"
@@ -255,7 +255,7 @@
VerticalAlignment="Center"
IsVisible="{Binding !ShowLoadProgress}"
Text="{Binding BackendText}"
TextAlignment="Left" />
TextAlignment="Start" />
<Border
Width="2"
Height="12"
@@ -270,7 +270,7 @@
VerticalAlignment="Center"
IsVisible="{Binding !ShowLoadProgress}"
Text="{Binding GpuNameText}"
TextAlignment="Left" />
TextAlignment="Start" />
</StackPanel>
<StackPanel
Grid.Column="3"

View File

@@ -27,7 +27,7 @@
Grid.Row="0"
TextWrapping="Wrap"
HorizontalAlignment="Left"
TextAlignment="Left"
TextAlignment="Start"
Text="{locale:Locale ProfileImageSelectionNote}" />
<StackPanel
Grid.Row="2"
@@ -59,4 +59,4 @@
</Button>
</StackPanel>
</Grid>
</UserControl>
</UserControl>

View File

@@ -49,7 +49,7 @@
<TextBlock
HorizontalAlignment="Stretch"
Text="{Binding UserId}"
TextAlignment="Left"
TextAlignment="Start"
TextWrapping="Wrap" />
<Button Grid.Column="1"
HorizontalAlignment="Right"
@@ -79,4 +79,4 @@
</Button>
</StackPanel>
</Grid>
</UserControl>
</UserControl>

View File

@@ -238,7 +238,7 @@
<TextBlock
FontSize="10"
Text="{locale:Locale AboutRyujinxContributorsButtonHeader}"
TextAlignment="Right"
TextAlignment="End"
ToolTip.Tip="{locale:Locale AboutRyujinxMaintainersContentTooltipMessage}" />
</Button>
</StackPanel>

View File

@@ -72,4 +72,4 @@
Click="CancelButton_Click" />
</Grid>
</Grid>
</window:StyleableWindow>
</window:StyleableWindow>

View File

@@ -158,7 +158,7 @@
FontWeight="Bold"
IsVisible="{Binding ShowLoadProgress}"
Text="{Binding LoadHeading}"
TextAlignment="Left"
TextAlignment="Start"
TextWrapping="Wrap"
MaxWidth="500" />
<Border
@@ -192,7 +192,7 @@
FontSize="18"
IsVisible="{Binding ShowLoadProgress}"
Text="{Binding CacheLoadStatus}"
TextAlignment="Left"
TextAlignment="Start"
MaxWidth="500" />
</Grid>
</Grid>
@@ -202,4 +202,4 @@
Grid.Row="2" />
</Grid>
</Grid>
</window:StyleableWindow>
</window:StyleableWindow>

View File

@@ -101,6 +101,9 @@
<Style Selector="Grid#PlaceholderGrid">
<Setter Property="Height" Value="40" />
</Style>
<Style Selector="ui|NavigationViewItem ui|SymbolIcon">
<Setter Property="FlowDirection" Value="LeftToRight" />
</Style>
</ui:NavigationView.Styles>
</ui:NavigationView>
<ReversibleStackPanel

View File

@@ -1,7 +1,9 @@
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Media;
using Avalonia.Media.Imaging;
using Avalonia.Platform;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ui.Common.Configuration;
using System.IO;
using System.Reflection;
@@ -22,6 +24,14 @@ namespace Ryujinx.Ava.UI.Windows
Icon = new WindowIcon(stream);
stream.Position = 0;
IconImage = new Bitmap(stream);
LocaleManager.Instance.LocaleChanged += LocaleChanged;
LocaleChanged();
}
private void LocaleChanged()
{
FlowDirection = LocaleManager.Instance.IsRTL() ? FlowDirection.RightToLeft : FlowDirection.LeftToRight;
}
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)

View File

@@ -130,4 +130,4 @@
</StackPanel>
</Panel>
</Grid>
</UserControl>
</UserControl>

View File

@@ -1,10 +1,12 @@
using Microsoft.IdentityModel.JsonWebTokens;
using Microsoft.IdentityModel.Tokens;
using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS.Kernel.Threading;
using Ryujinx.HLE.HOS.Services.Account.Acc.AsyncContext;
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Security.Principal;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
@@ -37,11 +39,6 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc.AccountService
credentials.Key.KeyId = parameters.ToString();
var header = new JwtHeader(credentials)
{
{ "jku", "https://e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com/1.0.0/certificates" },
};
byte[] rawUserId = new byte[0x10];
RandomNumberGenerator.Fill(rawUserId);
@@ -51,23 +48,25 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc.AccountService
byte[] deviceAccountId = new byte[0x10];
RandomNumberGenerator.Fill(deviceId);
var payload = new JwtPayload
var descriptor = new SecurityTokenDescriptor
{
{ "sub", Convert.ToHexString(rawUserId).ToLower() },
{ "aud", "ed9e2f05d286f7b8" },
{ "di", Convert.ToHexString(deviceId).ToLower() },
{ "sn", "XAW10000000000" },
{ "bs:did", Convert.ToHexString(deviceAccountId).ToLower() },
{ "iss", "https://e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com" },
{ "typ", "id_token" },
{ "iat", DateTimeOffset.UtcNow.ToUnixTimeSeconds() },
{ "jti", Guid.NewGuid().ToString() },
{ "exp", (DateTimeOffset.UtcNow + TimeSpan.FromHours(3)).ToUnixTimeSeconds() },
Subject = new GenericIdentity(Convert.ToHexString(rawUserId).ToLower()),
SigningCredentials = credentials,
Audience = "ed9e2f05d286f7b8",
Issuer = "https://e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com",
TokenType = "id_token",
IssuedAt = DateTime.UtcNow,
Expires = DateTime.UtcNow + TimeSpan.FromHours(3),
Claims = new Dictionary<string, object>
{
{ "jku", "https://e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com/1.0.0/certificates" },
{ "di", Convert.ToHexString(deviceId).ToLower() },
{ "sn", "XAW10000000000" },
{ "bs:did", Convert.ToHexString(deviceAccountId).ToLower() }
}
};
JwtSecurityToken securityToken = new(header, payload);
return new JwtSecurityTokenHandler().WriteToken(securityToken);
return new JsonWebTokenHandler().CreateToken(descriptor);
}
public ResultCode CheckAvailability(ServiceCtx context)

View File

@@ -23,10 +23,10 @@
<ItemGroup>
<PackageReference Include="Concentus" />
<PackageReference Include="LibHac" />
<PackageReference Include="Microsoft.IdentityModel.JsonWebTokens" />
<PackageReference Include="MsgPack.Cli" />
<PackageReference Include="SixLabors.ImageSharp" />
<PackageReference Include="SixLabors.ImageSharp.Drawing" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" />
<PackageReference Include="NetCoreServer" />
</ItemGroup>