mirror of
https://jihulab.com/DGP-Studio/Snap.Hutao.git
synced 2025-11-19 21:02:53 +08:00
add documentation client
This commit is contained in:
@@ -48,10 +48,10 @@ internal static class DependencyInjection
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static void InitializeCulture(this IServiceProvider serviceProvider)
|
||||
{
|
||||
AppOptions appOptions = serviceProvider.GetRequiredService<AppOptions>();
|
||||
appOptions.PreviousCulture = CultureInfo.CurrentCulture;
|
||||
CultureOptions cultureOptions = serviceProvider.GetRequiredService<CultureOptions>();
|
||||
cultureOptions.SystemCulture = CultureInfo.CurrentCulture;
|
||||
|
||||
CultureInfo cultureInfo = appOptions.CurrentCulture;
|
||||
CultureInfo cultureInfo = cultureOptions.CurrentCulture;
|
||||
|
||||
CultureInfo.DefaultThreadCurrentCulture = cultureInfo;
|
||||
CultureInfo.DefaultThreadCurrentUICulture = cultureInfo;
|
||||
|
||||
@@ -38,8 +38,8 @@ internal static class IocConfiguration
|
||||
|
||||
private static void AddDbContextCore(IServiceProvider provider, DbContextOptionsBuilder builder)
|
||||
{
|
||||
RuntimeOptions hutaoOptions = provider.GetRequiredService<RuntimeOptions>();
|
||||
string dbFile = System.IO.Path.Combine(hutaoOptions.DataFolder, "Userdata.db");
|
||||
RuntimeOptions runtimeOptions = provider.GetRequiredService<RuntimeOptions>();
|
||||
string dbFile = System.IO.Path.Combine(runtimeOptions.DataFolder, "Userdata.db");
|
||||
string sqlConnectionString = $"Data Source={dbFile}";
|
||||
|
||||
// Temporarily create a context
|
||||
|
||||
@@ -29,10 +29,10 @@ internal static partial class IocHttpClientConfiguration
|
||||
/// <param name="client">配置后的客户端</param>
|
||||
private static void DefaultConfiguration(IServiceProvider serviceProvider, HttpClient client)
|
||||
{
|
||||
RuntimeOptions hutaoOptions = serviceProvider.GetRequiredService<RuntimeOptions>();
|
||||
RuntimeOptions runtimeOptions = serviceProvider.GetRequiredService<RuntimeOptions>();
|
||||
|
||||
client.Timeout = Timeout.InfiniteTimeSpan;
|
||||
client.DefaultRequestHeaders.UserAgent.ParseAdd(hutaoOptions.UserAgent);
|
||||
client.DefaultRequestHeaders.UserAgent.ParseAdd(runtimeOptions.UserAgent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -53,10 +53,10 @@ internal sealed class WindowController
|
||||
|
||||
private void InitializeCore()
|
||||
{
|
||||
RuntimeOptions hutaoOptions = serviceProvider.GetRequiredService<RuntimeOptions>();
|
||||
RuntimeOptions runtimeOptions = serviceProvider.GetRequiredService<RuntimeOptions>();
|
||||
|
||||
window.AppWindow.Title = SH.FormatAppNameAndVersion(hutaoOptions.Version);
|
||||
window.AppWindow.SetIcon(Path.Combine(hutaoOptions.InstalledLocation, "Assets/Logo.ico"));
|
||||
window.AppWindow.Title = SH.FormatAppNameAndVersion(runtimeOptions.Version);
|
||||
window.AppWindow.SetIcon(Path.Combine(runtimeOptions.InstalledLocation, "Assets/Logo.ico"));
|
||||
ExtendsContentIntoTitleBar();
|
||||
|
||||
RecoverOrInitWindowSize();
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
using Snap.Hutao.Core;
|
||||
using Snap.Hutao.Core.Abstraction;
|
||||
using Snap.Hutao.Service;
|
||||
using Snap.Hutao.Service.Metadata;
|
||||
using Snap.Hutao.Web.Hoyolab;
|
||||
|
||||
@@ -12,7 +13,7 @@ namespace Snap.Hutao.Model.InterChange.GachaLog;
|
||||
/// UIGF格式的信息
|
||||
/// </summary>
|
||||
[HighQuality]
|
||||
internal sealed class UIGFInfo : IMappingFrom<UIGFInfo, RuntimeOptions, MetadataOptions, string>
|
||||
internal sealed class UIGFInfo : IMappingFrom<UIGFInfo, RuntimeOptions, CultureOptions, string>
|
||||
{
|
||||
/// <summary>
|
||||
/// 用户Uid
|
||||
@@ -65,12 +66,12 @@ internal sealed class UIGFInfo : IMappingFrom<UIGFInfo, RuntimeOptions, Metadata
|
||||
[JsonPropertyName("region_time_zone")]
|
||||
public int? RegionTimeZone { get; set; } = default!;
|
||||
|
||||
public static UIGFInfo From(RuntimeOptions runtimeOptions, MetadataOptions metadataOptions, string uid)
|
||||
public static UIGFInfo From(RuntimeOptions runtimeOptions, CultureOptions cultureOptions, string uid)
|
||||
{
|
||||
return new()
|
||||
{
|
||||
Uid = uid,
|
||||
Language = metadataOptions.LanguageCode,
|
||||
Language = cultureOptions.LanguageCode,
|
||||
ExportTimestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds(),
|
||||
ExportApp = SH.AppName,
|
||||
ExportAppVersion = runtimeOptions.Version.ToString(),
|
||||
|
||||
@@ -64,14 +64,14 @@ internal sealed class UIIFInfo
|
||||
/// <returns>专用 UIGF 信息</returns>
|
||||
public static UIIFInfo From(IServiceProvider serviceProvider, string uid)
|
||||
{
|
||||
RuntimeOptions hutaoOptions = serviceProvider.GetRequiredService<RuntimeOptions>();
|
||||
RuntimeOptions runtimeOptions = serviceProvider.GetRequiredService<RuntimeOptions>();
|
||||
|
||||
return new()
|
||||
{
|
||||
Uid = uid,
|
||||
ExportTimestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds(),
|
||||
ExportApp = SH.AppName,
|
||||
ExportAppVersion = hutaoOptions.Version.ToString(),
|
||||
ExportAppVersion = runtimeOptions.Version.ToString(),
|
||||
UIIFVersion = UIIF.CurrentVersion,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ using Snap.Hutao.Model;
|
||||
using Snap.Hutao.Model.Entity;
|
||||
using Snap.Hutao.Service.Abstraction;
|
||||
using Snap.Hutao.Web.Hoyolab;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Snap.Hutao.Service;
|
||||
|
||||
@@ -16,7 +15,6 @@ internal sealed partial class AppOptions : DbStoreOptions
|
||||
{
|
||||
private bool? isEmptyHistoryWishVisible;
|
||||
private BackdropType? backdropType;
|
||||
private CultureInfo? currentCulture;
|
||||
private Region? region;
|
||||
private string? geetestCustomCompositeUrl;
|
||||
|
||||
@@ -34,14 +32,6 @@ internal sealed partial class AppOptions : DbStoreOptions
|
||||
set => SetOption(ref backdropType, SettingEntry.SystemBackdropType, value, value => value.ToStringOrEmpty());
|
||||
}
|
||||
|
||||
public List<NameValue<CultureInfo>> Cultures { get; } = SupportedCultures.Get();
|
||||
|
||||
public CultureInfo CurrentCulture
|
||||
{
|
||||
get => GetOption(ref currentCulture, SettingEntry.Culture, CultureInfo.GetCultureInfo, CultureInfo.CurrentCulture);
|
||||
set => SetOption(ref currentCulture, SettingEntry.Culture, value, value => value.Name);
|
||||
}
|
||||
|
||||
public Lazy<List<NameValue<Region>>> LazyRegions { get; } = new(KnownRegions.Get);
|
||||
|
||||
public Region Region
|
||||
@@ -55,6 +45,4 @@ internal sealed partial class AppOptions : DbStoreOptions
|
||||
get => GetOption(ref geetestCustomCompositeUrl, SettingEntry.GeetestCustomCompositeUrl);
|
||||
set => SetOption(ref geetestCustomCompositeUrl, SettingEntry.GeetestCustomCompositeUrl, value);
|
||||
}
|
||||
|
||||
internal CultureInfo PreviousCulture { get; set; } = default!;
|
||||
}
|
||||
@@ -3,17 +3,11 @@
|
||||
|
||||
using Snap.Hutao.Model;
|
||||
using Snap.Hutao.Web.Hoyolab;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Snap.Hutao.Service;
|
||||
|
||||
internal static class AppOptionsExtension
|
||||
{
|
||||
public static NameValue<CultureInfo>? GetCurrentCultureForSelectionOrDefault(this AppOptions appOptions)
|
||||
{
|
||||
return appOptions.Cultures.SingleOrDefault(c => c.Value == appOptions.CurrentCulture);
|
||||
}
|
||||
|
||||
public static NameValue<Region>? GetCurrentRegionForSelectionOrDefault(this AppOptions appOptions)
|
||||
{
|
||||
return appOptions.LazyRegions.Value.SingleOrDefault(c => c.Value.Value == appOptions.Region.Value);
|
||||
|
||||
43
src/Snap.Hutao/Snap.Hutao/Service/CultureOptions.cs
Normal file
43
src/Snap.Hutao/Snap.Hutao/Service/CultureOptions.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Model;
|
||||
using Snap.Hutao.Model.Entity;
|
||||
using Snap.Hutao.Service.Abstraction;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Snap.Hutao.Service;
|
||||
|
||||
[ConstructorGenerated(CallBaseConstructor = true)]
|
||||
[Injection(InjectAs.Singleton)]
|
||||
internal sealed partial class CultureOptions : DbStoreOptions
|
||||
{
|
||||
private CultureInfo? currentCulture;
|
||||
private string? localeName;
|
||||
private string? languageCode;
|
||||
|
||||
public List<NameValue<CultureInfo>> Cultures { get; } = SupportedCultures.Get();
|
||||
|
||||
public CultureInfo CurrentCulture
|
||||
{
|
||||
get => GetOption(ref currentCulture, SettingEntry.Culture, CultureInfo.GetCultureInfo, CultureInfo.CurrentCulture);
|
||||
set => SetOption(ref currentCulture, SettingEntry.Culture, value, value => value.Name);
|
||||
}
|
||||
|
||||
public CultureInfo SystemCulture { get; set; } = default!;
|
||||
|
||||
public string LocaleName { get => localeName ??= CultureOptionsExtension.GetLocaleName(CurrentCulture); }
|
||||
|
||||
public string LanguageCode
|
||||
{
|
||||
get
|
||||
{
|
||||
if (languageCode is null && !LocaleNames.TryGetLanguageCodeFromLocaleName(LocaleName, out languageCode))
|
||||
{
|
||||
throw new KeyNotFoundException($"Invalid localeName: '{LocaleName}'");
|
||||
}
|
||||
|
||||
return languageCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,24 +1,19 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Model;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
|
||||
namespace Snap.Hutao.Service.Metadata;
|
||||
namespace Snap.Hutao.Service;
|
||||
|
||||
internal static class MetadataOptionsExtension
|
||||
internal static class CultureOptionsExtension
|
||||
{
|
||||
public static string GetLocalizedLocalFile(this MetadataOptions options, string fileNameWithExtension)
|
||||
public static NameValue<CultureInfo>? GetCurrentCultureForSelectionOrDefault(this CultureOptions options)
|
||||
{
|
||||
return Path.Combine(options.LocalizedDataFolder, fileNameWithExtension);
|
||||
return options.Cultures.SingleOrDefault(c => c.Value == options.CurrentCulture);
|
||||
}
|
||||
|
||||
public static string GetLocalizedRemoteFile(this MetadataOptions options, string fileNameWithExtension)
|
||||
{
|
||||
return Web.HutaoEndpoints.Metadata(options.LocaleName, fileNameWithExtension);
|
||||
}
|
||||
|
||||
public static bool LanguageCodeFitsCurrentLocale(this MetadataOptions options, string? languageCode)
|
||||
public static bool LanguageCodeFitsCurrentLocale(this CultureOptions options, string? languageCode)
|
||||
{
|
||||
if (string.IsNullOrEmpty(languageCode))
|
||||
{
|
||||
@@ -18,7 +18,7 @@ namespace Snap.Hutao.Service.GachaLog.QueryProvider;
|
||||
internal sealed partial class GachaLogQueryManualInputProvider : IGachaLogQueryProvider
|
||||
{
|
||||
private readonly IContentDialogFactory contentDialogFactory;
|
||||
private readonly MetadataOptions metadataOptions;
|
||||
private readonly CultureOptions cultureOptions;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async ValueTask<ValueResult<bool, GachaLogQuery>> GetQueryAsync()
|
||||
@@ -33,13 +33,13 @@ internal sealed partial class GachaLogQueryManualInputProvider : IGachaLogQueryP
|
||||
if (query.TryGetSingleValue("auth_appid", out string? appId) && appId is "webview_gacha")
|
||||
{
|
||||
string? queryLanguageCode = query["lang"];
|
||||
if (metadataOptions.LanguageCodeFitsCurrentLocale(queryLanguageCode))
|
||||
if (cultureOptions.LanguageCodeFitsCurrentLocale(queryLanguageCode))
|
||||
{
|
||||
return new(true, new(queryString));
|
||||
}
|
||||
else
|
||||
{
|
||||
string message = SH.FormatServiceGachaLogUrlProviderUrlLanguageNotMatchCurrentLocale(queryLanguageCode, metadataOptions.LanguageCode);
|
||||
string message = SH.FormatServiceGachaLogUrlProviderUrlLanguageNotMatchCurrentLocale(queryLanguageCode, cultureOptions.LanguageCode);
|
||||
return new(false, message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace Snap.Hutao.Service.GachaLog.QueryProvider;
|
||||
internal sealed partial class GachaLogQuerySTokenProvider : IGachaLogQueryProvider
|
||||
{
|
||||
private readonly BindingClient2 bindingClient2;
|
||||
private readonly MetadataOptions metadataOptions;
|
||||
private readonly CultureOptions cultureOptions;
|
||||
private readonly IUserService userService;
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -38,7 +38,7 @@ internal sealed partial class GachaLogQuerySTokenProvider : IGachaLogQueryProvid
|
||||
|
||||
if (authkeyResponse.IsOk())
|
||||
{
|
||||
return new(true, new(ComposeQueryString(data, authkeyResponse.Data, metadataOptions.LanguageCode)));
|
||||
return new(true, new(ComposeQueryString(data, authkeyResponse.Data, cultureOptions.LanguageCode)));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Snap.Hutao.Service.GachaLog.QueryProvider;
|
||||
internal sealed partial class GachaLogQueryWebCacheProvider : IGachaLogQueryProvider
|
||||
{
|
||||
private readonly IGameServiceFacade gameService;
|
||||
private readonly MetadataOptions metadataOptions;
|
||||
private readonly CultureOptions cultureOptions;
|
||||
|
||||
/// <summary>
|
||||
/// 获取缓存文件路径
|
||||
@@ -90,12 +90,12 @@ internal sealed partial class GachaLogQueryWebCacheProvider : IGachaLogQueryProv
|
||||
NameValueCollection query = HttpUtility.ParseQueryString(result.TrimEnd("#/log"));
|
||||
string? queryLanguageCode = query["lang"];
|
||||
|
||||
if (metadataOptions.LanguageCodeFitsCurrentLocale(queryLanguageCode))
|
||||
if (cultureOptions.LanguageCodeFitsCurrentLocale(queryLanguageCode))
|
||||
{
|
||||
return new(true, new(result));
|
||||
}
|
||||
|
||||
string message = SH.FormatServiceGachaLogUrlProviderUrlLanguageNotMatchCurrentLocale(queryLanguageCode, metadataOptions.LanguageCode);
|
||||
string message = SH.FormatServiceGachaLogUrlProviderUrlLanguageNotMatchCurrentLocale(queryLanguageCode, cultureOptions.LanguageCode);
|
||||
return new(false, message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ internal sealed partial class UIGFExportService : IUIGFExportService
|
||||
{
|
||||
private readonly IGachaLogDbService gachaLogDbService;
|
||||
private readonly RuntimeOptions runtimeOptions;
|
||||
private readonly MetadataOptions metadataOptions;
|
||||
private readonly CultureOptions cultureOptions;
|
||||
private readonly ITaskContext taskContext;
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -31,7 +31,7 @@ internal sealed partial class UIGFExportService : IUIGFExportService
|
||||
|
||||
UIGF uigf = new()
|
||||
{
|
||||
Info = UIGFInfo.From(runtimeOptions, metadataOptions, archive.Uid),
|
||||
Info = UIGFInfo.From(runtimeOptions, cultureOptions, archive.Uid),
|
||||
List = list,
|
||||
};
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace Snap.Hutao.Service.GachaLog;
|
||||
internal sealed partial class UIGFImportService : IUIGFImportService
|
||||
{
|
||||
private readonly ILogger<UIGFImportService> logger;
|
||||
private readonly MetadataOptions metadataOptions;
|
||||
private readonly CultureOptions cultureOptions;
|
||||
private readonly IGachaLogDbService gachaLogDbService;
|
||||
private readonly ITaskContext taskContext;
|
||||
|
||||
@@ -37,9 +37,9 @@ internal sealed partial class UIGFImportService : IUIGFImportService
|
||||
// v2.1 only support CHS
|
||||
if (version is UIGFVersion.Major2Minor2OrLower)
|
||||
{
|
||||
if (!metadataOptions.LanguageCodeFitsCurrentLocale(uigf.Info.Language))
|
||||
if (!cultureOptions.LanguageCodeFitsCurrentLocale(uigf.Info.Language))
|
||||
{
|
||||
string message = SH.FormatServiceGachaUIGFImportLanguageNotMatch(uigf.Info.Language, metadataOptions.LanguageCode);
|
||||
string message = SH.FormatServiceGachaUIGFImportLanguageNotMatch(uigf.Info.Language, cultureOptions.LanguageCode);
|
||||
ThrowHelper.InvalidOperation(message);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,11 +7,9 @@ using Snap.Hutao.Factory.ContentDialog;
|
||||
using Snap.Hutao.Factory.Progress;
|
||||
using Snap.Hutao.Model.Intrinsic;
|
||||
using Snap.Hutao.Service.Game.Package;
|
||||
using Snap.Hutao.Service.Game.PathAbstraction;
|
||||
using Snap.Hutao.View.Dialog;
|
||||
using Snap.Hutao.Web.Hoyolab.SdkStatic.Hk4e.Launcher;
|
||||
using Snap.Hutao.Web.Response;
|
||||
using System.Collections.Immutable;
|
||||
using System.IO;
|
||||
|
||||
namespace Snap.Hutao.Service.Game.Launching.Handler;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Snap.Hutao.Service.Metadata;
|
||||
namespace Snap.Hutao.Service;
|
||||
|
||||
/// <summary>
|
||||
/// 本地化名称
|
||||
@@ -2,6 +2,7 @@
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Core;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
|
||||
namespace Snap.Hutao.Service.Metadata;
|
||||
@@ -10,10 +11,9 @@ namespace Snap.Hutao.Service.Metadata;
|
||||
[Injection(InjectAs.Singleton)]
|
||||
internal sealed partial class MetadataOptions
|
||||
{
|
||||
private readonly AppOptions appOptions;
|
||||
private readonly RuntimeOptions hutaoOptions;
|
||||
private readonly CultureOptions cultureOptions;
|
||||
private readonly RuntimeOptions runtimeOptions;
|
||||
|
||||
private string? localeName;
|
||||
private string? fallbackDataFolder;
|
||||
private string? localizedDataFolder;
|
||||
|
||||
@@ -23,7 +23,7 @@ internal sealed partial class MetadataOptions
|
||||
{
|
||||
if (fallbackDataFolder is null)
|
||||
{
|
||||
fallbackDataFolder = Path.Combine(hutaoOptions.DataFolder, "Metadata", "CHS");
|
||||
fallbackDataFolder = Path.Combine(runtimeOptions.DataFolder, "Metadata", "CHS");
|
||||
Directory.CreateDirectory(fallbackDataFolder);
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ internal sealed partial class MetadataOptions
|
||||
{
|
||||
if (localizedDataFolder is null)
|
||||
{
|
||||
localizedDataFolder = Path.Combine(hutaoOptions.DataFolder, "Metadata", LocaleName);
|
||||
localizedDataFolder = Path.Combine(runtimeOptions.DataFolder, "Metadata", cultureOptions.LocaleName);
|
||||
Directory.CreateDirectory(localizedDataFolder);
|
||||
}
|
||||
|
||||
@@ -45,21 +45,13 @@ internal sealed partial class MetadataOptions
|
||||
}
|
||||
}
|
||||
|
||||
public string LocaleName
|
||||
public string GetLocalizedLocalFile(string fileNameWithExtension)
|
||||
{
|
||||
get => localeName ??= MetadataOptionsExtension.GetLocaleName(appOptions.CurrentCulture);
|
||||
return Path.Combine(LocalizedDataFolder, fileNameWithExtension);
|
||||
}
|
||||
|
||||
public string LanguageCode
|
||||
public string GetLocalizedRemoteFile(string fileNameWithExtension)
|
||||
{
|
||||
get
|
||||
{
|
||||
if (LocaleNames.TryGetLanguageCodeFromLocaleName(LocaleName, out string? languageCode))
|
||||
{
|
||||
return languageCode;
|
||||
}
|
||||
|
||||
throw new KeyNotFoundException($"Invalid localeName: '{LocaleName}'");
|
||||
}
|
||||
return Web.HutaoEndpoints.Metadata(cultureOptions.LocaleName, fileNameWithExtension);
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,7 @@
|
||||
<GridView
|
||||
Grid.Row="0"
|
||||
ItemTemplate="{StaticResource LanguageTemplate}"
|
||||
ItemsSource="{Binding AppOptions.Cultures}"
|
||||
ItemsSource="{Binding CultureOptions.Cultures}"
|
||||
SelectedItem="{Binding SelectedCulture, Mode=TwoWay}"
|
||||
SelectionMode="Single"/>
|
||||
</Grid>
|
||||
|
||||
@@ -97,7 +97,7 @@
|
||||
Description="{shcm:ResourceString Name=ViewPageSettingElevatedModeDescription}"
|
||||
Header="{shcm:ResourceString Name=ViewPageSettingElevatedModeRestartAction}"
|
||||
IsClickEnabled="True"
|
||||
IsEnabled="{Binding HutaoOptions.IsElevated, Converter={StaticResource BoolNegationConverter}}"/>
|
||||
IsEnabled="{Binding RuntimeOptions.IsElevated, Converter={StaticResource BoolNegationConverter}}"/>
|
||||
<cwc:SettingsCard
|
||||
ActionIconToolTip="{shcm:ResourceString Name=ViewPageSettingCreateDesktopShortcutAction}"
|
||||
Command="{Binding CreateDesktopShortcutCommand}"
|
||||
@@ -112,7 +112,7 @@
|
||||
<Grid Padding="16" HorizontalAlignment="Left">
|
||||
<StackPanel Grid.Column="0" Spacing="{StaticResource SettingsCardSpacing}">
|
||||
<cwc:SettingsExpander
|
||||
Description="{Binding HutaoOptions.Version}"
|
||||
Description="{Binding RuntimeOptions.Version}"
|
||||
Header="{shcm:ResourceString Name=AppName}"
|
||||
HeaderIcon="{shcm:FontIcon Glyph=}"
|
||||
IsExpanded="True">
|
||||
@@ -121,11 +121,11 @@
|
||||
ActionIcon="{shcm:FontIcon Glyph=}"
|
||||
ActionIconToolTip="{shcm:ResourceString Name=ViewPageSettingCopyDeviceIdAction}"
|
||||
Command="{Binding CopyDeviceIdCommand}"
|
||||
Description="{Binding HutaoOptions.DeviceId}"
|
||||
Description="{Binding RuntimeOptions.DeviceId}"
|
||||
Header="{shcm:ResourceString Name=ViewPageSettingDeviceIdHeader}"
|
||||
IsClickEnabled="True"/>
|
||||
<cwc:SettingsCard Description="{Binding IPInformation}" Header="{shcm:ResourceString Name=ViewPageSettingDeviceIpHeader}"/>
|
||||
<cwc:SettingsCard Description="{Binding HutaoOptions.WebView2Version}" Header="{shcm:ResourceString Name=ViewPageSettingWebview2Header}"/>
|
||||
<cwc:SettingsCard Description="{Binding RuntimeOptions.WebView2Version}" Header="{shcm:ResourceString Name=ViewPageSettingWebview2Header}"/>
|
||||
</cwc:SettingsExpander.Items>
|
||||
</cwc:SettingsExpander>
|
||||
<!--
|
||||
@@ -213,7 +213,7 @@
|
||||
<shc:SizeRestrictedContentControl>
|
||||
<ComboBox
|
||||
DisplayMemberPath="Name"
|
||||
ItemsSource="{Binding AppOptions.Cultures}"
|
||||
ItemsSource="{Binding CultureOptions.Cultures}"
|
||||
SelectedItem="{Binding SelectedCulture, Mode=TwoWay}"/>
|
||||
</shc:SizeRestrictedContentControl>
|
||||
</cwc:SettingsCard>
|
||||
@@ -416,7 +416,7 @@
|
||||
<cwc:SettingsCard
|
||||
Header="{shcm:ResourceString Name=ViewPageSettingIsAdvancedLaunchOptionsEnabledHeader}"
|
||||
HeaderIcon="{shcm:FontIcon Glyph=}"
|
||||
IsEnabled="{Binding HutaoOptions.IsElevated}">
|
||||
IsEnabled="{Binding RuntimeOptions.IsElevated}">
|
||||
<cwc:SettingsCard.Description>
|
||||
<StackPanel>
|
||||
<TextBlock
|
||||
@@ -427,7 +427,7 @@
|
||||
</StackPanel>
|
||||
</cwc:SettingsCard.Description>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<shvc:Elevation Visibility="{Binding HutaoOptions.IsElevated, Converter={StaticResource BoolToVisibilityRevertConverter}}"/>
|
||||
<shvc:Elevation Visibility="{Binding RuntimeOptions.IsElevated, Converter={StaticResource BoolToVisibilityRevertConverter}}"/>
|
||||
<ToggleSwitch Width="120" IsOn="{Binding IsAdvancedLaunchOptionsEnabled, Mode=TwoWay}"/>
|
||||
</StackPanel>
|
||||
</cwc:SettingsCard>
|
||||
|
||||
@@ -37,8 +37,8 @@ internal sealed class DownloadSummary : ObservableObject
|
||||
taskContext = serviceProvider.GetRequiredService<ITaskContext>();
|
||||
httpClient = serviceProvider.GetRequiredService<HttpClient>();
|
||||
imageCache = serviceProvider.GetRequiredService<IImageCache>();
|
||||
RuntimeOptions hutaoOptions = serviceProvider.GetRequiredService<RuntimeOptions>();
|
||||
httpClient.DefaultRequestHeaders.UserAgent.ParseAdd(hutaoOptions.UserAgent);
|
||||
RuntimeOptions runtimeOptions = serviceProvider.GetRequiredService<RuntimeOptions>();
|
||||
httpClient.DefaultRequestHeaders.UserAgent.ParseAdd(runtimeOptions.UserAgent);
|
||||
|
||||
this.serviceProvider = serviceProvider;
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ internal sealed partial class GuideViewModel : Abstraction.ViewModel
|
||||
{
|
||||
private readonly IServiceProvider serviceProvider;
|
||||
private readonly ITaskContext taskContext;
|
||||
private readonly AppOptions appOptions;
|
||||
private readonly CultureOptions cultureOptions;
|
||||
private readonly RuntimeOptions runtimeOptions;
|
||||
|
||||
private string nextOrCompleteButtonText = SH.ViewModelGuideActionNext;
|
||||
@@ -75,18 +75,18 @@ internal sealed partial class GuideViewModel : Abstraction.ViewModel
|
||||
|
||||
public bool IsNextOrCompleteButtonEnabled { get => isNextOrCompleteButtonEnabled; set => SetProperty(ref isNextOrCompleteButtonEnabled, value); }
|
||||
|
||||
public AppOptions AppOptions { get => appOptions; }
|
||||
public CultureOptions CultureOptions { get => cultureOptions; }
|
||||
|
||||
public RuntimeOptions RuntimeOptions { get => runtimeOptions; }
|
||||
|
||||
public NameValue<CultureInfo>? SelectedCulture
|
||||
{
|
||||
get => selectedCulture ??= AppOptions.GetCurrentCultureForSelectionOrDefault();
|
||||
get => selectedCulture ??= CultureOptions.GetCurrentCultureForSelectionOrDefault();
|
||||
set
|
||||
{
|
||||
if (SetProperty(ref selectedCulture, value) && value is not null)
|
||||
{
|
||||
AppOptions.CurrentCulture = value.Value;
|
||||
CultureOptions.CurrentCulture = value.Value;
|
||||
++State;
|
||||
AppInstance.Restart(string.Empty);
|
||||
}
|
||||
|
||||
@@ -24,8 +24,8 @@ internal sealed partial class AnnouncementViewModel : Abstraction.ViewModel
|
||||
private readonly IHutaoAsAService hutaoAsAService;
|
||||
private readonly IAnnouncementService announcementService;
|
||||
private readonly HutaoUserOptions hutaoUserOptions;
|
||||
private readonly CultureOptions cultureOptions;
|
||||
private readonly ITaskContext taskContext;
|
||||
private readonly MetadataOptions metadataOptions;
|
||||
private readonly AppOptions appOptions;
|
||||
|
||||
private AnnouncementWrapper? announcement;
|
||||
@@ -65,7 +65,7 @@ internal sealed partial class AnnouncementViewModel : Abstraction.ViewModel
|
||||
{
|
||||
try
|
||||
{
|
||||
AnnouncementWrapper announcementWrapper = await announcementService.GetAnnouncementWrapperAsync(metadataOptions.LanguageCode, appOptions.Region, CancellationToken).ConfigureAwait(false);
|
||||
AnnouncementWrapper announcementWrapper = await announcementService.GetAnnouncementWrapperAsync(cultureOptions.LanguageCode, appOptions.Region, CancellationToken).ConfigureAwait(false);
|
||||
await taskContext.SwitchToMainThreadAsync();
|
||||
Announcement = announcementWrapper;
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ internal sealed partial class SettingViewModel : Abstraction.ViewModel
|
||||
private readonly IShellLinkInterop shellLinkInterop;
|
||||
private readonly HutaoUserOptions hutaoUserOptions;
|
||||
private readonly IInfoBarService infoBarService;
|
||||
private readonly CultureOptions cultureOptions;
|
||||
private readonly RuntimeOptions runtimeOptions;
|
||||
private readonly LaunchOptions launchOptions;
|
||||
private readonly HotKeyOptions hotKeyOptions;
|
||||
@@ -67,7 +68,9 @@ internal sealed partial class SettingViewModel : Abstraction.ViewModel
|
||||
|
||||
public AppOptions AppOptions { get => appOptions; }
|
||||
|
||||
public RuntimeOptions HutaoOptions { get => runtimeOptions; }
|
||||
public CultureOptions CultureOptions { get => cultureOptions; }
|
||||
|
||||
public RuntimeOptions RuntimeOptions { get => runtimeOptions; }
|
||||
|
||||
public HutaoUserOptions UserOptions { get => hutaoUserOptions; }
|
||||
|
||||
@@ -93,12 +96,12 @@ internal sealed partial class SettingViewModel : Abstraction.ViewModel
|
||||
|
||||
public NameValue<CultureInfo>? SelectedCulture
|
||||
{
|
||||
get => selectedCulture ??= AppOptions.GetCurrentCultureForSelectionOrDefault();
|
||||
get => selectedCulture ??= CultureOptions.GetCurrentCultureForSelectionOrDefault();
|
||||
set
|
||||
{
|
||||
if (SetProperty(ref selectedCulture, value) && value is not null)
|
||||
{
|
||||
AppOptions.CurrentCulture = value.Value;
|
||||
CultureOptions.CurrentCulture = value.Value;
|
||||
AppInstance.Restart(string.Empty);
|
||||
}
|
||||
}
|
||||
@@ -298,7 +301,7 @@ internal sealed partial class SettingViewModel : Abstraction.ViewModel
|
||||
{
|
||||
try
|
||||
{
|
||||
clipboardInterop.SetText(HutaoOptions.DeviceId);
|
||||
clipboardInterop.SetText(RuntimeOptions.DeviceId);
|
||||
infoBarService.Success(SH.ViewModelSettingCopyDeviceIdSuccess);
|
||||
}
|
||||
catch (COMException ex)
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
using Microsoft.Web.WebView2.Core;
|
||||
using Snap.Hutao.Core.DependencyInjection.Abstraction;
|
||||
using Snap.Hutao.Core.IO.DataTransfer;
|
||||
using Snap.Hutao.Service;
|
||||
using Snap.Hutao.Service.Metadata;
|
||||
using Snap.Hutao.Service.Notification;
|
||||
using Snap.Hutao.Service.User;
|
||||
@@ -183,13 +184,13 @@ internal class MiHoYoJSBridge
|
||||
|
||||
protected virtual JsResult<Dictionary<string, string>> GetCurrentLocale(JsParam<PushPagePayload> param)
|
||||
{
|
||||
MetadataOptions metadataOptions = serviceProvider.GetRequiredService<MetadataOptions>();
|
||||
CultureOptions cultureOptions = serviceProvider.GetRequiredService<CultureOptions>();
|
||||
|
||||
return new()
|
||||
{
|
||||
Data = new()
|
||||
{
|
||||
["language"] = metadataOptions.LanguageCode,
|
||||
["language"] = cultureOptions.LanguageCode,
|
||||
["timeZone"] = "GMT+8",
|
||||
},
|
||||
};
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient;
|
||||
using Snap.Hutao.Service;
|
||||
using Snap.Hutao.Service.Metadata;
|
||||
using Snap.Hutao.ViewModel.User;
|
||||
using Snap.Hutao.Web.Hoyolab.DataSigning;
|
||||
@@ -23,14 +24,14 @@ internal sealed partial class SignInClient : ISignInClient
|
||||
{
|
||||
private readonly IHttpRequestMessageBuilderFactory httpRequestMessageBuilderFactory;
|
||||
private readonly HomaGeetestClient homaGeetestClient;
|
||||
private readonly MetadataOptions metadataOptions;
|
||||
private readonly CultureOptions cultureOptions;
|
||||
private readonly ILogger<SignInClient> logger;
|
||||
private readonly HttpClient httpClient;
|
||||
|
||||
public async ValueTask<Response<ExtraAwardInfo>> GetExtraAwardInfoAsync(UserAndUid userAndUid, CancellationToken token = default)
|
||||
{
|
||||
HttpRequestMessageBuilder builder = httpRequestMessageBuilderFactory.Create()
|
||||
.SetRequestUri(ApiEndpoints.LunaExtraAward(userAndUid.Uid, metadataOptions.LanguageCode))
|
||||
.SetRequestUri(ApiEndpoints.LunaExtraAward(userAndUid.Uid, cultureOptions.LanguageCode))
|
||||
.SetUserCookieAndFpHeader(userAndUid, CookieType.CookieToken)
|
||||
.SetHeader("x-rpc-signgame", "hk4e")
|
||||
.Get();
|
||||
@@ -47,7 +48,7 @@ internal sealed partial class SignInClient : ISignInClient
|
||||
public async ValueTask<Response<SignInRewardInfo>> GetInfoAsync(UserAndUid userAndUid, CancellationToken token = default)
|
||||
{
|
||||
HttpRequestMessageBuilder builder = httpRequestMessageBuilderFactory.Create()
|
||||
.SetRequestUri(ApiEndpoints.LunaInfo(userAndUid.Uid, metadataOptions.LanguageCode))
|
||||
.SetRequestUri(ApiEndpoints.LunaInfo(userAndUid.Uid, cultureOptions.LanguageCode))
|
||||
.SetUserCookieAndFpHeader(userAndUid, CookieType.CookieToken)
|
||||
.SetHeader("x-rpc-signgame", "hk4e")
|
||||
.Get();
|
||||
@@ -81,7 +82,7 @@ internal sealed partial class SignInClient : ISignInClient
|
||||
public async ValueTask<Response<Reward>> GetRewardAsync(Model.Entity.User user, CancellationToken token = default)
|
||||
{
|
||||
HttpRequestMessageBuilder builder = httpRequestMessageBuilderFactory.Create()
|
||||
.SetRequestUri(ApiEndpoints.LunaHome(metadataOptions.LanguageCode))
|
||||
.SetRequestUri(ApiEndpoints.LunaHome(cultureOptions.LanguageCode))
|
||||
.SetUserCookieAndFpHeader(user, CookieType.CookieToken)
|
||||
.SetHeader("x-rpc-signgame", "hk4e")
|
||||
.Get();
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient;
|
||||
using Snap.Hutao.Web.Hutao.Response;
|
||||
using Snap.Hutao.Web.Request.Builder;
|
||||
using Snap.Hutao.Web.Request.Builder.Abstraction;
|
||||
using System.Net.Http;
|
||||
|
||||
namespace Snap.Hutao.Web.Hutao.Algolia;
|
||||
|
||||
internal sealed class AlgoliaHierarchy
|
||||
{
|
||||
[JsonPropertyName("lvl0")]
|
||||
public string? Lvl0 { get; set; }
|
||||
|
||||
[JsonPropertyName("lvl1")]
|
||||
public string? Lvl1 { get; set; }
|
||||
|
||||
[JsonPropertyName("lvl2")]
|
||||
public string? Lvl2 { get; set; }
|
||||
|
||||
[JsonPropertyName("lvl3")]
|
||||
public string? Lvl3 { get; set; }
|
||||
|
||||
[JsonPropertyName("lvl4")]
|
||||
public string? Lvl4 { get; set; }
|
||||
|
||||
[JsonPropertyName("lvl5")]
|
||||
public string? Lvl5 { get; set; }
|
||||
|
||||
[JsonPropertyName("lvl6")]
|
||||
public string? Lvl6 { get; set; }
|
||||
}
|
||||
19
src/Snap.Hutao/Snap.Hutao/Web/Hutao/Algolia/AlgoliaHit.cs
Normal file
19
src/Snap.Hutao/Snap.Hutao/Web/Hutao/Algolia/AlgoliaHit.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient;
|
||||
using Snap.Hutao.Web.Hutao.Response;
|
||||
using Snap.Hutao.Web.Request.Builder;
|
||||
using Snap.Hutao.Web.Request.Builder.Abstraction;
|
||||
using System.Net.Http;
|
||||
|
||||
namespace Snap.Hutao.Web.Hutao.Algolia;
|
||||
|
||||
internal sealed class AlgoliaHit
|
||||
{
|
||||
[JsonPropertyName("url")]
|
||||
public string Url { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("hierarchy")]
|
||||
public AlgoliaHierarchy Hierarchy { get; set; } = default!;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient;
|
||||
using Snap.Hutao.Web.Hutao.Response;
|
||||
using Snap.Hutao.Web.Request.Builder;
|
||||
using Snap.Hutao.Web.Request.Builder.Abstraction;
|
||||
using System.Net.Http;
|
||||
|
||||
namespace Snap.Hutao.Web.Hutao.Algolia;
|
||||
|
||||
internal sealed class AlgoliaRequest
|
||||
{
|
||||
[JsonPropertyName("query")]
|
||||
public string Query { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("indexName")]
|
||||
public string IndexName { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("params")]
|
||||
public string Params { get; set; } = default!;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Snap.Hutao.Web.Hutao.Algolia;
|
||||
|
||||
internal sealed class AlgoliaRequestsWrapper
|
||||
{
|
||||
[JsonPropertyName("requests")]
|
||||
public List<AlgoliaRequest> Requests { get; set; } = default!;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Snap.Hutao.Web.Hutao.Algolia;
|
||||
|
||||
internal sealed class AlgoliaResponse
|
||||
{
|
||||
public List<AlgoliaResult> Results { get; set; } = default!;
|
||||
}
|
||||
16
src/Snap.Hutao/Snap.Hutao/Web/Hutao/Algolia/AlgoliaResult.cs
Normal file
16
src/Snap.Hutao/Snap.Hutao/Web/Hutao/Algolia/AlgoliaResult.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient;
|
||||
using Snap.Hutao.Web.Hutao.Response;
|
||||
using Snap.Hutao.Web.Request.Builder;
|
||||
using Snap.Hutao.Web.Request.Builder.Abstraction;
|
||||
using System.Net.Http;
|
||||
|
||||
namespace Snap.Hutao.Web.Hutao.Algolia;
|
||||
|
||||
internal sealed class AlgoliaResult
|
||||
{
|
||||
[JsonPropertyName("hits")]
|
||||
public List<AlgoliaHit> Hits { get; set; } = default!;
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient;
|
||||
using Snap.Hutao.Web.Request.Builder;
|
||||
using Snap.Hutao.Web.Request.Builder.Abstraction;
|
||||
using System.Net.Http;
|
||||
|
||||
namespace Snap.Hutao.Web.Hutao.Algolia;
|
||||
|
||||
[HttpClient(HttpClientConfiguration.Default)]
|
||||
[ConstructorGenerated(ResolveHttpClient = true)]
|
||||
internal sealed partial class HutaoDocumentationClient
|
||||
{
|
||||
private const string AlgoliaApiKey = "72d7a9a0f9f0466218ea19988886dce8";
|
||||
private const string AlgoliaApplicationId = "28CTGDOOQD";
|
||||
private const string AlgolianetIndexesQueries = $"https://28ctgdooqd-1.algolianet.com/1/indexes/*/queries";
|
||||
|
||||
private readonly IHttpRequestMessageBuilderFactory httpRequestMessageBuilderFactory;
|
||||
private readonly ILogger<HutaoDocumentationClient> logger;
|
||||
private readonly HttpClient httpClient;
|
||||
|
||||
public async ValueTask<AlgoliaResponse?> QueryAsync(string query, string language, CancellationToken token)
|
||||
{
|
||||
AlgoliaRequestsWrapper data = new()
|
||||
{
|
||||
Requests =
|
||||
[
|
||||
new AlgoliaRequest
|
||||
{
|
||||
Query = query,
|
||||
IndexName = "hutao",
|
||||
Params = $"""facetFilters=["lang:{language}"]""",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
HttpRequestMessageBuilder builder = httpRequestMessageBuilderFactory.Create()
|
||||
.SetRequestUri(AlgolianetIndexesQueries)
|
||||
.SetHeader("x-algolia-api-key", AlgoliaApiKey)
|
||||
.SetHeader("x-algolia-application-id", AlgoliaApplicationId)
|
||||
.PostJson(data);
|
||||
|
||||
return await builder.TryCatchSendAsync<AlgoliaResponse>(httpClient, logger, token).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient;
|
||||
using Snap.Hutao.Service;
|
||||
using Snap.Hutao.Service.Hutao;
|
||||
using Snap.Hutao.Service.Metadata;
|
||||
using Snap.Hutao.Web.Hutao.Response;
|
||||
@@ -21,13 +22,13 @@ internal sealed partial class HutaoAsAServiceClient
|
||||
private readonly IHttpRequestMessageBuilderFactory httpRequestMessageBuilderFactory;
|
||||
private readonly ILogger<HutaoAsAServiceClient> logger;
|
||||
private readonly HutaoUserOptions hutaoUserOptions;
|
||||
private readonly MetadataOptions metadataOptions;
|
||||
private readonly CultureOptions cultureOptions;
|
||||
private readonly HttpClient httpClient;
|
||||
|
||||
public async ValueTask<HutaoResponse<List<Announcement>>> GetAnnouncementListAsync(List<long> excluedeIds, CancellationToken token = default)
|
||||
{
|
||||
HttpRequestMessageBuilder builder = httpRequestMessageBuilderFactory.Create()
|
||||
.SetRequestUri(HutaoEndpoints.Announcement(metadataOptions.LocaleName))
|
||||
.SetRequestUri(HutaoEndpoints.Announcement(cultureOptions.LocaleName))
|
||||
.PostJson(excluedeIds);
|
||||
|
||||
HutaoResponse<List<Announcement>>? resp = await builder
|
||||
|
||||
Reference in New Issue
Block a user