This commit is contained in:
Lightczx
2023-07-16 16:37:29 +08:00
parent c5dada3f72
commit 8631933ef4
10 changed files with 178 additions and 44 deletions

View File

@@ -150,7 +150,7 @@ internal sealed class Activation : IActivation
// Increase launch times
LocalSetting.Set(SettingKeys.LaunchTimes, LocalSetting.Get(SettingKeys.LaunchTimes, 0) + 1);
if (LocalSetting.Get(SettingKeys.Major1Minor7Revision0GuideState, (uint)GuideState.None) < (uint)GuideState.Completed)
if (false && LocalSetting.Get(SettingKeys.Major1Minor7Revision0GuideState, (uint)GuideState.None) < (uint)GuideState.Completed)
{
await taskContext.SwitchToMainThreadAsync();
serviceProvider.GetRequiredService<GuideWindow>();

View File

@@ -21,4 +21,20 @@ internal static class StringExtension
{
return new(value);
}
/// <summary>
/// 移除结尾可能存在的字符串
/// </summary>
/// <param name="source">源</param>
/// <param name="value">值</param>
/// <returns>新的字符串</returns>
public static string TrimEnd(this string source, string value)
{
while (source.EndsWith(value))
{
source = source[..^value.Length];
}
return source;
}
}

View File

@@ -1374,6 +1374,15 @@ namespace Snap.Hutao.Resource.Localization {
}
}
/// <summary>
/// 查找类似 Url 中的语言:{0} 与胡桃的语言:{1} 不匹配,请切换到对应语言重试 的本地化字符串。
/// </summary>
internal static string ServiceGachaLogUrlProviderUrlLanguageNotMatchCurrentLocale {
get {
return ResourceManager.GetString("ServiceGachaLogUrlProviderUrlLanguageNotMatchCurrentLocale", resourceCulture);
}
}
/// <summary>
/// 查找类似 不支持的 Item Id{0} 的本地化字符串。
/// </summary>

View File

@@ -2135,4 +2135,7 @@
<data name="GuideWindowTitle" xml:space="preserve">
<value>欢迎使用胡桃</value>
</data>
<data name="ServiceGachaLogUrlProviderUrlLanguageNotMatchCurrentLocale" xml:space="preserve">
<value>Url 中的语言:{0} 与胡桃的语言:{1} 不匹配,请切换到对应语言重试</value>
</data>
</root>

View File

@@ -1,7 +1,9 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Snap.Hutao.Service.Metadata;
using Snap.Hutao.View.Dialog;
using Snap.Hutao.Web.Request.QueryString;
namespace Snap.Hutao.Service.GachaLog.QueryProvider;
@@ -14,6 +16,7 @@ namespace Snap.Hutao.Service.GachaLog.QueryProvider;
internal sealed partial class GachaLogQueryManualInputProvider : IGachaLogQueryProvider
{
private readonly IServiceProvider serviceProvider;
private readonly MetadataOptions metadataOptions;
private readonly ITaskContext taskContext;
/// <inheritdoc/>
@@ -25,13 +28,26 @@ internal sealed partial class GachaLogQueryManualInputProvider : IGachaLogQueryP
// ContentDialog must be created by main thread.
await taskContext.SwitchToMainThreadAsync();
GachaLogUrlDialog dialog = serviceProvider.CreateInstance<GachaLogUrlDialog>();
(bool isOk, string query) = await dialog.GetInputUrlAsync().ConfigureAwait(false);
(bool isOk, string queryString) = await dialog.GetInputUrlAsync().ConfigureAwait(false);
if (isOk)
{
if (query.Contains("&auth_appid=webview_gacha"))
QueryString query = QueryString.Parse(queryString);
string queryLanguageCode = query["lang"];
if (query["auth_appid"] == "webview_gacha")
{
return new(true, new(query));
if (metadataOptions.IsCurrentLocale(queryLanguageCode))
{
return new(true, new(queryString));
}
else
{
string message = string.Format(
SH.ServiceGachaLogUrlProviderUrlLanguageNotMatchCurrentLocale,
queryLanguageCode,
metadataOptions.LocaleName);
return new(false, message);
}
}
else
{

View File

@@ -1,6 +1,7 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Snap.Hutao.Service.Metadata;
using Snap.Hutao.Service.User;
using Snap.Hutao.ViewModel.User;
using Snap.Hutao.Web.Hoyolab.Hk4e.Event.GachaInfo;
@@ -18,6 +19,7 @@ namespace Snap.Hutao.Service.GachaLog.QueryProvider;
internal sealed partial class GachaLogQuerySTokenProvider : IGachaLogQueryProvider
{
private readonly BindingClient2 bindingClient2;
private readonly MetadataOptions metadataOptions;
private readonly IUserService userService;
/// <inheritdoc/>
@@ -38,7 +40,7 @@ internal sealed partial class GachaLogQuerySTokenProvider : IGachaLogQueryProvid
if (authkeyResponse.IsOk())
{
return new(true, new(GachaLogQueryOptions.AsQuery(data, authkeyResponse.Data)));
return new(true, new(GachaLogQueryOptions.AsQuery(data, authkeyResponse.Data, metadataOptions.LanguageCode)));
}
else
{

View File

@@ -3,6 +3,9 @@
using Snap.Hutao.Core.IO;
using Snap.Hutao.Service.Game;
using Snap.Hutao.Service.Metadata;
using Snap.Hutao.Web.Request.QueryString;
using System.Globalization;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
@@ -18,6 +21,7 @@ namespace Snap.Hutao.Service.GachaLog.QueryProvider;
internal sealed partial class GachaLogQueryWebCacheProvider : IGachaLogQueryProvider
{
private readonly IGameService gameService;
private readonly MetadataOptions metadataOptions;
/// <inheritdoc/>
public string Name { get => nameof(GachaLogQueryWebCacheProvider); }
@@ -63,7 +67,20 @@ internal sealed partial class GachaLogQueryWebCacheProvider : IGachaLogQueryProv
if (!string.IsNullOrEmpty(result))
{
return new(true, new(result));
QueryString query = QueryString.Parse(result.TrimEnd("#/log"));
string queryLanguageCode = query["lang"];
if (metadataOptions.IsCurrentLocale(queryLanguageCode))
{
return new(true, new(result));
}
else
{
string message = string.Format(
SH.ServiceGachaLogUrlProviderUrlLanguageNotMatchCurrentLocale,
queryLanguageCode,
metadataOptions.LocaleName);
return new(false, message);
}
}
else
{

View File

@@ -3,6 +3,7 @@
using Microsoft.Extensions.Options;
using Snap.Hutao.Core;
using System.Collections.Immutable;
using System.Globalization;
using System.IO;
@@ -15,6 +16,8 @@ namespace Snap.Hutao.Service.Metadata;
[Injection(InjectAs.Singleton)]
internal sealed partial class MetadataOptions : IOptions<MetadataOptions>
{
private readonly AppOptions appOptions;
private readonly HutaoOptions hutaoOptions;
@@ -61,12 +64,51 @@ internal sealed partial class MetadataOptions : IOptions<MetadataOptions>
/// </summary>
public string LocaleName
{
get => localeName ??= GetLocaleName();
get => localeName ??= GetLocaleName(appOptions.CurrentCulture);
}
/// <summary>
/// 当前语言代码
/// </summary>
public string LanguageCode
{
get => LocaleNames.LocaleNameLanguageCodeMap[LocaleName];
}
/// <inheritdoc/>
public MetadataOptions Value { get => this; }
/// <summary>
/// 获取语言名称
/// </summary>
/// <param name="cultureInfo">语言信息</param>
/// <returns>元数据语言名称</returns>
public static string GetLocaleName(CultureInfo cultureInfo)
{
while (true)
{
if (LocaleNames.LanguageNameLocaleNameMap.TryGetValue(cultureInfo.Name, out string? localeName))
{
return localeName;
}
else
{
cultureInfo = cultureInfo.Parent;
}
}
}
/// <summary>
/// 检查是否为当前语言名称
/// </summary>
/// <param name="languageCode">语言代码</param>
/// <returns>是否为当前语言名称</returns>
public bool IsCurrentLocale(string languageCode)
{
CultureInfo cultureInfo = CultureInfo.GetCultureInfo(languageCode);
return GetLocaleName(cultureInfo) == LocaleName;
}
/// <summary>
/// 获取本地的本地化元数据文件
/// </summary>
@@ -90,38 +132,65 @@ internal sealed partial class MetadataOptions : IOptions<MetadataOptions>
return Web.HutaoEndpoints.HutaoMetadata2File(LocaleName, fileNameWithExtension);
#endif
}
private string GetLocaleName()
{
CultureInfo cultureInfo = appOptions.CurrentCulture;
while (true)
{
if (Equals(cultureInfo, CultureInfo.InvariantCulture))
{
// Fallback to Chinese.
return "CHS";
}
switch (cultureInfo.Name)
{
case "de": return "DE"; // German
case "en": return "EN"; // English
case "es": return "ES"; // Spanish
case "fr": return "FR"; // French
case "id": return "ID"; // Indonesian
case "it": return "IT"; // Italian
case "ja": return "JP"; // Japanese
case "ko": return "KR"; // Korean
case "pt": return "PT"; // Portuguese
case "ru": return "RU"; // Russian
case "th": return "TH"; // Thai
case "tr": return "TR"; // Turkish
case "vi": return "TR"; // Vietnamese
case "zh-Hans": return "CHS"; // Chinese (Simplified)
case "zh-Hant": return "CHT"; // Chinese (Traditional)
default: cultureInfo = cultureInfo.Parent; break;
}
}
}
}
/// <summary>
/// 本地化名称
/// </summary>
internal static class LocaleNames
{
public const string DE = "DE"; // German
public const string EN = "EN"; // English
public const string ES = "ES"; // Spanish
public const string FR = "FR"; // French
public const string ID = "ID"; // Indonesian
public const string IT = "IT"; // Italian
public const string JP = "JP"; // Japanese
public const string KR = "KR"; // Korean
public const string PT = "PT"; // Portuguese
public const string RU = "RU"; // Russian
public const string TH = "TH"; // Thai
public const string TR = "TR"; // Turkish
public const string VI = "VI"; // Vietnamese
public const string CHS = "CHS"; // Chinese (Simplified)
public const string CHT = "CHT"; // Chinese (Traditional)
public static readonly ImmutableDictionary<string, string> LanguageNameLocaleNameMap = new Dictionary<string, string>()
{
["de"] = DE,
["en"] = EN,
["es"] = ES,
["fr"] = FR,
["id"] = ID,
["it"] = IT,
["ja"] = JP,
["ko"] = KR,
["pt"] = PT,
["ru"] = RU,
["th"] = TH,
["tr"] = TR,
["vi"] = VI,
["zh-Hans"] = CHS,
["zh-Hant"] = CHT,
[string.Empty] = CHS, // Fallback to Chinese.
}.ToImmutableDictionary();
public static readonly ImmutableDictionary<string, string> LocaleNameLanguageCodeMap = new Dictionary<string, string>()
{
[DE] = "de-de",
[EN] = "en-us",
[ES] = "es-es",
[FR] = "fr-fr",
[ID] = "id-id",
[IT] = "it-it",
[JP] = "ja-jp",
[KR] = "ko-kr",
[PT] = "pt-pt",
[RU] = "ru-ru",
[TH] = "th-th",
[TR] = "tr-tr",
[VI] = "vi-vn",
[CHS] = "zh-cn",
[CHT] = "zh-tw",
}.ToImmutableDictionary();
}

View File

@@ -33,7 +33,7 @@ internal sealed partial class GachaLogUrlDialog : ContentDialog
{
await taskContext.SwitchToMainThreadAsync();
ContentDialogResult result = await ShowAsync();
string url = InputText.Text;
string url = InputText.Text.TrimEnd("#/log");
return new(result == ContentDialogResult.Primary, url);
}

View File

@@ -56,7 +56,7 @@ internal struct GachaLogQueryOptions
IsOversea = query.IsOversea;
innerQuery = QueryString.Parse(query.Query);
innerQuery.Set("lang", "zh-cn");
// innerQuery.Set("lang", "zh-cn");
innerQuery.Set("gacha_type", (int)type);
innerQuery.Set("size", Size);
@@ -68,10 +68,12 @@ internal struct GachaLogQueryOptions
/// </summary>
/// <param name="genAuthKeyData">生成信息</param>
/// <param name="gameAuthKey">验证包装</param>
/// <param name="lang">语言</param>
/// <returns>查询</returns>
public static string AsQuery(GenAuthKeyData genAuthKeyData, GameAuthKey gameAuthKey)
public static string AsQuery(GenAuthKeyData genAuthKeyData, GameAuthKey gameAuthKey, string lang)
{
QueryString queryString = new();
queryString.Set("lang", lang);
queryString.Set("auth_appid", genAuthKeyData.AuthAppId);
queryString.Set("authkey", Uri.EscapeDataString(gameAuthKey.AuthKey));
queryString.Set("authkey_ver", gameAuthKey.AuthKeyVersion);