Frozen Collections

This commit is contained in:
Lightczx
2023-11-21 13:53:32 +08:00
parent 2bbf6f192e
commit 29d7d36b66
16 changed files with 140 additions and 183 deletions

View File

@@ -0,0 +1,63 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using System.Collections.Frozen;
namespace Snap.Hutao.Model.Intrinsic.Frozen;
/// <summary>
/// 本地化的不可变的原生枚举
/// </summary>
[HighQuality]
internal static class IntrinsicFrozen
{
/// <summary>
/// 所属地区
/// </summary>
public static readonly FrozenSet<string> AssociationTypes = Enum.GetValues<AssociationType>().Select(e => e.GetLocalizedDescriptionOrDefault()).OfType<string>().ToFrozenSet();
/// <summary>
/// 武器类型
/// </summary>
public static readonly FrozenSet<string> WeaponTypes = Enum.GetValues<WeaponType>().Select(e => e.GetLocalizedDescriptionOrDefault()).OfType<string>().ToFrozenSet();
/// <summary>
/// 物品类型
/// </summary>
public static readonly FrozenSet<string> ItemQualities = Enum.GetValues<QualityType>().Select(e => e.GetLocalizedDescriptionOrDefault()).OfType<string>().ToFrozenSet();
/// <summary>
/// 身材类型
/// </summary>
public static readonly FrozenSet<string> BodyTypes = Enum.GetValues<BodyType>().Select(e => e.GetLocalizedDescriptionOrDefault()).OfType<string>().ToFrozenSet();
/// <summary>
/// 战斗属性
/// </summary>
public static readonly FrozenSet<string> FightProperties = Enum.GetValues<FightProperty>().Select(e => e.GetLocalizedDescriptionOrDefault()).OfType<string>().ToFrozenSet();
/// <summary>
/// 元素名称
/// </summary>
public static readonly FrozenSet<string> ElementNames = FrozenSet.ToFrozenSet(
[
SH.ModelIntrinsicElementNameFire,
SH.ModelIntrinsicElementNameWater,
SH.ModelIntrinsicElementNameGrass,
SH.ModelIntrinsicElementNameElec,
SH.ModelIntrinsicElementNameWind,
SH.ModelIntrinsicElementNameIce,
SH.ModelIntrinsicElementNameRock,
]);
public static readonly FrozenSet<string> MaterialTypeDescriptions = FrozenSet.ToFrozenSet(
[
SH.ModelMetadataMaterialCharacterAndWeaponEnhancementMaterial,
SH.ModelMetadataMaterialCharacterEXPMaterial,
SH.ModelMetadataMaterialCharacterAscensionMaterial,
SH.ModelMetadataMaterialCharacterTalentMaterial,
SH.ModelMetadataMaterialCharacterLevelUpMaterial,
SH.ModelMetadataMaterialWeaponEnhancementMaterial,
SH.ModelMetadataMaterialWeaponAscensionMaterial,
]);
}

View File

@@ -1,63 +0,0 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using System.Collections.Immutable;
namespace Snap.Hutao.Model.Intrinsic.Immutable;
/// <summary>
/// 本地化的不可变的原生枚举
/// </summary>
[HighQuality]
internal static class IntrinsicImmutable
{
/// <summary>
/// 所属地区
/// </summary>
public static readonly ImmutableHashSet<string> AssociationTypes = Enum.GetValues<AssociationType>().Select(e => e.GetLocalizedDescriptionOrDefault()).OfType<string>().ToImmutableHashSet();
/// <summary>
/// 武器类型
/// </summary>
public static readonly ImmutableHashSet<string> WeaponTypes = Enum.GetValues<WeaponType>().Select(e => e.GetLocalizedDescriptionOrDefault()).OfType<string>().ToImmutableHashSet();
/// <summary>
/// 物品类型
/// </summary>
public static readonly ImmutableHashSet<string> ItemQualities = Enum.GetValues<QualityType>().Select(e => e.GetLocalizedDescriptionOrDefault()).OfType<string>().ToImmutableHashSet();
/// <summary>
/// 身材类型
/// </summary>
public static readonly ImmutableHashSet<string> BodyTypes = Enum.GetValues<BodyType>().Select(e => e.GetLocalizedDescriptionOrDefault()).OfType<string>().ToImmutableHashSet();
/// <summary>
/// 战斗属性
/// </summary>
public static readonly ImmutableHashSet<string> FightProperties = Enum.GetValues<FightProperty>().Select(e => e.GetLocalizedDescriptionOrDefault()).OfType<string>().ToImmutableHashSet();
/// <summary>
/// 元素名称
/// </summary>
public static readonly ImmutableHashSet<string> ElementNames = new HashSet<string>(7)
{
SH.ModelIntrinsicElementNameFire,
SH.ModelIntrinsicElementNameWater,
SH.ModelIntrinsicElementNameGrass,
SH.ModelIntrinsicElementNameElec,
SH.ModelIntrinsicElementNameWind,
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();
}

View File

@@ -2,7 +2,7 @@
// Licensed under the MIT license.
using Snap.Hutao.Model.Intrinsic;
using Snap.Hutao.Model.Intrinsic.Immutable;
using Snap.Hutao.Model.Intrinsic.Frozen;
using Snap.Hutao.ViewModel.Cultivation;
using System.Text.RegularExpressions;
@@ -58,7 +58,7 @@ internal sealed class Material : DisplayItem
// Character Level-Up Material // 40体BOSS/周本掉落
// Weapon Enhancement Material // 魔矿
// Weapon Ascension Material // 武器本
return IntrinsicImmutable.MaterialTypeDescriptions.Contains(TypeDescription);
return IntrinsicFrozen.MaterialTypeDescriptions.Contains(TypeDescription);
}
/// <summary>
@@ -69,12 +69,13 @@ internal sealed class Material : DisplayItem
/// <returns>是否为当日物品</returns>
public bool IsTodaysItem(bool treatSundayAsTrue = false)
{
return DateTimeOffset.UtcNow.AddHours(4).DayOfWeek switch
// TODO: support different time zone
return (DateTimeOffset.Now - new TimeSpan(4, 0, 0)).DayOfWeek switch
{
DayOfWeek.Monday or DayOfWeek.Thursday => Materials.MondayThursdayItems.Contains(Id),
DayOfWeek.Tuesday or DayOfWeek.Friday => Materials.TuesdayFridayItems.Contains(Id),
DayOfWeek.Wednesday or DayOfWeek.Saturday => Materials.WednesdaySaturdayItems.Contains(Id),
_ => false,
_ => treatSundayAsTrue,
};
}

View File

@@ -2,7 +2,7 @@
// Licensed under the MIT license.
using Snap.Hutao.Model.Primitive;
using System.Collections.Immutable;
using System.Collections.Frozen;
namespace Snap.Hutao.Model.Metadata.Item;
@@ -11,8 +11,8 @@ namespace Snap.Hutao.Model.Metadata.Item;
/// </summary>
internal static class Materials
{
private static readonly ImmutableHashSet<MaterialId> MondayThursdayItemsInner = new HashSet<MaterialId>
{
public static FrozenSet<MaterialId> MondayThursdayItems { get; } = FrozenSet.ToFrozenSet<MaterialId>(
[
104301U, 104302U, 104303U, // 「自由」
104310U, 104311U, 104312U, // 「繁荣」
104320U, 104321U, 104322U, // 「浮世」
@@ -23,10 +23,10 @@ internal static class Materials
114025U, 114026U, 114027U, 114028U, // 远海夷地
114037U, 114038U, 114039U, 114040U, // 谧林涓露
114049U, 114050U, 114051U, 114052U, // 悠古弦音
}.ToImmutableHashSet();
]);
private static readonly ImmutableHashSet<MaterialId> TuesdayFridayItemsInner = new HashSet<MaterialId>
{
public static FrozenSet<MaterialId> TuesdayFridayItems { get; } = FrozenSet.ToFrozenSet<MaterialId>(
[
104304U, 104305U, 104306U, // 「抗争」
104313U, 104314U, 104315U, // 「勤劳」
104323U, 104324U, 104325U, // 「风雅」
@@ -37,10 +37,10 @@ internal static class Materials
114029U, 114030U, 114031U, 114032U, // 鸣神御灵
114041U, 114042U, 114043U, 114044U, // 绿洲花园
114053U, 114054U, 114055U, 114056U, // 纯圣露滴
}.ToImmutableHashSet();
]);
private static readonly ImmutableHashSet<MaterialId> WednesdaySaturdayItemsInner = new HashSet<MaterialId>
{
public static FrozenSet<MaterialId> WednesdaySaturdayItems { get; } = FrozenSet.ToFrozenSet<MaterialId>(
[
104307U, 104308U, 104309U, // 「诗文」
104316U, 104317U, 104318U, // 「黄金」
104326U, 104327U, 104328U, // 「天光」
@@ -51,20 +51,5 @@ internal static class Materials
114033U, 114034U, 114035U, 114036U, // 今昔剧画
114045U, 114046U, 114047U, 114048U, // 谧林涓露
114057U, 114058U, 114059U, 114060U, // 无垢之海
}.ToImmutableHashSet();
/// <summary>
/// 周一/周四
/// </summary>
public static ImmutableHashSet<MaterialId> MondayThursdayItems { get => MondayThursdayItemsInner; }
/// <summary>
/// 周二/周五
/// </summary>
public static ImmutableHashSet<MaterialId> TuesdayFridayItems { get => TuesdayFridayItemsInner; }
/// <summary>
/// 周三/周六
/// </summary>
public static ImmutableHashSet<MaterialId> WednesdaySaturdayItems { get => WednesdaySaturdayItemsInner; }
]);
}

View File

@@ -12,7 +12,7 @@
<Identity
Name="60568DGPStudio.SnapHutao"
Publisher="CN=35C8E923-85DF-49A7-9172-B39DC6312C52"
Version="1.7.19.0" />
Version="1.7.17.0" />
<Properties>
<DisplayName>Snap Hutao</DisplayName>

View File

@@ -29,6 +29,11 @@ internal abstract partial class DbStoreOptions : ObservableObject, IOptions<DbSt
/// <param name="defaultValue">默认值</param>
/// <returns>值</returns>
protected string GetOption(ref string? storage, string key, string defaultValue = "")
{
return GetOption(ref storage, key, () => defaultValue);
}
protected string GetOption(ref string? storage, string key, Func<string> defaultValueFactory)
{
if (storage is not null)
{
@@ -38,7 +43,7 @@ internal abstract partial class DbStoreOptions : ObservableObject, IOptions<DbSt
using (IServiceScope scope = serviceProvider.CreateScope())
{
AppDbContext appDbContext = scope.ServiceProvider.GetRequiredService<AppDbContext>();
storage = appDbContext.Settings.SingleOrDefault(e => e.Key == key)?.Value ?? defaultValue;
storage = appDbContext.Settings.SingleOrDefault(e => e.Key == key)?.Value ?? defaultValueFactory();
}
return storage;
@@ -52,6 +57,11 @@ internal abstract partial class DbStoreOptions : ObservableObject, IOptions<DbSt
/// <param name="defaultValue">默认值</param>
/// <returns>值</returns>
protected bool GetOption(ref bool? storage, string key, bool defaultValue = false)
{
return GetOption(ref storage, key, () => defaultValue);
}
protected bool GetOption(ref bool? storage, string key, Func<bool> defaultValueFactory)
{
if (storage is not null)
{
@@ -62,7 +72,7 @@ internal abstract partial class DbStoreOptions : ObservableObject, IOptions<DbSt
{
AppDbContext appDbContext = scope.ServiceProvider.GetRequiredService<AppDbContext>();
string? value = appDbContext.Settings.SingleOrDefault(e => e.Key == key)?.Value;
storage = value is null ? defaultValue : bool.Parse(value);
storage = value is null ? defaultValueFactory() : bool.Parse(value);
}
return storage.Value;
@@ -76,6 +86,11 @@ internal abstract partial class DbStoreOptions : ObservableObject, IOptions<DbSt
/// <param name="defaultValue">默认值</param>
/// <returns>值</returns>
protected int GetOption(ref int? storage, string key, int defaultValue = 0)
{
return GetOption(ref storage, key, () => defaultValue);
}
protected int GetOption(ref int? storage, string key, Func<int> defaultValueFactory)
{
if (storage is not null)
{
@@ -86,7 +101,7 @@ internal abstract partial class DbStoreOptions : ObservableObject, IOptions<DbSt
{
AppDbContext appDbContext = scope.ServiceProvider.GetRequiredService<AppDbContext>();
string? value = appDbContext.Settings.SingleOrDefault(e => e.Key == key)?.Value;
storage = value is null ? defaultValue : int.Parse(value, CultureInfo.InvariantCulture);
storage = value is null ? defaultValueFactory() : int.Parse(value, CultureInfo.InvariantCulture);
}
return storage.Value;
@@ -101,8 +116,8 @@ internal abstract partial class DbStoreOptions : ObservableObject, IOptions<DbSt
/// <param name="deserializer">反序列化器</param>
/// <param name="defaultValue">默认值</param>
/// <returns>值</returns>
protected T GetOption<T>(ref T? storage, string key, Func<string, T> deserializer, T defaultValue)
where T : class
[return:NotNull]
protected T GetOption<T>(ref T? storage, string key, Func<string, T> deserializer, [DisallowNull] T defaultValue)
{
if (storage is not null)
{
@@ -113,37 +128,27 @@ internal abstract partial class DbStoreOptions : ObservableObject, IOptions<DbSt
{
AppDbContext appDbContext = scope.ServiceProvider.GetRequiredService<AppDbContext>();
string? value = appDbContext.Settings.SingleOrDefault(e => e.Key == key)?.Value;
storage = value is null ? defaultValue : deserializer(value);
storage = value is null ? defaultValue : deserializer(value)!;
}
return storage;
}
/// <summary>
/// 从数据库中获取任何类型的数据
/// </summary>
/// <typeparam name="T">数据的类型</typeparam>
/// <param name="storage">存储字段</param>
/// <param name="key">键</param>
/// <param name="deserializer">反序列化器</param>
/// <param name="defaultValue">默认值</param>
/// <returns>值</returns>
protected T GetOption<T>(ref T? storage, string key, Func<string, T> deserializer, T defaultValue)
where T : struct
protected T GetOption<T>(ref T? storage, string key, Func<string, T> deserializer, Func<T> defaultValueFactory)
{
if (storage is not null)
{
return storage.Value;
return storage;
}
using (IServiceScope scope = serviceProvider.CreateScope())
{
AppDbContext appDbContext = scope.ServiceProvider.GetRequiredService<AppDbContext>();
string? value = appDbContext.Settings.SingleOrDefault(e => e.Key == key)?.Value;
storage = value is null ? defaultValue : deserializer(value);
storage = value is null ? defaultValueFactory() : deserializer(value);
}
return storage.Value;
return storage;
}
/// <summary>
@@ -226,32 +231,6 @@ internal abstract partial class DbStoreOptions : ObservableObject, IOptions<DbSt
/// <param name="serializer">序列化器</param>
/// <param name="propertyName">属性名称</param>
protected void SetOption<T>(ref T? storage, string key, T value, Func<T, string> serializer, [CallerMemberName] string? propertyName = null)
where T : class
{
if (!SetProperty(ref storage, value, propertyName))
{
return;
}
using (IServiceScope scope = serviceProvider.CreateScope())
{
AppDbContext appDbContext = scope.ServiceProvider.GetRequiredService<AppDbContext>();
appDbContext.Settings.ExecuteDeleteWhere(e => e.Key == key);
appDbContext.Settings.AddAndSave(new(key, serializer(value)));
}
}
/// <summary>
/// 将值存入数据库
/// </summary>
/// <typeparam name="T">数据的类型</typeparam>
/// <param name="storage">存储字段</param>
/// <param name="key">键</param>
/// <param name="value">值</param>
/// <param name="serializer">序列化器</param>
/// <param name="propertyName">属性名称</param>
protected void SetOption<T>(ref T? storage, string key, T value, Func<T, string> serializer, [CallerMemberName] string? propertyName = null)
where T : struct
{
if (!SetProperty(ref storage, value, propertyName))
{

View File

@@ -52,7 +52,7 @@ internal sealed partial class AppOptions : DbStoreOptions
/// </summary>
public string PowerShellPath
{
get => GetOption(ref powerShellPath, SettingEntry.PowerShellPath, GetPowerShellLocationOrEmpty());
get => GetOption(ref powerShellPath, SettingEntry.PowerShellPath, GetPowerShellLocationOrEmpty);
set => SetOption(ref powerShellPath, SettingEntry.PowerShellPath, value);
}
@@ -75,8 +75,8 @@ internal sealed partial class AppOptions : DbStoreOptions
/// </summary>
public BackdropType BackdropType
{
get => GetOption(ref backdropType, SettingEntry.SystemBackdropType, Enum.Parse<BackdropType>, BackdropType.Mica);
set => SetOption(ref backdropType, SettingEntry.SystemBackdropType, value, value => value.ToString());
get => GetOption(ref backdropType, SettingEntry.SystemBackdropType, v => Enum.Parse<BackdropType>(v), BackdropType.Mica).Value;
set => SetOption(ref backdropType, SettingEntry.SystemBackdropType, value, value => value.ToString()!);
}
/// <summary>

View File

@@ -2,7 +2,7 @@
// Licensed under the MIT license.
using Snap.Hutao.Web.Hoyolab.Hk4e.Event.GachaInfo;
using System.Collections.Immutable;
using System.Collections.Frozen;
using System.Runtime.CompilerServices;
namespace Snap.Hutao.Service.GachaLog.Factory;
@@ -12,20 +12,20 @@ namespace Snap.Hutao.Service.GachaLog.Factory;
/// </summary>
internal sealed class GachaConfigTypeComparer : IComparer<GachaConfigType>
{
private static readonly GachaConfigTypeComparer InnerShared = new();
private static readonly ImmutableDictionary<GachaConfigType, int> OrderMap = new Dictionary<GachaConfigType, int>()
private static readonly Lazy<GachaConfigTypeComparer> LazyShared = new(() => new());
private static readonly FrozenDictionary<GachaConfigType, int> OrderMap = new Dictionary<GachaConfigType, int>()
{
[GachaConfigType.AvatarEventWish] = 0,
[GachaConfigType.AvatarEventWish2] = 1,
[GachaConfigType.WeaponEventWish] = 2,
[GachaConfigType.StandardWish] = 3,
[GachaConfigType.NoviceWish] = 4,
}.ToImmutableDictionary();
}.ToFrozenDictionary();
/// <summary>
/// 共享的比较器
/// </summary>
public static GachaConfigTypeComparer Shared { get => InnerShared; }
public static GachaConfigTypeComparer Shared { get => LazyShared.Value; }
/// <inheritdoc/>
public int Compare(GachaConfigType x, GachaConfigType y)

View File

@@ -2,18 +2,18 @@
// Licensed under the MIT license.
using Snap.Hutao.Model.Intrinsic;
using System.Collections.Immutable;
using System.Collections.Frozen;
namespace Snap.Hutao.Service.Game.Configuration;
internal static class IgnoredInvalidChannelOptions
{
private static readonly ImmutableHashSet<ChannelOptions> InvalidOptions = new HashSet<ChannelOptions>()
{
new(ChannelType.Bili, SubChannelType.Default, isOversea: true),
new(ChannelType.Bili, SubChannelType.Official, isOversea: true),
new(ChannelType.Official, SubChannelType.Google, isOversea: false),
}.ToImmutableHashSet();
private static readonly FrozenSet<ChannelOptions> InvalidOptions = FrozenSet.ToFrozenSet(
[
new ChannelOptions(ChannelType.Bili, SubChannelType.Default, isOversea: true),
new ChannelOptions(ChannelType.Bili, SubChannelType.Official, isOversea: true),
new ChannelOptions(ChannelType.Official, SubChannelType.Google, isOversea: false),
]);
public static bool Contains(in ChannelOptions options)
{

View File

@@ -7,7 +7,6 @@ using Snap.Hutao.Control.Collection.Alternating;
using Snap.Hutao.Model;
using Snap.Hutao.Model.Intrinsic;
using System.Collections.Frozen;
using System.Collections.Immutable;
namespace Snap.Hutao.ViewModel.AvatarProperty;

View File

@@ -2,7 +2,7 @@
// Licensed under the MIT license.
using Microsoft.Extensions.Primitives;
using Snap.Hutao.Model.Intrinsic.Immutable;
using Snap.Hutao.Model.Intrinsic.Frozen;
using Snap.Hutao.Model.Metadata.Avatar;
namespace Snap.Hutao.ViewModel.Wiki;
@@ -35,31 +35,31 @@ internal static class AvatarFilter
continue;
}
if (IntrinsicImmutable.ElementNames.Contains(value))
if (IntrinsicFrozen.ElementNames.Contains(value))
{
matches.Add(avatar.FetterInfo.VisionBefore == value);
continue;
}
if (IntrinsicImmutable.AssociationTypes.Contains(value))
if (IntrinsicFrozen.AssociationTypes.Contains(value))
{
matches.Add(avatar.FetterInfo.Association.GetLocalizedDescriptionOrDefault() == value);
continue;
}
if (IntrinsicImmutable.WeaponTypes.Contains(value))
if (IntrinsicFrozen.WeaponTypes.Contains(value))
{
matches.Add(avatar.Weapon.GetLocalizedDescriptionOrDefault() == value);
continue;
}
if (IntrinsicImmutable.ItemQualities.Contains(value))
if (IntrinsicFrozen.ItemQualities.Contains(value))
{
matches.Add(avatar.Quality.GetLocalizedDescriptionOrDefault() == value);
continue;
}
if (IntrinsicImmutable.BodyTypes.Contains(value))
if (IntrinsicFrozen.BodyTypes.Contains(value))
{
matches.Add(avatar.Body.GetLocalizedDescriptionOrDefault() == value);
continue;

View File

@@ -2,7 +2,7 @@
// Licensed under the MIT license.
using Microsoft.Extensions.Primitives;
using Snap.Hutao.Model.Intrinsic.Immutable;
using Snap.Hutao.Model.Intrinsic.Frozen;
using Snap.Hutao.Model.Metadata.Weapon;
namespace Snap.Hutao.ViewModel.Wiki;
@@ -36,19 +36,19 @@ internal static class WeaponFilter
continue;
}
if (IntrinsicImmutable.WeaponTypes.Contains(value))
if (IntrinsicFrozen.WeaponTypes.Contains(value))
{
matches.Add(weapon.WeaponType.GetLocalizedDescriptionOrDefault() == value);
continue;
}
if (IntrinsicImmutable.ItemQualities.Contains(value))
if (IntrinsicFrozen.ItemQualities.Contains(value))
{
matches.Add(weapon.Quality.GetLocalizedDescriptionOrDefault() == value);
continue;
}
if (IntrinsicImmutable.FightProperties.Contains(value))
if (IntrinsicFrozen.FightProperties.Contains(value))
{
matches.Add(weapon.GrowCurves.ElementAtOrDefault(1)?.Type.GetLocalizedDescriptionOrDefault() == value);
continue;

View File

@@ -17,7 +17,6 @@ using Snap.Hutao.Service.Notification;
using Snap.Hutao.Service.User;
using Snap.Hutao.View.Dialog;
using Snap.Hutao.Web.Response;
using System.Collections.Immutable;
using System.Runtime.InteropServices;
using CalculateAvatarPromotionDelta = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.AvatarPromotionDelta;
using CalculateClient = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.CalculateClient;

View File

@@ -7,7 +7,6 @@ using Snap.Hutao.Model.Metadata.Item;
using Snap.Hutao.Model.Metadata.Monster;
using Snap.Hutao.Model.Primitive;
using Snap.Hutao.Service.Metadata;
using System.Collections.Immutable;
namespace Snap.Hutao.ViewModel.Wiki;

View File

@@ -17,7 +17,6 @@ using Snap.Hutao.Service.Notification;
using Snap.Hutao.Service.User;
using Snap.Hutao.View.Dialog;
using Snap.Hutao.Web.Response;
using System.Collections.Immutable;
using System.Runtime.InteropServices;
using CalculateAvatarPromotionDelta = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.AvatarPromotionDelta;
using CalculateClient = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.CalculateClient;

View File

@@ -3,7 +3,7 @@
using Microsoft.Extensions.Options;
using Snap.Hutao.Web.Hoyolab.DataSigning;
using System.Collections.Immutable;
using System.Collections.Frozen;
namespace Snap.Hutao.Web.Hoyolab;
@@ -32,7 +32,15 @@ internal sealed class HoyolabOptions : IOptions<HoyolabOptions>
/// </summary>
public const string MobileUserAgentOversea = $"Mozilla/5.0 (Linux; Android 12) Mobile miHoYoBBSOversea/{SaltConstants.OSVersion}";
private static readonly ImmutableDictionary<SaltType, string> SaltsInner = new Dictionary<SaltType, string>()
/// <summary>
/// 米游社设备Id
/// </summary>
public static string DeviceId { get; } = Guid.NewGuid().ToString();
/// <summary>
/// 盐
/// </summary>
public static FrozenDictionary<SaltType, string> Salts { get; } = new Dictionary<SaltType, string>()
{
// Chinese
[SaltType.K2] = SaltConstants.CNK2,
@@ -46,19 +54,7 @@ internal sealed class HoyolabOptions : IOptions<HoyolabOptions>
[SaltType.OSLK2] = SaltConstants.OSLK2,
[SaltType.OSX4] = "h4c1d6ywfq5bsbnbhm1bzq7bxzzv6srt",
[SaltType.OSX6] = "okr4obncj8bw5a65hbnn5oo6ixjc3l9w",
}.ToImmutableDictionary();
private static string? deviceId;
/// <summary>
/// 米游社设备Id
/// </summary>
public static string DeviceId { get => deviceId ??= Guid.NewGuid().ToString(); }
/// <summary>
/// 盐
/// </summary>
public static ImmutableDictionary<SaltType, string> Salts { get => SaltsInner; }
}.ToFrozenDictionary();
/// <inheritdoc/>
public HoyolabOptions Value { get => this; }