From af3f886ea47a92abfcd261f9b245e858f7e583c1 Mon Sep 17 00:00:00 2001 From: WindDrift <115442729+WindDrift@users.noreply.github.com> Date: Sun, 26 Jul 2026 18:35:39 +0800 Subject: [PATCH 1/4] =?UTF-8?q?feat(gacha):=20=E5=8D=87=E7=BA=A7=20UIGF=20?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E8=87=B3=20v4.2=EF=BC=8C=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E5=8D=83=E6=98=9F=E5=A5=87=E5=9F=9F=E6=8A=BD=E5=8D=A1=E8=AE=B0?= =?UTF-8?q?=E5=BD=95=E5=AF=BC=E5=85=A5=E5=AF=BC=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Starward.Language/Lang.Designer.cs | 37 +++- src/Starward.Language/Lang.resx | 13 +- src/Starward.Language/Lang.zh-CN.resx | 13 +- src/Starward/Features/Gacha/GachaLogPage.xaml | 12 +- .../Features/Gacha/GachaLogPage.xaml.cs | 35 ++++ .../Gacha/UIGF/GachaUidArchiveDisplay.cs | 13 ++ src/Starward/Features/Gacha/UIGF/UIGF4File.cs | 17 +- .../Features/Gacha/UIGF/UIGF4GachaWindow.xaml | 30 +++- .../Features/Gacha/UIGF/UIGFGachaService.cs | 161 +++++++++++++++++- .../Features/Setting/ToolboxSetting.xaml.cs | 2 +- 10 files changed, 306 insertions(+), 27 deletions(-) diff --git a/src/Starward.Language/Lang.Designer.cs b/src/Starward.Language/Lang.Designer.cs index d42683ce9..2b9e95f83 100644 --- a/src/Starward.Language/Lang.Designer.cs +++ b/src/Starward.Language/Lang.Designer.cs @@ -1951,7 +1951,16 @@ public static string GachaImportAndExportWindow_Count { return ResourceManager.GetString("GachaImportAndExportWindow_Count", resourceCulture); } } - + + /// + /// 查找类似 Archive Type 的本地化字符串。 + /// + public static string GachaImportAndExportWindow_ArchiveType { + get { + return ResourceManager.GetString("GachaImportAndExportWindow_ArchiveType", resourceCulture); + } + } + /// /// 查找类似 Export 的本地化字符串。 /// @@ -2214,14 +2223,32 @@ public static string GachaLogPage_ImportAndExport { } /// - /// 查找类似 Import from JSON 的本地化字符串。 + /// 查找类似 Import from UIGF v3.0 的本地化字符串。 /// - public static string GachaLogPage_ImportFromJson { + public static string GachaLogPage_ImportFromUIGF30 { get { - return ResourceManager.GetString("GachaLogPage_ImportFromJson", resourceCulture); + return ResourceManager.GetString("GachaLogPage_ImportFromUIGF30", resourceCulture); } } - + + /// + /// 查找类似 UIGF v3.0 does not support Miliastra Wonderland Ode 的本地化字符串。 + /// + public static string GachaLogPage_UIGF30DoesNotSupportMiliastraWonderlandOde { + get { + return ResourceManager.GetString("GachaLogPage_UIGF30DoesNotSupportMiliastraWonderlandOde", resourceCulture); + } + } + + /// + /// 查找类似 This account has Miliastra Wonderland Ode records, but the UIGF v3.0 format cannot carry them. 的本地化字符串。 + /// + public static string GachaLogPage_UIGF30DoesNotSupportMiliastraWonderlandOdeDesc { + get { + return ResourceManager.GetString("GachaLogPage_UIGF30DoesNotSupportMiliastraWonderlandOdeDesc", resourceCulture); + } + } + /// /// 查找类似 Input URL 的本地化字符串。 /// diff --git a/src/Starward.Language/Lang.resx b/src/Starward.Language/Lang.resx index 131330879..d2618ac32 100644 --- a/src/Starward.Language/Lang.resx +++ b/src/Starward.Language/Lang.resx @@ -343,8 +343,14 @@ closing the program during decompression will cause game file corruption. Export as - - Import from JSON + + Import from UIGF v3.0 + + + UIGF v3.0 does not support Miliastra Wonderland Ode + + + This account has Miliastra Wonderland Ode records, but the UIGF v3.0 format cannot carry them. If you continue, those records will be left out of the exported file. To export them, use UIGF v4.2 instead. Show Novice Gacha Type @@ -1917,6 +1923,9 @@ You are welcome to submit the exported data to the following repository: Count + + Archive Type + Time (Server Time Zone) diff --git a/src/Starward.Language/Lang.zh-CN.resx b/src/Starward.Language/Lang.zh-CN.resx index bbc6bd77f..525fe0577 100644 --- a/src/Starward.Language/Lang.zh-CN.resx +++ b/src/Starward.Language/Lang.zh-CN.resx @@ -343,8 +343,14 @@ 导出为 - - 从 JSON 导入 + + 从 UIGF v3.0 导入 + + + UIGF v3.0 不支持千星奇域 + + + 当前账号存在千星奇域抽卡记录,但 UIGF v3.0 格式无法承载这部分数据。若选择继续,导出的文件将不包含千星奇域记录。如需导出,请改用 UIGF v4.2。 显示新手卡池 @@ -1917,6 +1923,9 @@ 数量 + + 档案类型 + 时间 (服务器时区) diff --git a/src/Starward/Features/Gacha/GachaLogPage.xaml b/src/Starward/Features/Gacha/GachaLogPage.xaml index 892827ba8..ed95c0e2f 100644 --- a/src/Starward/Features/Gacha/GachaLogPage.xaml +++ b/src/Starward/Features/Gacha/GachaLogPage.xaml @@ -209,10 +209,10 @@ HorizontalAlignment="Stretch" Command="{x:Bind ExportGachaLogCommand}" CommandParameter="json" - Content="Json" + Content="UIGF v3.0" CornerRadius="0,4,4,0" /> - + - + + + diff --git a/src/Starward/Features/Gacha/GachaLogPage.xaml.cs b/src/Starward/Features/Gacha/GachaLogPage.xaml.cs index 9b9237108..a1856b23e 100644 --- a/src/Starward/Features/Gacha/GachaLogPage.xaml.cs +++ b/src/Starward/Features/Gacha/GachaLogPage.xaml.cs @@ -58,6 +58,15 @@ protected override void OnNavigatedTo(NavigationEventArgs e) { base.OnNavigatedTo(e); GachaTypeText = GachaLogService.GetGachaLogText(CurrentGameBiz); + // 旧版导出对应的标准:原神是 UIGF v3.0,星铁是 SRGF v1.0, + // 绝区零没有对应标准,Starward 只是套用了同样的结构,故仍标为 JSON + LegacyFormatName = CurrentGameBiz.Game switch + { + GameBiz.hk4e => "UIGF v3.0", + GameBiz.hkrpg => "SRGF v1.0", + _ => "JSON", + }; + LegacyImportText = string.Format(Lang.GachaLogPage_ImportFrom0, LegacyFormatName); if (CurrentGameBiz.Game == GameBiz.hk4e) { EnableGenshinGachaItemStats = true; @@ -101,6 +110,18 @@ protected override void OnNavigatedTo(NavigationEventArgs e) public string GachaTypeText { get; set => SetProperty(ref field, value); } + /// + /// 旧版(非 UIGF v4.x)导出格式名称,随游戏变化 + /// + public string LegacyFormatName { get; set => SetProperty(ref field, value); } = "JSON"; + + + /// + /// 旧版导入按钮文字,如「从 UIGF v3.0 导入」 + /// + public string LegacyImportText { get; set => SetProperty(ref field, value); } = ""; + + public ObservableCollection UidList { get; set => SetProperty(ref field, value); } diff --git a/src/Starward/Features/Gacha/UIGF/UIGF4File.cs b/src/Starward/Features/Gacha/UIGF/UIGF4File.cs index 7e4d110a3..42f2561e9 100644 --- a/src/Starward/Features/Gacha/UIGF/UIGF4File.cs +++ b/src/Starward/Features/Gacha/UIGF/UIGF4File.cs @@ -98,8 +98,13 @@ public class UIGF4GachaArchive public int Timezone { get; set; } + /// + /// 语言代码。标准未将其列入 required,但定义了 enum,空字符串不是合法取值, + /// 因此无法确定语言时必须整个省略该字段,而不能写 ""。 + /// [JsonPropertyName("lang")] - public string Lang { get; set; } + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Lang { get; set; } [JsonPropertyName("list")] diff --git a/src/Starward/Features/Gacha/UIGF/UIGF4GachaWindow.xaml b/src/Starward/Features/Gacha/UIGF/UIGF4GachaWindow.xaml index a5264a492..5872f1bed 100644 --- a/src/Starward/Features/Gacha/UIGF/UIGF4GachaWindow.xaml +++ b/src/Starward/Features/Gacha/UIGF/UIGF4GachaWindow.xaml @@ -61,7 +61,7 @@ @@ -161,7 +161,7 @@ TextWrapping="Wrap" /> diff --git a/src/Starward/Features/Gacha/UIGF/UIGFGachaService.cs b/src/Starward/Features/Gacha/UIGF/UIGFGachaService.cs index 55ee6d6e7..157a100f5 100644 --- a/src/Starward/Features/Gacha/UIGF/UIGFGachaService.cs +++ b/src/Starward/Features/Gacha/UIGF/UIGFGachaService.cs @@ -201,7 +201,7 @@ private UIGF4GachaArchive GetUIGFGachaArchiveForGenshin(lo { Uid = uid, List = list.ToList(), - Lang = list.LastOrDefault()?.Lang ?? "", + Lang = list.LastOrDefault()?.Lang is { Length: > 0 } l ? l : null, }; archive.Timezone = uid.ToString()[0] switch { @@ -216,17 +216,24 @@ private UIGF4GachaArchive GetUIGFGachaArchiveForGenshin(lo /// /// 千星奇域,UIGF v4.2 的 hk4e_ugc 区段。 - /// 记录本身没有 lang 字段,region 与 is_up 是标准未定义的扩展字段,随记录一并写出以便无损往返。 + /// 记录本身没有 lang 字段,故从同一 Uid 的原神本体记录推导,再退回到抽卡语言设置; + /// 两者都拿不到时留 null 整个省略该字段,避免写出 enum 不允许的空字符串。 + /// region 与 is_up 是标准未定义的扩展字段,随记录一并写出以便无损往返。 /// private UIGF4GachaArchive GetUIGFGachaArchiveForGenshinBeyond(long uid) { using var dapper = DatabaseService.CreateConnection(); IEnumerable list = dapper.Query($"SELECT * FROM GenshinBeyondGachaItem WHERE Uid=@Uid ORDER BY Id;", new { Uid = uid }); + string? lang = dapper.QueryFirstOrDefault($"SELECT Lang FROM GenshinGachaItem WHERE Uid=@Uid AND Lang IS NOT NULL AND Lang <> '' ORDER BY Id DESC LIMIT 1;", new { Uid = uid }); + if (string.IsNullOrWhiteSpace(lang)) + { + lang = AppConfig.GachaLanguage; + } UIGF4GachaArchive archive = new() { Uid = uid, List = list.ToList(), - Lang = "", + Lang = string.IsNullOrWhiteSpace(lang) ? null : LanguageUtil.FilterLanguage(lang), }; archive.Timezone = uid.ToString()[0] switch { @@ -247,7 +254,7 @@ private UIGF4GachaArchive GetUIGFGachaArchiveForStarRail(long { Uid = uid, List = list.ToList(), - Lang = list.LastOrDefault()?.Lang ?? "", + Lang = list.LastOrDefault()?.Lang is { Length: > 0 } l ? l : null, }; archive.Timezone = uid.ToString()[0] switch { @@ -268,7 +275,7 @@ private UIGF4GachaArchive GetUIGFGachaArchiveForZZZ(long uid) { Uid = uid, List = list.ToList(), - Lang = list.LastOrDefault()?.Lang ?? "", + Lang = list.LastOrDefault()?.Lang is { Length: > 0 } l ? l : null, }; return archive; } From 5642018ac0654b3b5fd59d5064792fe5cbb9443e Mon Sep 17 00:00:00 2001 From: WindDrift <115442729+WindDrift@users.noreply.github.com> Date: Mon, 27 Jul 2026 22:54:04 +0800 Subject: [PATCH 3/4] =?UTF-8?q?fix(gacha):=20=E4=BC=98=E5=8C=96=20UIGF=20?= =?UTF-8?q?=E6=A1=A3=E6=A1=88=E7=B1=BB=E5=9E=8B=E5=90=8D=E7=A7=B0=E4=B8=8E?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E5=B8=83=E5=B1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Features/Gacha/UIGF/GachaUidArchiveDisplay.cs | 12 ++++++++++-- .../Features/Gacha/UIGF/UIGF4GachaWindow.xaml | 14 +++++++------- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/Starward/Features/Gacha/UIGF/GachaUidArchiveDisplay.cs b/src/Starward/Features/Gacha/UIGF/GachaUidArchiveDisplay.cs index 260346db7..aa5063968 100644 --- a/src/Starward/Features/Gacha/UIGF/GachaUidArchiveDisplay.cs +++ b/src/Starward/Features/Gacha/UIGF/GachaUidArchiveDisplay.cs @@ -22,9 +22,17 @@ public class GachaUidArchiveDisplay : ObservableObject public bool IsGenshinBeyond { get; set; } /// - /// 列表中显示的档案名称,如「原神」「千星奇域」 + /// 列表中显示的抽卡记录名称,如「祈愿记录」「千星奇域颂愿」 /// - public string ArchiveName => IsGenshinBeyond ? Lang.GenshinBeyondGachaPage_MiliastraWonderlandOde : Game.ToGameName(); + public string ArchiveName => IsGenshinBeyond + ? Lang.GenshinBeyondGachaPage_MiliastraWonderlandOde + : Game switch + { + GameBiz.hk4e => Lang.GachaLogService_WishRecords, + GameBiz.hkrpg => Lang.GachaLogService_WarpRecords, + GameBiz.nap => Lang.GachaLogService_SignalSearchRecords, + _ => Game.ToGameName(), + }; public long Uid { get; set; } diff --git a/src/Starward/Features/Gacha/UIGF/UIGF4GachaWindow.xaml b/src/Starward/Features/Gacha/UIGF/UIGF4GachaWindow.xaml index 5872f1bed..978be9c44 100644 --- a/src/Starward/Features/Gacha/UIGF/UIGF4GachaWindow.xaml +++ b/src/Starward/Features/Gacha/UIGF/UIGF4GachaWindow.xaml @@ -61,7 +61,7 @@ @@ -73,7 +73,7 @@ VerticalAlignment="Center" Foreground="{ThemeResource TextFillColorSecondaryBrush}" Text="Uid" /> - @@ -108,7 +108,7 @@ - @@ -173,7 +173,7 @@ VerticalAlignment="Center" Foreground="{ThemeResource TextFillColorSecondaryBrush}" Text="Uid" /> - @@ -215,7 +215,7 @@ - + @@ -233,7 +233,7 @@ VerticalAlignment="Center" Text="{x:Bind Uid}" /> Date: Mon, 27 Jul 2026 23:01:24 +0800 Subject: [PATCH 4/4] =?UTF-8?q?fix(gacha):=20=E4=BF=AE=E6=AD=A3=20UIGF=20?= =?UTF-8?q?=E6=A1=A3=E6=A1=88=E5=90=8D=E7=A7=B0=E7=9A=84=20GameBiz=20?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=E5=8C=B9=E9=85=8D=E7=BC=96=E8=AF=91=E9=94=99?= =?UTF-8?q?=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Starward/Features/Gacha/UIGF/GachaUidArchiveDisplay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Starward/Features/Gacha/UIGF/GachaUidArchiveDisplay.cs b/src/Starward/Features/Gacha/UIGF/GachaUidArchiveDisplay.cs index aa5063968..4bafbbda8 100644 --- a/src/Starward/Features/Gacha/UIGF/GachaUidArchiveDisplay.cs +++ b/src/Starward/Features/Gacha/UIGF/GachaUidArchiveDisplay.cs @@ -26,7 +26,7 @@ public class GachaUidArchiveDisplay : ObservableObject /// public string ArchiveName => IsGenshinBeyond ? Lang.GenshinBeyondGachaPage_MiliastraWonderlandOde - : Game switch + : Game.Value switch { GameBiz.hk4e => Lang.GachaLogService_WishRecords, GameBiz.hkrpg => Lang.GachaLogService_WarpRecords,