mirror of
https://jihulab.com/DGP-Studio/Snap.Hutao.git
synced 2025-11-19 21:02:53 +08:00
Add InventoryItems localization support
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -2,6 +2,7 @@ desktop.ini
|
||||
|
||||
*.csproj.user
|
||||
*.pubxml
|
||||
*.DotSettings.user
|
||||
|
||||
.vs/
|
||||
.idea/
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Navigation;
|
||||
using Snap.Hutao.Service.Navigation;
|
||||
@@ -25,7 +26,7 @@ internal class ScopedPage : Page
|
||||
/// <summary>
|
||||
/// 构造一个新的页面
|
||||
/// </summary>
|
||||
public ScopedPage()
|
||||
protected ScopedPage()
|
||||
{
|
||||
Unloaded += OnScopedPageUnloaded;
|
||||
currentScope = Ioc.Default.CreateScope();
|
||||
@@ -51,7 +52,7 @@ internal class ScopedPage : Page
|
||||
/// 应当在 InitializeComponent() 前调用
|
||||
/// </summary>
|
||||
/// <typeparam name="TViewModel">视图模型类型</typeparam>
|
||||
public void InitializeWith<TViewModel>()
|
||||
protected void InitializeWith<TViewModel>()
|
||||
where TViewModel : class, IViewModel
|
||||
{
|
||||
IViewModel viewModel = currentScope.ServiceProvider.GetRequiredService<TViewModel>();
|
||||
|
||||
@@ -23,6 +23,7 @@ internal sealed class ImageCache : IImageCache, IImageCacheFilePathOperation
|
||||
{
|
||||
private const string CacheFolderName = nameof(ImageCache);
|
||||
|
||||
// TODO: use FrozenDictionary
|
||||
private static readonly Dictionary<int, TimeSpan> RetryCountToDelay = new()
|
||||
{
|
||||
[0] = TimeSpan.FromSeconds(4),
|
||||
@@ -173,14 +174,14 @@ internal sealed class ImageCache : IImageCache, IImageCacheFilePathOperation
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogWarning(ex, "Remove Cache Image Failed:{file}", filePath);
|
||||
logger.LogWarning(ex, "Remove Cache Image Failed:{File}", filePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task DownloadFileAsync(Uri uri, string baseFile)
|
||||
{
|
||||
logger.LogInformation("Begin downloading for {uri}", uri);
|
||||
logger.LogInformation("Begin downloading for {Uri}", uri);
|
||||
|
||||
int retryCount = 0;
|
||||
while (retryCount < 6)
|
||||
@@ -209,7 +210,7 @@ internal sealed class ImageCache : IImageCache, IImageCacheFilePathOperation
|
||||
{
|
||||
retryCount++;
|
||||
TimeSpan delay = message.Headers.RetryAfter?.Delta ?? RetryCountToDelay[retryCount];
|
||||
logger.LogInformation("Retry {uri} after {delay}.", uri, delay);
|
||||
logger.LogInformation("Retry {Uri} after {Delay}.", uri, delay);
|
||||
await Task.Delay(delay).ConfigureAwait(false);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -14,17 +14,17 @@ internal sealed class HttpClientAttribute : Attribute
|
||||
/// <summary>
|
||||
/// 构造一个新的特性
|
||||
/// </summary>
|
||||
/// <param name="configration">配置</param>
|
||||
public HttpClientAttribute(HttpClientConfiguration configration)
|
||||
/// <param name="configuration">配置</param>
|
||||
public HttpClientAttribute(HttpClientConfiguration configuration)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构造一个新的特性
|
||||
/// </summary>
|
||||
/// <param name="configration">配置</param>
|
||||
/// <param name="configuration">配置</param>
|
||||
/// <param name="interfaceType">实现的接口类型</param>
|
||||
public HttpClientAttribute(HttpClientConfiguration configration, Type interfaceType)
|
||||
public HttpClientAttribute(HttpClientConfiguration configuration, Type interfaceType)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Snap.Hutao.Core.Json;
|
||||
using Snap.Hutao.Model.Entity.Database;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Snap.Hutao.Core.DependencyInjection;
|
||||
|
||||
|
||||
@@ -17,6 +17,6 @@ internal readonly struct MeasureExecutionToken : IDisposable
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
logger.LogInformation("{caller} toke {time} ms.", callerName, stopwatch.GetElapsedTime().TotalMilliseconds);
|
||||
logger.LogInformation("{Caller} toke {Time} ms", callerName, stopwatch.GetElapsedTime().TotalMilliseconds);
|
||||
}
|
||||
}
|
||||
@@ -41,16 +41,16 @@ internal sealed partial class ExceptionRecorder
|
||||
#pragma warning restore VSTHRD002
|
||||
#endif
|
||||
|
||||
logger.LogError("未经处理的全局异常:\r\n{detail}", ExceptionFormat.Format(e.Exception));
|
||||
logger.LogError("未经处理的全局异常:\r\n{Detail}", ExceptionFormat.Format(e.Exception));
|
||||
}
|
||||
|
||||
private void OnXamlBindingFailed(object? sender, BindingFailedEventArgs e)
|
||||
{
|
||||
logger.LogCritical("XAML 绑定失败:{message}", e.Message);
|
||||
logger.LogCritical("XAML 绑定失败:{Message}", e.Message);
|
||||
}
|
||||
|
||||
private void OnXamlResourceReferenceFailed(DebugSettings sender, XamlResourceReferenceFailedEventArgs e)
|
||||
{
|
||||
logger.LogCritical("XAML 资源引用失败:{message}", e.Message);
|
||||
logger.LogCritical("XAML 资源引用失败:{Message}", e.Message);
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,7 @@ internal static class MD5
|
||||
/// <returns>文件 Md5 摘要</returns>
|
||||
public static async Task<string> HashFileAsync(string filePath, CancellationToken token = default)
|
||||
{
|
||||
using (FileStream stream = File.OpenRead(filePath))
|
||||
await using (FileStream stream = File.OpenRead(filePath))
|
||||
{
|
||||
return await HashAsync(stream, token).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ internal static class XXH64
|
||||
/// <returns>摘要</returns>
|
||||
public static async Task<string> HashFileAsync(string path, CancellationToken token = default)
|
||||
{
|
||||
using (FileStream stream = File.OpenRead(path))
|
||||
await using (FileStream stream = File.OpenRead(path))
|
||||
{
|
||||
return await HashAsync(stream, token).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ internal sealed class IniComment : IniElement
|
||||
/// <summary>
|
||||
/// 注释
|
||||
/// </summary>
|
||||
public string Comment { get; set; }
|
||||
public string Comment { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
|
||||
@@ -23,12 +23,12 @@ internal sealed class IniParameter : IniElement
|
||||
/// <summary>
|
||||
/// 键
|
||||
/// </summary>
|
||||
public string Key { get; set; }
|
||||
public string Key { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 值
|
||||
/// </summary>
|
||||
public string Value { get; set; }
|
||||
public string Value { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 设置值
|
||||
|
||||
@@ -21,7 +21,7 @@ internal sealed class IniSection : IniElement
|
||||
/// <summary>
|
||||
/// 名称
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
public string Name { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
|
||||
@@ -39,7 +39,7 @@ internal static class IniSerializer
|
||||
|
||||
if (line.IndexOf('=') > 0)
|
||||
{
|
||||
string[] parameters = line.Split('=', 2);
|
||||
string[] parameters = line.Split('=', 2, StringSplitOptions.TrimEntries);
|
||||
yield return new IniParameter(parameters[0], parameters[1]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ internal sealed class TempFile : IDisposable
|
||||
/// 构造一个新的临时文件
|
||||
/// </summary>
|
||||
/// <param name="delete">是否在创建时删除文件</param>
|
||||
public TempFile(bool delete = false)
|
||||
private TempFile(bool delete = false)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
@@ -10,23 +10,20 @@ namespace Snap.Hutao.Core.IO;
|
||||
/// </summary>
|
||||
internal readonly struct ValueFile
|
||||
{
|
||||
/// <summary>
|
||||
/// 值
|
||||
/// </summary>
|
||||
public readonly string Value;
|
||||
private readonly string value;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ValueFile"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="value">value</param>
|
||||
public ValueFile(string value)
|
||||
private ValueFile(string value)
|
||||
{
|
||||
Value = value;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static implicit operator string(ValueFile value)
|
||||
{
|
||||
return value.Value;
|
||||
return value.value;
|
||||
}
|
||||
|
||||
public static implicit operator ValueFile(string value)
|
||||
@@ -45,7 +42,7 @@ internal readonly struct ValueFile
|
||||
{
|
||||
try
|
||||
{
|
||||
using (FileStream stream = File.OpenRead(Value))
|
||||
using (FileStream stream = File.OpenRead(value))
|
||||
{
|
||||
T? t = await JsonSerializer.DeserializeAsync<T>(stream, options).ConfigureAwait(false);
|
||||
return new(true, t);
|
||||
@@ -69,7 +66,7 @@ internal readonly struct ValueFile
|
||||
{
|
||||
try
|
||||
{
|
||||
using (FileStream stream = File.Create(Value))
|
||||
using (FileStream stream = File.Create(value))
|
||||
{
|
||||
await JsonSerializer.SerializeAsync(stream, obj, options).ConfigureAwait(false);
|
||||
}
|
||||
@@ -85,6 +82,6 @@ internal readonly struct ValueFile
|
||||
/// <inheritdoc/>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Value.GetHashCode();
|
||||
return value.GetHashCode();
|
||||
}
|
||||
}
|
||||
@@ -14,14 +14,17 @@ internal class JsonEnumAttribute : Attribute
|
||||
{
|
||||
private static readonly Type UnsafeEnumConverterType = typeof(UnsafeEnumConverter<>);
|
||||
|
||||
private readonly JsonSerializeType readAs;
|
||||
private readonly JsonSerializeType writeAs;
|
||||
|
||||
/// <summary>
|
||||
/// 构造一个新的Json枚举声明
|
||||
/// </summary>
|
||||
/// <param name="readAndWriteAs">读取与写入</param>
|
||||
public JsonEnumAttribute(JsonSerializeType readAndWriteAs)
|
||||
{
|
||||
ReadAs = readAndWriteAs;
|
||||
WriteAs = readAndWriteAs;
|
||||
readAs = readAndWriteAs;
|
||||
writeAs = readAndWriteAs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -31,20 +34,10 @@ internal class JsonEnumAttribute : Attribute
|
||||
/// <param name="writeAs">写入</param>
|
||||
public JsonEnumAttribute(JsonSerializeType readAs, JsonSerializeType writeAs)
|
||||
{
|
||||
ReadAs = readAs;
|
||||
WriteAs = writeAs;
|
||||
this.readAs = readAs;
|
||||
this.writeAs = writeAs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取形式
|
||||
/// </summary>
|
||||
public JsonSerializeType ReadAs { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 写入形式
|
||||
/// </summary>
|
||||
public JsonSerializeType WriteAs { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建一个新的转换器
|
||||
/// </summary>
|
||||
@@ -53,6 +46,6 @@ internal class JsonEnumAttribute : Attribute
|
||||
internal JsonConverter CreateConverter(JsonPropertyInfo info)
|
||||
{
|
||||
Type converterType = UnsafeEnumConverterType.MakeGenericType(info.PropertyType);
|
||||
return (JsonConverter)Activator.CreateInstance(converterType, ReadAs, WriteAs)!;
|
||||
return (JsonConverter)Activator.CreateInstance(converterType, readAs, writeAs)!;
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,7 @@ internal sealed class FeatureOptions : IReadOnlyCollection<Feature>
|
||||
{
|
||||
// TODO: Use source generator
|
||||
yield return IsDailyNoteSilentVerificationEnabled;
|
||||
yield return IsMetadataUpdateCheckSuppressed;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
||||
@@ -44,7 +44,7 @@ internal readonly struct DispatherQueueSwitchOperation : IAwaitable<DispatherQue
|
||||
/// <inheritdoc/>
|
||||
public void OnCompleted(Action continuation)
|
||||
{
|
||||
dispatherQueue.TryEnqueue(continuation.Invoke);
|
||||
dispatherQueue.TryEnqueue(new DispatcherQueueHandler(continuation));
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -52,7 +52,7 @@ internal readonly struct DispatherQueueSwitchOperation : IAwaitable<DispatherQue
|
||||
{
|
||||
using (ExecutionContext.SuppressFlow())
|
||||
{
|
||||
dispatherQueue.TryEnqueue(continuation.Invoke);
|
||||
dispatherQueue.TryEnqueue(new DispatcherQueueHandler(continuation));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -35,7 +35,7 @@ internal static class TaskExtension
|
||||
}
|
||||
}
|
||||
#else
|
||||
catch (Exception)
|
||||
catch
|
||||
{
|
||||
}
|
||||
#endif
|
||||
@@ -46,7 +46,7 @@ internal static class TaskExtension
|
||||
/// </summary>
|
||||
/// <param name="task">任务</param>
|
||||
/// <param name="logger">日志器</param>
|
||||
public static async void SafeForget(this Task task, ILogger? logger = null)
|
||||
public static async void SafeForget(this Task task, ILogger logger)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -58,7 +58,7 @@ internal static class TaskExtension
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger?.LogError(e, "{caller}:\r\n{exception}", nameof(SafeForget), e.GetBaseException());
|
||||
logger?.LogError(e, "{Caller}:\r\n{Exception}", nameof(SafeForget), e.GetBaseException());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ internal static class TaskExtension
|
||||
/// <param name="task">任务</param>
|
||||
/// <param name="logger">日志器</param>
|
||||
/// <param name="onException">发生异常时调用</param>
|
||||
public static async void SafeForget(this Task task, ILogger? logger = null, Action<Exception>? onException = null)
|
||||
public static async void SafeForget(this Task task, ILogger logger, Action<Exception> onException)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -80,7 +80,7 @@ internal static class TaskExtension
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger?.LogError(e, "{caller}:\r\n{exception}", nameof(SafeForget), e.GetBaseException());
|
||||
logger?.LogError(e, "{Caller}:\r\n{Exception}", nameof(SafeForget), e.GetBaseException());
|
||||
onException?.Invoke(e);
|
||||
}
|
||||
}
|
||||
@@ -92,7 +92,7 @@ internal static class TaskExtension
|
||||
/// <param name="logger">日志器</param>
|
||||
/// <param name="onCanceled">任务取消时调用</param>
|
||||
/// <param name="onException">发生异常时调用</param>
|
||||
public static async void SafeForget(this Task task, ILogger? logger = null, Action? onCanceled = null, Action<Exception>? onException = null)
|
||||
public static async void SafeForget(this Task task, ILogger logger, Action onCanceled, Action<Exception>? onException = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -104,7 +104,7 @@ internal static class TaskExtension
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger?.LogError(e, "{caller}:\r\n{exception}", nameof(SafeForget), e.GetBaseException());
|
||||
logger?.LogError(e, "{Caller}:\r\n{Exception}", nameof(SafeForget), e.GetBaseException());
|
||||
onException?.Invoke(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -185,7 +185,7 @@ internal sealed class ExtendedWindow<TWindow> : IRecipient<FlyoutOpenCloseMessag
|
||||
double scale = Persistence.GetScaleForWindowHandle(options.Hwnd);
|
||||
|
||||
// 48 is the navigation button leftInset
|
||||
RectInt32 dragRect = StructMarshal.RectInt32(new(48, 0), options.TitleBar.ActualSize).Scale(scale);
|
||||
RectInt32 dragRect = StructMarshal.RectInt32(48, 0, options.TitleBar.ActualSize).Scale(scale);
|
||||
appTitleBar.SetDragRectangles(dragRect.ToArray());
|
||||
|
||||
// workaround for https://github.com/microsoft/WindowsAppSDK/issues/2976
|
||||
|
||||
@@ -85,13 +85,13 @@ internal static class Persistence
|
||||
HWND fgHwnd = GetForegroundWindow();
|
||||
|
||||
uint threadIdHwnd = GetWindowThreadProcessId(hwnd);
|
||||
uint threadIdfgHwnd = GetWindowThreadProcessId(fgHwnd);
|
||||
uint threadIdFgHwnd = GetWindowThreadProcessId(fgHwnd);
|
||||
|
||||
if (threadIdHwnd != threadIdfgHwnd)
|
||||
if (threadIdHwnd != threadIdFgHwnd)
|
||||
{
|
||||
AttachThreadInput(threadIdHwnd, threadIdfgHwnd, true);
|
||||
AttachThreadInput(threadIdHwnd, threadIdFgHwnd, true);
|
||||
SetForegroundWindow(hwnd);
|
||||
AttachThreadInput(threadIdHwnd, threadIdfgHwnd, false);
|
||||
AttachThreadInput(threadIdHwnd, threadIdFgHwnd, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using System.Runtime.InteropServices;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Windows.Win32.Foundation;
|
||||
using Windows.Win32.UI.Shell;
|
||||
@@ -24,7 +25,7 @@ internal sealed class WindowSubclass<TWindow> : IDisposable
|
||||
|
||||
// We have to explicitly hold a reference to SUBCLASSPROC
|
||||
private SUBCLASSPROC? windowProc;
|
||||
private SUBCLASSPROC? dragBarProc;
|
||||
private SUBCLASSPROC? legacyDragBarProc;
|
||||
|
||||
/// <summary>
|
||||
/// 构造一个新的窗体子类管理器
|
||||
@@ -62,8 +63,8 @@ internal sealed class WindowSubclass<TWindow> : IDisposable
|
||||
return windowHooked && titleBarHooked;
|
||||
}
|
||||
|
||||
dragBarProc = OnDragBarProcedure;
|
||||
titleBarHooked = SetWindowSubclass(hwndDragBar, dragBarProc, DragBarSubclassId, 0);
|
||||
legacyDragBarProc = OnLegacyDragBarProcedure;
|
||||
titleBarHooked = SetWindowSubclass(hwndDragBar, legacyDragBarProc, DragBarSubclassId, 0);
|
||||
|
||||
return windowHooked && titleBarHooked;
|
||||
}
|
||||
@@ -81,8 +82,8 @@ internal sealed class WindowSubclass<TWindow> : IDisposable
|
||||
return;
|
||||
}
|
||||
|
||||
RemoveWindowSubclass(options.Hwnd, dragBarProc, DragBarSubclassId);
|
||||
dragBarProc = null;
|
||||
RemoveWindowSubclass(options.Hwnd, legacyDragBarProc, DragBarSubclassId);
|
||||
legacyDragBarProc = null;
|
||||
}
|
||||
|
||||
[SuppressMessage("", "SH002")]
|
||||
@@ -108,7 +109,7 @@ internal sealed class WindowSubclass<TWindow> : IDisposable
|
||||
}
|
||||
|
||||
[SuppressMessage("", "SH002")]
|
||||
private LRESULT OnDragBarProcedure(HWND hwnd, uint uMsg, WPARAM wParam, LPARAM lParam, nuint uIdSubclass, nuint dwRefData)
|
||||
private LRESULT OnLegacyDragBarProcedure(HWND hwnd, uint uMsg, WPARAM wParam, LPARAM lParam, nuint uIdSubclass, nuint dwRefData)
|
||||
{
|
||||
switch (uMsg)
|
||||
{
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Snap.Hutao.Extension;
|
||||
internal static partial class EnumerableExtension
|
||||
{
|
||||
/// <inheritdoc cref="Enumerable.Average(IEnumerable{int})"/>
|
||||
public static unsafe double UnsafeAverage(this List<int> source)
|
||||
public static double SpanAverage(this List<int> source)
|
||||
{
|
||||
Span<int> span = CollectionsMarshal.AsSpan(source);
|
||||
if (span.IsEmpty)
|
||||
|
||||
@@ -8,6 +8,7 @@ namespace Snap.Hutao.Message;
|
||||
/// </summary>
|
||||
/// <typeparam name="TValue">值的类型</typeparam>
|
||||
[HighQuality]
|
||||
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]
|
||||
internal abstract class ValueChangedMessage<TValue>
|
||||
where TValue : class
|
||||
{
|
||||
|
||||
@@ -25,7 +25,7 @@ internal sealed class CalculableSkill : ObservableObject, ICalculableSkill
|
||||
/// <param name="skill">技能</param>
|
||||
public CalculableSkill(ProudableSkill skill)
|
||||
{
|
||||
GruopId = skill.GroupId;
|
||||
GroupId = skill.GroupId;
|
||||
LevelMin = 1;
|
||||
LevelMax = 10; // hard coded 10 here
|
||||
Name = skill.Name;
|
||||
@@ -42,7 +42,7 @@ internal sealed class CalculableSkill : ObservableObject, ICalculableSkill
|
||||
/// <param name="skill">技能</param>
|
||||
public CalculableSkill(SkillView skill)
|
||||
{
|
||||
GruopId = skill.GroupId;
|
||||
GroupId = skill.GroupId;
|
||||
LevelMin = skill.LevelNumber;
|
||||
LevelMax = 10; // hard coded 10 here
|
||||
Name = skill.Name;
|
||||
@@ -54,7 +54,7 @@ internal sealed class CalculableSkill : ObservableObject, ICalculableSkill
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public SkillGroupId GruopId { get; }
|
||||
public SkillGroupId GroupId { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public uint LevelMin { get; }
|
||||
|
||||
@@ -14,7 +14,7 @@ internal interface ICalculableSkill : ICalculable
|
||||
/// <summary>
|
||||
/// 技能组Id
|
||||
/// </summary>
|
||||
SkillGroupId GruopId { get; }
|
||||
SkillGroupId GroupId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 最小等级
|
||||
|
||||
@@ -34,7 +34,7 @@ internal sealed class AppDbContext : DbContext
|
||||
: this(options)
|
||||
{
|
||||
this.logger = logger;
|
||||
logger.LogInformation("{name}[{id}] created.", nameof(AppDbContext), ContextId);
|
||||
logger.LogInformation("{Name}[{Id}] created", nameof(AppDbContext), ContextId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -136,7 +136,7 @@ internal sealed class AppDbContext : DbContext
|
||||
public override void Dispose()
|
||||
{
|
||||
base.Dispose();
|
||||
logger?.LogInformation("AppDbContext[{id}] disposed.", ContextId);
|
||||
logger?.LogInformation("{Name}[{Id}] disposed", nameof(AppDbContext), ContextId);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace Snap.Hutao.Model.Intrinsic;
|
||||
/// 成就信息状态
|
||||
/// </summary>
|
||||
[HighQuality]
|
||||
internal enum AchievementStatus
|
||||
internal enum AchievementStatus /*: int*/
|
||||
{
|
||||
/// <summary>
|
||||
/// 未识别
|
||||
|
||||
@@ -18,13 +18,13 @@ internal enum AssociationType
|
||||
/// <summary>
|
||||
/// 蒙德
|
||||
/// </summary>
|
||||
[LocalizationKey("ModelIntrinsicAssociationTypeMondstadt")]
|
||||
[LocalizationKey(nameof(SH.ModelIntrinsicAssociationTypeMondstadt))]
|
||||
ASSOC_TYPE_MONDSTADT,
|
||||
|
||||
/// <summary>
|
||||
/// 璃月
|
||||
/// </summary>
|
||||
[LocalizationKey("ModelIntrinsicAssociationTypeLiyue")]
|
||||
[LocalizationKey(nameof(SH.ModelIntrinsicAssociationTypeLiyue))]
|
||||
ASSOC_TYPE_LIYUE,
|
||||
|
||||
/// <summary>
|
||||
@@ -35,42 +35,42 @@ internal enum AssociationType
|
||||
/// <summary>
|
||||
/// 愚人众
|
||||
/// </summary>
|
||||
[LocalizationKey("ModelIntrinsicAssociationTypeFatui")]
|
||||
[LocalizationKey(nameof(SH.ModelIntrinsicAssociationTypeFatui))]
|
||||
ASSOC_TYPE_FATUI,
|
||||
|
||||
/// <summary>
|
||||
/// 稻妻
|
||||
/// </summary>
|
||||
[LocalizationKey("ModelIntrinsicAssociationTypeInazuma")]
|
||||
[LocalizationKey(nameof(SH.ModelIntrinsicAssociationTypeInazuma))]
|
||||
ASSOC_TYPE_INAZUMA,
|
||||
|
||||
/// <summary>
|
||||
/// 游侠
|
||||
/// </summary>
|
||||
[LocalizationKey("ModelIntrinsicAssociationTypeRanger")]
|
||||
[LocalizationKey(nameof(SH.ModelIntrinsicAssociationTypeRanger))]
|
||||
ASSOC_TYPE_RANGER,
|
||||
|
||||
/// <summary>
|
||||
/// 须弥
|
||||
/// </summary>
|
||||
[LocalizationKey("ModelIntrinsicAssociationTypeSumeru")]
|
||||
[LocalizationKey(nameof(SH.ModelIntrinsicAssociationTypeSumeru))]
|
||||
ASSOC_TYPE_SUMERU,
|
||||
|
||||
/// <summary>
|
||||
/// 枫丹
|
||||
/// </summary>
|
||||
[LocalizationKey("ModelIntrinsicAssociationTypeFontaine")]
|
||||
[LocalizationKey(nameof(SH.ModelIntrinsicAssociationTypeFontaine))]
|
||||
ASSOC_TYPE_FONTAINE,
|
||||
|
||||
/// <summary>
|
||||
/// 纳塔
|
||||
/// </summary>
|
||||
[LocalizationKey("ModelIntrinsicAssociationTypeNatlan")]
|
||||
[LocalizationKey(nameof(SH.ModelIntrinsicAssociationTypeNatlan))]
|
||||
ASSOC_TYPE_NATLAN,
|
||||
|
||||
/// <summary>
|
||||
/// 至冬
|
||||
/// </summary>
|
||||
[LocalizationKey("ModelIntrinsicAssociationTypeSnezhnaya")]
|
||||
[LocalizationKey(nameof(SH.ModelIntrinsicAssociationTypeSnezhnaya))]
|
||||
ASSOC_TYPE_SNEZHNAYA,
|
||||
}
|
||||
@@ -18,30 +18,30 @@ internal enum BodyType
|
||||
/// <summary>
|
||||
/// 男孩
|
||||
/// </summary>
|
||||
[LocalizationKey("ModelIntrinsicBodyTypeBoy")]
|
||||
[LocalizationKey(nameof(SH.ModelIntrinsicBodyTypeBoy))]
|
||||
BODY_BOY,
|
||||
|
||||
/// <summary>
|
||||
/// 女孩
|
||||
/// </summary>
|
||||
[LocalizationKey("ModelIntrinsicBodyTypeGirl")]
|
||||
[LocalizationKey(nameof(SH.ModelIntrinsicBodyTypeGirl))]
|
||||
BODY_GIRL,
|
||||
|
||||
/// <summary>
|
||||
/// 成女
|
||||
/// </summary>
|
||||
[LocalizationKey("ModelIntrinsicBodyTypeLady")]
|
||||
[LocalizationKey(nameof(SH.ModelIntrinsicBodyTypeLady))]
|
||||
BODY_LADY,
|
||||
|
||||
/// <summary>
|
||||
/// 成男
|
||||
/// </summary>
|
||||
[LocalizationKey("ModelIntrinsicBodyTypeMale")]
|
||||
[LocalizationKey(nameof(SH.ModelIntrinsicBodyTypeMale))]
|
||||
BODY_MALE,
|
||||
|
||||
/// <summary>
|
||||
/// 萝莉
|
||||
/// </summary>
|
||||
[LocalizationKey("ModelIntrinsicBodyTypeLoli")]
|
||||
[LocalizationKey(nameof(SH.ModelIntrinsicBodyTypeLoli))]
|
||||
BODY_LOLI,
|
||||
}
|
||||
@@ -18,55 +18,55 @@ internal enum FightProperty
|
||||
/// <summary>
|
||||
/// 基础生命值
|
||||
/// </summary>
|
||||
[LocalizationKey("ServiceAvatarInfoPropertyBaseHp")]
|
||||
[LocalizationKey(nameof(SH.ServiceAvatarInfoPropertyBaseHp))]
|
||||
FIGHT_PROP_BASE_HP = 1,
|
||||
|
||||
/// <summary>
|
||||
/// 小生命值加成
|
||||
/// </summary>
|
||||
[LocalizationKey("ServiceAvatarInfoPropertyHp")]
|
||||
[LocalizationKey(nameof(SH.ServiceAvatarInfoPropertyHp))]
|
||||
FIGHT_PROP_HP = 2,
|
||||
|
||||
/// <summary>
|
||||
/// 生命值加成百分比
|
||||
/// </summary>
|
||||
[LocalizationKey("ServiceAvatarInfoPropertyHp")]
|
||||
[LocalizationKey(nameof(SH.ServiceAvatarInfoPropertyHp))]
|
||||
FIGHT_PROP_HP_PERCENT = 3,
|
||||
|
||||
/// <summary>
|
||||
/// 基础攻击力
|
||||
/// </summary>
|
||||
[LocalizationKey("ServiceAvatarInfoPropertyBaseAtk")]
|
||||
[LocalizationKey(nameof(SH.ServiceAvatarInfoPropertyBaseAtk))]
|
||||
FIGHT_PROP_BASE_ATTACK = 4,
|
||||
|
||||
/// <summary>
|
||||
/// 攻击力加成
|
||||
/// </summary>
|
||||
[LocalizationKey("ServiceAvatarInfoPropertyAtk")]
|
||||
[LocalizationKey(nameof(SH.ServiceAvatarInfoPropertyAtk))]
|
||||
FIGHT_PROP_ATTACK = 5,
|
||||
|
||||
/// <summary>
|
||||
/// 攻击力百分比
|
||||
/// </summary>
|
||||
[LocalizationKey("ServiceAvatarInfoPropertyAtk")]
|
||||
[LocalizationKey(nameof(SH.ServiceAvatarInfoPropertyAtk))]
|
||||
FIGHT_PROP_ATTACK_PERCENT = 6,
|
||||
|
||||
/// <summary>
|
||||
/// 基础防御力
|
||||
/// </summary>
|
||||
[LocalizationKey("ServiceAvatarInfoPropertyBaseDef")]
|
||||
[LocalizationKey(nameof(SH.ServiceAvatarInfoPropertyBaseDef))]
|
||||
FIGHT_PROP_BASE_DEFENSE = 7,
|
||||
|
||||
/// <summary>
|
||||
/// 防御力加成
|
||||
/// </summary>
|
||||
[LocalizationKey("ServiceAvatarInfoPropertyDef")]
|
||||
[LocalizationKey(nameof(SH.ServiceAvatarInfoPropertyDef))]
|
||||
FIGHT_PROP_DEFENSE = 8,
|
||||
|
||||
/// <summary>
|
||||
/// 防御力百分比
|
||||
/// </summary>
|
||||
[LocalizationKey("ServiceAvatarInfoPropertyDef")]
|
||||
[LocalizationKey(nameof(SH.ServiceAvatarInfoPropertyDef))]
|
||||
FIGHT_PROP_DEFENSE_PERCENT = 9,
|
||||
|
||||
/// <summary>
|
||||
@@ -92,7 +92,7 @@ internal enum FightProperty
|
||||
/// <summary>
|
||||
/// 暴击率
|
||||
/// </summary>
|
||||
[LocalizationKey("ServiceAvatarInfoPropertyCR")]
|
||||
[LocalizationKey(nameof(SH.ServiceAvatarInfoPropertyCR))]
|
||||
FIGHT_PROP_CRITICAL = 20,
|
||||
|
||||
/// <summary>
|
||||
@@ -103,13 +103,13 @@ internal enum FightProperty
|
||||
/// <summary>
|
||||
/// 暴击伤害
|
||||
/// </summary>
|
||||
[LocalizationKey("ServiceAvatarInfoPropertyCDmg")]
|
||||
[LocalizationKey(nameof(SH.ServiceAvatarInfoPropertyCDmg))]
|
||||
FIGHT_PROP_CRITICAL_HURT = 22,
|
||||
|
||||
/// <summary>
|
||||
/// 元素充能效率
|
||||
/// </summary>
|
||||
[LocalizationKey("ServiceAvatarInfoPropertyCE")]
|
||||
[LocalizationKey(nameof(SH.ServiceAvatarInfoPropertyCE))]
|
||||
FIGHT_PROP_CHARGE_EFFICIENCY = 23,
|
||||
|
||||
/// <summary>
|
||||
@@ -125,7 +125,7 @@ internal enum FightProperty
|
||||
/// <summary>
|
||||
/// 治疗提升
|
||||
/// </summary>
|
||||
[LocalizationKey("ServiceAvatarInfoPropertyHB")]
|
||||
[LocalizationKey(nameof(SH.ServiceAvatarInfoPropertyHB))]
|
||||
FIGHT_PROP_HEAL_ADD = 26,
|
||||
|
||||
/// <summary>
|
||||
@@ -136,19 +136,19 @@ internal enum FightProperty
|
||||
/// <summary>
|
||||
/// 元素精通
|
||||
/// </summary>
|
||||
[LocalizationKey("ServiceAvatarInfoPropertyEM")]
|
||||
[LocalizationKey(nameof(SH.ServiceAvatarInfoPropertyEM))]
|
||||
FIGHT_PROP_ELEMENT_MASTERY = 28,
|
||||
|
||||
/// <summary>
|
||||
/// 物理抗性提升
|
||||
/// </summary>
|
||||
[LocalizationKey("ServiceAvatarInfoPropertyRESPhysical")]
|
||||
[LocalizationKey(nameof(SH.ServiceAvatarInfoPropertyRESPhysical))]
|
||||
FIGHT_PROP_PHYSICAL_SUB_HURT = 29,
|
||||
|
||||
/// <summary>
|
||||
/// 物理伤害加成
|
||||
/// </summary>
|
||||
[LocalizationKey("ServiceAvatarInfoPropertyDBPhyiscal")]
|
||||
[LocalizationKey(nameof(SH.ServiceAvatarInfoPropertyDBPhyiscal))]
|
||||
FIGHT_PROP_PHYSICAL_ADD_HURT = 30,
|
||||
|
||||
/// <summary>
|
||||
@@ -164,43 +164,43 @@ internal enum FightProperty
|
||||
/// <summary>
|
||||
/// 火元素伤害加成
|
||||
/// </summary>
|
||||
[LocalizationKey("ServiceAvatarInfoPropertyDBFire")]
|
||||
[LocalizationKey(nameof(SH.ServiceAvatarInfoPropertyDBFire))]
|
||||
FIGHT_PROP_FIRE_ADD_HURT = 40,
|
||||
|
||||
/// <summary>
|
||||
/// 雷元素伤害加成
|
||||
/// </summary>
|
||||
[LocalizationKey("ServiceAvatarInfoPropertyDBElec")]
|
||||
[LocalizationKey(nameof(SH.ServiceAvatarInfoPropertyDBElec))]
|
||||
FIGHT_PROP_ELEC_ADD_HURT = 41,
|
||||
|
||||
/// <summary>
|
||||
/// 水元素伤害加成
|
||||
/// </summary>
|
||||
[LocalizationKey("ServiceAvatarInfoPropertyDBWater")]
|
||||
[LocalizationKey(nameof(SH.ServiceAvatarInfoPropertyDBWater))]
|
||||
FIGHT_PROP_WATER_ADD_HURT = 42,
|
||||
|
||||
/// <summary>
|
||||
/// 草元素伤害加成
|
||||
/// </summary>
|
||||
[LocalizationKey("ServiceAvatarInfoPropertyDBGrass")]
|
||||
[LocalizationKey(nameof(SH.ServiceAvatarInfoPropertyDBGrass))]
|
||||
FIGHT_PROP_GRASS_ADD_HURT = 43,
|
||||
|
||||
/// <summary>
|
||||
/// 风元素伤害加成
|
||||
/// </summary>
|
||||
[LocalizationKey("ServiceAvatarInfoPropertyDBWind")]
|
||||
[LocalizationKey(nameof(SH.ServiceAvatarInfoPropertyDBWind))]
|
||||
FIGHT_PROP_WIND_ADD_HURT = 44,
|
||||
|
||||
/// <summary>
|
||||
/// 岩元素伤害加成
|
||||
/// </summary>
|
||||
[LocalizationKey("ServiceAvatarInfoPropertyDBRock")]
|
||||
[LocalizationKey(nameof(SH.ServiceAvatarInfoPropertyDBRock))]
|
||||
FIGHT_PROP_ROCK_ADD_HURT = 45,
|
||||
|
||||
/// <summary>
|
||||
/// 冰元素伤害加成
|
||||
/// </summary>
|
||||
[LocalizationKey("ServiceAvatarInfoPropertyDBIce")]
|
||||
[LocalizationKey(nameof(SH.ServiceAvatarInfoPropertyDBIce))]
|
||||
FIGHT_PROP_ICE_ADD_HURT = 46,
|
||||
|
||||
/// <summary>
|
||||
@@ -211,43 +211,43 @@ internal enum FightProperty
|
||||
/// <summary>
|
||||
/// 火元素抗性提升
|
||||
/// </summary>
|
||||
[LocalizationKey("ServiceAvatarInfoPropertyRESFire")]
|
||||
[LocalizationKey(nameof(SH.ServiceAvatarInfoPropertyRESFire))]
|
||||
FIGHT_PROP_FIRE_SUB_HURT = 50,
|
||||
|
||||
/// <summary>
|
||||
/// 雷元素抗性提升
|
||||
/// </summary>
|
||||
[LocalizationKey("ServiceAvatarInfoPropertyRESElec")]
|
||||
[LocalizationKey(nameof(SH.ServiceAvatarInfoPropertyRESElec))]
|
||||
FIGHT_PROP_ELEC_SUB_HURT = 51,
|
||||
|
||||
/// <summary>
|
||||
/// 雷元素抗性提升
|
||||
/// </summary>
|
||||
[LocalizationKey("ServiceAvatarInfoPropertyRESWater")]
|
||||
[LocalizationKey(nameof(SH.ServiceAvatarInfoPropertyRESWater))]
|
||||
FIGHT_PROP_WATER_SUB_HURT = 52,
|
||||
|
||||
/// <summary>
|
||||
/// 草元素抗性提升
|
||||
/// </summary>
|
||||
[LocalizationKey("ServiceAvatarInfoPropertyRESGrass")]
|
||||
[LocalizationKey(nameof(SH.ServiceAvatarInfoPropertyRESGrass))]
|
||||
FIGHT_PROP_GRASS_SUB_HURT = 53,
|
||||
|
||||
/// <summary>
|
||||
/// 风元素抗性提升
|
||||
/// </summary>
|
||||
[LocalizationKey("ServiceAvatarInfoPropertyRESWind")]
|
||||
[LocalizationKey(nameof(SH.ServiceAvatarInfoPropertyRESWind))]
|
||||
FIGHT_PROP_WIND_SUB_HURT = 54,
|
||||
|
||||
/// <summary>
|
||||
/// 岩元素抗性提升
|
||||
/// </summary>
|
||||
[LocalizationKey("ServiceAvatarInfoPropertyRESRock")]
|
||||
[LocalizationKey(nameof(SH.ServiceAvatarInfoPropertyRESRock))]
|
||||
FIGHT_PROP_ROCK_SUB_HURT = 55,
|
||||
|
||||
/// <summary>
|
||||
/// 冰元素抗性提升
|
||||
/// </summary>
|
||||
[LocalizationKey("ServiceAvatarInfoPropertyRESIce")]
|
||||
[LocalizationKey(nameof(SH.ServiceAvatarInfoPropertyRESIce))]
|
||||
FIGHT_PROP_ICE_SUB_HURT = 56,
|
||||
|
||||
/// <summary>
|
||||
@@ -378,19 +378,19 @@ internal enum FightProperty
|
||||
/// <summary>
|
||||
/// 最大生命值
|
||||
/// </summary>
|
||||
[LocalizationKey("ServiceAvatarInfoPropertyHp")]
|
||||
[LocalizationKey(nameof(SH.ServiceAvatarInfoPropertyHp))]
|
||||
FIGHT_PROP_MAX_HP = 2000,
|
||||
|
||||
/// <summary>
|
||||
/// 当前攻击力
|
||||
/// </summary>
|
||||
[LocalizationKey("ServiceAvatarInfoPropertyAtk")]
|
||||
[LocalizationKey(nameof(SH.ServiceAvatarInfoPropertyAtk))]
|
||||
FIGHT_PROP_CUR_ATTACK = 2001,
|
||||
|
||||
/// <summary>
|
||||
/// 当前防御力
|
||||
/// </summary>
|
||||
[LocalizationKey("ServiceAvatarInfoPropertyDef")]
|
||||
[LocalizationKey(nameof(SH.ServiceAvatarInfoPropertyDef))]
|
||||
FIGHT_PROP_CUR_DEFENSE = 2002,
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -49,4 +49,15 @@ internal static class IntrinsicImmutable
|
||||
SH.ModelIntrinsicElementNameIce,
|
||||
SH.ModelIntrinsicElementNameRock,
|
||||
}.ToImmutableHashSet();
|
||||
|
||||
public static readonly ImmutableHashSet<string> MaterialTypeDescriptions = new HashSet<string>(7)
|
||||
{
|
||||
SH.ModelMetadataMaterialCharacterAndWeaponEnhancementMaterial,
|
||||
SH.ModelMetadataMaterialCharacterEXPMaterial,
|
||||
SH.ModelMetadataMaterialCharacterAscensionMaterial,
|
||||
SH.ModelMetadataMaterialCharacterTalentMaterial,
|
||||
SH.ModelMetadataMaterialCharacterLevelUpMaterial,
|
||||
SH.ModelMetadataMaterialWeaponEnhancementMaterial,
|
||||
SH.ModelMetadataMaterialWeaponAscensionMaterial,
|
||||
}.ToImmutableHashSet();
|
||||
}
|
||||
@@ -18,36 +18,36 @@ internal enum QualityType
|
||||
/// <summary>
|
||||
/// 一星
|
||||
/// </summary>
|
||||
[LocalizationKey("ModelIntrinsicItemQualityWhite")]
|
||||
[LocalizationKey(nameof(SH.ModelIntrinsicItemQualityWhite))]
|
||||
QUALITY_WHITE = 1,
|
||||
|
||||
/// <summary>
|
||||
/// 二星
|
||||
/// </summary>
|
||||
[LocalizationKey("ModelIntrinsicItemQualityGreen")]
|
||||
[LocalizationKey(nameof(SH.ModelIntrinsicItemQualityGreen))]
|
||||
QUALITY_GREEN = 2,
|
||||
|
||||
/// <summary>
|
||||
/// 三星
|
||||
/// </summary>
|
||||
[LocalizationKey("ModelIntrinsicItemQualityBlue")]
|
||||
[LocalizationKey(nameof(SH.ModelIntrinsicItemQualityBlue))]
|
||||
QUALITY_BLUE = 3,
|
||||
|
||||
/// <summary>
|
||||
/// 四星
|
||||
/// </summary>
|
||||
[LocalizationKey("ModelIntrinsicItemQualityPurple")]
|
||||
[LocalizationKey(nameof(SH.ModelIntrinsicItemQualityPurple))]
|
||||
QUALITY_PURPLE = 4,
|
||||
|
||||
/// <summary>
|
||||
/// 五星
|
||||
/// </summary>
|
||||
[LocalizationKey("ModelIntrinsicItemQualityOrange")]
|
||||
[LocalizationKey(nameof(SH.ModelIntrinsicItemQualityOrange))]
|
||||
QUALITY_ORANGE = 5,
|
||||
|
||||
/// <summary>
|
||||
/// 限定五星
|
||||
/// </summary>
|
||||
[LocalizationKey("ModelIntrinsicItemQualityRed")]
|
||||
[LocalizationKey(nameof(SH.ModelIntrinsicItemQualityRed))]
|
||||
QUALITY_ORANGE_SP = 105,
|
||||
}
|
||||
@@ -19,7 +19,7 @@ internal enum WeaponType
|
||||
/// <summary>
|
||||
/// 单手剑
|
||||
/// </summary>
|
||||
[LocalizationKey("ModelIntrinsicWeaponTypeSwordOneHand")]
|
||||
[LocalizationKey(nameof(SH.ModelIntrinsicWeaponTypeSwordOneHand))]
|
||||
WEAPON_SWORD_ONE_HAND = 1,
|
||||
|
||||
#region Not Used
|
||||
@@ -76,24 +76,24 @@ internal enum WeaponType
|
||||
/// <summary>
|
||||
/// 法器
|
||||
/// </summary>
|
||||
[LocalizationKey("ModelIntrinsicWeaponTypeCatalyst")]
|
||||
[LocalizationKey(nameof(SH.ModelIntrinsicWeaponTypeCatalyst))]
|
||||
WEAPON_CATALYST = 10,
|
||||
|
||||
/// <summary>
|
||||
/// 双手剑
|
||||
/// </summary>
|
||||
[LocalizationKey("ModelIntrinsicWeaponTypeClaymore")]
|
||||
[LocalizationKey(nameof(SH.ModelIntrinsicWeaponTypeClaymore))]
|
||||
WEAPON_CLAYMORE = 11,
|
||||
|
||||
/// <summary>
|
||||
/// 弓
|
||||
/// </summary>
|
||||
[LocalizationKey("ModelIntrinsicWeaponTypeBow")]
|
||||
[LocalizationKey(nameof(SH.ModelIntrinsicWeaponTypeBow))]
|
||||
WEAPON_BOW = 12,
|
||||
|
||||
/// <summary>
|
||||
/// 长柄武器
|
||||
/// </summary>
|
||||
[LocalizationKey("ModelIntrinsicWeaponTypePole")]
|
||||
[LocalizationKey(nameof(SH.ModelIntrinsicWeaponTypePole))]
|
||||
WEAPON_POLE = 13,
|
||||
}
|
||||
@@ -19,7 +19,7 @@ internal sealed class WeaponTypeIconConverter : ValueConverter<WeaponType, Uri>
|
||||
/// <returns>图标链接</returns>
|
||||
public static Uri WeaponTypeToIconUri(WeaponType type)
|
||||
{
|
||||
string element = type switch
|
||||
string weapon = type switch
|
||||
{
|
||||
WeaponType.WEAPON_SWORD_ONE_HAND => "01",
|
||||
WeaponType.WEAPON_BOW => "02",
|
||||
@@ -29,7 +29,7 @@ internal sealed class WeaponTypeIconConverter : ValueConverter<WeaponType, Uri>
|
||||
_ => throw Must.NeverHappen(),
|
||||
};
|
||||
|
||||
return Web.HutaoEndpoints.StaticFile("Skill", $"Skill_A_{element}.png").ToUri();
|
||||
return Web.HutaoEndpoints.StaticFile("Skill", $"Skill_A_{weapon}.png").ToUri();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
||||
@@ -5,6 +5,8 @@ using Snap.Hutao.Model.Intrinsic;
|
||||
using Snap.Hutao.Model.Primitive;
|
||||
using Snap.Hutao.ViewModel.Cultivation;
|
||||
using System.Collections.Immutable;
|
||||
using System.Text.RegularExpressions;
|
||||
using Snap.Hutao.Model.Intrinsic.Immutable;
|
||||
|
||||
namespace Snap.Hutao.Model.Metadata.Item;
|
||||
|
||||
@@ -46,24 +48,19 @@ internal sealed class Material : DisplayItem
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: support non-CHS
|
||||
if (TypeDescription.EndsWith("区域特产"))
|
||||
if (Regex.IsMatch(TypeDescription, SH.ModelMetadataMaterialLocalSpecialtyRegex))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: support non-CHS
|
||||
return TypeDescription switch
|
||||
{
|
||||
"角色与武器培养素材" => true, // 怪物掉落
|
||||
"角色经验素材" => true, // 经验书
|
||||
"角色突破素材" => true, // 元素晶石
|
||||
"角色天赋素材" => true, // 天赋本
|
||||
"角色培养素材" => true, // 40体BOSS/周本掉落
|
||||
"武器强化素材" => true, // 魔矿
|
||||
"武器突破素材" => true, // 武器本
|
||||
_ => false,
|
||||
};
|
||||
// Character and Weapon Enhancement Material // 怪物掉落
|
||||
// Character EXP Material // 经验书
|
||||
// Character Ascension Material // 元素晶石
|
||||
// Character Talent Material // 天赋本
|
||||
// Character Level-Up Material // 40体BOSS/周本掉落
|
||||
// Weapon Enhancement Material // 魔矿
|
||||
// Weapon Ascension Material // 武器本
|
||||
return IntrinsicImmutable.MaterialTypeDescriptions.Contains(TypeDescription);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -273,7 +273,7 @@
|
||||
<data name="ModelIntrinsicBodyTypeLady" xml:space="preserve">
|
||||
<value>Lady</value>
|
||||
</data>
|
||||
<data name="ModelIntrinsicBodyTypeloli" xml:space="preserve">
|
||||
<data name="ModelIntrinsicBodyTypeLoli" xml:space="preserve">
|
||||
<value>Loli</value>
|
||||
</data>
|
||||
<data name="ModelIntrinsicBodyTypeMale" xml:space="preserve">
|
||||
|
||||
@@ -273,7 +273,7 @@
|
||||
<data name="ModelIntrinsicBodyTypeLady" xml:space="preserve">
|
||||
<value>女性</value>
|
||||
</data>
|
||||
<data name="ModelIntrinsicBodyTypeloli" xml:space="preserve">
|
||||
<data name="ModelIntrinsicBodyTypeLoli" xml:space="preserve">
|
||||
<value>幼女</value>
|
||||
</data>
|
||||
<data name="ModelIntrinsicBodyTypeMale" xml:space="preserve">
|
||||
|
||||
@@ -273,7 +273,7 @@
|
||||
<data name="ModelIntrinsicBodyTypeLady" xml:space="preserve">
|
||||
<value>여성</value>
|
||||
</data>
|
||||
<data name="ModelIntrinsicBodyTypeloli" xml:space="preserve">
|
||||
<data name="ModelIntrinsicBodyTypeLoli" xml:space="preserve">
|
||||
<value>로리</value>
|
||||
</data>
|
||||
<data name="ModelIntrinsicBodyTypeMale" xml:space="preserve">
|
||||
|
||||
@@ -273,7 +273,7 @@
|
||||
<data name="ModelIntrinsicBodyTypeLady" xml:space="preserve">
|
||||
<value>成女</value>
|
||||
</data>
|
||||
<data name="ModelIntrinsicBodyTypeloli" xml:space="preserve">
|
||||
<data name="ModelIntrinsicBodyTypeLoli" xml:space="preserve">
|
||||
<value>萝莉</value>
|
||||
</data>
|
||||
<data name="ModelIntrinsicBodyTypeMale" xml:space="preserve">
|
||||
@@ -2046,4 +2046,28 @@
|
||||
<data name="ViewPageGahcaLogPivotStatistics" xml:space="preserve">
|
||||
<value>统计</value>
|
||||
</data>
|
||||
<data name="ModelMetadataMaterialCharacterAndWeaponEnhancementMaterial" xml:space="preserve">
|
||||
<value>角色与武器培养素材</value>
|
||||
</data>
|
||||
<data name="ModelMetadataMaterialCharacterEXPMaterial" xml:space="preserve">
|
||||
<value>角色经验素材</value>
|
||||
</data>
|
||||
<data name="ModelMetadataMaterialCharacterAscensionMaterial" xml:space="preserve">
|
||||
<value>角色突破素材</value>
|
||||
</data>
|
||||
<data name="ModelMetadataMaterialCharacterTalentMaterial" xml:space="preserve">
|
||||
<value>角色天赋素材</value>
|
||||
</data>
|
||||
<data name="ModelMetadataMaterialCharacterLevelUpMaterial" xml:space="preserve">
|
||||
<value>角色培养素材</value>
|
||||
</data>
|
||||
<data name="ModelMetadataMaterialWeaponEnhancementMaterial" xml:space="preserve">
|
||||
<value>武器强化素材</value>
|
||||
</data>
|
||||
<data name="ModelMetadataMaterialWeaponAscensionMaterial" xml:space="preserve">
|
||||
<value>武器突破素材</value>
|
||||
</data>
|
||||
<data name="ModelMetadataMaterialLocalSpecialtyRegex" xml:space="preserve">
|
||||
<value>[\u4e00-\u9fa5]{2}区域特产$</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -273,7 +273,7 @@
|
||||
<data name="ModelIntrinsicBodyTypeLady" xml:space="preserve">
|
||||
<value>成女</value>
|
||||
</data>
|
||||
<data name="ModelIntrinsicBodyTypeloli" xml:space="preserve">
|
||||
<data name="ModelIntrinsicBodyTypeLoli" xml:space="preserve">
|
||||
<value>蘿莉</value>
|
||||
</data>
|
||||
<data name="ModelIntrinsicBodyTypeMale" xml:space="preserve">
|
||||
|
||||
@@ -151,8 +151,8 @@ internal sealed class TypedWishSummaryBuilder
|
||||
TotalOrangePercent = totalOrangePullTracker / totalCount,
|
||||
TotalPurplePercent = totalPurplePullTracker / totalCount,
|
||||
TotalBluePercent = totalBluePullTracker / totalCount,
|
||||
AverageOrangePull = averageOrangePullTracker.UnsafeAverage(),
|
||||
AverageUpOrangePull = averageUpOrangePullTracker.UnsafeAverage(),
|
||||
AverageOrangePull = averageOrangePullTracker.SpanAverage(),
|
||||
AverageUpOrangePull = averageUpOrangePullTracker.SpanAverage(),
|
||||
OrangeList = summaryItems,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ internal sealed partial class CultivatePromotionDeltaDialog : ContentDialog
|
||||
AvatarLevelTarget = Avatar?.LevelTarget ?? 0,
|
||||
SkillList = Avatar?.Skills.Select(s => new PromotionDelta()
|
||||
{
|
||||
Id = s.GruopId,
|
||||
Id = s.GroupId,
|
||||
LevelCurrent = s.LevelCurrent,
|
||||
LevelTarget = s.LevelTarget,
|
||||
}),
|
||||
|
||||
@@ -14,34 +14,34 @@ internal enum GachaConfigType
|
||||
/// 新手池
|
||||
/// </summary>
|
||||
[Description("新手祈愿")]
|
||||
[LocalizationKey("WebGachaConfigTypeNoviceWish")]
|
||||
[LocalizationKey(nameof(SH.WebGachaConfigTypeNoviceWish))]
|
||||
NoviceWish = 100,
|
||||
|
||||
/// <summary>
|
||||
/// 常驻池
|
||||
/// </summary>
|
||||
[Description("常驻祈愿")]
|
||||
[LocalizationKey("WebGachaConfigTypePermanentWish")]
|
||||
[LocalizationKey(nameof(SH.WebGachaConfigTypePermanentWish))]
|
||||
StandardWish = 200,
|
||||
|
||||
/// <summary>
|
||||
/// 角色1池
|
||||
/// </summary>
|
||||
[Description("角色活动祈愿")]
|
||||
[LocalizationKey("WebGachaConfigTypeAvatarEventWish")]
|
||||
[LocalizationKey(nameof(SH.WebGachaConfigTypeAvatarEventWish))]
|
||||
AvatarEventWish = 301,
|
||||
|
||||
/// <summary>
|
||||
/// 武器池
|
||||
/// </summary>
|
||||
[Description("武器活动祈愿")]
|
||||
[LocalizationKey("WebGachaConfigTypeWeaponEventWish")]
|
||||
[LocalizationKey(nameof(SH.WebGachaConfigTypeWeaponEventWish))]
|
||||
WeaponEventWish = 302,
|
||||
|
||||
/// <summary>
|
||||
/// 角色2池
|
||||
/// </summary>
|
||||
[Description("角色活动祈愿-2")]
|
||||
[LocalizationKey("WebGachaConfigTypeAvatarEventWish2")]
|
||||
[LocalizationKey(nameof(SH.WebGachaConfigTypeAvatarEventWish2))]
|
||||
AvatarEventWish2 = 400,
|
||||
}
|
||||
@@ -66,7 +66,19 @@ internal static class StructMarshal
|
||||
/// <returns>新的实例</returns>
|
||||
public static RectInt32 RectInt32(PointInt32 point, Vector2 size)
|
||||
{
|
||||
return new(point.X, point.Y, (int)size.X, (int)size.Y);
|
||||
return RectInt32(point.X, point.Y, size);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构造一个新的<see cref="Windows.Graphics.RectInt32"/>
|
||||
/// </summary>
|
||||
/// <param name="x">X</param>
|
||||
/// <param name="y">Y</param>
|
||||
/// <param name="size">尺寸</param>
|
||||
/// <returns>新的实例</returns>
|
||||
public static RectInt32 RectInt32(int x, int y, Vector2 size)
|
||||
{
|
||||
return new(x, y, (int)size.X, (int)size.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user