diff --git a/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.resx b/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.resx
index 1f7e8c14..f6d73cbe 100644
--- a/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.resx
+++ b/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.resx
@@ -2249,6 +2249,12 @@
设备 ID
+
+ IP:{0},归属:{1}
+
+
+ 设备 IP
+
在祈愿记录页面显示或隐藏无记录的历史祈愿活动
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Hutao/HutaoUserOptions.cs b/src/Snap.Hutao/Snap.Hutao/Service/Hutao/HutaoUserOptions.cs
index 87074a42..efdd065f 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/Hutao/HutaoUserOptions.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/Hutao/HutaoUserOptions.cs
@@ -19,6 +19,7 @@ internal sealed class HutaoUserOptions : ObservableObject, IOptions
public string? ActualUserName { get => IsLoggedIn ? UserName : null; }
+ ///
+ /// 设备当前IP
+ ///
+ public IPInfo IPInfo { get => ipInfo; set => ipInfo = value; }
+
///
/// 是否已登录
///
@@ -131,6 +137,11 @@ internal sealed class HutaoUserOptions : ObservableObject, IOptions
+
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/HomaPassportClient.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/HomaPassportClient.cs
index 6e93e96a..4c35a2a3 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/HomaPassportClient.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/HomaPassportClient.cs
@@ -193,6 +193,17 @@ internal sealed partial class HomaPassportClient
return HutaoResponse.DefaultIfNull(resp);
}
+ public async ValueTask GetIPInfoAsync(CancellationToken token = default)
+ {
+ HttpRequestMessageBuilder builder = httpRequestMessageBuilderFactory.Create()
+ .SetRequestUri(HutaoEndpoints.Ip)
+ .Get();
+
+ IPInfo? resp = await builder.TryCatchSendAsync(httpClient, logger, token).ConfigureAwait(false);
+
+ return resp ?? new();
+ }
+
private static string Encrypt(string text)
{
byte[] plaintextBytes = Encoding.UTF8.GetBytes(text);
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/IPInfo.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/IPInfo.cs
new file mode 100644
index 00000000..3a080ea4
--- /dev/null
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/IPInfo.cs
@@ -0,0 +1,24 @@
+namespace Snap.Hutao.Web.Hutao;
+
+internal sealed class IPInfo
+{
+ public IPInfo()
+ {
+ }
+
+ [JsonConstructor]
+ public IPInfo(string ip, string division)
+ {
+ Ip = ip;
+ Division = division;
+ }
+
+ public string Ip { get; set; } = "Unknown";
+
+ public string Division { get; set; } = "Unknown";
+
+ public override string ToString()
+ {
+ return SH.FormatViewPageSettingDeviceIpDescription(Ip, Division);
+ }
+}
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/HutaoEndpoints.cs b/src/Snap.Hutao/Snap.Hutao/Web/HutaoEndpoints.cs
index 1ee466fb..dbf33add 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/HutaoEndpoints.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/HutaoEndpoints.cs
@@ -11,6 +11,7 @@ namespace Snap.Hutao.Web;
///
[HighQuality]
[SuppressMessage("", "SA1201")]
+[SuppressMessage("", "SA1203")]
[SuppressMessage("", "SA1124")]
internal static class HutaoEndpoints
{
@@ -22,6 +23,8 @@ internal static class HutaoEndpoints
public const string AnnouncementUpload = $"{HomaSnapGenshinApi}/Service/Announcement/Upload";
+ public const string Ip = $"{ApiSnapGenshin}/ip";
+
public static string GachaLogCompensation(int days)
{
return $"{HomaSnapGenshinApi}/Service/GachaLog/Compensation?days={days}";