diff --git a/src/Snap.Hutao/Snap.Hutao.SourceGeneration/Identity/IdentityGenerator.cs b/src/Snap.Hutao/Snap.Hutao.SourceGeneration/Identity/IdentityGenerator.cs
index 3447bb91..26de90b7 100644
--- a/src/Snap.Hutao/Snap.Hutao.SourceGeneration/Identity/IdentityGenerator.cs
+++ b/src/Snap.Hutao/Snap.Hutao.SourceGeneration/Identity/IdentityGenerator.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
using System.Linq;
+using System.Text;
namespace Snap.Hutao.SourceGeneration.Identity;
@@ -32,8 +33,6 @@ internal sealed class IdentityGenerator : IIncrementalGenerator
if (identities.Any())
{
- GenerateIdentityConverter(context);
-
foreach (IdentityStructMetadata identityStruct in identities)
{
GenerateIdentityStruct(context, identityStruct);
@@ -41,137 +40,157 @@ internal sealed class IdentityGenerator : IIncrementalGenerator
}
}
- private static void GenerateIdentityConverter(SourceProductionContext context)
+ private static void GenerateIdentityStruct(SourceProductionContext context, IdentityStructMetadata metadata)
{
- string source = $$"""
- // Copyright (c) DGP Studio. All rights reserved.
- // Licensed under the MIT license.
+ string name = metadata.Name;
- namespace Snap.Hutao.Model.Primitive.Converter;
-
- ///
- /// Id 转换器
- ///
- /// 包装类型
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("{{nameof(IdentityGenerator)}}", "1.0.0.0")]
- internal unsafe sealed class IdentityConverter : JsonConverter
- where TWrapper : unmanaged
- {
- ///
- public override TWrapper Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
- {
- if (reader.TokenType == JsonTokenType.Number)
- {
- int value = reader.GetInt32();
- return *(TWrapper*)&value;
- }
-
- throw new JsonException();
- }
-
- ///
- public override void Write(Utf8JsonWriter writer, TWrapper value, JsonSerializerOptions options)
- {
- writer.WriteNumberValue(*(int*)&value);
- }
- }
- """;
-
- context.AddSource("IdentityConverter.g.cs", source);
- }
-
- private static void GenerateIdentityStruct(SourceProductionContext context, IdentityStructMetadata identityStruct)
- {
- string name = identityStruct.Name;
- string type = identityStruct.Type;
-
- string source = $$"""
+ StringBuilder sourceBuilder = new StringBuilder().AppendLine($$"""
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Snap.Hutao.Model.Primitive.Converter;
+ using System.Numerics;
namespace Snap.Hutao.Model.Primitive;
///
- /// {{identityStruct.Documentation}}
+ /// {{metadata.Documentation}}
///
[JsonConverter(typeof(IdentityConverter<{{name}}>))]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("{{nameof(IdentityGenerator)}}","1.0.0.0")]
- internal readonly struct {{name}} : IEquatable<{{name}}>
+ internal readonly partial struct {{name}}
{
///
/// 值
///
- public readonly {{type}} Value;
+ public readonly uint Value;
///
/// Initializes a new instance of the struct.
///
/// value
- public {{name}}({{type}} value)
+ public {{name}}(uint value)
{
Value = value;
}
- public static implicit operator {{type}}({{name}} value)
+ public static implicit operator uint({{name}} value)
{
return value.Value;
}
- public static implicit operator {{name}}({{type}} value)
+ public static implicit operator {{name}}(uint value)
{
return new(value);
}
- public static bool operator ==({{name}} left, {{name}} right)
- {
- return left.Value == right.Value;
- }
-
- public static bool operator !=({{name}} left, {{name}} right)
- {
- return !(left == right);
- }
-
- ///
- public bool Equals({{name}} other)
- {
- return Value == other.Value;
- }
-
- ///
- public override bool Equals(object obj)
- {
- return obj is {{name}} other && Equals(other);
- }
-
///
public override int GetHashCode()
{
return Value.GetHashCode();
}
}
- """;
+ """);
- context.AddSource($"{name}.g.cs", source);
+ if (metadata.Equatable)
+ {
+ sourceBuilder.AppendLine($$"""
+
+ internal readonly partial struct {{name}} : IEquatable<{{name}}>
+ {
+ ///
+ public override bool Equals(object obj)
+ {
+ return obj is {{name}} other && Equals(other);
+ }
+
+ ///
+ public bool Equals({{name}} other)
+ {
+ return Value == other.Value;
+ }
+ }
+ """);
+ }
+
+ if (metadata.EqualityOperators)
+ {
+ sourceBuilder.AppendLine($$"""
+
+ internal readonly partial struct {{name}} : IEqualityOperators<{{name}}, {{name}}, bool>, IEqualityOperators<{{name}}, uint, bool>
+ {
+ public static bool operator ==({{name}} left, {{name}} right)
+ {
+ return left.Value == right.Value;
+ }
+
+ public static bool operator ==({{name}} left, uint right)
+ {
+ return left.Value == right;
+ }
+
+ public static bool operator !=({{name}} left, {{name}} right)
+ {
+ return !(left == right);
+ }
+
+ public static bool operator !=({{name}} left, uint right)
+ {
+ return !(left == right);
+ }
+ }
+ """);
+ }
+
+ if (metadata.AdditionOperators)
+ {
+ sourceBuilder.AppendLine($$"""
+
+ internal readonly partial struct {{name}} : IAdditionOperators<{{name}}, {{name}}, {{name}}>, IAdditionOperators<{{name}}, uint, {{name}}>
+ {
+ public static {{name}} operator +({{name}} left, {{name}} right)
+ {
+ return left.Value + right.Value;
+ }
+
+ public static {{name}} operator +({{name}} left, uint right)
+ {
+ return left.Value + right;
+ }
+ }
+ """);
+ }
+
+ if (metadata.IncrementOperators)
+ {
+ sourceBuilder.AppendLine($$"""
+
+ internal readonly partial struct {{name}} : IIncrementOperators<{{name}}>
+ {
+ public static unsafe {{name}} operator ++({{name}} value)
+ {
+ ++*(uint*)&value;
+ return value;
+ }
+ }
+ """);
+ }
+
+ context.AddSource($"{name}.g.cs", sourceBuilder.ToString());
}
private sealed class IdentityStructMetadata
{
- ///
- /// 名称
- ///
public string Name { get; set; } = default!;
- ///
- /// 基底类型
- ///
- public string Type { get; set; } = default!;
-
- ///
- /// 文档
- ///
public string? Documentation { get; set; }
+
+ public bool Equatable { get; set; }
+
+ public bool EqualityOperators { get; set; }
+
+ public bool AdditionOperators { get; set; }
+
+ public bool IncrementOperators { get; set; }
}
}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao.Test/JsonSerializeTest.cs b/src/Snap.Hutao/Snap.Hutao.Test/JsonSerializeTest.cs
index 40724e6b..718408d1 100644
--- a/src/Snap.Hutao/Snap.Hutao.Test/JsonSerializeTest.cs
+++ b/src/Snap.Hutao/Snap.Hutao.Test/JsonSerializeTest.cs
@@ -1,4 +1,5 @@
-using System.Text.Json;
+using System.Collections.Generic;
+using System.Text.Json;
using System.Text.Json.Serialization;
namespace Snap.Hutao.Test;
@@ -18,6 +19,13 @@ public class JsonSerializeTest
}
""";
+ private const string SmapleNumberDictionaryJson = """
+ {
+ "111" : "12",
+ "222" : "34"
+ }
+ """;
+
[TestMethod]
public void DelegatePropertyCanSerialize()
{
@@ -26,11 +34,33 @@ public class JsonSerializeTest
}
[TestMethod]
- public void EmptyStringCanSerializeAsNumber()
+ public void EmptyStringCannotSerializeAsNumber()
{
- // Throw
- StringNumberSample sample = JsonSerializer.Deserialize(SmapleNumberObjectJson)!;
- Assert.AreEqual(sample.A, 0);
+ bool caught = false;
+ try
+ {
+ // Throw
+ StringNumberSample sample = JsonSerializer.Deserialize(SmapleNumberObjectJson)!;
+ Assert.AreEqual(sample.A, 0);
+ }
+ catch
+ {
+ caught = true;
+ }
+
+ Assert.IsTrue(caught);
+ }
+
+ [TestMethod]
+ public void NumberStringKeyCanSerializeAsKey()
+ {
+ JsonSerializerOptions options = new()
+ {
+ NumberHandling = JsonNumberHandling.AllowReadingFromString,
+ };
+
+ Dictionary sample = JsonSerializer.Deserialize>(SmapleNumberDictionaryJson, options)!;
+ Assert.AreEqual(sample[111], "12");
}
private class Sample
diff --git a/src/Snap.Hutao/Snap.Hutao/Core/ExceptionService/UserdataCorruptedException.cs b/src/Snap.Hutao/Snap.Hutao/Core/ExceptionService/UserdataCorruptedException.cs
index d0e18b58..dae43281 100644
--- a/src/Snap.Hutao/Snap.Hutao/Core/ExceptionService/UserdataCorruptedException.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Core/ExceptionService/UserdataCorruptedException.cs
@@ -14,8 +14,8 @@ internal sealed class UserdataCorruptedException : Exception
///
/// 消息
/// 内部错误
- public UserdataCorruptedException(string message, Exception innerException)
- : base(string.Format(SH.CoreExceptionServiceUserdataCorruptedMessage, $"{message}\n{innerException.Message}"), innerException)
+ public UserdataCorruptedException(string message, Exception? innerException)
+ : base(string.Format(SH.CoreExceptionServiceUserdataCorruptedMessage, $"{message}\n{innerException?.Message}"), innerException)
{
}
}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Core/IO/Digest.cs b/src/Snap.Hutao/Snap.Hutao/Core/IO/Hashing/MD5.cs
similarity index 60%
rename from src/Snap.Hutao/Snap.Hutao/Core/IO/Digest.cs
rename to src/Snap.Hutao/Snap.Hutao/Core/IO/Hashing/MD5.cs
index 1cb59b3a..2d05ee09 100644
--- a/src/Snap.Hutao/Snap.Hutao/Core/IO/Digest.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Core/IO/Hashing/MD5.cs
@@ -2,39 +2,38 @@
// Licensed under the MIT license.
using System.IO;
-using System.Security.Cryptography;
-namespace Snap.Hutao.Core.IO;
+namespace Snap.Hutao.Core.IO.Hashing;
///
/// 摘要
///
[HighQuality]
-internal static class Digest
+internal static class MD5
{
///
- /// 异步获取文件 Md5 摘要
+ /// 异步获取文件 MD5 摘要
///
/// 文件路径
/// 取消令牌
/// 文件 Md5 摘要
- public static async Task GetFileMD5Async(string filePath, CancellationToken token = default)
+ public static async Task HashFileAsync(string filePath, CancellationToken token = default)
{
using (FileStream stream = File.OpenRead(filePath))
{
- return await GetStreamMD5Async(stream, token).ConfigureAwait(false);
+ return await HashAsync(stream, token).ConfigureAwait(false);
}
}
///
- /// 获取流的 Md5 摘要
+ /// 获取流的 MD5 摘要
///
/// 流
/// 取消令牌
/// 流 Md5 摘要
- public static async Task GetStreamMD5Async(Stream stream, CancellationToken token = default)
+ public static async Task HashAsync(Stream stream, CancellationToken token = default)
{
- using (MD5 md5 = MD5.Create())
+ using (System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create())
{
byte[] bytes = await md5.ComputeHashAsync(stream, token).ConfigureAwait(false);
return System.Convert.ToHexString(bytes);
diff --git a/src/Snap.Hutao/Snap.Hutao/Core/IO/Hashing/XXH64.cs b/src/Snap.Hutao/Snap.Hutao/Core/IO/Hashing/XXH64.cs
new file mode 100644
index 00000000..3a980e26
--- /dev/null
+++ b/src/Snap.Hutao/Snap.Hutao/Core/IO/Hashing/XXH64.cs
@@ -0,0 +1,41 @@
+// Copyright (c) DGP Studio. All rights reserved.
+// Licensed under the MIT license.
+
+using System.IO;
+using System.IO.Hashing;
+
+namespace Snap.Hutao.Core.IO.Hashing;
+
+///
+/// XXH64 摘要
+///
+internal static class XXH64
+{
+ ///
+ /// 获取流的 XXH64 摘要
+ ///
+ /// 流
+ /// 取消令牌
+ /// 摘要
+ public static async Task HashAsync(Stream stream, CancellationToken token = default)
+ {
+ XxHash64 xxHash64 = new();
+ await xxHash64.AppendAsync(stream, token).ConfigureAwait(false);
+ byte[] bytes = xxHash64.GetHashAndReset();
+ return System.Convert.ToHexString(bytes);
+ }
+
+ ///
+ /// 获取文件的 XXH64 摘要
+ ///
+ /// 路径
+ /// 取消令牌
+ /// 摘要
+ public static async Task HashFileAsync(string path, CancellationToken token = default)
+ {
+ using (FileStream stream = File.OpenRead(path))
+ {
+ return await HashAsync(stream, token).ConfigureAwait(false);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Core/Json/JsonOptions.cs b/src/Snap.Hutao/Snap.Hutao/Core/Json/JsonOptions.cs
index fe2e35ee..33c06adc 100644
--- a/src/Snap.Hutao/Snap.Hutao/Core/Json/JsonOptions.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Core/Json/JsonOptions.cs
@@ -20,6 +20,7 @@ internal static class JsonOptions
ReadCommentHandling = JsonCommentHandling.Skip,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
+ NumberHandling = JsonNumberHandling.AllowReadingFromString,
PropertyNameCaseInsensitive = true,
WriteIndented = true,
TypeInfoResolver = new DefaultJsonTypeInfoResolver()
diff --git a/src/Snap.Hutao/Snap.Hutao/Extension/EnumerableExtension.Dictionary.cs b/src/Snap.Hutao/Snap.Hutao/Extension/EnumerableExtension.Dictionary.cs
index be2988a0..419bc009 100644
--- a/src/Snap.Hutao/Snap.Hutao/Extension/EnumerableExtension.Dictionary.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Extension/EnumerableExtension.Dictionary.cs
@@ -1,6 +1,7 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
+using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@@ -15,10 +16,12 @@ internal static partial class EnumerableExtension
/// 增加计数
///
/// 键类型
+ /// 值类型
/// 字典
/// 键
- public static void Increase(this Dictionary dict, TKey key)
+ public static void IncreaseOne(this Dictionary dict, TKey key)
where TKey : notnull
+ where TValue : struct, IIncrementOperators
{
++CollectionsMarshal.GetValueRefOrAddDefault(dict, key, out _);
}
@@ -27,14 +30,16 @@ internal static partial class EnumerableExtension
/// 增加计数
///
/// 键类型
+ /// 值类型
/// 字典
/// 键
/// 增加的值
- public static void Increase(this Dictionary dict, TKey key, int value)
+ public static void IncreaseValue(this Dictionary dict, TKey key, TValue value)
where TKey : notnull
+ where TValue : struct, IAdditionOperators
{
// ref the value, so that we can manipulate it outside the dict.
- ref int current = ref CollectionsMarshal.GetValueRefOrAddDefault(dict, key, out _);
+ ref TValue current = ref CollectionsMarshal.GetValueRefOrAddDefault(dict, key, out _);
current += value;
}
@@ -42,13 +47,15 @@ internal static partial class EnumerableExtension
/// 增加计数
///
/// 键类型
+ /// 值类型
/// 字典
/// 键
/// 是否存在键值
- public static bool TryIncrease(this Dictionary dict, TKey key)
+ public static bool TryIncreaseOne(this Dictionary dict, TKey key)
where TKey : notnull
+ where TValue : struct, IIncrementOperators
{
- ref int value = ref CollectionsMarshal.GetValueRefOrNullRef(dict, key);
+ ref TValue value = ref CollectionsMarshal.GetValueRefOrNullRef(dict, key);
if (!Unsafe.IsNullRef(ref value))
{
++value;
diff --git a/src/Snap.Hutao/Snap.Hutao/Extension/NumberExtension.cs b/src/Snap.Hutao/Snap.Hutao/Extension/NumberExtension.cs
index 1d026191..268a24ba 100644
--- a/src/Snap.Hutao/Snap.Hutao/Extension/NumberExtension.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Extension/NumberExtension.cs
@@ -17,9 +17,9 @@ internal static class NumberExtension
/// 给定的整数
/// 位数
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static int Place(in this int x)
+ public static uint Place(in this uint x)
{
// Benchmarked and compared as a most optimized solution
- return (int)(MathF.Log10(x) + 1);
+ return (uint)(MathF.Log10(x) + 1);
}
}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/IdentityStructs.json b/src/Snap.Hutao/Snap.Hutao/IdentityStructs.json
index e3a3baac..8d57f038 100644
--- a/src/Snap.Hutao/Snap.Hutao/IdentityStructs.json
+++ b/src/Snap.Hutao/Snap.Hutao/IdentityStructs.json
@@ -1,82 +1,166 @@
[
{
"Name": "AchievementGoalId",
- "Type": "int",
- "Documentation": "1-2位 成就分类Id"
+ "Documentation": "成就分类 Id",
+ "Equatable": true,
+ "EqualityOperators": true
},
{
"Name": "AchievementId",
- "Type": "int",
- "Documentation": "5位 成就Id"
+ "Documentation": "成就 Id",
+ "Equatable": true,
+ "EqualityOperators": true
},
{
"Name": "AvatarId",
- "Type": "int",
- "Documentation": "8位 角色Id"
+ "Documentation": "角色 Id",
+ "Equatable": true,
+ "EqualityOperators": true
},
{
"Name": "CostumeId",
- "Type": "int",
- "Documentation": "6位 角色装扮Id"
+ "Documentation": "角色装扮 Id",
+ "Equatable": true,
+ "EqualityOperators": true
},
{
"Name": "EquipAffixId",
- "Type": "int",
- "Documentation": "6位 装备属性Id"
+ "Documentation": "装备属性 Id",
+ "Equatable": true,
+ "EqualityOperators": true
},
{
"Name": "ExtendedEquipAffixId",
- "Type": "int",
- "Documentation": "7位 装备属性Id"
+ "Documentation": "装备属性 Id",
+ "Equatable": true,
+ "EqualityOperators": true
+ },
+ {
+ "Name": "FetterLevel",
+ "Documentation": "好感等级 1 - 10",
+ "Equatable": true,
+ "EqualityOperators": true
+ },
+ {
+ "Name": "Level",
+ "Documentation": "等级 1 - 90",
+ "Equatable": true,
+ "EqualityOperators": true
},
{
"Name": "MaterialId",
- "Type": "int",
- "Documentation": "3-6位 材料Id"
+ "Documentation": "材料 Id",
+ "Equatable": true,
+ "EqualityOperators": true
+ },
+ {
+ "Name": "MonsterDescribeId",
+ "Documentation": "怪物描述 Id",
+ "Equatable": true,
+ "EqualityOperators": true
},
{
"Name": "MonsterId",
- "Type": "int",
- "Documentation": "8位 怪物Id"
+ "Documentation": "怪物 Id",
+ "Equatable": true,
+ "EqualityOperators": true
},
{
"Name": "PromoteId",
- "Type": "int",
- "Documentation": "1-5位 角色突破提升Id"
+ "Documentation": "角色突破提升 Id",
+ "Equatable": true,
+ "EqualityOperators": true
},
{
- "Name": "ReliquaryAffixId",
- "Type": "int",
- "Documentation": "6位 圣遗物副词条Id"
+ "Name": "PromoteLevel",
+ "Documentation": "突破等级 0 - 6",
+ "Equatable": true,
+ "EqualityOperators": true
+ },
+ {
+ "Name": "ReliquaryLevel",
+ "Documentation": "圣遗物等级 1 - 21",
+ "Equatable": true,
+ "EqualityOperators": true
+ },
+ {
+ "Name": "ReliquarySubAffixId",
+ "Documentation": "圣遗物副词条 Id",
+ "Equatable": true,
+ "EqualityOperators": true
},
{
"Name": "ReliquaryId",
- "Type": "int",
- "Documentation": "5位 圣遗物Id"
+ "Documentation": "圣遗物 Id",
+ "Equatable": true,
+ "EqualityOperators": true
},
{
"Name": "ReliquaryMainAffixId",
- "Type": "int",
- "Documentation": "5位 圣遗物主属性Id"
+ "Documentation": "圣遗物主属性 Id",
+ "Equatable": true,
+ "EqualityOperators": true
},
{
"Name": "ReliquarySetId",
- "Type": "int",
- "Documentation": "5位 圣遗物套装Id"
+ "Documentation": "圣遗物套装 Id",
+ "Equatable": true,
+ "EqualityOperators": true
},
{
"Name": "SkillGroupId",
- "Type": "int",
- "Documentation": "3-4位 技能组Id"
+ "Documentation": "技能组 Id",
+ "Equatable": true,
+ "EqualityOperators": true
},
{
"Name": "SkillId",
- "Type": "int",
- "Documentation": "5-6位 技能Id"
+ "Documentation": "技能 Id",
+ "Equatable": true,
+ "EqualityOperators": true
+ },
+ {
+ "Name": "SkillLevel",
+ "Documentation": "技能等级 1 - 15",
+ "Equatable": true,
+ "EqualityOperators": true,
+ "AdditionOperators": true,
+ "IncrementOperators": true
+ },
+ {
+ "Name": "TowerLevelId",
+ "Documentation": "深渊间 Id",
+ "Equatable": true,
+ "EqualityOperators": true
+ },
+ {
+ "Name": "TowerLevelGroupId",
+ "Documentation": "深渊间分组 Id",
+ "Equatable": true,
+ "EqualityOperators": true
+ },
+ {
+ "Name": "TowerFloorId",
+ "Documentation": "深渊层 Id",
+ "Equatable": true,
+ "EqualityOperators": true
+ },
+ {
+ "Name": "TowerScheduleId",
+ "Documentation": "深渊计划 Id",
+ "Equatable": true,
+ "EqualityOperators": true
+ },
+ {
+ "Name": "WeaponAffixLevel",
+ "Documentation": "武器精炼等级 0 - 4",
+ "Equatable": true,
+ "EqualityOperators": true
},
{
"Name": "WeaponId",
- "Type": "int",
- "Documentation": "5位 武器Id"
+ "Documentation": "武器 Id",
+ "Equatable": true,
+ "EqualityOperators": true
}
]
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Migrations/AppDbContextModelSnapshot.cs b/src/Snap.Hutao/Snap.Hutao/Migrations/AppDbContextModelSnapshot.cs
index 82afbde1..0e896111 100644
--- a/src/Snap.Hutao/Snap.Hutao/Migrations/AppDbContextModelSnapshot.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Migrations/AppDbContextModelSnapshot.cs
@@ -42,7 +42,7 @@ namespace Snap.Hutao.Migrations
b.HasIndex("ArchiveId");
- b.ToTable("achievements");
+ b.ToTable("achievements", (string)null);
});
modelBuilder.Entity("Snap.Hutao.Model.Entity.AchievementArchive", b =>
@@ -60,7 +60,7 @@ namespace Snap.Hutao.Migrations
b.HasKey("InnerId");
- b.ToTable("achievement_archives");
+ b.ToTable("achievement_archives", (string)null);
});
modelBuilder.Entity("Snap.Hutao.Model.Entity.AvatarInfo", b =>
@@ -79,7 +79,7 @@ namespace Snap.Hutao.Migrations
b.HasKey("InnerId");
- b.ToTable("avatar_infos");
+ b.ToTable("avatar_infos", (string)null);
});
modelBuilder.Entity("Snap.Hutao.Model.Entity.CultivateEntry", b =>
@@ -101,7 +101,7 @@ namespace Snap.Hutao.Migrations
b.HasIndex("ProjectId");
- b.ToTable("cultivate_entries");
+ b.ToTable("cultivate_entries", (string)null);
});
modelBuilder.Entity("Snap.Hutao.Model.Entity.CultivateItem", b =>
@@ -126,7 +126,7 @@ namespace Snap.Hutao.Migrations
b.HasIndex("EntryId");
- b.ToTable("cultivate_items");
+ b.ToTable("cultivate_items", (string)null);
});
modelBuilder.Entity("Snap.Hutao.Model.Entity.CultivateProject", b =>
@@ -147,7 +147,7 @@ namespace Snap.Hutao.Migrations
b.HasKey("InnerId");
- b.ToTable("cultivate_projects");
+ b.ToTable("cultivate_projects", (string)null);
});
modelBuilder.Entity("Snap.Hutao.Model.Entity.DailyNoteEntry", b =>
@@ -200,7 +200,7 @@ namespace Snap.Hutao.Migrations
b.HasIndex("UserId");
- b.ToTable("daily_notes");
+ b.ToTable("daily_notes", (string)null);
});
modelBuilder.Entity("Snap.Hutao.Model.Entity.GachaArchive", b =>
@@ -218,7 +218,7 @@ namespace Snap.Hutao.Migrations
b.HasKey("InnerId");
- b.ToTable("gacha_archives");
+ b.ToTable("gacha_archives", (string)null);
});
modelBuilder.Entity("Snap.Hutao.Model.Entity.GachaItem", b =>
@@ -249,7 +249,7 @@ namespace Snap.Hutao.Migrations
b.HasIndex("ArchiveId");
- b.ToTable("gacha_items");
+ b.ToTable("gacha_items", (string)null);
});
modelBuilder.Entity("Snap.Hutao.Model.Entity.GameAccount", b =>
@@ -274,7 +274,7 @@ namespace Snap.Hutao.Migrations
b.HasKey("InnerId");
- b.ToTable("game_accounts");
+ b.ToTable("game_accounts", (string)null);
});
modelBuilder.Entity("Snap.Hutao.Model.Entity.InventoryItem", b =>
@@ -296,7 +296,7 @@ namespace Snap.Hutao.Migrations
b.HasIndex("ProjectId");
- b.ToTable("inventory_items");
+ b.ToTable("inventory_items", (string)null);
});
modelBuilder.Entity("Snap.Hutao.Model.Entity.InventoryReliquary", b =>
@@ -325,7 +325,7 @@ namespace Snap.Hutao.Migrations
b.HasIndex("ProjectId");
- b.ToTable("inventory_reliquaries");
+ b.ToTable("inventory_reliquaries", (string)null);
});
modelBuilder.Entity("Snap.Hutao.Model.Entity.InventoryWeapon", b =>
@@ -350,7 +350,7 @@ namespace Snap.Hutao.Migrations
b.HasIndex("ProjectId");
- b.ToTable("inventory_weapons");
+ b.ToTable("inventory_weapons", (string)null);
});
modelBuilder.Entity("Snap.Hutao.Model.Entity.ObjectCacheEntry", b =>
@@ -366,7 +366,7 @@ namespace Snap.Hutao.Migrations
b.HasKey("Key");
- b.ToTable("object_cache");
+ b.ToTable("object_cache", (string)null);
});
modelBuilder.Entity("Snap.Hutao.Model.Entity.SettingEntry", b =>
@@ -379,7 +379,7 @@ namespace Snap.Hutao.Migrations
b.HasKey("Key");
- b.ToTable("settings");
+ b.ToTable("settings", (string)null);
});
modelBuilder.Entity("Snap.Hutao.Model.Entity.SpiralAbyssEntry", b =>
@@ -401,7 +401,7 @@ namespace Snap.Hutao.Migrations
b.HasKey("InnerId");
- b.ToTable("spiral_abysses");
+ b.ToTable("spiral_abysses", (string)null);
});
modelBuilder.Entity("Snap.Hutao.Model.Entity.User", b =>
@@ -435,7 +435,7 @@ namespace Snap.Hutao.Migrations
b.HasKey("InnerId");
- b.ToTable("users");
+ b.ToTable("users", (string)null);
});
modelBuilder.Entity("Snap.Hutao.Model.Entity.Achievement", b =>
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Calculable/CalculableAvatar.cs b/src/Snap.Hutao/Snap.Hutao/Model/Calculable/CalculableAvatar.cs
index 16444f23..cc44896c 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Calculable/CalculableAvatar.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Calculable/CalculableAvatar.cs
@@ -15,8 +15,8 @@ namespace Snap.Hutao.Model.Calculable;
[HighQuality]
internal sealed class CalculableAvatar : ObservableObject, ICalculableAvatar
{
- private int levelCurrent;
- private int levelTarget;
+ private uint levelCurrent;
+ private uint levelTarget;
///
/// 构造一个新的可计算角色
@@ -58,10 +58,10 @@ internal sealed class CalculableAvatar : ObservableObject, ICalculableAvatar
public AvatarId AvatarId { get; }
///
- public int LevelMin { get; }
+ public uint LevelMin { get; }
///
- public int LevelMax { get; }
+ public uint LevelMax { get; }
///
public List Skills { get; }
@@ -73,11 +73,11 @@ internal sealed class CalculableAvatar : ObservableObject, ICalculableAvatar
public Uri Icon { get; }
///
- public ItemQuality Quality { get; }
+ public QualityType Quality { get; }
///
- public int LevelCurrent { get => levelCurrent; set => SetProperty(ref levelCurrent, value); }
+ public uint LevelCurrent { get => levelCurrent; set => SetProperty(ref levelCurrent, value); }
///
- public int LevelTarget { get => levelTarget; set => SetProperty(ref levelTarget, value); }
+ public uint LevelTarget { get => levelTarget; set => SetProperty(ref levelTarget, value); }
}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Calculable/CalculableSkill.cs b/src/Snap.Hutao/Snap.Hutao/Model/Calculable/CalculableSkill.cs
index a1668b43..0093ce25 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Calculable/CalculableSkill.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Calculable/CalculableSkill.cs
@@ -5,6 +5,7 @@ using CommunityToolkit.Mvvm.ComponentModel;
using Snap.Hutao.Model.Intrinsic;
using Snap.Hutao.Model.Metadata.Avatar;
using Snap.Hutao.Model.Metadata.Converter;
+using Snap.Hutao.Model.Primitive;
using Snap.Hutao.ViewModel.AvatarProperty;
namespace Snap.Hutao.Model.Calculable;
@@ -15,8 +16,8 @@ namespace Snap.Hutao.Model.Calculable;
[HighQuality]
internal sealed class CalculableSkill : ObservableObject, ICalculableSkill
{
- private int levelCurrent;
- private int levelTarget;
+ private uint levelCurrent;
+ private uint levelTarget;
///
/// 构造一个新的可计算的技能
@@ -29,7 +30,7 @@ internal sealed class CalculableSkill : ObservableObject, ICalculableSkill
LevelMax = 10; // hard coded 10 here
Name = skill.Name;
Icon = SkillIconConverter.IconNameToUri(skill.Icon);
- Quality = ItemQuality.QUALITY_NONE;
+ Quality = QualityType.QUALITY_NONE;
LevelCurrent = LevelMin;
LevelTarget = LevelMax;
@@ -46,20 +47,20 @@ internal sealed class CalculableSkill : ObservableObject, ICalculableSkill
LevelMax = 10; // hard coded 10 here
Name = skill.Name;
Icon = skill.Icon;
- Quality = ItemQuality.QUALITY_NONE;
+ Quality = QualityType.QUALITY_NONE;
LevelCurrent = LevelMin;
LevelTarget = LevelMax;
}
///
- public int GruopId { get; }
+ public SkillGroupId GruopId { get; }
///
- public int LevelMin { get; }
+ public uint LevelMin { get; }
///
- public int LevelMax { get; }
+ public uint LevelMax { get; }
///
public string Name { get; }
@@ -68,11 +69,11 @@ internal sealed class CalculableSkill : ObservableObject, ICalculableSkill
public Uri Icon { get; }
///
- public ItemQuality Quality { get; }
+ public QualityType Quality { get; }
///
- public int LevelCurrent { get => levelCurrent; set => SetProperty(ref levelCurrent, value); }
+ public uint LevelCurrent { get => levelCurrent; set => SetProperty(ref levelCurrent, value); }
///
- public int LevelTarget { get => levelTarget; set => SetProperty(ref levelTarget, value); }
+ public uint LevelTarget { get => levelTarget; set => SetProperty(ref levelTarget, value); }
}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Calculable/CalculableWeapon.cs b/src/Snap.Hutao/Snap.Hutao/Model/Calculable/CalculableWeapon.cs
index 938a6d23..aef8eda9 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Calculable/CalculableWeapon.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Calculable/CalculableWeapon.cs
@@ -15,8 +15,8 @@ namespace Snap.Hutao.Model.Calculable;
[HighQuality]
internal class CalculableWeapon : ObservableObject, ICalculableWeapon
{
- private int levelCurrent;
- private int levelTarget;
+ private uint levelCurrent;
+ private uint levelTarget;
///
/// 构造一个新的可计算武器
@@ -56,10 +56,10 @@ internal class CalculableWeapon : ObservableObject, ICalculableWeapon
public WeaponId WeaponId { get; }
///
- public int LevelMin { get; }
+ public uint LevelMin { get; }
///
- public int LevelMax { get; }
+ public uint LevelMax { get; }
///
public string Name { get; }
@@ -68,11 +68,11 @@ internal class CalculableWeapon : ObservableObject, ICalculableWeapon
public Uri Icon { get; }
///
- public ItemQuality Quality { get; }
+ public QualityType Quality { get; }
///
- public int LevelCurrent { get => levelCurrent; set => SetProperty(ref levelCurrent, value); }
+ public uint LevelCurrent { get => levelCurrent; set => SetProperty(ref levelCurrent, value); }
///
- public int LevelTarget { get => levelTarget; set => SetProperty(ref levelTarget, value); }
+ public uint LevelTarget { get => levelTarget; set => SetProperty(ref levelTarget, value); }
}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Calculable/ICalculable.cs b/src/Snap.Hutao/Snap.Hutao/Model/Calculable/ICalculable.cs
index b3cefa82..1b92e545 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Calculable/ICalculable.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Calculable/ICalculable.cs
@@ -14,15 +14,15 @@ internal interface ICalculable : INameIcon
///
/// 星级
///
- ItemQuality Quality { get; }
+ QualityType Quality { get; }
///
/// 当前等级
///
- int LevelCurrent { get; set; }
+ uint LevelCurrent { get; set; }
///
/// 目标等级
///
- int LevelTarget { get; set; }
+ uint LevelTarget { get; set; }
}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Calculable/ICalculableAvatar.cs b/src/Snap.Hutao/Snap.Hutao/Model/Calculable/ICalculableAvatar.cs
index 7f888290..1c595729 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Calculable/ICalculableAvatar.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Calculable/ICalculableAvatar.cs
@@ -19,12 +19,12 @@ internal interface ICalculableAvatar : ICalculable
///
/// 最小等级
///
- int LevelMin { get; }
+ uint LevelMin { get; }
///
/// 最大等级
///
- int LevelMax { get; }
+ uint LevelMax { get; }
///
/// 技能组
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Calculable/ICalculableSkill.cs b/src/Snap.Hutao/Snap.Hutao/Model/Calculable/ICalculableSkill.cs
index 15a1b19a..839a7a0e 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Calculable/ICalculableSkill.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Calculable/ICalculableSkill.cs
@@ -1,6 +1,8 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
+using Snap.Hutao.Model.Primitive;
+
namespace Snap.Hutao.Model.Calculable;
///
@@ -12,15 +14,15 @@ internal interface ICalculableSkill : ICalculable
///
/// 技能组Id
///
- int GruopId { get; }
+ SkillGroupId GruopId { get; }
///
/// 最小等级
///
- int LevelMin { get; }
+ uint LevelMin { get; }
///
/// 最大等级
///
- int LevelMax { get; }
+ uint LevelMax { get; }
}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Calculable/ICalculableWeapon.cs b/src/Snap.Hutao/Snap.Hutao/Model/Calculable/ICalculableWeapon.cs
index 2020a532..b0af82b5 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Calculable/ICalculableWeapon.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Calculable/ICalculableWeapon.cs
@@ -19,10 +19,10 @@ internal interface ICalculableWeapon : ICalculable
///
/// 最小等级
///
- int LevelMin { get; }
+ uint LevelMin { get; }
///
/// 最大等级
///
- int LevelMax { get; }
+ uint LevelMax { get; }
}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Entity/Achievement.cs b/src/Snap.Hutao/Snap.Hutao/Model/Entity/Achievement.cs
index 8b5febbb..cb2d4dfb 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Entity/Achievement.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Entity/Achievement.cs
@@ -37,12 +37,12 @@ internal sealed class Achievement : IEquatable
///
/// Id
///
- public int Id { get; set; }
+ public uint Id { get; set; }
///
/// 当前进度
///
- public int Current { get; set; }
+ public uint Current { get; set; }
///
/// 完成时间
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Entity/CultivateEntry.cs b/src/Snap.Hutao/Snap.Hutao/Model/Entity/CultivateEntry.cs
index 48d303b2..e986bf09 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Entity/CultivateEntry.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Entity/CultivateEntry.cs
@@ -40,7 +40,7 @@ internal sealed class CultivateEntry
///
/// 角色/武器/家具 Id
///
- public int Id { get; set; }
+ public uint Id { get; set; }
///
/// 创建一个新的养成入口点
@@ -49,7 +49,7 @@ internal sealed class CultivateEntry
/// 类型
/// 主Id
/// 养成入口点
- public static CultivateEntry Create(in Guid projectId, CultivateType type, int id)
+ public static CultivateEntry Create(in Guid projectId, CultivateType type, uint id)
{
return new()
{
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Entity/GachaItem.cs b/src/Snap.Hutao/Snap.Hutao/Model/Entity/GachaItem.cs
index 4661d460..85799237 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Entity/GachaItem.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Entity/GachaItem.cs
@@ -49,7 +49,7 @@ internal sealed class GachaItem
///
/// 物品Id
///
- public int ItemId { get; set; }
+ public uint ItemId { get; set; }
///
/// 获取时间
@@ -66,12 +66,12 @@ internal sealed class GachaItem
///
/// 物品Id
/// 物品类型字符串
- public static string GetItemTypeStringByItemId(int itemId)
+ public static string GetItemTypeStringByItemId(uint itemId)
{
return itemId.Place() switch
{
- 8 => "角色",
- 5 => "武器",
+ 8U => "角色",
+ 5U => "武器",
_ => "未知",
};
}
@@ -83,7 +83,7 @@ internal sealed class GachaItem
/// 祈愿物品
/// 物品Id
/// 新的祈愿物品
- public static GachaItem Create(in Guid archiveId, GachaLogItem item, int itemId)
+ public static GachaItem Create(in Guid archiveId, GachaLogItem item, uint itemId)
{
return new()
{
@@ -103,7 +103,7 @@ internal sealed class GachaItem
/// 祈愿物品
/// 物品Id
/// 新的祈愿物品
- public static GachaItem CreateForMajor2Minor2OrLower(in Guid archiveId, UIGFItem item, int itemId)
+ public static GachaItem CreateForMajor2Minor2OrLower(in Guid archiveId, UIGFItem item, uint itemId)
{
return new()
{
@@ -129,7 +129,7 @@ internal sealed class GachaItem
ArchiveId = archiveId,
GachaType = item.GachaType,
QueryType = item.UIGFGachaType,
- ItemId = int.Parse(item.ItemId),
+ ItemId = uint.Parse(item.ItemId),
Time = item.Time,
Id = item.Id,
};
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Entity/InventoryItem.cs b/src/Snap.Hutao/Snap.Hutao/Model/Entity/InventoryItem.cs
index 03c3a703..50f4e8b3 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Entity/InventoryItem.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Entity/InventoryItem.cs
@@ -34,7 +34,7 @@ internal sealed class InventoryItem
///
/// 物品Id
///
- public int ItemId { get; set; }
+ public uint ItemId { get; set; }
///
/// 个数 4294967295
@@ -47,7 +47,7 @@ internal sealed class InventoryItem
/// 项目Id
/// 物品Id
/// 新的个数为0的物品
- public static InventoryItem Create(in Guid projectId, int itemId)
+ public static InventoryItem Create(in Guid projectId, uint itemId)
{
return new()
{
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/InterChange/Achievement/UIAFItem.cs b/src/Snap.Hutao/Snap.Hutao/Model/InterChange/Achievement/UIAFItem.cs
index bafe336e..dacbcd45 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/InterChange/Achievement/UIAFItem.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/InterChange/Achievement/UIAFItem.cs
@@ -14,7 +14,7 @@ internal sealed class UIAFItem
/// 成就Id
///
[JsonPropertyName("id")]
- public int Id { get; set; }
+ public uint Id { get; set; }
///
/// 完成时间
@@ -27,7 +27,7 @@ internal sealed class UIAFItem
/// 对于progress为1的项,该属性始终为0
///
[JsonPropertyName("current")]
- public int Current { get; set; }
+ public uint Current { get; set; }
///
/// 完成状态
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/InterChange/GachaLog/UIGFInfo.cs b/src/Snap.Hutao/Snap.Hutao/Model/InterChange/GachaLog/UIGFInfo.cs
index a8bacc4a..19a93699 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/InterChange/GachaLog/UIGFInfo.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/InterChange/GachaLog/UIGFInfo.cs
@@ -27,7 +27,6 @@ internal sealed class UIGFInfo
/// 导出的时间戳
///
[JsonPropertyName("export_timestamp")]
- [JsonNumberHandling(JsonNumberHandling.AllowReadingFromString)]
public long? ExportTimestamp { get; set; }
///
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/InterChange/Inventory/UIIFInfo.cs b/src/Snap.Hutao/Snap.Hutao/Model/InterChange/Inventory/UIIFInfo.cs
index 00cfa0c7..8e199745 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/InterChange/Inventory/UIIFInfo.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/InterChange/Inventory/UIIFInfo.cs
@@ -27,7 +27,6 @@ internal sealed class UIIFInfo
/// 导出的时间戳
///
[JsonPropertyName("export_timestamp")]
- [JsonNumberHandling(JsonNumberHandling.AllowReadingFromString)]
public long? ExportTimestamp { get; set; }
///
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Intrinsic/GrowCurveType.cs b/src/Snap.Hutao/Snap.Hutao/Model/Intrinsic/GrowCurveType.cs
index ddd7079b..66ccf5b2 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Intrinsic/GrowCurveType.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Intrinsic/GrowCurveType.cs
@@ -36,37 +36,45 @@ internal enum GrowCurveType
GROW_CURVE_HP_2 = 23,
GROW_CURVE_ATTACK_2 = 24,
GROW_CURVE_HP_ENVIRONMENT = 25,
+
GROW_CURVE_ATTACK_S5 = 31,
GROW_CURVE_ATTACK_S4 = 32,
GROW_CURVE_ATTACK_S3 = 33,
GROW_CURVE_STRIKE_S5 = 34,
+
GROW_CURVE_DEFENSE_S5 = 41,
GROW_CURVE_DEFENSE_S4 = 42,
+
GROW_CURVE_ATTACK_101 = 1101,
GROW_CURVE_ATTACK_102 = 1102,
GROW_CURVE_ATTACK_103 = 1103,
GROW_CURVE_ATTACK_104 = 1104,
GROW_CURVE_ATTACK_105 = 1105,
+
GROW_CURVE_ATTACK_201 = 1201,
GROW_CURVE_ATTACK_202 = 1202,
GROW_CURVE_ATTACK_203 = 1203,
GROW_CURVE_ATTACK_204 = 1204,
GROW_CURVE_ATTACK_205 = 1205,
+
GROW_CURVE_ATTACK_301 = 1301,
GROW_CURVE_ATTACK_302 = 1302,
GROW_CURVE_ATTACK_303 = 1303,
GROW_CURVE_ATTACK_304 = 1304,
GROW_CURVE_ATTACK_305 = 1305,
+
GROW_CURVE_CRITICAL_101 = 2101,
GROW_CURVE_CRITICAL_102 = 2102,
GROW_CURVE_CRITICAL_103 = 2103,
GROW_CURVE_CRITICAL_104 = 2104,
GROW_CURVE_CRITICAL_105 = 2105,
+
GROW_CURVE_CRITICAL_201 = 2201,
GROW_CURVE_CRITICAL_202 = 2202,
GROW_CURVE_CRITICAL_203 = 2203,
GROW_CURVE_CRITICAL_204 = 2204,
GROW_CURVE_CRITICAL_205 = 2205,
+
GROW_CURVE_CRITICAL_301 = 2301,
GROW_CURVE_CRITICAL_302 = 2302,
GROW_CURVE_CRITICAL_303 = 2303,
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Intrinsic/Immutable/IntrinsicImmutables.cs b/src/Snap.Hutao/Snap.Hutao/Model/Intrinsic/Immutable/IntrinsicImmutables.cs
index 47d9f869..88f18668 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Intrinsic/Immutable/IntrinsicImmutables.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Intrinsic/Immutable/IntrinsicImmutables.cs
@@ -24,7 +24,7 @@ internal static class IntrinsicImmutables
///
/// 物品类型
///
- public static readonly ImmutableHashSet ItemQualities = Enum.GetValues().Select(e => e.GetLocalizedDescriptionOrDefault()).OfType().ToImmutableHashSet();
+ public static readonly ImmutableHashSet ItemQualities = Enum.GetValues().Select(e => e.GetLocalizedDescriptionOrDefault()).OfType().ToImmutableHashSet();
///
/// 身材类型
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Intrinsic/MaterialType.cs b/src/Snap.Hutao/Snap.Hutao/Model/Intrinsic/MaterialType.cs
index 3ac2fefa..40200b84 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Intrinsic/MaterialType.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Intrinsic/MaterialType.cs
@@ -12,6 +12,7 @@ internal enum MaterialType
MATERIAL_NONE = 0,
MATERIAL_FOOD = 1,
MATERIAL_QUEST = 2,
+
MATERIAL_EXCHANGE = 4,
MATERIAL_CONSUME = 5,
MATERIAL_EXP_FRUIT = 6,
@@ -34,6 +35,7 @@ internal enum MaterialType
MATERIAL_FAKE_ABSORBATE = 23,
MATERIAL_CONSUME_BATCH_USE = 24,
MATERIAL_WOOD = 25,
+
MATERIAL_FURNITURE_FORMULA = 27,
MATERIAL_CHANNELLER_SLAB_BUFF = 28,
MATERIAL_FURNITURE_SUITE_FORMULA = 29,
@@ -41,7 +43,7 @@ internal enum MaterialType
MATERIAL_HOME_SEED = 31,
MATERIAL_FISH_BAIT = 32,
MATERIAL_FISH_ROD = 33,
- MATERIAL_SUMO_BUFF = 34, // never appear
+ MATERIAL_SUMO_BUFF = 34, // sumo 活动道具,never appear
MATERIAL_FIREWORKS = 35,
MATERIAL_BGM = 36,
MATERIAL_SPICE_FOOD = 37,
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Intrinsic/ItemQuality.cs b/src/Snap.Hutao/Snap.Hutao/Model/Intrinsic/QualityType.cs
similarity index 97%
rename from src/Snap.Hutao/Snap.Hutao/Model/Intrinsic/ItemQuality.cs
rename to src/Snap.Hutao/Snap.Hutao/Model/Intrinsic/QualityType.cs
index 489a3f20..4e37baaa 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Intrinsic/ItemQuality.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Intrinsic/QualityType.cs
@@ -8,7 +8,7 @@ namespace Snap.Hutao.Model.Intrinsic;
///
[HighQuality]
[Localization]
-internal enum ItemQuality
+internal enum QualityType
{
///
/// 无
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Item.cs b/src/Snap.Hutao/Snap.Hutao/Model/Item.cs
index 3ff05ba7..e82ea419 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Item.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Item.cs
@@ -29,5 +29,5 @@ internal class Item : INameIcon
///
/// 星级
///
- public ItemQuality Quality { get; set; }
+ public QualityType Quality { get; set; }
}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Abstraction/INameQuality.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Abstraction/INameQuality.cs
index fc8b60f2..b29640d9 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Abstraction/INameQuality.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Abstraction/INameQuality.cs
@@ -19,5 +19,5 @@ internal interface INameQuality
///
/// 星级
///
- ItemQuality Quality { get; }
+ QualityType Quality { get; }
}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Abstraction/ISummaryItemSource.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Abstraction/ISummaryItemSource.cs
index 69b5f3de..2be603a4 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Abstraction/ISummaryItemSource.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Abstraction/ISummaryItemSource.cs
@@ -15,7 +15,7 @@ internal interface ISummaryItemSource
///
/// 星级
///
- ItemQuality Quality { get; }
+ QualityType Quality { get; }
///
/// 转换到简述统计物品
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Achievement/Achievement.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Achievement/Achievement.cs
index 89f05571..54ed3441 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Achievement/Achievement.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Achievement/Achievement.cs
@@ -24,7 +24,7 @@ internal sealed class Achievement
///
/// 排序顺序
///
- public int Order { get; set; }
+ public uint Order { get; set; }
///
/// 标题
@@ -44,7 +44,7 @@ internal sealed class Achievement
///
/// 总进度
///
- public int Progress { get; set; }
+ public uint Progress { get; set; }
///
/// 图标
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Achievement/AchievementGoal.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Achievement/AchievementGoal.cs
index 9c943822..7c3695e4 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Achievement/AchievementGoal.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Achievement/AchievementGoal.cs
@@ -19,7 +19,7 @@ internal sealed class AchievementGoal
///
/// 排序顺序
///
- public int Order { get; set; }
+ public uint Order { get; set; }
///
/// 名称
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Achievement/Reward.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Achievement/Reward.cs
index a80a6ce0..40749e14 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Achievement/Reward.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Achievement/Reward.cs
@@ -18,5 +18,5 @@ internal sealed class Reward
///
/// 数量
///
- public int Count { get; set; }
+ public uint Count { get; set; }
}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Avatar/Avatar.Implementation.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Avatar/Avatar.Implementation.cs
index 0b90a050..73db31c0 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Avatar/Avatar.Implementation.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Avatar/Avatar.Implementation.cs
@@ -18,6 +18,7 @@ internal partial class Avatar : IStatisticsItemSource, ISummaryItemSource, IName
{
///
/// [非元数据] 搭配数据
+ /// TODO:Add View suffix.
///
[JsonIgnore]
public AvatarCollocationView? Collocation { get; set; }
@@ -37,7 +38,7 @@ internal partial class Avatar : IStatisticsItemSource, ISummaryItemSource, IName
/// 最大等级
///
[SuppressMessage("", "CA1822")]
- public int MaxLevel { get => 90; }
+ public uint MaxLevel { get => 90U; }
///
public ICalculableAvatar ToCalculable()
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Avatar/Avatar.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Avatar/Avatar.cs
index 0a228c51..7875b53b 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Avatar/Avatar.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Avatar/Avatar.cs
@@ -26,12 +26,11 @@ internal partial class Avatar
///
/// 排序号
///
- public int Sort { get; set; }
+ public uint Sort { get; set; }
///
/// 体型
///
- [JsonEnum(JsonSerializeType.String)]
public BodyType Body { get; set; } = default!;
///
@@ -62,7 +61,7 @@ internal partial class Avatar
///
/// 星级
///
- public ItemQuality Quality { get; set; }
+ public QualityType Quality { get; set; }
///
/// 武器类型
@@ -72,12 +71,12 @@ internal partial class Avatar
///
/// 基础数值
///
- public BaseValue BaseValue { get; set; } = default!;
+ public AvatarBaseValue BaseValue { get; set; } = default!;
///
/// 生长曲线
///
- public Dictionary GrowCurves { get; set; } = default!;
+ public List> GrowCurves { get; set; } = default!;
///
/// 技能
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Avatar/AvatarBaseValue.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Avatar/AvatarBaseValue.cs
new file mode 100644
index 00000000..04bd2365
--- /dev/null
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Avatar/AvatarBaseValue.cs
@@ -0,0 +1,21 @@
+// Copyright (c) DGP Studio. All rights reserved.
+// Licensed under the MIT license.
+
+using Snap.Hutao.Core.Json.Annotation;
+using Snap.Hutao.Model.Intrinsic;
+using Snap.Hutao.Model.Primitive;
+using Snap.Hutao.ViewModel.Wiki;
+
+namespace Snap.Hutao.Model.Metadata.Avatar;
+
+///
+/// 角色基础数值
+///
+internal sealed class AvatarBaseValue : BaseValue
+{
+ public PropertyCurveValue GetPropertyCurveValue(FightProperty fightProperty)
+ {
+ // TODO: impl
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Avatar/Costume.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Avatar/Costume.cs
index b90ce93d..a0005f5a 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Avatar/Costume.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Avatar/Costume.cs
@@ -34,7 +34,7 @@ internal sealed class Costume
///
/// 图标
///
- public string Icon { get; set; } = default!;
+ public string FrontIcon { get; set; } = default!;
///
/// 侧面图标
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Avatar/FetterInfo.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Avatar/FetterInfo.cs
index 5ae8899f..c0003efd 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Avatar/FetterInfo.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Avatar/FetterInfo.cs
@@ -25,7 +25,6 @@ internal sealed class FetterInfo
///
/// 地区
///
- [JsonEnum(JsonSerializeType.String)]
public AssociationType Association { get; set; } = default!;
///
@@ -36,12 +35,12 @@ internal sealed class FetterInfo
///
/// 生月
///
- public int BirthMonth { get; set; }
+ public uint BirthMonth { get; set; }
///
/// 生日
///
- public int BirthDay { get; set; }
+ public uint BirthDay { get; set; }
///
/// 格式化的生日日期
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/AvatarIds.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/AvatarIds.cs
index dec36089..5f1c79ba 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/AvatarIds.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/AvatarIds.cs
@@ -12,6 +12,7 @@ namespace Snap.Hutao.Model.Metadata;
[SuppressMessage("", "SA1600")]
internal static class AvatarIds
{
+ // 此处的变量名称以 UI_AvatarIcon 为准
public static readonly AvatarId Ayaka = 10000002;
public static readonly AvatarId Qin = 10000003;
@@ -106,7 +107,7 @@ internal static class AvatarIds
Name = "旅行者",
Icon = "UI_AvatarIcon_PlayerBoy",
SideIcon = "UI_AvatarIcon_Side_PlayerBoy",
- Quality = Intrinsic.ItemQuality.QUALITY_ORANGE,
+ Quality = Intrinsic.QualityType.QUALITY_ORANGE,
},
[PlayerGirl] = new()
@@ -114,7 +115,7 @@ internal static class AvatarIds
Name = "旅行者",
Icon = "UI_AvatarIcon_PlayerGirl",
SideIcon = "UI_AvatarIcon_Side_PlayerGirl",
- Quality = Intrinsic.ItemQuality.QUALITY_ORANGE,
+ Quality = Intrinsic.QualityType.QUALITY_ORANGE,
},
};
}
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/BaseValue.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/BaseValue.cs
index 4b5d2cd4..552d96c9 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/BaseValue.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/BaseValue.cs
@@ -30,7 +30,7 @@ internal class BaseValue
///
/// 战斗属性
/// 值
- public float GetValue(FightProperty fightProperty)
+ public virtual float GetValue(FightProperty fightProperty)
{
return fightProperty switch
{
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/DescriptionsParametersDescriptor.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/DescriptionsParametersDescriptor.cs
index 76c9004e..cce1db7d 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/DescriptionsParametersDescriptor.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/DescriptionsParametersDescriptor.cs
@@ -20,7 +20,7 @@ internal sealed partial class DescriptionsParametersDescriptor : ValueConverter<
/// 源
/// 等级
/// 特定等级的解释
- public static LevelParameters Convert(DescriptionsParameters from, int level)
+ public static LevelParameters Convert(DescriptionsParameters from, uint level)
{
LevelParameters param = from.Parameters.Single(param => param.Level == level);
return new LevelParameters($"Lv.{param.Level}", GetParameterDescription(from.Descriptions, param.Parameters));
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/QualityColorConverter.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/QualityColorConverter.cs
index c4ce4ef1..20df90d1 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/QualityColorConverter.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/QualityColorConverter.cs
@@ -13,18 +13,18 @@ namespace Snap.Hutao.Model.Metadata.Converter;
/// 品质颜色转换器
///
[HighQuality]
-internal sealed class QualityColorConverter : ValueConverter
+internal sealed class QualityColorConverter : ValueConverter
{
///
- public override Color Convert(ItemQuality from)
+ public override Color Convert(QualityType from)
{
return from switch
{
- ItemQuality.QUALITY_WHITE => StructMarshal.Color(0xFF72778B),
- ItemQuality.QUALITY_GREEN => StructMarshal.Color(0xFF2A8F72),
- ItemQuality.QUALITY_BLUE => StructMarshal.Color(0xFF5180CB),
- ItemQuality.QUALITY_PURPLE => StructMarshal.Color(0xFFA156E0),
- ItemQuality.QUALITY_ORANGE or ItemQuality.QUALITY_ORANGE_SP => StructMarshal.Color(0xFFBC6932),
+ QualityType.QUALITY_WHITE => StructMarshal.Color(0xFF72778B),
+ QualityType.QUALITY_GREEN => StructMarshal.Color(0xFF2A8F72),
+ QualityType.QUALITY_BLUE => StructMarshal.Color(0xFF5180CB),
+ QualityType.QUALITY_PURPLE => StructMarshal.Color(0xFFA156E0),
+ QualityType.QUALITY_ORANGE or QualityType.QUALITY_ORANGE_SP => StructMarshal.Color(0xFFBC6932),
_ => Colors.Transparent,
};
}
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/QualityConverter.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/QualityConverter.cs
index 5306edef..39cea05f 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/QualityConverter.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/QualityConverter.cs
@@ -10,13 +10,13 @@ namespace Snap.Hutao.Model.Metadata.Converter;
/// 物品等级转换器
///
[HighQuality]
-internal sealed class QualityConverter : ValueConverter
+internal sealed class QualityConverter : ValueConverter
{
///
- public override Uri Convert(ItemQuality from)
+ public override Uri Convert(QualityType from)
{
string name = Enum.GetName(from) ?? from.ToString();
- if (name == nameof(ItemQuality.QUALITY_ORANGE_SP))
+ if (name == nameof(QualityType.QUALITY_ORANGE_SP))
{
name = "QUALITY_RED";
}
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/GachaEvent.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/GachaEvent.cs
index 35ea775b..3cbcc597 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/GachaEvent.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/GachaEvent.cs
@@ -21,11 +21,21 @@ internal sealed class GachaEvent
///
public string Version { get; set; } = default!;
+ ///
+ /// 顺序
+ ///
+ public uint Order { get; set; }
+
///
/// 卡池图
///
public Uri Banner { get; set; } = default!;
+ ///
+ /// 卡池图2
+ ///
+ public Uri Banner2 { get; set; } = default!;
+
///
/// 开始时间
///
@@ -44,10 +54,10 @@ internal sealed class GachaEvent
///
/// 五星列表
///
- public List UpOrangeList { get; set; } = default!;
+ public List UpOrangeList { get; set; } = default!;
///
/// 四星列表
///
- public List UpPurpleList { get; set; } = default!;
+ public List UpPurpleList { get; set; } = default!;
}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/GrowCurve.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/GrowCurve.cs
index dffb1d06..e11e55ea 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/GrowCurve.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/GrowCurve.cs
@@ -2,6 +2,7 @@
// Licensed under the MIT license.
using Snap.Hutao.Model.Intrinsic;
+using Snap.Hutao.Model.Primitive;
namespace Snap.Hutao.Model.Metadata;
@@ -11,13 +12,23 @@ namespace Snap.Hutao.Model.Metadata;
[HighQuality]
internal sealed class GrowCurve
{
+ private Dictionary? curveMap;
+
///
/// 等级
///
- public int Level { get; set; }
+ public Level Level { get; set; }
///
/// 曲线 值相乘
///
- public Dictionary Curves { get; set; } = default!;
+ public List> Curves { get; set; } = default!;
+
+ ///
+ /// 曲线映射
+ ///
+ public Dictionary CurveMap
+ {
+ get => curveMap ??= Curves.ToDictionary(v => v.Type, v => v.Value);
+ }
}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Item/Display.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Item/DisplayItem.cs
similarity index 92%
rename from src/Snap.Hutao/Snap.Hutao/Model/Metadata/Item/Display.cs
rename to src/Snap.Hutao/Snap.Hutao/Model/Metadata/Item/DisplayItem.cs
index a9071979..d952a480 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Item/Display.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Item/DisplayItem.cs
@@ -10,7 +10,7 @@ namespace Snap.Hutao.Model.Metadata.Item;
/// 展示物品
///
[HighQuality]
-internal class Display
+internal class DisplayItem
{
///
/// 物品Id
@@ -20,7 +20,7 @@ internal class Display
///
/// 等级
///
- public ItemQuality RankLevel { get; set; }
+ public QualityType RankLevel { get; set; }
///
/// 物品类型
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Item/Material.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Item/Material.cs
index 131e0462..01501f34 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Item/Material.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Item/Material.cs
@@ -11,44 +11,8 @@ namespace Snap.Hutao.Model.Metadata.Item;
///
/// 材料
///
-internal sealed class Material : Display
+internal sealed class Material : DisplayItem
{
- private static readonly ImmutableHashSet MondayThursdayItems = new HashSet
- {
- 104301, 104302, 104303, // 「自由」
- 104310, 104311, 104312, // 「繁荣」
- 104320, 104321, 104322, // 「浮世」
- 104329, 104330, 104331, // 「诤言」
- 114001, 114002, 114003, 114004, // 高塔孤王
- 114013, 114014, 114015, 114016, // 孤云寒林
- 114025, 114026, 114027, 114028, // 远海夷地
- 114037, 114038, 114039, 114040, // 谧林涓露
- }.ToImmutableHashSet();
-
- private static readonly ImmutableHashSet TuesdayFridayItems = new HashSet
- {
- 104304, 104305, 104306, // 「抗争」
- 104313, 104314, 104315, // 「勤劳」
- 104323, 104324, 104325, // 「风雅」
- 104332, 104333, 104334, // 「巧思」
- 114005, 114006, 114007, 114008, // 凛风奔狼
- 114017, 114018, 114019, 114020, // 雾海云间
- 114029, 114030, 114031, 114032, // 鸣神御灵
- 114041, 114042, 114043, 114044, // 绿洲花园
- }.ToImmutableHashSet();
-
- private static readonly ImmutableHashSet WednesdaySaturdayItems = new HashSet
- {
- 104307, 104308, 104309, // 「诗文」
- 104316, 104317, 104318, // 「黄金」
- 104326, 104327, 104328, // 「天光」
- 104335, 104336, 104337, // 「笃行」
- 114009, 114010, 114011, 114012, // 狮牙斗士
- 114021, 114022, 114023, 114024, // 漆黑陨铁
- 114033, 114034, 114035, 114036, // 今昔剧画
- 114045, 114046, 114047, 114048, // 谧林涓露
- }.ToImmutableHashSet();
-
///
/// 材料类型
///
@@ -66,23 +30,24 @@ internal sealed class Material : Display
public bool IsInventoryItem()
{
// 原质
- if (Id == 112001)
+ if (Id == 112001U)
{
return false;
}
// 摩拉
- if (Id == 202)
+ if (Id == 202U)
{
return true;
}
+ // TODO: support non-CHS
if (TypeDescription.EndsWith("区域特产"))
{
return true;
}
- // TODO: Currently only support CN
+ // TODO: support non-CHS
return TypeDescription switch
{
"角色与武器培养素材" => true, // 怪物掉落
@@ -106,9 +71,9 @@ internal sealed class Material : Display
{
return DateTimeOffset.UtcNow.AddHours(4).DayOfWeek switch
{
- DayOfWeek.Monday or DayOfWeek.Thursday => MondayThursdayItems.Contains(Id),
- DayOfWeek.Tuesday or DayOfWeek.Friday => TuesdayFridayItems.Contains(Id),
- DayOfWeek.Wednesday or DayOfWeek.Saturday => WednesdaySaturdayItems.Contains(Id),
+ 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,
};
}
@@ -119,17 +84,17 @@ internal sealed class Material : Display
/// DaysOfWeek
public DaysOfWeek GetDaysOfWeek()
{
- if (MondayThursdayItems.Contains(Id))
+ if (Materials.MondayThursdayItems.Contains(Id))
{
return DaysOfWeek.MondayAndThursday;
}
- if (TuesdayFridayItems.Contains(Id))
+ if (Materials.TuesdayFridayItems.Contains(Id))
{
return DaysOfWeek.TuesdayAndFriday;
}
- if (WednesdaySaturdayItems.Contains(Id))
+ if (Materials.WednesdaySaturdayItems.Contains(Id))
{
return DaysOfWeek.WednesdayAndSaturday;
}
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Item/Materials.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Item/Materials.cs
new file mode 100644
index 00000000..ce04c4f3
--- /dev/null
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Item/Materials.cs
@@ -0,0 +1,66 @@
+// Copyright (c) DGP Studio. All rights reserved.
+// Licensed under the MIT license.
+
+using Snap.Hutao.Model.Intrinsic;
+using Snap.Hutao.Model.Primitive;
+using Snap.Hutao.ViewModel.Cultivation;
+using System.Collections.Immutable;
+
+namespace Snap.Hutao.Model.Metadata.Item;
+
+///
+/// 材料表
+///
+internal static class Materials
+{
+ private static readonly ImmutableHashSet MondayThursdayItemsInner = new HashSet
+ {
+ 104301, 104302, 104303, // 「自由」
+ 104310, 104311, 104312, // 「繁荣」
+ 104320, 104321, 104322, // 「浮世」
+ 104329, 104330, 104331, // 「诤言」
+ 114001, 114002, 114003, 114004, // 高塔孤王
+ 114013, 114014, 114015, 114016, // 孤云寒林
+ 114025, 114026, 114027, 114028, // 远海夷地
+ 114037, 114038, 114039, 114040, // 谧林涓露
+ }.ToImmutableHashSet();
+
+ private static readonly ImmutableHashSet TuesdayFridayItemsInner = new HashSet
+ {
+ 104304, 104305, 104306, // 「抗争」
+ 104313, 104314, 104315, // 「勤劳」
+ 104323, 104324, 104325, // 「风雅」
+ 104332, 104333, 104334, // 「巧思」
+ 114005, 114006, 114007, 114008, // 凛风奔狼
+ 114017, 114018, 114019, 114020, // 雾海云间
+ 114029, 114030, 114031, 114032, // 鸣神御灵
+ 114041, 114042, 114043, 114044, // 绿洲花园
+ }.ToImmutableHashSet();
+
+ private static readonly ImmutableHashSet WednesdaySaturdayItemsInner = new HashSet
+ {
+ 104307, 104308, 104309, // 「诗文」
+ 104316, 104317, 104318, // 「黄金」
+ 104326, 104327, 104328, // 「天光」
+ 104335, 104336, 104337, // 「笃行」
+ 114009, 114010, 114011, 114012, // 狮牙斗士
+ 114021, 114022, 114023, 114024, // 漆黑陨铁
+ 114033, 114034, 114035, 114036, // 今昔剧画
+ 114045, 114046, 114047, 114048, // 谧林涓露
+ }.ToImmutableHashSet();
+
+ ///
+ /// 周一/周四
+ ///
+ public static ImmutableHashSet MondayThursdayItems { get => MondayThursdayItemsInner; }
+
+ ///
+ /// 周二/周五
+ ///
+ public static ImmutableHashSet TuesdayFridayItems { get => TuesdayFridayItemsInner; }
+
+ ///
+ /// 周三/周六
+ ///
+ public static ImmutableHashSet WednesdaySaturdayItems { get => WednesdaySaturdayItemsInner; }
+}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Monster/Monster.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Monster/Monster.cs
index 42c3b74b..3ddab034 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Monster/Monster.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Monster/Monster.cs
@@ -17,6 +17,11 @@ internal sealed class Monster
///
public MonsterId Id { get; set; }
+ ///
+ /// 描述 Id
+ ///
+ public MonsterDescribeId DescribeId { get; set; }
+
///
/// 内部代号
///
@@ -60,10 +65,11 @@ internal sealed class Monster
///
/// 生长曲线
///
- public Dictionary GrowCurves { get; set; } = default!;
+ public List> GrowCurves { get; set; } = default!;
///
/// 养成物品视图
///
- public List? DropsView { get; set; }
+ [JsonIgnore]
+ public List? DropsView { get; set; }
}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Promote.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Promote.cs
index 85670c71..b61de4af 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Promote.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Promote.cs
@@ -12,6 +12,8 @@ namespace Snap.Hutao.Model.Metadata;
[HighQuality]
internal sealed class Promote
{
+ private Dictionary? addPropertyMap;
+
///
/// Id
///
@@ -20,10 +22,18 @@ internal sealed class Promote
///
/// 突破等级
///
- public int Level { get; set; }
+ public PromoteLevel Level { get; set; }
///
/// 增加的属性
///
- public Dictionary AddProperties { get; set; } = default!;
+ public List> AddProperties { get; set; } = default!;
+
+ ///
+ /// 属性映射
+ ///
+ public Dictionary AddPropertyMap
+ {
+ get => addPropertyMap ??= AddProperties.ToDictionary(a => a.Type, a => a.Value);
+ }
}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Reliquary/Reliquary.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Reliquary/Reliquary.cs
index 4bb61753..5a2fa5ff 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Reliquary/Reliquary.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Reliquary/Reliquary.cs
@@ -20,7 +20,7 @@ internal sealed class Reliquary
///
/// 允许出现的等级
///
- public ItemQuality RankLevel { get; set; } = default!;
+ public QualityType RankLevel { get; set; } = default!;
///
/// 套装Id
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Reliquary/ReliquaryAffixWeight.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Reliquary/ReliquaryAffixWeight.cs
new file mode 100644
index 00000000..f1212ee9
--- /dev/null
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Reliquary/ReliquaryAffixWeight.cs
@@ -0,0 +1,109 @@
+// Copyright (c) DGP Studio. All rights reserved.
+// Licensed under the MIT license.
+
+using Snap.Hutao.Model.Intrinsic;
+using Snap.Hutao.Model.Primitive;
+
+namespace Snap.Hutao.Model.Metadata.Reliquary;
+
+///
+/// 圣遗物词条权重
+///
+internal sealed class ReliquaryAffixWeight
+{
+ ///
+ /// 角色 Id
+ ///
+ public AvatarId AvatarId { get; set; }
+
+ ///
+ /// 生命值
+ ///
+ public float HpPercent { get; set; }
+
+ ///
+ /// 攻击力
+ ///
+ public float AttackPercent { get; set; }
+
+ ///
+ /// 防御力
+ ///
+ public float DefensePercent { get; set; }
+
+ ///
+ /// 暴击率
+ ///
+ public float Critical { get; set; }
+
+ ///
+ /// 暴击伤害
+ ///
+ public float CriticalHurt { get; set; }
+
+ ///
+ /// 元素精通
+ ///
+ public float ElementMastery { get; set; }
+
+ ///
+ /// 元素充能效率
+ ///
+ public float ChargeEfficiency { get; set; }
+
+ ///
+ /// 治疗加成
+ ///
+ public float HealAdd { get; set; }
+
+ ///
+ /// 物理伤害加成
+ ///
+ public float PhysicalAddHurt { get; set; }
+
+ ///
+ /// 伤害加成
+ ///
+ public float AddHurt { get; set; }
+
+ ///
+ /// 元素类型
+ ///
+ public ElementType ElementType { get; set; }
+
+ ///
+ /// 获取权重
+ ///
+ /// 属性
+ /// 权重
+ public float this[FightProperty fightProperty]
+ {
+ get
+ {
+ if ((ElementType == ElementType.Fire && fightProperty == FightProperty.FIGHT_PROP_FIRE_ADD_HURT) ||
+ (ElementType == ElementType.Water && fightProperty == FightProperty.FIGHT_PROP_WATER_ADD_HURT) ||
+ (ElementType == ElementType.Grass && fightProperty == FightProperty.FIGHT_PROP_GRASS_ADD_HURT) ||
+ (ElementType == ElementType.Electric && fightProperty == FightProperty.FIGHT_PROP_ELEC_ADD_HURT) ||
+ (ElementType == ElementType.Ice && fightProperty == FightProperty.FIGHT_PROP_ICE_ADD_HURT) ||
+ (ElementType == ElementType.Wind && fightProperty == FightProperty.FIGHT_PROP_WIND_ADD_HURT) ||
+ (ElementType == ElementType.Rock && fightProperty == FightProperty.FIGHT_PROP_ROCK_ADD_HURT))
+ {
+ return AddHurt;
+ }
+
+ return fightProperty switch
+ {
+ FightProperty.FIGHT_PROP_HP_PERCENT => HpPercent,
+ FightProperty.FIGHT_PROP_ATTACK_PERCENT => AttackPercent,
+ FightProperty.FIGHT_PROP_DEFENSE_PERCENT => DefensePercent,
+ FightProperty.FIGHT_PROP_CRITICAL => Critical,
+ FightProperty.FIGHT_PROP_CRITICAL_HURT => CriticalHurt,
+ FightProperty.FIGHT_PROP_ELEMENT_MASTERY => ElementMastery,
+ FightProperty.FIGHT_PROP_CHARGE_EFFICIENCY => ChargeEfficiency,
+ FightProperty.FIGHT_PROP_HEALED_ADD => HealAdd,
+ FightProperty.FIGHT_PROP_PHYSICAL_ADD_HURT => PhysicalAddHurt,
+ _ => 0,
+ };
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Reliquary/ReliquaryMainAffixLevel.PropertyMap.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Reliquary/ReliquaryMainAffixLevel.PropertyMap.cs
new file mode 100644
index 00000000..342b312a
--- /dev/null
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Reliquary/ReliquaryMainAffixLevel.PropertyMap.cs
@@ -0,0 +1,22 @@
+// Copyright (c) DGP Studio. All rights reserved.
+// Licensed under the MIT license.
+
+using Snap.Hutao.Model.Intrinsic;
+
+namespace Snap.Hutao.Model.Metadata.Reliquary;
+
+///
+/// 属性映射
+///
+internal sealed partial class ReliquaryMainAffixLevel
+{
+ private Dictionary? propertyMap;
+
+ ///
+ /// 属性映射
+ ///
+ public Dictionary PropertyMap
+ {
+ get => propertyMap ??= Properties.ToDictionary(t => t.Type, t => t.Value);
+ }
+}
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Reliquary/ReliquaryLevel.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Reliquary/ReliquaryMainAffixLevel.cs
similarity index 64%
rename from src/Snap.Hutao/Snap.Hutao/Model/Metadata/Reliquary/ReliquaryLevel.cs
rename to src/Snap.Hutao/Snap.Hutao/Model/Metadata/Reliquary/ReliquaryMainAffixLevel.cs
index 740fece8..3523ca04 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Reliquary/ReliquaryLevel.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Reliquary/ReliquaryMainAffixLevel.cs
@@ -9,20 +9,20 @@ namespace Snap.Hutao.Model.Metadata.Reliquary;
/// 圣遗物等级
///
[HighQuality]
-internal sealed class ReliquaryLevel
+internal sealed partial class ReliquaryMainAffixLevel
{
///
/// 品质
///
- public ItemQuality Quality { get; set; }
+ public QualityType Rank { get; set; }
///
/// 等级 1-21
///
- public int Level { get; set; }
+ public uint Level { get; set; }
///
/// 属性
///
- public Dictionary Properties { get; set; } = default!;
+ public List> Properties { get; set; } = default!;
}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Reliquary/ReliquarySet.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Reliquary/ReliquarySet.cs
index 07a01baa..3398e9b4 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Reliquary/ReliquarySet.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Reliquary/ReliquarySet.cs
@@ -14,7 +14,7 @@ internal sealed class ReliquarySet
///
/// 套装Id
///
- public int SetId { get; set; }
+ public ReliquarySetId SetId { get; set; }
///
/// 装备被动Id
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Reliquary/ReliquaryAffix.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Reliquary/ReliquarySubAffix.cs
similarity index 77%
rename from src/Snap.Hutao/Snap.Hutao/Model/Metadata/Reliquary/ReliquaryAffix.cs
rename to src/Snap.Hutao/Snap.Hutao/Model/Metadata/Reliquary/ReliquarySubAffix.cs
index 34c1bb2c..a76eb698 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Reliquary/ReliquaryAffix.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Reliquary/ReliquarySubAffix.cs
@@ -9,12 +9,12 @@ namespace Snap.Hutao.Model.Metadata.Reliquary;
/// 圣遗物突破属性
///
[HighQuality]
-internal sealed class ReliquaryAffix : ReliquaryMainAffix
+internal sealed class ReliquarySubAffix : ReliquaryMainAffix
{
///
/// Id
///
- public new ReliquaryAffixId Id { get; set; }
+ public new ReliquarySubAffixId Id { get; set; }
///
/// 值
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Tower/TowerFloor.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Tower/TowerFloor.cs
new file mode 100644
index 00000000..4fc7f280
--- /dev/null
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Tower/TowerFloor.cs
@@ -0,0 +1,32 @@
+// Copyright (c) DGP Studio. All rights reserved.
+// Licensed under the MIT license.
+
+using Snap.Hutao.Model.Primitive;
+
+namespace Snap.Hutao.Model.Metadata.Tower;
+
+///
+/// 深渊 层
+///
+internal sealed class TowerFloor
+{
+ ///
+ /// Id
+ ///
+ public TowerFloorId Id { get; set; }
+
+ ///
+ /// 编号 [1-12]
+ ///
+ public uint Index { get; set; }
+
+ ///
+ /// 深渊间分组编号
+ ///
+ public TowerLevelGroupId LevelGroupId { get; set; }
+
+ ///
+ /// 背景图片
+ ///
+ public string Background { get; set; } = default!;
+}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Tower/TowerLevel.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Tower/TowerLevel.cs
new file mode 100644
index 00000000..0848167f
--- /dev/null
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Tower/TowerLevel.cs
@@ -0,0 +1,42 @@
+// Copyright (c) DGP Studio. All rights reserved.
+// Licensed under the MIT license.
+
+using Snap.Hutao.Model.Primitive;
+
+namespace Snap.Hutao.Model.Metadata.Tower;
+
+///
+/// 深渊 间
+///
+internal sealed class TowerLevel
+{
+ ///
+ /// Id
+ ///
+ public TowerLevelId Id { get; set; }
+
+ ///
+ /// 深渊间分组编号
+ ///
+ public TowerLevelGroupId GroupId { get; set; }
+
+ ///
+ /// 编号
+ ///
+ public uint Index { get; set; }
+
+ ///
+ /// 怪物等级
+ ///
+ public uint MonsterLevel { get; set; }
+
+ ///
+ /// 上半怪物预览
+ ///
+ public List FirstMonsters { get; set; } = default!;
+
+ ///
+ /// 下半怪物预览
+ ///
+ public List SecondMonsters { get; set; } = default!;
+}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Tower/TowerSchedule.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Tower/TowerSchedule.cs
new file mode 100644
index 00000000..c6b95efd
--- /dev/null
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Tower/TowerSchedule.cs
@@ -0,0 +1,47 @@
+// Copyright (c) DGP Studio. All rights reserved.
+// Licensed under the MIT license.
+
+using Snap.Hutao.Model.Primitive;
+
+namespace Snap.Hutao.Model.Metadata.Tower;
+
+///
+/// 深渊 计划
+///
+internal sealed class TowerSchedule
+{
+ ///
+ /// 计划 Id
+ ///
+ public TowerScheduleId Id { get; set; }
+
+ ///
+ /// 层 Id 表
+ ///
+ public List FloorIds { get; set; } = default!;
+
+ ///
+ /// 开始时间
+ ///
+ public DateTimeOffset Open { get; set; }
+
+ ///
+ /// 结束时间
+ ///
+ public DateTimeOffset Close { get; set; }
+
+ ///
+ /// 渊月祝福
+ ///
+ public string BuffName { get; set; } = default!;
+
+ ///
+ /// 描述
+ ///
+ public List Descriptions { get; set; } = default!;
+
+ ///
+ /// 图标
+ ///
+ public string Icon { get; set; } = default!;
+}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/TypeValue.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/TypeValue.cs
new file mode 100644
index 00000000..5ed06b0b
--- /dev/null
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/TypeValue.cs
@@ -0,0 +1,33 @@
+// Copyright (c) DGP Studio. All rights reserved.
+// Licensed under the MIT license.
+
+namespace Snap.Hutao.Model.Metadata;
+
+///
+/// 类型与值
+///
+/// 类型
+/// 值
+internal class TypeValue
+{
+ ///
+ /// 构造一个新的类型与值
+ ///
+ /// 类型
+ /// 值
+ public TypeValue(TType type, TValue value)
+ {
+ Type = type;
+ Value = value;
+ }
+
+ ///
+ /// 类型
+ ///
+ public TType Type { get; set; }
+
+ ///
+ /// 值
+ ///
+ public TValue Value { get; set; }
+}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Weapon/GrowCurveTypeValue.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Weapon/GrowCurveTypeValue.cs
deleted file mode 100644
index aba413a2..00000000
--- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Weapon/GrowCurveTypeValue.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) DGP Studio. All rights reserved.
-// Licensed under the MIT license.
-
-using Snap.Hutao.Model.Intrinsic;
-
-namespace Snap.Hutao.Model.Metadata.Weapon;
-
-///
-/// 生长曲线与值
-///
-[HighQuality]
-internal sealed class GrowCurveTypeValue
-{
- ///
- /// 类型
- ///
- public GrowCurveType Type { get; set; }
-
- ///
- /// 值
- ///
- public float Value { get; set; }
-}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Weapon/Weapon.Implementation.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Weapon/Weapon.Implementation.cs
index 500fb366..87b1b1e3 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Weapon/Weapon.Implementation.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Weapon/Weapon.Implementation.cs
@@ -23,7 +23,7 @@ internal sealed partial class Weapon : IStatisticsItemSource, ISummaryItemSource
///
[JsonIgnore]
- public ItemQuality Quality
+ public QualityType Quality
{
get => RankLevel;
}
@@ -31,7 +31,7 @@ internal sealed partial class Weapon : IStatisticsItemSource, ISummaryItemSource
///
/// 最大等级
///
- internal int MaxLevel { get => ((int)Quality) >= 3 ? 90 : 70; }
+ internal uint MaxLevel { get => ((int)Quality) >= 3 ? 90U : 70U; }
///
public ICalculableWeapon ToCalculable()
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Weapon/Weapon.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Weapon/Weapon.cs
index 19b0d9b1..01cc7e55 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Weapon/Weapon.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Weapon/Weapon.cs
@@ -30,7 +30,7 @@ internal sealed partial class Weapon
///
/// 等级
///
- public ItemQuality RankLevel { get; set; }
+ public QualityType RankLevel { get; set; }
///
/// 名称
@@ -55,7 +55,7 @@ internal sealed partial class Weapon
///
/// 生长曲线
///
- public Dictionary GrowCurves { get; set; } = default!;
+ public List GrowCurves { get; set; } = default!;
///
/// 被动信息, 无被动的武器为
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Weapon/WeaponTypeValue.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Weapon/WeaponTypeValue.cs
new file mode 100644
index 00000000..902c2f1d
--- /dev/null
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Weapon/WeaponTypeValue.cs
@@ -0,0 +1,29 @@
+// Copyright (c) DGP Studio. All rights reserved.
+// Licensed under the MIT license.
+
+using Snap.Hutao.Model.Intrinsic;
+
+namespace Snap.Hutao.Model.Metadata.Weapon;
+
+///
+/// 武器曲线值
+///
+internal sealed class WeaponTypeValue : TypeValue
+{
+ ///
+ /// 构造一个新的武器曲线值
+ ///
+ /// 属性类型
+ /// 曲线类型
+ /// 初始值
+ public WeaponTypeValue(FightProperty type, GrowCurveType value, float initValue)
+ : base(type, value)
+ {
+ InitValue = initValue;
+ }
+
+ ///
+ /// 初始值
+ ///
+ public float InitValue { get; set; }
+}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Primitive/Converter/IdentityConverter.cs b/src/Snap.Hutao/Snap.Hutao/Model/Primitive/Converter/IdentityConverter.cs
new file mode 100644
index 00000000..579be071
--- /dev/null
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Primitive/Converter/IdentityConverter.cs
@@ -0,0 +1,46 @@
+// Copyright (c) DGP Studio. All rights reserved.
+// Licensed under the MIT license.
+
+using System.Text.Json.Serialization.Metadata;
+
+namespace Snap.Hutao.Model.Primitive.Converter;
+
+///
+/// Id 转换器
+///
+/// 包装类型
+internal unsafe sealed class IdentityConverter : JsonConverter
+ where TWrapper : unmanaged
+{
+ ///
+ public override TWrapper Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ uint value = JsonSerializer.Deserialize(ref reader, options);
+ return *(TWrapper*)&value;
+ }
+
+ ///
+ public override TWrapper ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ if (reader.TokenType == JsonTokenType.PropertyName)
+ {
+ string? value = reader.GetString();
+ _ = uint.TryParse(value,out uint result);
+ return *(TWrapper*)&result;
+ }
+
+ throw new JsonException();
+ }
+
+ ///
+ public override void Write(Utf8JsonWriter writer, TWrapper value, JsonSerializerOptions options)
+ {
+ JsonSerializer.Serialize(writer, *(uint*)&value, options);
+ }
+
+ ///
+ public override void WriteAsPropertyName(Utf8JsonWriter writer, TWrapper value, JsonSerializerOptions options)
+ {
+ writer.WritePropertyName((*(uint*)&value).ToString());
+ }
+}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Achievement/AchievementService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Achievement/AchievementService.cs
index c3aea34c..9b42a5b7 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/Achievement/AchievementService.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/Achievement/AchievementService.cs
@@ -34,7 +34,7 @@ internal sealed partial class AchievementService : IAchievementService
///
public List GetAchievements(AchievementArchive archive, List metadata)
{
- Dictionary entityMap;
+ Dictionary entityMap;
try
{
using (IServiceScope scope = serviceProvider.CreateScope())
@@ -43,7 +43,7 @@ internal sealed partial class AchievementService : IAchievementService
entityMap = appDbContext.Achievements
.Where(a => a.ArchiveId == archive.InnerId)
.AsEnumerable()
- .ToDictionary(a => a.Id);
+ .ToDictionary(a => (AchievementId)a.Id);
}
}
catch (ArgumentException ex)
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/AvatarInfoDbBulkOperation.cs b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/AvatarInfoDbBulkOperation.cs
index ffd9e1ba..6a438af7 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/AvatarInfoDbBulkOperation.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/AvatarInfoDbBulkOperation.cs
@@ -4,6 +4,7 @@
using Snap.Hutao.Core.Database;
using Snap.Hutao.Model.Entity.Database;
using Snap.Hutao.Model.Metadata;
+using Snap.Hutao.Model.Primitive;
using Snap.Hutao.Service.AvatarInfo.Transformer;
using Snap.Hutao.Service.Metadata;
using Snap.Hutao.ViewModel.User;
@@ -202,7 +203,7 @@ internal sealed partial class AvatarInfoDbBulkOperation
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static void AddOrUpdateAvatarInfo(ModelAvatarInfo? entity, int avatarId, string uid, AppDbContext appDbContext, IAvatarInfoTransformer transformer, TSource source)
+ private static void AddOrUpdateAvatarInfo(ModelAvatarInfo? entity, AvatarId avatarId, string uid, AppDbContext appDbContext, IAvatarInfoTransformer transformer, TSource source)
{
if (entity == null)
{
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/AffixWeight.cs b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/AffixWeight.cs
index f6f6476c..66904676 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/AffixWeight.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/AffixWeight.cs
@@ -26,7 +26,7 @@ internal sealed class AffixWeight : Dictionary
/// 治疗加成
/// 名称
public AffixWeight(
- int avatarId,
+ uint avatarId,
float hp,
float atk,
float def,
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/SummaryAvatarFactory.cs b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/SummaryAvatarFactory.cs
index 74fb2401..856c6b6d 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/SummaryAvatarFactory.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/SummaryAvatarFactory.cs
@@ -2,6 +2,7 @@
// Licensed under the MIT license.
using Snap.Hutao.Model.Intrinsic;
+using Snap.Hutao.Model.Primitive;
using Snap.Hutao.Model.Metadata.Converter;
using Snap.Hutao.ViewModel.AvatarProperty;
using Snap.Hutao.Web.Enka.Model;
@@ -79,7 +80,7 @@ internal sealed class SummaryAvatarFactory
Model.Metadata.Avatar.Costume costume = avatar.Costumes.Single(c => c.Id == avatarInfo.CostumeId.Value);
// Set to costume icon
- propertyAvatar.Icon = AvatarIconConverter.IconNameToUri(costume.Icon);
+ propertyAvatar.Icon = AvatarIconConverter.IconNameToUri(costume.FrontIcon);
propertyAvatar.SideIcon = AvatarIconConverter.IconNameToUri(costume.SideIcon);
}
else
@@ -116,9 +117,9 @@ internal sealed class SummaryAvatarFactory
{
MetadataWeapon weapon = metadataContext.IdWeaponMap[equip.ItemId];
- // AffixMap can be empty when it's a white weapon.
- KeyValuePair? idLevel = equip.Weapon!.AffixMap?.Single();
- int affixLevel = idLevel?.Value ?? 0;
+ // AffixMap can be null when it's a white weapon.
+ KeyValuePair? idLevel = equip.Weapon!.AffixMap?.Single();
+ uint affixLevel = idLevel?.Value ?? 0U;
WeaponStat? mainStat = equip.Flat.WeaponStats?.ElementAtOrDefault(0);
WeaponStat? subStat = equip.Flat.WeaponStats?.ElementAtOrDefault(1);
@@ -145,7 +146,7 @@ internal sealed class SummaryAvatarFactory
Description = weapon.Description,
// EquipBase
- Level = $"Lv.{equip.Weapon!.Level}",
+ Level = $"Lv.{equip.Weapon!.Level.Value}",
Quality = weapon.Quality,
MainProperty = mainStat != null ? FightPropertyFormat.ToNameValue(mainStat.AppendPropId, mainStat.StatValue) : default!,
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/SummaryFactory.cs b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/SummaryFactory.cs
index ed0324c0..c06ed801 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/SummaryFactory.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/SummaryFactory.cs
@@ -26,7 +26,7 @@ internal sealed partial class SummaryFactory : ISummaryFactory
IdAvatarMap = await metadataService.GetIdToAvatarMapAsync(token).ConfigureAwait(false),
IdWeaponMap = await metadataService.GetIdToWeaponMapAsync(token).ConfigureAwait(false),
IdRelicMainPropMap = await metadataService.GetIdToReliquaryMainPropertyMapAsync(token).ConfigureAwait(false),
- IdReliquaryAffixMap = await metadataService.GetIdToReliquaryAffixMapAsync(token).ConfigureAwait(false),
+ IdReliquarySubAffixMap = await metadataService.GetIdToReliquarySubAffixMapAsync(token).ConfigureAwait(false),
ReliqueryLevels = await metadataService.GetReliquaryLevelsAsync(token).ConfigureAwait(false),
Reliquaries = await metadataService.GetReliquariesAsync(token).ConfigureAwait(false),
};
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/SummaryHelper.cs b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/SummaryHelper.cs
index 8c254c99..e8f6906c 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/SummaryHelper.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/SummaryHelper.cs
@@ -39,29 +39,26 @@ internal static class SummaryHelper
/// 额外提升等级映射
/// 技能列表
/// 技能
- public static List CreateSkills(Dictionary skillLevelMap, Dictionary? proudSkillExtraLevelMap, List proudSkills)
+ public static List CreateSkills(Dictionary skillLevelMap, Dictionary? proudSkillExtraLevelMap, List proudSkills)
{
if (skillLevelMap == null)
{
return new();
}
- Dictionary skillExtraLeveledMap = new(skillLevelMap);
+ Dictionary skillExtraLeveledMap = new(skillLevelMap);
if (proudSkillExtraLevelMap != null)
{
- foreach ((string skillGroupIdString, int extraLevel) in proudSkillExtraLevelMap)
+ foreach ((SkillGroupId groupId, SkillLevel extraLevel) in proudSkillExtraLevelMap)
{
- SkillGroupId skillGroupId = int.Parse(skillGroupIdString);
- SkillId skillId = proudSkills.Single(p => p.GroupId == skillGroupId).Id;
-
- skillExtraLeveledMap.Increase($"{skillId.Value}", extraLevel);
+ skillExtraLeveledMap.IncreaseValue(proudSkills.Single(p => p.GroupId == groupId).Id, extraLevel);
}
}
return proudSkills.SelectList(proudableSkill =>
{
- string skillId = $"{proudableSkill.Id.Value}";
+ SkillId skillId = proudableSkill.Id;
return new SkillView()
{
@@ -81,10 +78,10 @@ internal static class SummaryHelper
///
/// 属性Id
/// 最大属性Id
- public static int GetAffixMaxId(int appendId)
+ public static ReliquarySubAffixId GetAffixMaxId(in ReliquarySubAffixId appendId)
{
- int value = appendId / 100000;
- int max = value switch
+ uint value = (uint)appendId / 100000U;
+ uint max = value switch
{
1 => 2,
2 => 3,
@@ -100,10 +97,10 @@ internal static class SummaryHelper
///
/// id
/// 分数
- public static float GetPercentSubAffixScore(int appendId)
+ public static float GetPercentSubAffixScore(ReliquarySubAffixId appendId)
{
- int maxId = GetAffixMaxId(appendId);
- int delta = maxId - appendId;
+ uint maxId = GetAffixMaxId(appendId);
+ uint delta = maxId - appendId;
return (maxId / 100000, delta) switch
{
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/SummaryMetadataContext.cs b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/SummaryMetadataContext.cs
index 9cbab40d..612c3448 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/SummaryMetadataContext.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/SummaryMetadataContext.cs
@@ -34,12 +34,12 @@ internal sealed class SummaryMetadataContext
///
/// 圣遗物副属性映射
///
- public Dictionary IdReliquaryAffixMap { get; set; } = default!;
+ public Dictionary IdReliquarySubAffixMap { get; set; } = default!;
///
/// 圣遗物等级
///
- public List ReliqueryLevels { get; set; } = default!;
+ public List ReliqueryLevels { get; set; } = default!;
///
/// 圣遗物
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/SummaryReliquaryFactory.cs b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/SummaryReliquaryFactory.cs
index 06c851c6..90c248bc 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/SummaryReliquaryFactory.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/SummaryReliquaryFactory.cs
@@ -5,11 +5,12 @@ using Snap.Hutao.Model.Intrinsic;
using Snap.Hutao.Model.Intrinsic.Format;
using Snap.Hutao.Model.Metadata.Converter;
using Snap.Hutao.Model.Metadata.Reliquary;
+using Snap.Hutao.Model.Primitive;
using Snap.Hutao.ViewModel.AvatarProperty;
using Snap.Hutao.Web.Enka.Model;
using System.Runtime.InteropServices;
using MetadataReliquary = Snap.Hutao.Model.Metadata.Reliquary.Reliquary;
-using MetadataReliquaryAffix = Snap.Hutao.Model.Metadata.Reliquary.ReliquaryAffix;
+using MetadataReliquaryAffix = Snap.Hutao.Model.Metadata.Reliquary.ReliquarySubAffix;
using ModelAvatarInfo = Snap.Hutao.Web.Enka.Model.AvatarInfo;
using PropertyReliquary = Snap.Hutao.ViewModel.AvatarProperty.ReliquaryView;
@@ -67,11 +68,10 @@ internal sealed class SummaryReliquaryFactory
result.PrimarySubProperties = new(span[..^affixCount].ToArray());
result.SecondarySubProperties = new(span[^affixCount..].ToArray());
result.ComposedSubProperties = equip.Flat.ReliquarySubstats!.SelectList(CreateComposedSubProperty);
-
- ReliquaryLevel relicLevel = metadataContext.ReliqueryLevels.Single(r => r.Level == equip.Reliquary!.Level && r.Quality == reliquary.RankLevel);
+ ReliquaryMainAffixLevel relicLevel = metadataContext.ReliqueryLevels.Single(r => r.Level == equip.Reliquary!.Level && r.Rank == reliquary.RankLevel);
FightProperty property = metadataContext.IdRelicMainPropMap[equip.Reliquary.MainPropId];
- result.MainProperty = FightPropertyFormat.ToNameValue(property, relicLevel.Properties[property]);
+ result.MainProperty = FightPropertyFormat.ToNameValue(property, relicLevel.PropertyMap[property]);
result.Score = ScoreReliquary(property, reliquary, relicLevel, subProperty);
}
@@ -81,46 +81,46 @@ internal sealed class SummaryReliquaryFactory
private int GetSecondaryAffixCount(MetadataReliquary reliquary)
{
// 强化词条个数
- return (reliquary.RankLevel, equip.Reliquary!.Level) switch
+ return (reliquary.RankLevel, equip.Reliquary!.Level.Value) switch
{
- (ItemQuality.QUALITY_ORANGE, > 20) => 5,
- (ItemQuality.QUALITY_ORANGE, > 16) => 4,
- (ItemQuality.QUALITY_ORANGE, > 12) => 3,
- (ItemQuality.QUALITY_ORANGE, > 8) => 2,
- (ItemQuality.QUALITY_ORANGE, > 4) => 1,
- (ItemQuality.QUALITY_ORANGE, _) => 0,
+ (QualityType.QUALITY_ORANGE, > 20U) => 5,
+ (QualityType.QUALITY_ORANGE, > 16U) => 4,
+ (QualityType.QUALITY_ORANGE, > 12U) => 3,
+ (QualityType.QUALITY_ORANGE, > 8U) => 2,
+ (QualityType.QUALITY_ORANGE, > 4U) => 1,
+ (QualityType.QUALITY_ORANGE, _) => 0,
- (ItemQuality.QUALITY_PURPLE, > 16) => 4,
- (ItemQuality.QUALITY_PURPLE, > 12) => 3,
- (ItemQuality.QUALITY_PURPLE, > 8) => 2,
- (ItemQuality.QUALITY_PURPLE, > 4) => 1,
- (ItemQuality.QUALITY_PURPLE, _) => 0,
+ (QualityType.QUALITY_PURPLE, > 16U) => 4,
+ (QualityType.QUALITY_PURPLE, > 12U) => 3,
+ (QualityType.QUALITY_PURPLE, > 8U) => 2,
+ (QualityType.QUALITY_PURPLE, > 4U) => 1,
+ (QualityType.QUALITY_PURPLE, _) => 0,
- (ItemQuality.QUALITY_BLUE, > 12) => 3,
- (ItemQuality.QUALITY_BLUE, > 8) => 2,
- (ItemQuality.QUALITY_BLUE, > 4) => 1,
- (ItemQuality.QUALITY_BLUE, _) => 0,
+ (QualityType.QUALITY_BLUE, > 12U) => 3,
+ (QualityType.QUALITY_BLUE, > 8U) => 2,
+ (QualityType.QUALITY_BLUE, > 4U) => 1,
+ (QualityType.QUALITY_BLUE, _) => 0,
- (ItemQuality.QUALITY_GREEN, > 4) => 1,
- (ItemQuality.QUALITY_GREEN, _) => 0,
+ (QualityType.QUALITY_GREEN, > 4U) => 1,
+ (QualityType.QUALITY_GREEN, _) => 0,
- (ItemQuality.QUALITY_WHITE, > 4) => 1,
- (ItemQuality.QUALITY_WHITE, _) => 0,
+ (QualityType.QUALITY_WHITE, > 4U) => 1,
+ (QualityType.QUALITY_WHITE, _) => 0,
_ => 0,
};
}
- private float ScoreReliquary(FightProperty property, MetadataReliquary reliquary, ReliquaryLevel relicLevel, List subProperties)
+ private float ScoreReliquary(FightProperty property, MetadataReliquary reliquary, ReliquaryMainAffixLevel relicLevel, List subProperties)
{
// 沙 杯 头
// equip.Flat.EquipType is EquipType.EQUIP_SHOES or EquipType.EQUIP_RING or EquipType.EQUIP_DRESS
if ((int)equip.Flat.EquipType > 3)
{
AffixWeight weightConfig = GetAffixWeightForAvatarId();
- ReliquaryLevel maxRelicLevel = metadataContext.ReliqueryLevels.Where(r => r.Quality == reliquary.RankLevel).MaxBy(r => r.Level)!;
+ ReliquaryMainAffixLevel maxRelicLevel = metadataContext.ReliqueryLevels.Where(r => r.Rank == reliquary.RankLevel).MaxBy(r => r.Level)!;
- float percent = relicLevel.Properties[property] / maxRelicLevel.Properties[property];
+ float percent = relicLevel.PropertyMap[property] / maxRelicLevel.PropertyMap[property];
float baseScore = 8 * percent * weightConfig.GetValueOrDefault(property);
float score = subProperties.Sum(p => p.Score);
@@ -151,9 +151,10 @@ internal sealed class SummaryReliquaryFactory
return new(substat.AppendPropId.GetLocalizedDescription(), valueFormatted, 0);
}
- private ReliquarySubProperty CreateSubProperty(int appendPropId)
+ [SuppressMessage("", "SH002")]
+ private ReliquarySubProperty CreateSubProperty(ReliquarySubAffixId appendPropId)
{
- MetadataReliquaryAffix affix = metadataContext.IdReliquaryAffixMap[appendPropId];
+ MetadataReliquaryAffix affix = metadataContext.IdReliquarySubAffixMap[appendPropId];
FightProperty property = affix.Type;
return new(
@@ -162,9 +163,9 @@ internal sealed class SummaryReliquaryFactory
ScoreSubAffix(appendPropId));
}
- private float ScoreSubAffix(int appendId)
+ private float ScoreSubAffix(in ReliquarySubAffixId appendId)
{
- MetadataReliquaryAffix affix = metadataContext.IdReliquaryAffixMap[appendId];
+ MetadataReliquaryAffix affix = metadataContext.IdReliquarySubAffixMap[appendId];
AffixWeight weightConfig = GetAffixWeightForAvatarId();
float weight = weightConfig.GetValueOrDefault(affix.Type) / 100F;
@@ -179,7 +180,7 @@ internal sealed class SummaryReliquaryFactory
weight = weightConfig.GetValueOrDefault(affix.Type + 1) / 100F;
// 最大同属性百分比数值 最大同属性百分比Id 第四五位是战斗属性位
- MetadataReliquaryAffix maxPercentAffix = metadataContext.IdReliquaryAffixMap[SummaryHelper.GetAffixMaxId(appendId + 10)];
+ MetadataReliquaryAffix maxPercentAffix = metadataContext.IdReliquarySubAffixMap[SummaryHelper.GetAffixMaxId(appendId + 10U)];
float equalScore = equalPercent / maxPercentAffix.Value;
return weight * equalScore * 100;
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Transformer/CalculateAvatarDetailAvatarInfoTransformer.cs b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Transformer/CalculateAvatarDetailAvatarInfoTransformer.cs
index 1041ad72..493c7fc8 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Transformer/CalculateAvatarDetailAvatarInfoTransformer.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Transformer/CalculateAvatarDetailAvatarInfoTransformer.cs
@@ -1,6 +1,7 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
+using Snap.Hutao.Model.Primitive;
using Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate;
namespace Snap.Hutao.Service.AvatarInfo.Transformer;
@@ -16,6 +17,6 @@ internal sealed class CalculateAvatarDetailAvatarInfoTransformer : IAvatarInfoTr
public void Transform(ref Web.Enka.Model.AvatarInfo avatarInfo, AvatarDetail source)
{
// update skills
- avatarInfo.SkillLevelMap = source.SkillList.ToDictionary(s => $"{s.Id}", s => s.LevelCurrent);
+ avatarInfo.SkillLevelMap = source.SkillList.ToDictionary(s => (SkillId)s.Id, s => (SkillLevel)s.LevelCurrent);
}
}
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Transformer/GameRecordCharacterAvatarInfoTransformer.cs b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Transformer/GameRecordCharacterAvatarInfoTransformer.cs
index ac493b69..be4cdb66 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Transformer/GameRecordCharacterAvatarInfoTransformer.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Transformer/GameRecordCharacterAvatarInfoTransformer.cs
@@ -57,7 +57,10 @@ internal sealed class GameRecordCharacterAvatarInfoTransformer : IAvatarInfoTran
equip.Weapon = new()
{
Level = source.Weapon.Level,
- AffixMap = new() { { $"1{source.Weapon.Id}", source.Weapon.AffixLevel - 1 }, },
+ AffixMap = new()
+ {
+ [100000 + source.Weapon.Id] = source.Weapon.AffixLevel - 1,
+ },
};
// Special case here, don't set EQUIP_WEAPON
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationService.cs
index 977c3dad..96dd6742 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationService.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationService.cs
@@ -186,7 +186,7 @@ internal sealed partial class CultivationService : ICultivationService
}
///
- public async Task SaveConsumptionAsync(CultivateType type, int itemId, List items)
+ public async Task SaveConsumptionAsync(CultivateType type, uint itemId, List items)
{
if (items.Count == 0)
{
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/ICultivationService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/ICultivationService.cs
index d0c4f0cc..8ce4e53e 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/ICultivationService.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/ICultivationService.cs
@@ -71,7 +71,7 @@ internal interface ICultivationService
/// 主Id
/// 待存物品
/// 是否保存成功
- Task SaveConsumptionAsync(CultivateType type, int itemId, List- items);
+ Task SaveConsumptionAsync(CultivateType type, uint itemId, List
- items);
///
/// 保存养成物品状态
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaStatisticsFactory.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaStatisticsFactory.cs
index 96e6cee3..273800cc 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaStatisticsFactory.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaStatisticsFactory.cs
@@ -60,19 +60,19 @@ internal sealed partial class GachaStatisticsFactory : IGachaStatisticsFactory
// It's an avatar
switch (item.ItemId.Place())
{
- case 8:
+ case 8U:
{
Avatar avatar = context.IdAvatarMap[item.ItemId];
bool isUp = false;
switch (avatar.Quality)
{
- case ItemQuality.QUALITY_ORANGE:
- orangeAvatarCounter.Increase(avatar);
+ case QualityType.QUALITY_ORANGE:
+ orangeAvatarCounter.IncreaseOne(avatar);
isUp = targetHistoryWishBuilder?.IncreaseOrange(avatar) ?? false;
break;
- case ItemQuality.QUALITY_PURPLE:
- purpleAvatarCounter.Increase(avatar);
+ case QualityType.QUALITY_PURPLE:
+ purpleAvatarCounter.IncreaseOne(avatar);
targetHistoryWishBuilder?.IncreasePurple(avatar);
break;
}
@@ -83,24 +83,24 @@ internal sealed partial class GachaStatisticsFactory : IGachaStatisticsFactory
break;
}
- case 5:
+ case 5U:
{
Weapon weapon = context.IdWeaponMap[item.ItemId];
bool isUp = false;
switch (weapon.RankLevel)
{
- case ItemQuality.QUALITY_ORANGE:
+ case QualityType.QUALITY_ORANGE:
isUp = targetHistoryWishBuilder?.IncreaseOrange(weapon) ?? false;
- orangeWeaponCounter.Increase(weapon);
+ orangeWeaponCounter.IncreaseOne(weapon);
break;
- case ItemQuality.QUALITY_PURPLE:
+ case QualityType.QUALITY_PURPLE:
targetHistoryWishBuilder?.IncreasePurple(weapon);
- purpleWeaponCounter.Increase(weapon);
+ purpleWeaponCounter.IncreaseOne(weapon);
break;
- case ItemQuality.QUALITY_BLUE:
+ case QualityType.QUALITY_BLUE:
targetHistoryWishBuilder?.IncreaseBlue(weapon);
- blueWeaponCounter.Increase(weapon);
+ blueWeaponCounter.IncreaseOne(weapon);
break;
}
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaStatisticsSlimFactory.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaStatisticsSlimFactory.cs
index 04c35179..e306f135 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaStatisticsSlimFactory.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaStatisticsSlimFactory.cs
@@ -73,15 +73,15 @@ internal sealed partial class GachaStatisticsSlimFactory : IGachaStatisticsSlimF
{
switch (nameQuality.Quality)
{
- case ItemQuality.QUALITY_ORANGE:
+ case QualityType.QUALITY_ORANGE:
orangeTracker = 0;
++purpleTracker;
break;
- case ItemQuality.QUALITY_PURPLE:
+ case QualityType.QUALITY_PURPLE:
++orangeTracker;
purpleTracker = 0;
break;
- case ItemQuality.QUALITY_BLUE:
+ case QualityType.QUALITY_BLUE:
++orangeTracker;
++purpleTracker;
break;
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/HistoryWishBuilder.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/HistoryWishBuilder.cs
index 2e1553c7..35b44267 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/HistoryWishBuilder.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/HistoryWishBuilder.cs
@@ -71,10 +71,10 @@ internal sealed class HistoryWishBuilder
/// 是否为Up物品
public bool IncreaseOrange(IStatisticsItemSource item)
{
- orangeCounter.Increase(item);
+ orangeCounter.IncreaseOne(item);
++totalCountTracker;
- return orangeUpCounter.TryIncrease(item);
+ return orangeUpCounter.TryIncreaseOne(item);
}
///
@@ -83,8 +83,8 @@ internal sealed class HistoryWishBuilder
/// 物品
public void IncreasePurple(IStatisticsItemSource item)
{
- purpleUpCounter.TryIncrease(item);
- purpleCounter.Increase(item);
+ purpleUpCounter.TryIncreaseOne(item);
+ purpleCounter.IncreaseOne(item);
++totalCountTracker;
}
@@ -94,7 +94,7 @@ internal sealed class HistoryWishBuilder
/// 武器
public void IncreaseBlue(IStatisticsItemSource item)
{
- blueCounter.Increase(item);
+ blueCounter.IncreaseOne(item);
++totalCountTracker;
}
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/TypedWishSummaryBuilder.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/TypedWishSummaryBuilder.cs
index 71cc466b..9b14e459 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/TypedWishSummaryBuilder.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/TypedWishSummaryBuilder.cs
@@ -87,7 +87,7 @@ internal sealed class TypedWishSummaryBuilder
switch (source.Quality)
{
- case ItemQuality.QUALITY_ORANGE:
+ case QualityType.QUALITY_ORANGE:
{
TrackMinMaxOrangePull(lastOrangePullTracker);
averageOrangePullTracker.Add(lastOrangePullTracker);
@@ -105,14 +105,14 @@ internal sealed class TypedWishSummaryBuilder
break;
}
- case ItemQuality.QUALITY_PURPLE:
+ case QualityType.QUALITY_PURPLE:
{
lastPurplePullTracker = 0;
++totalPurplePullTracker;
break;
}
- case ItemQuality.QUALITY_BLUE:
+ case QualityType.QUALITY_BLUE:
{
++totalBluePullTracker;
break;
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogServiceContext.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogServiceContext.cs
index 2520a94d..541636ce 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogServiceContext.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogServiceContext.cs
@@ -104,13 +104,13 @@ internal readonly struct GachaLogServiceContext
///
/// Id
/// 名称星级
- public INameQuality GetNameQualityByItemId(int id)
+ public INameQuality GetNameQualityByItemId(uint id)
{
- int place = id.Place();
+ uint place = id.Place();
return place switch
{
- 8 => IdAvatarMap![id],
- 5 => IdWeaponMap![id],
+ 8U => IdAvatarMap![id],
+ 5U => IdWeaponMap![id],
_ => throw Must.NeverHappen($"Id places: {place}"),
};
}
@@ -121,13 +121,13 @@ internal readonly struct GachaLogServiceContext
///
/// 祈愿物品
/// 物品 Id
- public int GetItemId(GachaLogItem item)
+ public uint GetItemId(GachaLogItem item)
{
return item.ItemType switch
{
"角色" => NameAvatarMap!.GetValueOrDefault(item.Name)?.Id ?? 0,
"武器" => NameWeaponMap!.GetValueOrDefault(item.Name)?.Id ?? 0,
- _ => 0,
+ _ => 0U,
};
}
}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Game/Package/PackageConverter.cs b/src/Snap.Hutao/Snap.Hutao/Service/Game/Package/PackageConverter.cs
index 22400011..8b40d5bc 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/Game/Package/PackageConverter.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/Game/Package/PackageConverter.cs
@@ -4,6 +4,7 @@
using Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient;
using Snap.Hutao.Core.ExceptionService;
using Snap.Hutao.Core.IO;
+using Snap.Hutao.Core.IO.Hashing;
using Snap.Hutao.Service.Notification;
using Snap.Hutao.Web.Hoyolab.SdkStatic.Hk4e.Launcher;
using System.IO;
@@ -240,7 +241,7 @@ internal sealed partial class PackageConverter
{
if (File.Exists(cacheFilePath))
{
- string remoteMd5 = await Digest.GetFileMD5Async(cacheFilePath).ConfigureAwait(false);
+ string remoteMd5 = await MD5.HashFileAsync(cacheFilePath).ConfigureAwait(false);
if (info.Md5 == remoteMd5.ToLowerInvariant() && new FileInfo(cacheFilePath).Length == info.TotalBytes)
{
// Valid, move it to target path
@@ -270,7 +271,7 @@ internal sealed partial class PackageConverter
StreamCopyWorker streamCopyWorker = new(webStream, fileStream, bytesRead => new(info.Target, bytesRead, totalBytes));
await streamCopyWorker.CopyAsync(progress).ConfigureAwait(false);
fileStream.Seek(0, SeekOrigin.Begin);
- string remoteMd5 = await Digest.GetStreamMD5Async(fileStream).ConfigureAwait(false);
+ string remoteMd5 = await MD5.HashAsync(fileStream).ConfigureAwait(false);
if (string.Equals(info.Md5, remoteMd5, StringComparison.OrdinalIgnoreCase))
{
return;
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Game/ProcessInterop.cs b/src/Snap.Hutao/Snap.Hutao/Service/Game/ProcessInterop.cs
index efded4c2..a3ab702c 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/Game/ProcessInterop.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/Game/ProcessInterop.cs
@@ -58,7 +58,7 @@ internal static class ProcessInterop
public static Task UnlockFpsAsync(IServiceProvider serviceProvider, Process game)
{
IGameFpsUnlocker unlocker = serviceProvider.CreateInstance(game);
- UnlockTimingOptions options = new(100, 10000, 3000);
+ UnlockTimingOptions options = new(100, 20000, 3000);
return unlocker.UnlockAsync(options);
}
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Metadata/IMetadataService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/IMetadataService.cs
index c7d3406d..20a7dbb5 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/Metadata/IMetadataService.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/IMetadataService.cs
@@ -90,14 +90,14 @@ internal interface IMetadataService : ICastableService
///
/// 取消令牌
/// 圣遗物强化属性列表
- ValueTask> GetReliquaryAffixesAsync(CancellationToken token = default);
+ ValueTask> GetReliquarySubAffixesAsync(CancellationToken token = default);
///
/// 异步获取圣遗物等级数据
///
/// 取消令牌
/// 圣遗物等级数据
- ValueTask> GetReliquaryLevelsAsync(CancellationToken token = default);
+ ValueTask> GetReliquaryLevelsAsync(CancellationToken token = default);
///
/// 异步获取圣遗物主属性强化属性列表
@@ -156,7 +156,7 @@ internal interface IMetadataService : ICastableService
///
/// 取消令牌
/// 显示与材料映射
- ValueTask> GetIdToDisplayAndMaterialMapAsync(CancellationToken token = default);
+ ValueTask> GetIdToDisplayAndMaterialMapAsync(CancellationToken token = default);
///
/// 异步获取Id到材料的字典
@@ -170,7 +170,7 @@ internal interface IMetadataService : ICastableService
///
/// 取消令牌
/// 字典
- ValueTask> GetIdToReliquaryAffixMapAsync(CancellationToken token = default);
+ ValueTask> GetIdToReliquarySubAffixMapAsync(CancellationToken token = default);
///
/// 异步获取圣遗物主词条Id与属性的字典
@@ -211,20 +211,20 @@ internal interface IMetadataService : ICastableService
///
/// 取消令牌
/// 等级角色曲线映射
- ValueTask>> GetLevelToAvatarCurveMapAsync(CancellationToken token = default);
+ ValueTask>> GetLevelToAvatarCurveMapAsync(CancellationToken token = default);
///
/// 异步获取等级怪物曲线映射
///
/// 取消令牌
/// 等级怪物曲线映射
- ValueTask>> GetLevelToMonsterCurveMapAsync(CancellationToken token = default);
+ ValueTask>> GetLevelToMonsterCurveMapAsync(CancellationToken token = default);
///
/// 异步获取等级武器曲线映射
///
/// 取消令牌
/// 等级武器曲线映射
- ValueTask>> GetLevelToWeaponCurveMapAsync(CancellationToken token = default);
+ ValueTask>> GetLevelToWeaponCurveMapAsync(CancellationToken token = default);
#endregion
}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataOptions.cs b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataOptions.cs
index 3afe4e70..9e36b491 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataOptions.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataOptions.cs
@@ -84,7 +84,7 @@ internal sealed partial class MetadataOptions : IOptions
/// 服务器上的本地化元数据文件
public string GetLocalizedRemoteFile(string fileNameWithExtension)
{
- return Web.HutaoEndpoints.HutaoMetadataFile(LocaleName, fileNameWithExtension);
+ return Web.HutaoEndpoints.RawGithubUserContentMetadataFile(LocaleName, fileNameWithExtension);
}
private string GetLocaleName()
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataService.Constants.cs b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataService.Constants.cs
new file mode 100644
index 00000000..662ddc54
--- /dev/null
+++ b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataService.Constants.cs
@@ -0,0 +1,33 @@
+// Copyright (c) DGP Studio. All rights reserved.
+// Licensed under the MIT license.
+
+namespace Snap.Hutao.Service.Metadata;
+
+///
+/// 名称常量
+///
+internal partial class MetadataService
+{
+ private const string FileNameAchievement = "Achievement";
+ private const string FileNameAchievementGoal = "AchievementGoal";
+ private const string FileNameAvatar = "Avatar";
+ private const string FileNameAvatarCurve = "AvatarCurve";
+ private const string FileNameAvatarPromote = "AvatarPromote";
+ private const string FileNameDisplayItem = "DisplayItem";
+ private const string FileNameGachaEvent = "GachaEvent";
+ private const string FileNameMaterial = "Material";
+ private const string FileNameMonster = "Monster";
+ private const string FileNameMonsterCurve = "MonsterCurve";
+ private const string FileNameReliquary = "Reliquary";
+ private const string FileNameReliquaryAffixWeight = "ReliquaryAffixWeight";
+ private const string FileNameReliquaryMainAffix = "ReliquaryMainAffix";
+ private const string FileNameReliquaryMainAffixLevel = "ReliquaryMainAffixLevel";
+ private const string FileNameReliquarySet = "ReliquarySet";
+ private const string FileNameReliquarySubAffix = "ReliquarySubAffix";
+ private const string FileNameTowerFloor = "TowerFloor";
+ private const string FileNameTowerLevel = "TowerLevel";
+ private const string FileNameTowerSchedule = "TowerSchedule";
+ private const string FileNameWeapon = "Weapon";
+ private const string FileNameWeaponCurve = "WeaponCurve";
+ private const string FileNameWeaponPromote = "WeaponPromote";
+}
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataService.Implementation.cs b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataService.Implementation.cs
index 17c2fe26..c8423955 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataService.Implementation.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataService.Implementation.cs
@@ -19,84 +19,84 @@ internal sealed partial class MetadataService
///
public ValueTask> GetAchievementGoalsAsync(CancellationToken token = default)
{
- return FromCacheOrFileAsync>("AchievementGoal", token);
+ return FromCacheOrFileAsync>(FileNameAchievementGoal, token);
}
///
public ValueTask> GetAchievementsAsync(CancellationToken token = default)
{
- return FromCacheOrFileAsync>("Achievement", token);
+ return FromCacheOrFileAsync>(FileNameAchievement, token);
}
///
public ValueTask> GetAvatarsAsync(CancellationToken token = default)
{
- return FromCacheOrFileAsync>("Avatar", token);
+ return FromCacheOrFileAsync>(FileNameAvatar, token);
}
///
public ValueTask> GetAvatarPromotesAsync(CancellationToken token = default)
{
- return FromCacheOrFileAsync>("AvatarPromote", token);
- }
-
- ///
- public ValueTask> GetWeaponPromotesAsync(CancellationToken token = default)
- {
- return FromCacheOrFileAsync>("WeaponPromote", token);
+ return FromCacheOrFileAsync>(FileNameAvatarPromote, token);
}
///
public ValueTask> GetGachaEventsAsync(CancellationToken token = default)
{
- return FromCacheOrFileAsync>("GachaEvent2", token);
+ return FromCacheOrFileAsync>(FileNameGachaEvent, token);
}
///
public ValueTask> GetMaterialsAsync(CancellationToken token = default)
{
- return FromCacheOrFileAsync>("Material", token);
+ return FromCacheOrFileAsync>(FileNameMaterial, token);
}
///
public ValueTask> GetMonstersAsync(CancellationToken token = default)
{
- return FromCacheOrFileAsync>("Monster", token);
+ return FromCacheOrFileAsync>(FileNameMonster, token);
}
///
public ValueTask> GetReliquariesAsync(CancellationToken token = default)
{
- return FromCacheOrFileAsync>("Reliquary", token);
+ return FromCacheOrFileAsync>(FileNameReliquary, token);
}
///
- public ValueTask> GetReliquaryAffixesAsync(CancellationToken token = default)
+ public ValueTask> GetReliquaryLevelsAsync(CancellationToken token = default)
{
- return FromCacheOrFileAsync>("ReliquaryAffix", token);
- }
-
- ///
- public ValueTask> GetReliquaryLevelsAsync(CancellationToken token = default)
- {
- return FromCacheOrFileAsync>("ReliquaryMainAffixLevel", token);
+ return FromCacheOrFileAsync>(FileNameReliquaryMainAffixLevel, token);
}
///
public ValueTask> GetReliquaryMainAffixesAsync(CancellationToken token = default)
{
- return FromCacheOrFileAsync>("ReliquaryMainAffix", token);
+ return FromCacheOrFileAsync>(FileNameReliquaryMainAffix, token);
}
///
public ValueTask> GetReliquarySetsAsync(CancellationToken token = default)
{
- return FromCacheOrFileAsync>("ReliquarySet", token);
+ return FromCacheOrFileAsync>(FileNameReliquarySet, token);
+ }
+
+ ///
+ public ValueTask> GetReliquarySubAffixesAsync(CancellationToken token = default)
+ {
+ return FromCacheOrFileAsync>(FileNameReliquarySubAffix, token);
}
///
public ValueTask> GetWeaponsAsync(CancellationToken token = default)
{
- return FromCacheOrFileAsync>("Weapon", token);
+ return FromCacheOrFileAsync>(FileNameWeapon, token);
+ }
+
+ ///
+ public ValueTask> GetWeaponPromotesAsync(CancellationToken token = default)
+ {
+ return FromCacheOrFileAsync>(FileNameWeaponPromote, token);
}
}
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataService.Indexing.cs b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataService.Indexing.cs
index 0ac415ab..f1f6f1e2 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataService.Indexing.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataService.Indexing.cs
@@ -9,6 +9,7 @@ using Snap.Hutao.Model.Metadata.Item;
using Snap.Hutao.Model.Metadata.Reliquary;
using Snap.Hutao.Model.Metadata.Weapon;
using Snap.Hutao.Model.Primitive;
+using System.Runtime.CompilerServices;
namespace Snap.Hutao.Service.Metadata;
@@ -20,38 +21,38 @@ internal sealed partial class MetadataService
///
public ValueTask> GetEquipAffixIdToReliquarySetMapAsync(CancellationToken token = default)
{
- return FromCacheAsDictionaryAsync("ReliquarySet", r => r.EquipAffixId, token);
+ return FromCacheAsDictionaryAsync(FileNameReliquarySet, r => r.EquipAffixId, token);
}
///
public ValueTask> GetIdToAchievementMapAsync(CancellationToken token = default)
{
- return FromCacheAsDictionaryAsync("Achievement", a => a.Id, token);
+ return FromCacheAsDictionaryAsync(FileNameAchievement, a => a.Id, token);
}
///
public ValueTask> GetIdToAvatarMapAsync(CancellationToken token = default)
{
- return FromCacheAsDictionaryAsync("Avatar", a => a.Id, token);
+ return FromCacheAsDictionaryAsync(FileNameAvatar, a => a.Id, token);
}
///
- public async ValueTask> GetIdToDisplayAndMaterialMapAsync(CancellationToken token = default)
+ public async ValueTask> GetIdToDisplayAndMaterialMapAsync(CancellationToken token = default)
{
string cacheKey = $"{nameof(MetadataService)}.Cache.DisplayAndMaterial.Map.{typeof(MaterialId).Name}";
if (memoryCache.TryGetValue(cacheKey, out object? value))
{
- return Must.NotNull((Dictionary)value!);
+ return Must.NotNull((Dictionary)value!);
}
- Dictionary displays = await FromCacheAsDictionaryAsync("Display", a => a.Id, token).ConfigureAwait(false);
+ Dictionary displays = await FromCacheAsDictionaryAsync(FileNameDisplayItem, a => a.Id, token).ConfigureAwait(false);
Dictionary materials = await GetIdToMaterialMapAsync(token).ConfigureAwait(false);
// TODO: Cache this
- Dictionary results = new(displays);
+ Dictionary results = new(displays);
- foreach ((MaterialId id, Display material) in materials)
+ foreach ((MaterialId id, DisplayItem material) in materials)
{
results[id] = material;
}
@@ -62,54 +63,54 @@ internal sealed partial class MetadataService
///
public ValueTask> GetIdToMaterialMapAsync(CancellationToken token = default)
{
- return FromCacheAsDictionaryAsync("Material", a => a.Id, token);
+ return FromCacheAsDictionaryAsync(FileNameMaterial, a => a.Id, token);
}
///
- public ValueTask> GetIdToReliquaryAffixMapAsync(CancellationToken token = default)
+ public ValueTask> GetIdToReliquarySubAffixMapAsync(CancellationToken token = default)
{
- return FromCacheAsDictionaryAsync("ReliquaryAffix", a => a.Id, token);
+ return FromCacheAsDictionaryAsync(FileNameReliquarySubAffix, a => a.Id, token);
}
///
public ValueTask> GetIdToReliquaryMainPropertyMapAsync(CancellationToken token = default)
{
- return FromCacheAsDictionaryAsync("ReliquaryMainAffix", r => r.Id, r => r.Type, token);
+ return FromCacheAsDictionaryAsync(FileNameReliquaryMainAffix, r => r.Id, r => r.Type, token);
}
///
public ValueTask> GetIdToWeaponMapAsync(CancellationToken token = default)
{
- return FromCacheAsDictionaryAsync("Weapon", w => w.Id, token);
+ return FromCacheAsDictionaryAsync(FileNameWeapon, w => w.Id, token);
}
///
- public ValueTask>> GetLevelToAvatarCurveMapAsync(CancellationToken token = default)
+ public ValueTask>> GetLevelToAvatarCurveMapAsync(CancellationToken token = default)
{
- return FromCacheAsDictionaryAsync, GrowCurve>("AvatarCurve", a => a.Level, a => a.Curves, token);
+ return FromCacheAsDictionaryAsync, GrowCurve>(FileNameAvatarCurve, a => a.Level, a => a.CurveMap, token);
}
///
- public ValueTask>> GetLevelToMonsterCurveMapAsync(CancellationToken token = default)
+ public ValueTask>> GetLevelToMonsterCurveMapAsync(CancellationToken token = default)
{
- return FromCacheAsDictionaryAsync, GrowCurve>("MonsterCurve", m => m.Level, m => m.Curves, token);
+ return FromCacheAsDictionaryAsync, GrowCurve>(FileNameMonsterCurve, m => m.Level, m => m.CurveMap, token);
}
///
- public ValueTask>> GetLevelToWeaponCurveMapAsync(CancellationToken token = default)
+ public ValueTask>> GetLevelToWeaponCurveMapAsync(CancellationToken token = default)
{
- return FromCacheAsDictionaryAsync, GrowCurve>("WeaponCurve", w => w.Level, w => w.Curves, token);
+ return FromCacheAsDictionaryAsync, GrowCurve>(FileNameWeaponCurve, w => w.Level, w => w.CurveMap, token);
}
///
public ValueTask> GetNameToAvatarMapAsync(CancellationToken token = default)
{
- return FromCacheAsDictionaryAsync("Avatar", a => a.Name, token);
+ return FromCacheAsDictionaryAsync(FileNameAvatar, a => a.Name, token);
}
///
public ValueTask> GetNameToWeaponMapAsync(CancellationToken token = default)
{
- return FromCacheAsDictionaryAsync("Weapon", w => w.Name, token);
+ return FromCacheAsDictionaryAsync(FileNameWeapon, w => w.Name, token);
}
}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataService.cs
index 3b7f0b46..f06b1d65 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataService.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataService.cs
@@ -6,7 +6,7 @@ using Snap.Hutao.Core;
using Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient;
using Snap.Hutao.Core.Diagnostics;
using Snap.Hutao.Core.ExceptionService;
-using Snap.Hutao.Core.IO;
+using Snap.Hutao.Core.IO.Hashing;
using Snap.Hutao.Service.Notification;
using System.IO;
using System.Net.Http;
@@ -122,12 +122,12 @@ internal sealed partial class MetadataService : IMetadataService, IMetadataServi
string fileFullPath = metadataOptions.GetLocalizedLocalFile(fileFullName);
if (File.Exists(fileFullPath))
{
- skip = md5 == await Digest.GetFileMD5Async(fileFullPath, token).ConfigureAwait(false);
+ skip = md5 == await XXH64.HashFileAsync(fileFullPath, token).ConfigureAwait(false);
}
if (!skip)
{
- logger.LogInformation("MD5 of {file} not matched, begin downloading", fileFullName);
+ logger.LogInformation("{hash} of {file} not matched, begin downloading", nameof(XXH64), fileFullName);
await DownloadMetadataAsync(fileFullName, token).ConfigureAwait(false);
}
@@ -182,6 +182,7 @@ internal sealed partial class MetadataService : IMetadataService, IMetadataServi
}
else
{
+ FileNotFoundException exception = new(SH.ServiceMetadataFileNotFound, fileName);
throw ThrowHelper.UserdataCorrupted(SH.ServiceMetadataFileNotFound, null!);
}
}
diff --git a/src/Snap.Hutao/Snap.Hutao/Snap.Hutao.csproj b/src/Snap.Hutao/Snap.Hutao/Snap.Hutao.csproj
index 565ba4f7..0a198dd6 100644
--- a/src/Snap.Hutao/Snap.Hutao/Snap.Hutao.csproj
+++ b/src/Snap.Hutao/Snap.Hutao/Snap.Hutao.csproj
@@ -253,7 +253,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
@@ -268,6 +268,7 @@
all
runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/src/Snap.Hutao/Snap.Hutao/View/Control/ItemIcon.xaml.cs b/src/Snap.Hutao/Snap.Hutao/View/Control/ItemIcon.xaml.cs
index 0e29cf2b..41ee5d44 100644
--- a/src/Snap.Hutao/Snap.Hutao/View/Control/ItemIcon.xaml.cs
+++ b/src/Snap.Hutao/Snap.Hutao/View/Control/ItemIcon.xaml.cs
@@ -14,7 +14,7 @@ namespace Snap.Hutao.View.Control;
[HighQuality]
internal sealed partial class ItemIcon : UserControl
{
- private static readonly DependencyProperty QualityProperty = Property.Depend(nameof(Quality), ItemQuality.QUALITY_NONE);
+ private static readonly DependencyProperty QualityProperty = Property.Depend(nameof(Quality), QualityType.QUALITY_NONE);
private static readonly DependencyProperty IconProperty = Property.Depend(nameof(Icon));
private static readonly DependencyProperty BadgeProperty = Property.Depend(nameof(Badge));
@@ -29,9 +29,9 @@ internal sealed partial class ItemIcon : UserControl
///
/// 等阶
///
- public ItemQuality Quality
+ public QualityType Quality
{
- get => (ItemQuality)GetValue(QualityProperty);
+ get => (QualityType)GetValue(QualityProperty);
set => SetValue(QualityProperty, value);
}
diff --git a/src/Snap.Hutao/Snap.Hutao/View/Page/WikiAvatarPage.xaml b/src/Snap.Hutao/Snap.Hutao/View/Page/WikiAvatarPage.xaml
index f36c911f..27c31222 100644
--- a/src/Snap.Hutao/Snap.Hutao/View/Page/WikiAvatarPage.xaml
+++ b/src/Snap.Hutao/Snap.Hutao/View/Page/WikiAvatarPage.xaml
@@ -521,7 +521,7 @@
Width="80"
Height="80"
Margin="0,0,16,0"
- Source="{Binding Icon, Converter={StaticResource AvatarCardConverter}}"/>
+ Source="{Binding FrontIcon, Converter={StaticResource AvatarCardConverter}}"/>
/// 排序顺序
///
- public int Order { get; }
+ public uint Order { get; }
///
/// 名称
diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/AvatarProperty/AvatarView.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/AvatarProperty/AvatarView.cs
index 97ebfdb2..4432dc38 100644
--- a/src/Snap.Hutao/Snap.Hutao/ViewModel/AvatarProperty/AvatarView.cs
+++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/AvatarProperty/AvatarView.cs
@@ -36,7 +36,7 @@ internal sealed class AvatarView : INameIconSide, ICalculableSource
/// 星级
///
- public ItemQuality Quality { get; set; }
+ public QualityType Quality { get; set; }
///
/// 元素类型
@@ -91,7 +91,7 @@ internal sealed class AvatarView : INameIconSide, ICalculableSource
/// 好感度等级
///
- public int FetterLevel { get; set; }
+ public uint FetterLevel { get; set; }
///
/// Id
@@ -101,7 +101,7 @@ internal sealed class AvatarView : INameIconSide, ICalculableSource
/// 等级数字
///
- internal int LevelNumber { get; set; }
+ internal uint LevelNumber { get; set; }
///
public ICalculableAvatar ToCalculable()
diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/AvatarProperty/Equip.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/AvatarProperty/Equip.cs
index f55ccdc8..e797f7db 100644
--- a/src/Snap.Hutao/Snap.Hutao/ViewModel/AvatarProperty/Equip.cs
+++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/AvatarProperty/Equip.cs
@@ -20,7 +20,7 @@ internal abstract class Equip : NameIconDescription
///
/// 品质
///
- public ItemQuality Quality { get; set; }
+ public QualityType Quality { get; set; }
///
/// 主属性
diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/AvatarProperty/SkillView.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/AvatarProperty/SkillView.cs
index 19c73b39..5a6e899b 100644
--- a/src/Snap.Hutao/Snap.Hutao/ViewModel/AvatarProperty/SkillView.cs
+++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/AvatarProperty/SkillView.cs
@@ -3,6 +3,7 @@
using Snap.Hutao.Model.Calculable;
using Snap.Hutao.Model.Metadata;
+using Snap.Hutao.Model.Primitive;
namespace Snap.Hutao.ViewModel.AvatarProperty;
@@ -20,7 +21,7 @@ internal sealed class SkillView : NameIconDescription, ICalculableSource
/// 不计算命座的技能等级
///
- public int LevelNumber { get; set; }
+ public uint LevelNumber { get; set; }
///
/// 不计算命座的技能等级字符串
@@ -30,7 +31,7 @@ internal sealed class SkillView : NameIconDescription, ICalculableSource
/// 技能组Id
///
- internal int GroupId { get; set; }
+ internal SkillGroupId GroupId { get; set; }
///
public ICalculableSkill ToCalculable()
diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/AvatarProperty/WeaponView.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/AvatarProperty/WeaponView.cs
index 6374a0f1..f7225181 100644
--- a/src/Snap.Hutao/Snap.Hutao/ViewModel/AvatarProperty/WeaponView.cs
+++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/AvatarProperty/WeaponView.cs
@@ -20,7 +20,7 @@ internal sealed class WeaponView : Equip, ICalculableSource
///
/// 精炼等级
///
- public int AffixLevelNumber { get; set; }
+ public uint AffixLevelNumber { get; set; }
///
/// 精炼属性
@@ -45,12 +45,12 @@ internal sealed class WeaponView : Equip, ICalculableSource
///
/// 等级数字
///
- internal int LevelNumber { get; set; }
+ internal uint LevelNumber { get; set; }
///
/// 最大等级
///
- internal int MaxLevel { get => ((int)Quality) >= 3 ? 90 : 70; }
+ internal uint MaxLevel { get => ((int)Quality) >= 3 ? 90U : 70U; }
///
public ICalculableWeapon ToCalculable()
diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/Complex/AvatarView.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/Complex/AvatarView.cs
index 95eff5e3..433541ba 100644
--- a/src/Snap.Hutao/Snap.Hutao/ViewModel/Complex/AvatarView.cs
+++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/Complex/AvatarView.cs
@@ -46,7 +46,7 @@ internal class AvatarView : INameIconSide
///
/// 星级
///
- public ItemQuality Quality { get; }
+ public QualityType Quality { get; }
///
/// 比率
diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/Complex/Team.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/Complex/Team.cs
index eb60033d..56b267c7 100644
--- a/src/Snap.Hutao/Snap.Hutao/ViewModel/Complex/Team.cs
+++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/Complex/Team.cs
@@ -24,7 +24,7 @@ internal sealed class Team : List
{
foreach (StringSegment item in new StringTokenizer(team.Item, new char[] { ',' }))
{
- int id = int.Parse(item.AsSpan());
+ uint id = uint.Parse(item.AsSpan());
Add(new(idAvatarMap[id], 0));
}
diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/Complex/WeaponView.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/Complex/WeaponView.cs
index 9bae0908..8b7956dd 100644
--- a/src/Snap.Hutao/Snap.Hutao/ViewModel/Complex/WeaponView.cs
+++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/Complex/WeaponView.cs
@@ -40,7 +40,7 @@ internal sealed class WeaponView : INameIcon
///
/// 星级
///
- public ItemQuality Quality { get; }
+ public QualityType Quality { get; }
///
/// 比率
diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/Cultivation/CultivateEntryView.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/Cultivation/CultivateEntryView.cs
index 71cc5ced..78f3fd97 100644
--- a/src/Snap.Hutao/Snap.Hutao/ViewModel/Cultivation/CultivateEntryView.cs
+++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/Cultivation/CultivateEntryView.cs
@@ -31,7 +31,7 @@ internal sealed class CultivateEntryView : Item
///
/// Id
///
- public int Id { get; set; }
+ public uint Id { get; set; }
///
/// 入口Id
diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLog/GachaLogViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLog/GachaLogViewModel.cs
index 8860c25c..ca019ffd 100644
--- a/src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLog/GachaLogViewModel.cs
+++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLog/GachaLogViewModel.cs
@@ -350,10 +350,11 @@ internal sealed partial class GachaLogViewModel : Abstraction.ViewModel
// ContentDialog must be created by main thread.
await taskContext.SwitchToMainThreadAsync();
GachaLogImportDialog importDialog = serviceProvider.CreateInstance(uigf);
- if (await importDialog.GetShouldImportAsync().ConfigureAwait(true))
+ if (await importDialog.GetShouldImportAsync().ConfigureAwait(false))
{
if (CanImport(version, uigf))
{
+ await taskContext.SwitchToMainThreadAsync();
ContentDialog dialog = await contentDialogFactory.CreateForIndeterminateProgressAsync(SH.ViewModelGachaLogImportProgress).ConfigureAwait(true);
using (await dialog.BlockAsync(taskContext).ConfigureAwait(false))
{
diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/SpiralAbyss/AvatarView.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/SpiralAbyss/AvatarView.cs
index b8f4f718..8f748b76 100644
--- a/src/Snap.Hutao/Snap.Hutao/ViewModel/SpiralAbyss/AvatarView.cs
+++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/SpiralAbyss/AvatarView.cs
@@ -53,5 +53,5 @@ internal class AvatarView : INameIconSide
///
/// 星级
///
- public ItemQuality Quality { get; }
+ public QualityType Quality { get; }
}
diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/SpiralAbyss/LevelView.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/SpiralAbyss/LevelView.cs
index 7bfe4b77..8f7dbde2 100644
--- a/src/Snap.Hutao/Snap.Hutao/ViewModel/SpiralAbyss/LevelView.cs
+++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/SpiralAbyss/LevelView.cs
@@ -2,7 +2,6 @@
// Licensed under the MIT license.
using Snap.Hutao.Model.Primitive;
-using Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.SpiralAbyss;
namespace Snap.Hutao.ViewModel.SpiralAbyss;
@@ -17,7 +16,7 @@ internal sealed class LevelView
///
/// 间
/// Id角色映射
- public LevelView(Level level, Dictionary idAvatarMap)
+ public LevelView(Web.Hoyolab.Takumi.GameRecord.SpiralAbyss.Level level, Dictionary idAvatarMap)
{
Index = string.Format(SH.ModelBindingHutaoComplexRankLevel, level.Index);
Star = level.Star;
diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/Wiki/BaseValueInfo.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/Wiki/BaseValueInfo.cs
index 724ba27e..19b5bc04 100644
--- a/src/Snap.Hutao/Snap.Hutao/ViewModel/Wiki/BaseValueInfo.cs
+++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/Wiki/BaseValueInfo.cs
@@ -6,6 +6,7 @@ using Snap.Hutao.Model;
using Snap.Hutao.Model.Intrinsic;
using Snap.Hutao.Model.Metadata;
using Snap.Hutao.Model.Metadata.Converter;
+using Snap.Hutao.Model.Primitive;
namespace Snap.Hutao.ViewModel.Wiki;
@@ -15,10 +16,10 @@ namespace Snap.Hutao.ViewModel.Wiki;
internal sealed class BaseValueInfo : ObservableObject
{
private readonly List propValues;
- private readonly Dictionary> growCurveMap;
- private readonly Dictionary? promoteMap;
+ private readonly Dictionary> growCurveMap;
+ private readonly Dictionary? promoteMap;
- private int currentLevel;
+ private uint currentLevel;
private List> values = default!;
private bool promoted = true;
@@ -29,7 +30,7 @@ internal sealed class BaseValueInfo : ObservableObject
/// 属性与初始值
/// 生长曲线
/// 突破加成
- public BaseValueInfo(int maxLevel, List propValues, Dictionary> growCurveMap, Dictionary? promoteMap = null)
+ public BaseValueInfo(uint maxLevel, List propValues, Dictionary> growCurveMap, Dictionary? promoteMap = null)
{
this.propValues = propValues;
this.growCurveMap = growCurveMap;
@@ -42,7 +43,7 @@ internal sealed class BaseValueInfo : ObservableObject
///
/// 最大等级
///
- public int MaxLevel { get; }
+ public uint MaxLevel { get; }
///
/// 对应的基础值
@@ -52,7 +53,7 @@ internal sealed class BaseValueInfo : ObservableObject
///
/// 当前等级
///
- public int CurrentLevel
+ public uint CurrentLevel
{
get => currentLevel;
set
@@ -88,15 +89,16 @@ internal sealed class BaseValueInfo : ObservableObject
}
}
- private void UpdateValues(int level, bool promoted)
+ [SuppressMessage("", "SH002")]
+ private void UpdateValues(Level level, bool promoted)
{
Values = propValues.SelectList(propValue =>
{
float value = propValue.Value * growCurveMap[level].GetValueOrDefault(propValue.Type);
if (promoteMap != null)
{
- int promoteLevel = GetPromoteLevel(level, promoted);
- float addValue = promoteMap[promoteLevel].AddProperties.GetValueOrDefault(propValue.Property, 0F);
+ PromoteLevel promoteLevel = GetPromoteLevel(level, promoted);
+ float addValue = promoteMap[promoteLevel].AddPropertyMap.GetValueOrDefault(propValue.Property, 0F);
value += addValue;
}
@@ -105,29 +107,29 @@ internal sealed class BaseValueInfo : ObservableObject
});
}
- private int GetPromoteLevel(int level, bool promoted)
+ private PromoteLevel GetPromoteLevel(in Level level, bool promoted)
{
if (MaxLevel <= 70)
{
if (promoted)
{
- return level switch
+ return level.Value switch
{
- >= 60 => 4,
- >= 50 => 3,
- >= 40 => 2,
- >= 20 => 1,
+ >= 60U => 4,
+ >= 50U => 3,
+ >= 40U => 2,
+ >= 20U => 1,
_ => 0,
};
}
else
{
- return level switch
+ return level.Value switch
{
- > 60 => 4,
- > 50 => 3,
- > 40 => 2,
- > 20 => 1,
+ > 60U => 4,
+ > 50U => 3,
+ > 40U => 2,
+ > 20U => 1,
_ => 0,
};
}
@@ -136,27 +138,27 @@ internal sealed class BaseValueInfo : ObservableObject
{
if (promoted)
{
- return level switch
+ return level.Value switch
{
- >= 80 => 6,
- >= 70 => 5,
- >= 60 => 4,
- >= 50 => 3,
- >= 40 => 2,
- >= 20 => 1,
+ >= 80U => 6,
+ >= 70U => 5,
+ >= 60U => 4,
+ >= 50U => 3,
+ >= 40U => 2,
+ >= 20U => 1,
_ => 0,
};
}
else
{
- return level switch
+ return level.Value switch
{
- > 80 => 6,
- > 70 => 5,
- > 60 => 4,
- > 50 => 3,
- > 40 => 2,
- > 20 => 1,
+ > 80U => 6,
+ > 70U => 5,
+ > 60U => 4,
+ > 50U => 3,
+ > 40U => 2,
+ > 20U => 1,
_ => 0,
};
}
diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/Wiki/WeaponFilter.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/Wiki/WeaponFilter.cs
index 7d079239..75745da1 100644
--- a/src/Snap.Hutao/Snap.Hutao/ViewModel/Wiki/WeaponFilter.cs
+++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/Wiki/WeaponFilter.cs
@@ -50,7 +50,7 @@ internal static class WeaponFilter
if (IntrinsicImmutables.FightProperties.Contains(value))
{
- matches.Add(weapon.GrowCurves.ElementAtOrDefault(1).Key.GetLocalizedDescriptionOrDefault() == value);
+ matches.Add(weapon.GrowCurves.ElementAtOrDefault(1)?.Type.GetLocalizedDescriptionOrDefault() == value);
continue;
}
}
diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/Wiki/WikiAvatarViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/Wiki/WikiAvatarViewModel.cs
index f89b67c4..2e4df383 100644
--- a/src/Snap.Hutao/Snap.Hutao/ViewModel/Wiki/WikiAvatarViewModel.cs
+++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/Wiki/WikiAvatarViewModel.cs
@@ -46,7 +46,7 @@ internal sealed partial class WikiAvatarViewModel : Abstraction.ViewModel
private Avatar? selected;
private string? filterText;
private BaseValueInfo? baseValueInfo;
- private Dictionary>? levelAvatarCurveMap;
+ private Dictionary>? levelAvatarCurveMap;
private List? promotes;
///
@@ -182,15 +182,15 @@ internal sealed partial class WikiAvatarViewModel : Abstraction.ViewModel
}
else
{
- Dictionary avatarPromoteMap = promotes!.Where(p => p.Id == avatar.PromoteId).ToDictionary(p => p.Level);
-
- FightProperty promoteProperty = avatarPromoteMap[0].AddProperties.Keys.Last();
+ Dictionary avatarPromoteMap = promotes!.Where(p => p.Id == avatar.PromoteId).ToDictionary(p => p.Level);
+ Dictionary avatarGrowCurve = avatar.GrowCurves.ToDictionary(g => g.Type, g => g.Value);
+ FightProperty promoteProperty = avatarPromoteMap[0].AddProperties.Last().Type;
List propertyCurveValues = new()
{
- new(FightProperty.FIGHT_PROP_BASE_HP, avatar.GrowCurves[FightProperty.FIGHT_PROP_BASE_HP], avatar.BaseValue.HpBase),
- new(FightProperty.FIGHT_PROP_BASE_ATTACK, avatar.GrowCurves[FightProperty.FIGHT_PROP_BASE_ATTACK], avatar.BaseValue.AttackBase),
- new(FightProperty.FIGHT_PROP_BASE_DEFENSE, avatar.GrowCurves[FightProperty.FIGHT_PROP_BASE_DEFENSE], avatar.BaseValue.DefenseBase),
+ new(FightProperty.FIGHT_PROP_BASE_HP, avatarGrowCurve[FightProperty.FIGHT_PROP_BASE_HP], avatar.BaseValue.HpBase),
+ new(FightProperty.FIGHT_PROP_BASE_ATTACK, avatarGrowCurve[FightProperty.FIGHT_PROP_BASE_ATTACK], avatar.BaseValue.AttackBase),
+ new(FightProperty.FIGHT_PROP_BASE_DEFENSE, avatarGrowCurve[FightProperty.FIGHT_PROP_BASE_DEFENSE], avatar.BaseValue.DefenseBase),
new(promoteProperty, GrowCurveType.GROW_CURVE_NONE, 0),
};
diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/Wiki/WikiMonsterViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/Wiki/WikiMonsterViewModel.cs
index e0cc1629..bae18d11 100644
--- a/src/Snap.Hutao/Snap.Hutao/ViewModel/Wiki/WikiMonsterViewModel.cs
+++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/Wiki/WikiMonsterViewModel.cs
@@ -24,7 +24,7 @@ internal sealed partial class WikiMonsterViewModel : Abstraction.ViewModel
private AdvancedCollectionView? monsters;
private Monster? selected;
private BaseValueInfo? baseValueInfo;
- private Dictionary>? levelMonsterCurveMap;
+ private Dictionary>? levelMonsterCurveMap;
///
/// 角色列表
@@ -58,7 +58,7 @@ internal sealed partial class WikiMonsterViewModel : Abstraction.ViewModel
levelMonsterCurveMap = await metadataService.GetLevelToMonsterCurveMapAsync().ConfigureAwait(false);
List monsters = await metadataService.GetMonstersAsync().ConfigureAwait(false);
- Dictionary idDisplayMap = await metadataService.GetIdToDisplayAndMaterialMapAsync().ConfigureAwait(false);
+ Dictionary idDisplayMap = await metadataService.GetIdToDisplayAndMaterialMapAsync().ConfigureAwait(false);
foreach (Monster monster in monsters)
{
monster.DropsView ??= monster.Drops?.SelectList(i => idDisplayMap.GetValueOrDefault(i)!);
@@ -81,7 +81,7 @@ internal sealed partial class WikiMonsterViewModel : Abstraction.ViewModel
else
{
List propertyCurveValues = monster.GrowCurves
- .Select(curveInfo => new PropertyCurveValue(curveInfo.Key, curveInfo.Value, monster.BaseValue.GetValue(curveInfo.Key)))
+ .Select(curveInfo => new PropertyCurveValue(curveInfo.Type, curveInfo.Value, monster.BaseValue.GetValue(curveInfo.Type)))
.ToList();
BaseValueInfo = new(100, propertyCurveValues, levelMonsterCurveMap!);
diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/Wiki/WikiWeaponViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/Wiki/WikiWeaponViewModel.cs
index 937bcab9..abe6ba8f 100644
--- a/src/Snap.Hutao/Snap.Hutao/ViewModel/Wiki/WikiWeaponViewModel.cs
+++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/Wiki/WikiWeaponViewModel.cs
@@ -46,7 +46,7 @@ internal sealed partial class WikiWeaponViewModel : Abstraction.ViewModel
private Weapon? selected;
private string? filterText;
private BaseValueInfo? baseValueInfo;
- private Dictionary>? levelWeaponCurveMap;
+ private Dictionary>? levelWeaponCurveMap;
private List? promotes;
///
@@ -177,10 +177,10 @@ internal sealed partial class WikiWeaponViewModel : Abstraction.ViewModel
}
else
{
- Dictionary weaponPromoteMap = promotes!.Where(p => p.Id == weapon.PromoteId).ToDictionary(p => p.Level);
+ Dictionary weaponPromoteMap = promotes!.Where(p => p.Id == weapon.PromoteId).ToDictionary(p => p.Level);
List propertyCurveValues = weapon.GrowCurves
- .Select(curveInfo => new PropertyCurveValue(curveInfo.Key, curveInfo.Value.Type, curveInfo.Value.Value))
+ .Select(curveInfo => new PropertyCurveValue(curveInfo.Type, curveInfo.Value, curveInfo.InitValue))
.ToList();
BaseValueInfo = new(weapon.MaxLevel, propertyCurveValues, levelWeaponCurveMap!, weaponPromoteMap);
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/ApiEndpoints.cs b/src/Snap.Hutao/Snap.Hutao/Web/ApiEndpoints.cs
index 6bb9da32..e6cb482f 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/ApiEndpoints.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/ApiEndpoints.cs
@@ -101,6 +101,11 @@ internal static class ApiEndpoints
///
public const string CardWidgetData = $"{ApiTakumiCardApi}/getWidgetData?game_id=2";
+ ///
+ /// 小组件数据v2
+ ///
+ public const string CardWidgetData2 = $"{ApiTakumiRecordAapi}/widget/v2?game_id=2";
+
///
/// 发起验证码
///
@@ -346,6 +351,7 @@ internal static class ApiEndpoints
private const string ApiTakumiRecord = "https://api-takumi-record.mihoyo.com";
private const string ApiTakumiRecordApi = $"{ApiTakumiRecord}/game_record/app/genshin/api";
+ private const string ApiTakumiRecordAapi = $"{ApiTakumiRecord}/game_record/app/genshin/aapi";
///
/// Referer: https://app.mihoyo.com
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/AvatarInfo.cs b/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/AvatarInfo.cs
index d867cba9..b5f8ac2d 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/AvatarInfo.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/AvatarInfo.cs
@@ -52,13 +52,13 @@ internal sealed class AvatarInfo
/// 被动天赋
///
[JsonPropertyName("inherentProudSkillList")]
- public List InherentProudSkillList { get; set; } = default!;
+ public List InherentProudSkillList { get; set; } = default!;
///
/// Map of Skill Levels
///
[JsonPropertyName("skillLevelMap")]
- public Dictionary SkillLevelMap { get; set; } = default!;
+ public Dictionary SkillLevelMap { get; set; } = default!;
///
/// 装备列表
@@ -85,5 +85,5 @@ internal sealed class AvatarInfo
/// 命座额外技能等级
///
[JsonPropertyName("proudSkillExtraLevelMap")]
- public Dictionary? ProudSkillExtraLevelMap { get; set; } = default!;
+ public Dictionary? ProudSkillExtraLevelMap { get; set; } = default!;
}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/EnkaResponse.cs b/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/EnkaResponse.cs
index 8f331f66..7c99346a 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/EnkaResponse.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/EnkaResponse.cs
@@ -19,14 +19,14 @@ internal sealed class EnkaResponse
/// 展示的角色详细信息列表
///
[JsonPropertyName("avatarInfoList")]
- public IList? AvatarInfoList { get; set; } = default!;
+ public List? AvatarInfoList { get; set; } = default!;
///
/// 刷新剩余秒数
/// 生存时间值
///
[JsonPropertyName("ttl")]
- public int? Ttl { get; set; }
+ public int? TimeToLive { get; set; }
///
/// 此响应是否有效
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/Equip.cs b/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/Equip.cs
index 8e363dde..b61741d2 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/Equip.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/Equip.cs
@@ -14,7 +14,7 @@ internal sealed class Equip
/// Equipment ID
///
[JsonPropertyName("itemId")]
- public int ItemId { get; set; }
+ public uint ItemId { get; set; }
///
/// 圣遗物
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/FetterInfo.cs b/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/FetterInfo.cs
index 637e96c8..e3858b9b 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/FetterInfo.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/FetterInfo.cs
@@ -1,6 +1,8 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
+using Snap.Hutao.Model.Primitive;
+
namespace Snap.Hutao.Web.Enka.Model;
///
@@ -13,5 +15,5 @@ internal sealed class FetterInfo
/// 好感度等级
///
[JsonPropertyName("expLevel")]
- public int ExpLevel { get; set; }
+ public FetterLevel ExpLevel { get; set; }
}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/Flat.cs b/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/Flat.cs
index 4049eb1e..40bec224 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/Flat.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/Flat.cs
@@ -1,6 +1,7 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
+using Snap.Hutao.Core.Json.Annotation;
using Snap.Hutao.Model.Intrinsic;
namespace Snap.Hutao.Web.Enka.Model;
@@ -16,21 +17,21 @@ internal sealed class Flat
/// Hash for Equipment Name
///
[JsonPropertyName("nameTextMapHash")]
- public string NameTextMapHash { get; set; } = default!;
+ public ulong NameTextMapHash { get; set; }
///
/// 套装名称
/// Hash for Artifact Set Name
///
[JsonPropertyName("setNameTextMapHash")]
- public string? SetNameTextMapHash { get; set; }
+ public ulong SetNameTextMapHash { get; set; }
///
/// 等级
/// Rarity Level of Equipment
///
[JsonPropertyName("rankLevel")]
- public int RankLevel { get; set; }
+ public QualityType RankLevel { get; set; }
///
/// 圣遗物主属性
@@ -53,7 +54,7 @@ internal sealed class Flat
/// ITEM_RELIQUARY
///
[JsonPropertyName("itemType")]
- [JsonConverter(typeof(JsonStringEnumConverter))]
+ [JsonEnum(JsonSerializeType.String)]
public ItemType ItemType { get; set; } = default!;
///
@@ -69,7 +70,7 @@ internal sealed class Flat
/// 值为
///
[JsonPropertyName("equipType")]
- [JsonConverter(typeof(JsonStringEnumConverter))]
+ [JsonEnum(JsonSerializeType.String)]
public EquipType EquipType { get; set; }
///
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/PlayerInfo.cs b/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/PlayerInfo.cs
index 2095bd98..b58afd71 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/PlayerInfo.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/PlayerInfo.cs
@@ -20,7 +20,7 @@ internal sealed class PlayerInfo
/// 等级
///
[JsonPropertyName("level")]
- public int Level { get; set; }
+ public uint Level { get; set; }
///
/// 签名
@@ -34,42 +34,42 @@ internal sealed class PlayerInfo
/// Player World Level
///
[JsonPropertyName("worldLevel")]
- public int WorldLevel { get; set; }
+ public uint WorldLevel { get; set; }
///
/// 名片的Id
/// Profile Namecard ID
///
[JsonPropertyName("nameCardId")]
- public int NameCardId { get; set; }
+ public uint NameCardId { get; set; }
///
/// 完成的成就个数
/// Number of Completed Achievements
///
[JsonPropertyName("finishAchievementNum")]
- public int FinishAchievementNum { get; set; }
+ public uint FinishAchievementNum { get; set; }
///
/// 深渊层数
/// Abyss Floor
///
[JsonPropertyName("towerFloorIndex")]
- public int TowerFloorIndex { get; set; }
+ public uint TowerFloorIndex { get; set; }
///
/// 深渊间数
/// Abyss Floor's Level
///
[JsonPropertyName("towerLevelIndex")]
- public int TowerLevelIndex { get; set; }
+ public uint TowerLevelIndex { get; set; }
///
/// 展示的角色信息
/// List of Character IDs and Levels
///
[JsonPropertyName("showAvatarInfoList")]
- public IList ShowAvatarInfoList { get; set; } = default!;
+ public List ShowAvatarInfoList { get; set; } = default!;
///
/// 展示的名片信息
@@ -84,4 +84,4 @@ internal sealed class PlayerInfo
///
[JsonPropertyName("profilePicture")]
public ProfilePicture ProfilePicture { get; set; } = default!;
-}
+}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/ProfilePicture.cs b/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/ProfilePicture.cs
index d7d90b28..c37aabe5 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/ProfilePicture.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/ProfilePicture.cs
@@ -1,6 +1,8 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
+using Snap.Hutao.Model.Primitive;
+
namespace Snap.Hutao.Web.Enka.Model;
///
@@ -13,11 +15,11 @@ internal sealed class ProfilePicture
/// 使用的角色Id
///
[JsonPropertyName("avatarId")]
- public int AvatarId { get; set; }
+ public AvatarId AvatarId { get; set; }
///
/// 衣装Id
///
[JsonPropertyName("costumeId")]
- public int? CostumeId { get; set; }
+ public CostumeId? CostumeId { get; set; }
}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/Reliquary.cs b/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/Reliquary.cs
index 5f7a1060..28b0936b 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/Reliquary.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/Reliquary.cs
@@ -1,6 +1,8 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
+using Snap.Hutao.Model.Primitive;
+
namespace Snap.Hutao.Web.Enka.Model;
///
@@ -11,22 +13,22 @@ internal sealed class Reliquary
{
///
/// 等级 +20 = 21
- /// [1,21]
+ /// [1-21]
/// Artifact Level [1-21]
///
[JsonPropertyName("level")]
- public int Level { get; set; }
+ public ReliquaryLevel Level { get; set; }
///
/// 主属性Id
/// Artifact Main Stat ID
///
[JsonPropertyName("mainPropId")]
- public int MainPropId { get; set; }
+ public ReliquaryMainAffixId MainPropId { get; set; }
///
/// 强化属性Id
///
[JsonPropertyName("appendPropIdList")]
- public List AppendPropIdList { get; set; } = default!;
+ public List AppendPropIdList { get; set; } = default!;
}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/ReliquaryMainstat.cs b/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/ReliquaryMainstat.cs
index c7b423d5..70a1428a 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/ReliquaryMainstat.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/ReliquaryMainstat.cs
@@ -10,7 +10,7 @@ namespace Snap.Hutao.Web.Enka.Model;
/// 圣遗物主属性
///
[HighQuality]
-internal sealed class ReliquaryMainstat
+internal sealed class ReliquaryMainstat : Stat
{
///
/// Equipment Append Property Name.
@@ -18,10 +18,4 @@ internal sealed class ReliquaryMainstat
[JsonPropertyName("mainPropId")]
[JsonEnum(JsonSerializeType.String)]
public FightProperty MainPropId { get; set; }
-
- ///
- /// Property Value
- ///
- [JsonPropertyName("statValue")]
- public double StatValue { get; set; }
}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/ReliquarySubstat.cs b/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/ReliquarySubstat.cs
index a827df1f..a71a44f0 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/ReliquarySubstat.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/ReliquarySubstat.cs
@@ -10,7 +10,7 @@ namespace Snap.Hutao.Web.Enka.Model;
/// 圣遗物副属性
///
[HighQuality]
-internal sealed class ReliquarySubstat
+internal class ReliquarySubstat : Stat
{
///
/// 增加属性
@@ -18,10 +18,4 @@ internal sealed class ReliquarySubstat
[JsonPropertyName("appendPropId")]
[JsonEnum(JsonSerializeType.String)]
public FightProperty AppendPropId { get; set; }
-
- ///
- /// 值
- ///
- [JsonPropertyName("statValue")]
- public double StatValue { get; set; }
}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/ShowAvatarInfo.cs b/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/ShowAvatarInfo.cs
index 724928ca..07d6a38e 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/ShowAvatarInfo.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/ShowAvatarInfo.cs
@@ -1,6 +1,8 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
+using Snap.Hutao.Model.Primitive;
+
namespace Snap.Hutao.Web.Enka.Model;
///
@@ -14,18 +16,18 @@ internal sealed class ShowAvatarInfo
/// Character ID
///
[JsonPropertyName("avatarId")]
- public int AvatarId { get; set; }
+ public AvatarId AvatarId { get; set; }
///
/// 角色等级
/// Character Level
///
[JsonPropertyName("level")]
- public int Level { get; set; }
+ public Level Level { get; set; }
///
/// 可能的皮肤Id
///
[JsonPropertyName("costumeId")]
- public int? CostumeId { get; set; }
+ public CostumeId? CostumeId { get; set; }
}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/Stat.cs b/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/Stat.cs
new file mode 100644
index 00000000..04cd5fa3
--- /dev/null
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/Stat.cs
@@ -0,0 +1,17 @@
+// Copyright (c) DGP Studio. All rights reserved.
+// Licensed under the MIT license.
+
+namespace Snap.Hutao.Web.Enka.Model;
+
+///
+/// 圣遗物属性值
+///
+internal abstract class Stat
+{
+ ///
+ /// 属性值
+ /// Property Value
+ ///
+ [JsonPropertyName("statValue")]
+ public float StatValue { get; set; }
+}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/TypeValue.cs b/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/TypeValue.cs
index d0fb21d6..9d0c95b9 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/TypeValue.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/TypeValue.cs
@@ -7,6 +7,7 @@ namespace Snap.Hutao.Web.Enka.Model;
///
/// 类型与值
+/// 与元数据的 TypeValue 不同!
///
[HighQuality]
internal sealed class TypeValue
@@ -24,7 +25,7 @@ internal sealed class TypeValue
///
/// 类型
/// 值
- public TypeValue(PlayerProperty type, int value)
+ public TypeValue(PlayerProperty type, uint value)
{
Type = type;
Value = value;
@@ -40,6 +41,5 @@ internal sealed class TypeValue
/// 值
///
[JsonPropertyName("val")]
- [JsonNumberHandling(JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)]
- public int Value { get; set; }
+ public uint Value { get; set; }
}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/Weapon.cs b/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/Weapon.cs
index b941ecf6..42f6e2db 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/Weapon.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/Weapon.cs
@@ -1,6 +1,8 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
+using Snap.Hutao.Model.Primitive;
+
namespace Snap.Hutao.Web.Enka.Model;
///
@@ -14,19 +16,19 @@ internal sealed class Weapon
/// Weapon Level
///
[JsonPropertyName("level")]
- public int Level { get; set; }
+ public Level Level { get; set; }
///
/// 突破等级
/// Weapon Ascension Level
///
[JsonPropertyName("promoteLevel")]
- public int PromoteLevel { get; set; }
+ public Level PromoteLevel { get; set; }
///
/// 精炼 相较于实际等级 -1
/// Weapon Refinement Level [0-4]
///
[JsonPropertyName("affixMap")]
- public Dictionary AffixMap { get; set; } = default!;
+ public Dictionary AffixMap { get; set; } = default!;
}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/WeaponStat.cs b/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/WeaponStat.cs
index 840f19da..a916087d 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/WeaponStat.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Enka/Model/WeaponStat.cs
@@ -1,26 +1,11 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
-using Snap.Hutao.Core.Json.Annotation;
-using Snap.Hutao.Model.Intrinsic;
-
namespace Snap.Hutao.Web.Enka.Model;
///
/// 武器属性
///
-internal sealed class WeaponStat
+internal sealed class WeaponStat : ReliquarySubstat
{
- ///
- /// 提升属性Id
- ///
- [JsonPropertyName("appendPropId")]
- [JsonEnum(JsonSerializeType.String)]
- public FightProperty AppendPropId { get; set; }
-
- ///
- /// 值
- ///
- [JsonPropertyName("statValue")]
- public float StatValue { get; set; }
}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/HttpClientDynamicSecretExtensions.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/HttpClientDynamicSecretExtension.cs
similarity index 93%
rename from src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/HttpClientDynamicSecretExtensions.cs
rename to src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/HttpClientDynamicSecretExtension.cs
index 6fcb149e..692d9f2a 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/HttpClientDynamicSecretExtensions.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/HttpClientDynamicSecretExtension.cs
@@ -10,7 +10,7 @@ namespace Snap.Hutao.Web.Hoyolab.DynamicSecret;
/// 动态密钥扩展
///
[HighQuality]
-internal static class HttpClientDynamicSecretExtensions
+internal static class HttpClientDynamicSecretExtension
{
///
/// 使用动态密钥
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Hk4e/Event/GachaInfo/GachaLogItem.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Hk4e/Event/GachaInfo/GachaLogItem.cs
index 85145295..ee0a60bf 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Hk4e/Event/GachaInfo/GachaLogItem.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Hk4e/Event/GachaInfo/GachaLogItem.cs
@@ -69,7 +69,7 @@ internal class GachaLogItem
///
[JsonPropertyName("rank_type")]
[JsonEnum(JsonSerializeType.NumberString)]
- public ItemQuality Rank { get; set; } = default!;
+ public QualityType Rank { get; set; } = default!;
///
/// Id
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Package.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Package.cs
index bf9cc75a..821e67f5 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Package.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Package.cs
@@ -25,7 +25,6 @@ internal class Package : PathMd5
/// 尺寸
///
[JsonPropertyName("size")]
- [JsonNumberHandling(JsonNumberHandling.AllowReadingFromString)]
public long Size { get; set; } = default!;
///
@@ -52,6 +51,5 @@ internal class Package : PathMd5
/// 包大小 bytes
///
[JsonPropertyName("package_size")]
- [JsonNumberHandling(JsonNumberHandling.AllowReadingFromString)]
public long PackageSize { get; set; } = default!;
}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/PluginItem.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/PluginItem.cs
index 67b0a00a..52f14be5 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/PluginItem.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/PluginItem.cs
@@ -25,7 +25,6 @@ internal sealed class PluginItem : NameMd5
/// 尺寸
///
[JsonPropertyName("size")]
- [JsonNumberHandling(JsonNumberHandling.AllowReadingFromString)]
public long Size { get; set; } = default!;
///
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/VoicePackage.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/VoicePackage.cs
index 0dcaf831..5329b291 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/VoicePackage.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/VoicePackage.cs
@@ -25,13 +25,11 @@ internal sealed class VoicePackage : PathMd5
/// 解压尺寸
///
[JsonPropertyName("size")]
- [JsonNumberHandling(JsonNumberHandling.AllowReadingFromString)]
public long Size { get; set; }
///
/// 包尺寸
///
[JsonPropertyName("package_size")]
- [JsonNumberHandling(JsonNumberHandling.AllowReadingFromString)]
public long PackageSize { get; set; } = default!;
}
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Event/Calculate/Avatar.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Event/Calculate/Avatar.cs
index 0f84ac09..de399c11 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Event/Calculate/Avatar.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Event/Calculate/Avatar.cs
@@ -15,7 +15,7 @@ internal sealed class Avatar : Calculable
/// 角色的星级
///
[JsonPropertyName("avatar_level")]
- public ItemQuality AvatarLevel { get; set; }
+ public QualityType AvatarLevel { get; set; }
///
/// 武器类型
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Event/Calculate/AvatarPromotionDelta.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Event/Calculate/AvatarPromotionDelta.cs
index b8a4d0a2..5fb04134 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Event/Calculate/AvatarPromotionDelta.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Event/Calculate/AvatarPromotionDelta.cs
@@ -21,13 +21,13 @@ internal sealed class AvatarPromotionDelta
/// 当前角色等级
///
[JsonPropertyName("avatar_level_current")]
- public int AvatarLevelCurrent { get; set; }
+ public uint AvatarLevelCurrent { get; set; }
///
/// 目标角色等级
///
[JsonPropertyName("avatar_level_target")]
- public int AvatarLevelTarget { get; set; }
+ public uint AvatarLevelTarget { get; set; }
///
/// 元素类型
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Event/Calculate/Calculable.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Event/Calculate/Calculable.cs
index ada77885..411b6c73 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Event/Calculate/Calculable.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Event/Calculate/Calculable.cs
@@ -1,6 +1,8 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
+using Snap.Hutao.Model.Primitive;
+
namespace Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate;
///
@@ -13,7 +15,7 @@ internal class Calculable
/// Id
///
[JsonPropertyName("id")]
- public int Id { get; set; }
+ public uint Id { get; set; }
///
/// 名称
@@ -31,7 +33,7 @@ internal class Calculable
/// 默认值设为1,因为部分API不返回该字段
///
[JsonPropertyName("level_current")]
- public int LevelCurrent { get; set; } = 1;
+ public uint LevelCurrent { get; set; } = 1;
///
/// 最大等级
@@ -43,7 +45,7 @@ internal class Calculable
/// 目标等级
///
[JsonIgnore]
- public int LevelTarget { get; set; }
+ public uint LevelTarget { get; set; }
///
/// 转化到提升差异
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Event/Calculate/GroupCalculable.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Event/Calculate/GroupCalculable.cs
index 1e623122..a47ff43c 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Event/Calculate/GroupCalculable.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Event/Calculate/GroupCalculable.cs
@@ -13,7 +13,7 @@ internal abstract class GroupCalculable : Calculable
/// 组Id
///
[JsonPropertyName("group_id")]
- public int GroupId { get; set; }
+ public uint GroupId { get; set; }
///
public override PromotionDelta ToPromotionDelta()
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Event/Calculate/Item.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Event/Calculate/Item.cs
index 93468585..2ef8573d 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Event/Calculate/Item.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Event/Calculate/Item.cs
@@ -39,5 +39,5 @@ internal sealed class Item
/// 物品星级 仅有家具为有效值
///
[JsonPropertyName("level")]
- public ItemQuality Level { get; set; }
+ public QualityType Level { get; set; }
}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Event/Calculate/PromotionDelta.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Event/Calculate/PromotionDelta.cs
index abb4972f..c32c939d 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Event/Calculate/PromotionDelta.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Event/Calculate/PromotionDelta.cs
@@ -13,17 +13,17 @@ internal sealed class PromotionDelta
/// 物品Id
///
[JsonPropertyName("id")]
- public int Id { get; set; }
+ public uint Id { get; set; }
///
/// 当前等级
///
[JsonPropertyName("level_current")]
- public int LevelCurrent { get; set; }
+ public uint LevelCurrent { get; set; }
///
/// 目标等级
///
[JsonPropertyName("level_target")]
- public int LevelTarget { get; set; }
+ public uint LevelTarget { get; set; }
}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/Avatar/Avatar.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/Avatar/Avatar.cs
index 64e50b45..23466e02 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/Avatar/Avatar.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/Avatar/Avatar.cs
@@ -40,19 +40,19 @@ internal class Avatar
/// 好感度
///
[JsonPropertyName("fetter")]
- public int Fetter { get; set; }
+ public FetterLevel Fetter { get; set; }
///
/// 等级
///
[JsonPropertyName("level")]
- public int Level { get; set; }
+ public Level Level { get; set; }
///
/// 稀有度
///
[JsonPropertyName("rarity")]
- public ItemQuality Rarity { get; set; }
+ public QualityType Rarity { get; set; }
///
/// 激活的命座数
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/Avatar/Reliquary.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/Avatar/Reliquary.cs
index 60df79f6..32a6bb13 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/Avatar/Reliquary.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/Avatar/Reliquary.cs
@@ -2,6 +2,7 @@
// Licensed under the MIT license.
using Snap.Hutao.Model.Intrinsic;
+using Snap.Hutao.Model.Primitive;
namespace Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.Avatar;
@@ -15,7 +16,7 @@ internal sealed class Reliquary
/// Id
///
[JsonPropertyName("id")]
- public int Id { get; set; }
+ public ReliquaryId Id { get; set; }
///
/// 名称
@@ -39,13 +40,13 @@ internal sealed class Reliquary
/// 稀有度
///
[JsonPropertyName("rarity")]
- public ItemQuality Rarity { get; set; }
+ public QualityType Rarity { get; set; }
///
/// 等级
///
[JsonPropertyName("level")]
- public int Level { get; set; }
+ public uint Level { get; set; }
///
/// 圣遗物套装
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/Avatar/Weapon.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/Avatar/Weapon.cs
index aca7a305..9f7f9991 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/Avatar/Weapon.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/Avatar/Weapon.cs
@@ -40,13 +40,13 @@ internal sealed class Weapon
/// 稀有度
///
[JsonPropertyName("rarity")]
- public ItemQuality Rarity { get; set; }
+ public QualityType Rarity { get; set; }
///
/// 等级
///
[JsonPropertyName("level")]
- public int Level { get; set; }
+ public Level Level { get; set; }
///
/// 突破等级
@@ -70,5 +70,5 @@ internal sealed class Weapon
/// 精炼等级
///
[JsonPropertyName("affix_level")]
- public int AffixLevel { get; set; }
+ public uint AffixLevel { get; set; }
}
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/CardClient.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/CardClient.cs
index b863f3ce..eb13bea3 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/CardClient.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/CardClient.cs
@@ -5,7 +5,6 @@ using Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient;
using Snap.Hutao.Model.Entity;
using Snap.Hutao.Web.Hoyolab.Annotation;
using Snap.Hutao.Web.Hoyolab.DynamicSecret;
-using Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.Widget;
using Snap.Hutao.Web.Response;
using System.Net.Http;
@@ -78,12 +77,12 @@ internal sealed class CardClient
/// 取消令牌
/// 桌面小组件数据
[ApiInformation(Cookie = CookieType.SToken, Salt = SaltType.X6)]
- public async Task>> GetWidgetDataAsync(User user, CancellationToken token)
+ public async Task> GetWidgetDataAsync(User user, CancellationToken token)
{
- Response>? resp = await httpClient
+ Response? resp = await httpClient
.SetUser(user, CookieType.SToken)
.UseDynamicSecret(DynamicSecretVersion.Gen2, SaltType.X6, false)
- .TryCatchGetFromJsonAsync>>(ApiEndpoints.CardWidgetData, options, logger, token)
+ .TryCatchGetFromJsonAsync>(ApiEndpoints.CardWidgetData2, options, logger, token)
.ConfigureAwait(false);
return Response.Response.DefaultIfNull(resp);
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/DailyNote/DailyNote.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/DailyNote/DailyNote.cs
index 95149d9a..a5110318 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/DailyNote/DailyNote.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/DailyNote/DailyNote.cs
@@ -7,27 +7,8 @@ namespace Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.DailyNote;
/// 实时便笺
///
[HighQuality]
-internal sealed class DailyNote
+internal sealed class DailyNote : DailyNoteCommon
{
- ///
- /// 当前树脂
- ///
- [JsonPropertyName("current_resin")]
- public int CurrentResin { get; set; }
-
- ///
- /// 最大树脂
- ///
- [JsonPropertyName("max_resin")]
- public int MaxResin { get; set; }
-
- ///
- /// 树脂恢复时间 类型的秒数
- ///
- [JsonPropertyName("resin_recovery_time")]
- [JsonNumberHandling(JsonNumberHandling.AllowReadingFromString)]
- public int ResinRecoveryTime { get; set; }
-
///
/// 格式化的树脂显示
///
@@ -59,18 +40,6 @@ internal sealed class DailyNote
}
}
- ///
- /// 委托完成数
- ///
- [JsonPropertyName("finished_task_num")]
- public int FinishedTaskNum { get; set; }
-
- ///
- /// 委托总数
- ///
- [JsonPropertyName("total_task_num")]
- public int TotalTaskNum { get; set; }
-
///
/// 格式化任务
///
@@ -80,12 +49,6 @@ internal sealed class DailyNote
get => $"{FinishedTaskNum}/{TotalTaskNum}";
}
- ///
- /// 4次委托额外奖励是否领取
- ///
- [JsonPropertyName("is_extra_task_reward_received")]
- public bool IsExtraTaskRewardReceived { get; set; }
-
///
/// 每日委托奖励字符串
///
@@ -131,41 +94,10 @@ internal sealed class DailyNote
get => $"{ResinDiscountUsedNum}/{ResinDiscountNumLimit}";
}
- ///
- /// 当前派遣数
- ///
- [JsonPropertyName("current_expedition_num")]
- public int CurrentExpeditionNum { get; set; }
-
- ///
- /// 最大派遣数
- ///
- [JsonPropertyName("max_expedition_num")]
- public int MaxExpeditionNum { get; set; }
-
- ///
- /// 派遣
- ///
- [JsonPropertyName("expeditions")]
- public List Expeditions { get; set; } = default!;
-
- ///
- /// 当前洞天宝钱
- ///
- [JsonPropertyName("current_home_coin")]
- public int CurrentHomeCoin { get; set; }
-
- ///
- /// 最大洞天宝钱
- ///
- [JsonPropertyName("max_home_coin")]
- public int MaxHomeCoin { get; set; }
-
///
/// 洞天宝钱恢复时间 类型的秒数
///
[JsonPropertyName("home_coin_recovery_time")]
- [JsonNumberHandling(JsonNumberHandling.AllowReadingFromString)]
public int HomeCoinRecoveryTime { get; set; }
///
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/DailyNote/DailyNoteCommon.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/DailyNote/DailyNoteCommon.cs
new file mode 100644
index 00000000..935a3019
--- /dev/null
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/DailyNote/DailyNoteCommon.cs
@@ -0,0 +1,76 @@
+// Copyright (c) DGP Studio. All rights reserved.
+// Licensed under the MIT license.
+
+namespace Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.DailyNote;
+
+///
+/// 实时便笺通用
+///
+internal abstract class DailyNoteCommon
+{
+ ///
+ /// 当前派遣数
+ ///
+ [JsonPropertyName("current_expedition_num")]
+ public int CurrentExpeditionNum { get; set; }
+
+ ///
+ /// 当前洞天宝钱
+ ///
+ [JsonPropertyName("current_home_coin")]
+ public int CurrentHomeCoin { get; set; }
+
+ ///
+ /// 当前树脂
+ ///
+ [JsonPropertyName("current_resin")]
+ public int CurrentResin { get; set; }
+
+ ///
+ /// 派遣
+ ///
+ [JsonPropertyName("expeditions")]
+ public List Expeditions { get; set; } = default!;
+
+ ///
+ /// 委托完成数
+ ///
+ [JsonPropertyName("finished_task_num")]
+ public int FinishedTaskNum { get; set; }
+
+ ///
+ /// 4次委托额外奖励是否领取
+ ///
+ [JsonPropertyName("is_extra_task_reward_received")]
+ public bool IsExtraTaskRewardReceived { get; set; }
+
+ ///
+ /// 最大派遣数
+ ///
+ [JsonPropertyName("max_expedition_num")]
+ public int MaxExpeditionNum { get; set; }
+
+ ///
+ /// 最大洞天宝钱
+ ///
+ [JsonPropertyName("max_home_coin")]
+ public int MaxHomeCoin { get; set; }
+
+ ///
+ /// 最大树脂
+ ///
+ [JsonPropertyName("max_resin")]
+ public int MaxResin { get; set; }
+
+ ///
+ /// 树脂恢复时间 类型的秒数
+ ///
+ [JsonPropertyName("resin_recovery_time")]
+ public int ResinRecoveryTime { get; set; }
+
+ ///
+ /// 委托总数
+ ///
+ [JsonPropertyName("total_task_num")]
+ public int TotalTaskNum { get; set; }
+}
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/DailyNote/Expedition.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/DailyNote/Expedition.cs
index 20975bcc..ceef0ebf 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/DailyNote/Expedition.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/DailyNote/Expedition.cs
@@ -39,7 +39,6 @@ internal sealed class Expedition
/// 剩余时间
///
[JsonPropertyName("remained_time")]
- [JsonNumberHandling(JsonNumberHandling.AllowReadingFromString)]
public int RemainedTime { get; set; }
///
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/DailyNote/ExpeditionStatus.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/DailyNote/ExpeditionStatus.cs
index 9f929e8d..541b7af4 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/DailyNote/ExpeditionStatus.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/DailyNote/ExpeditionStatus.cs
@@ -9,13 +9,13 @@ namespace Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.DailyNote;
[HighQuality]
internal enum ExpeditionStatus
{
- ///
- /// 进行中
- ///
- Ongoing,
-
///
/// 完成
///
Finished,
+
+ ///
+ /// 进行中
+ ///
+ Ongoing,
}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/DailyNote/WidgetDailyNote.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/DailyNote/WidgetDailyNote.cs
new file mode 100644
index 00000000..9ff9efa0
--- /dev/null
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/DailyNote/WidgetDailyNote.cs
@@ -0,0 +1,22 @@
+// Copyright (c) DGP Studio. All rights reserved.
+// Licensed under the MIT license.
+
+namespace Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.DailyNote;
+
+///
+/// 实时便笺小组件数据
+///
+internal sealed class WidgetDailyNote : DailyNoteCommon
+{
+ ///
+ /// 是否签到
+ ///
+ [JsonPropertyName("has_signed")]
+ public bool HasSigned { get; set; }
+
+ ///
+ /// 签到页面链接
+ ///
+ [JsonPropertyName("sign_url")]
+ public Uri SignUrl { get; set; } = default!;
+}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/Avatar.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/Avatar.cs
index 3bfae5a6..4961e810 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/Avatar.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/Avatar.cs
@@ -1,6 +1,8 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
+using Snap.Hutao.Model.Primitive;
+
namespace Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.SpiralAbyss;
///
@@ -13,7 +15,7 @@ internal sealed class Avatar
/// Id
///
[JsonPropertyName("id")]
- public int Id { get; set; }
+ public AvatarId Id { get; set; }
///
/// 图标
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/Battle.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/Battle.cs
index 4efef4e9..2c89f184 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/Battle.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/Battle.cs
@@ -19,7 +19,6 @@ internal sealed class Battle
/// 时间戳
///
[JsonPropertyName("timestamp")]
- [JsonNumberHandling(JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)]
public long Timestamp { get; set; } = default!;
///
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/Floor.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/Floor.cs
index cc495f67..4a20f960 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/Floor.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/Floor.cs
@@ -31,7 +31,6 @@ internal sealed class Floor
/// 结束时间
///
[JsonPropertyName("settle_time")]
- [JsonNumberHandling(JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)]
public long SettleTime { get; set; } = default!;
///
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/Rank.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/Rank.cs
index 3cce519c..8964640a 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/Rank.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/Rank.cs
@@ -1,6 +1,8 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
+using Snap.Hutao.Model.Primitive;
+
namespace Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.SpiralAbyss;
///
@@ -13,7 +15,7 @@ internal sealed class Rank
/// 角色Id
///
[JsonPropertyName("avatar_id")]
- public int AvatarId { get; set; }
+ public AvatarId AvatarId { get; set; }
///
/// 角色图标
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/SpiralAbyss.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/SpiralAbyss.cs
index a4eead2b..9f1c1cab 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/SpiralAbyss.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/SpiralAbyss.cs
@@ -19,14 +19,12 @@ internal sealed class SpiralAbyss
/// 开始时间
///
[JsonPropertyName("start_time")]
- [JsonNumberHandling(JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)]
public long StartTime { get; set; }
///
/// 结束时间
///
[JsonPropertyName("end_time")]
- [JsonNumberHandling(JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)]
public long EndTime { get; set; }
///
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/Widget/WidgetData.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/Widget/WidgetData.cs
deleted file mode 100644
index 9fe391d2..00000000
--- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/Widget/WidgetData.cs
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright (c) DGP Studio. All rights reserved.
-// Licensed under the MIT license.
-
-namespace Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.Widget;
-
-///
-/// 小组件数据
-///
-[HighQuality]
-internal sealed class WidgetData
-{
- ///
- /// 游戏Id 2
- ///
- [JsonPropertyName("game_id")]
- public int GameId { get; set; }
-
- ///
- /// 游戏内Uid
- ///
- [JsonPropertyName("game_role_id")]
- public string GameRoleId { get; set; } = default!;
-
- ///
- /// 昵称
- ///
- [JsonPropertyName("nickname")]
- public string Nickname { get; set; } = default!;
-
- ///
- /// 区服
- ///
- [JsonPropertyName("region")]
- public string Region { get; set; } = default!;
-
- ///
- /// 冒险等阶
- ///
- [JsonPropertyName("level")]
- public int Level { get; set; }
-
- ///
- /// 背景图片
- ///
- [JsonPropertyName("background_image")]
- public string BackgroundImage { get; set; } = default!;
-
- ///
- /// 数据
- ///
- [JsonPropertyName("data")]
- public List Data { get; set; } = default!;
-
- ///
- /// 区服名称
- ///
- [JsonPropertyName("region_name")]
- public string RegionName { get; set; } = default!;
-}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/Widget/WidgetDataItem.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/Widget/WidgetDataItem.cs
deleted file mode 100644
index a7dbd902..00000000
--- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/Widget/WidgetDataItem.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) DGP Studio. All rights reserved.
-// Licensed under the MIT license.
-
-namespace Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.Widget;
-
-///
-/// 小组件数据项
-///
-[HighQuality]
-internal sealed class WidgetDataItem
-{
- ///
- /// 项目名称
- ///
- [JsonPropertyName("name")]
- public string Name { get; set; } = default!;
-
- ///
- /// 类型 均为 "String"
- ///
- [JsonPropertyName("type")]
- public string Type { get; set; } = default!;
-
- ///
- /// 显示值
- ///
- [JsonPropertyName("value")]
- public string Value { get; set; } = default!;
-}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/GachaLog/GachaItem.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/GachaLog/GachaItem.cs
index d7c72a00..066894a2 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/GachaLog/GachaItem.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/GachaLog/GachaItem.cs
@@ -25,7 +25,7 @@ internal sealed class GachaItem
///
/// 物品Id
///
- public int ItemId { get; set; }
+ public uint ItemId { get; set; }
///
/// 获取时间
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/AvatarAppearanceRank.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/AvatarAppearanceRank.cs
index fa027196..c2c37248 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/AvatarAppearanceRank.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/AvatarAppearanceRank.cs
@@ -1,6 +1,8 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
+using Snap.Hutao.Model.Primitive;
+
namespace Snap.Hutao.Web.Hutao.Model;
///
@@ -17,5 +19,5 @@ internal sealed class AvatarAppearanceRank
///
/// 排行
///
- public List> Ranks { get; set; } = default!;
+ public List> Ranks { get; set; } = default!;
}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/AvatarCollocation.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/AvatarCollocation.cs
index 2c3cc637..2cfa44ed 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/AvatarCollocation.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/AvatarCollocation.cs
@@ -1,6 +1,8 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
+using Snap.Hutao.Model.Primitive;
+
namespace Snap.Hutao.Web.Hutao.Model;
///
@@ -12,12 +14,12 @@ internal sealed class AvatarCollocation : AvatarBuild
///
/// 其他角色
///
- public List> Avatars { get; set; } = default!;
+ public List> Avatars { get; set; } = default!;
///
/// 武器
///
- public List> Weapons { get; set; } = default!;
+ public List> Weapons { get; set; } = default!;
///
/// 圣遗物
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/AvatarUsageRank.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/AvatarUsageRank.cs
index 26e15d61..a6bd71ed 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/AvatarUsageRank.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/AvatarUsageRank.cs
@@ -1,6 +1,8 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
+using Snap.Hutao.Model.Primitive;
+
namespace Snap.Hutao.Web.Hutao.Model;
///
@@ -17,5 +19,5 @@ internal sealed class AvatarUsageRank
///
/// 排行
///
- public List> Ranks { get; set; } = default!;
+ public List> Ranks { get; set; } = default!;
}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/Post/SimpleAvatar.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/Post/SimpleAvatar.cs
index bef43bf5..241714cf 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/Post/SimpleAvatar.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/Post/SimpleAvatar.cs
@@ -1,6 +1,7 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
+using Snap.Hutao.Model.Primitive;
using Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.Avatar;
namespace Snap.Hutao.Web.Hutao.Model.Post;
@@ -26,12 +27,12 @@ internal sealed class SimpleAvatar
///
/// 角色 Id
///
- public int AvatarId { get; set; }
+ public AvatarId AvatarId { get; set; }
///
/// 武器 Id
///
- public int WeaponId { get; set; }
+ public WeaponId WeaponId { get; set; }
///
/// 圣遗物套装Id
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/Post/SimpleBattle.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/Post/SimpleBattle.cs
index cc470cb8..a0263152 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/Post/SimpleBattle.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/Post/SimpleBattle.cs
@@ -1,6 +1,7 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
+using Snap.Hutao.Model.Primitive;
using Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.SpiralAbyss;
namespace Snap.Hutao.Web.Hutao.Model.Post;
@@ -29,5 +30,5 @@ internal sealed class SimpleBattle
///
/// 角色列表
///
- public IEnumerable Avatars { get; set; } = default!;
+ public IEnumerable Avatars { get; set; } = default!;
}
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/Post/SimpleRank.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/Post/SimpleRank.cs
index cf701355..73c80517 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/Post/SimpleRank.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/Post/SimpleRank.cs
@@ -1,6 +1,7 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
+using Snap.Hutao.Model.Primitive;
using Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.SpiralAbyss;
namespace Snap.Hutao.Web.Hutao.Model.Post;
@@ -23,7 +24,7 @@ internal sealed class SimpleRank
///
/// 角色Id
///
- public int AvatarId { get; set; }
+ public AvatarId AvatarId { get; set; }
///
/// 值
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/ReliquarySet.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/ReliquarySet.cs
index 9ac806df..0bc584b2 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/ReliquarySet.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/ReliquarySet.cs
@@ -19,7 +19,7 @@ internal sealed class ReliquarySet
{
string[]? deconstructed = set.Split('-');
- EquipAffixId = int.Parse(deconstructed[0]);
+ EquipAffixId = uint.Parse(deconstructed[0]);
Count = int.Parse(deconstructed[1]);
}
@@ -36,6 +36,6 @@ internal sealed class ReliquarySet
///
public override string ToString()
{
- return $"{(int)EquipAffixId}-{Count}";
+ return $"{EquipAffixId.Value}-{Count}";
}
}
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/WeaponCollocation.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/WeaponCollocation.cs
index 093f539c..0d170e95 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/WeaponCollocation.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/WeaponCollocation.cs
@@ -1,6 +1,8 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
+using Snap.Hutao.Model.Primitive;
+
namespace Snap.Hutao.Web.Hutao.Model;
///
@@ -12,5 +14,5 @@ internal sealed class WeaponCollocation : WeaponBuild
///
/// 其他角色
///
- public List> Avatars { get; set; } = default!;
+ public List> Avatars { get; set; } = default!;
}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/HutaoEndpoints.cs b/src/Snap.Hutao/Snap.Hutao/Web/HutaoEndpoints.cs
index 7b76ac61..390d4b54 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/HutaoEndpoints.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/HutaoEndpoints.cs
@@ -157,6 +157,28 @@ internal static class HutaoEndpoints
{
return $"{HutaoMetadataSnapGenshinApi}/{locale}/{fileName}";
}
+
+ ///
+ /// 胡桃元数据2文件
+ ///
+ /// 语言
+ /// 文件名称
+ /// 路径
+ public static string HutaoMetadata2File(string locale, string fileName)
+ {
+ return $"{HutaoMetadata2SnapGenshinApi}/Genshin/{locale}/{fileName}";
+ }
+
+ ///
+ /// Github 元数据文件
+ ///
+ /// 语言
+ /// 文件名称
+ /// 路径
+ public static string RawGithubUserContentMetadataFile(string locale, string fileName)
+ {
+ return $"{RawGithubUserContentSnapMetadataApi}/Genshin/{locale}/{fileName}";
+ }
#endregion
#region Static & Zip
@@ -200,6 +222,8 @@ internal static class HutaoEndpoints
private const string HomaSnapGenshinApi = "https://homa.snapgenshin.com";
private const string HutaoMetadataSnapGenshinApi = "https://hutao-metadata.snapgenshin.com";
+ private const string HutaoMetadata2SnapGenshinApi = "https://hutao-metadata2.snapgenshin.com";
+ private const string RawGithubUserContentSnapMetadataApi = "https://raw.githubusercontent.com/DGP-Studio/Snap.Metadata/main";
private const string StaticSnapGenshinApi = "https://static.snapgenshin.com";
private const string StaticZipSnapGenshinApi = "https://static-zip.snapgenshin.com";
}
\ No newline at end of file