diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Cultivation/CultivateProjectAvatarPropertyBatchPreferences.cs b/src/Snap.Hutao/Snap.Hutao/Model/Cultivation/CultivateProjectAvatarPropertyBatchPreferences.cs
index 1f79c48..d295a56 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Cultivation/CultivateProjectAvatarPropertyBatchPreferences.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Cultivation/CultivateProjectAvatarPropertyBatchPreferences.cs
@@ -21,4 +21,14 @@ internal sealed class CultivateProjectAvatarPropertyBatchPreferences
public int ConsumptionSaveStrategyIndex { get; set; }
public bool ClearAvatarAndWeaponEntriesBeforeSync { get; set; }
+
+ ///
+ /// 执行批量前是否先通过养成计算器将游戏背包同步到当前计划(与养成计划「同步背包物品」一致)。
+ ///
+ public bool SyncInventoryItems { get; set; }
+
+ ///
+ /// 执行批量前是否先从米游社原神战绩同步「我的角色」数据(与我的角色「同步角色信息」一致)。
+ ///
+ public bool SyncCharacterInfo { get; set; }
}
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/AvatarPropertyBatchCultivateService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/AvatarPropertyBatchCultivateService.cs
index a86e938..b017724 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/AvatarPropertyBatchCultivateService.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/AvatarPropertyBatchCultivateService.cs
@@ -5,10 +5,17 @@ using Microsoft.UI.Xaml.Controls;
using Snap.Hutao.Factory.ContentDialog;
using Snap.Hutao.Model.Calculable;
using Snap.Hutao.Model.Cultivation;
+using Snap.Hutao.Model.Entity;
using Snap.Hutao.Model.Entity.Primitive;
+using Snap.Hutao.Model.Primitive;
+using Snap.Hutao.Service.AvatarInfo;
using Snap.Hutao.Service.AvatarInfo.Factory;
using Snap.Hutao.Service.Cultivation.Consumption;
using Snap.Hutao.Service.Cultivation.Offline;
+using Snap.Hutao.Service.Inventory;
+using Snap.Hutao.Service.Metadata;
+using Snap.Hutao.Service.Metadata.ContextAbstraction;
+using Snap.Hutao.Service.User;
using Snap.Hutao.UI.Xaml.View.Dialog;
using Snap.Hutao.ViewModel.AvatarProperty;
using Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate;
@@ -62,13 +69,66 @@ internal sealed partial class AvatarPropertyBatchCultivateService : IAvatarPrope
BatchCultivateResult result = default;
using (await contentDialogFactory.BlockAsync(progressDialog).ConfigureAwait(false))
{
+ ImmutableArray avatarsToProcess = targetAvatars;
+
+ if (baseline.SyncCharacterInfo)
+ {
+ IUserService userService = serviceProvider.GetRequiredService();
+ if (await userService.GetCurrentUserAndUidAsync().ConfigureAwait(false) is { } userAndUid)
+ {
+ IServiceScopeFactory scopeFactory = serviceProvider.GetRequiredService();
+ using (IServiceScope scope = scopeFactory.CreateScope())
+ {
+ IAvatarInfoService avatarInfoService = scope.ServiceProvider.GetRequiredService();
+ Summary? refreshed = await avatarInfoService
+ .GetSummaryAsync(metadataContext, userAndUid, global::Snap.Hutao.Service.AvatarInfo.RefreshOptionKind.RequestFromHoyolabGameRecord, cancellationToken)
+ .ConfigureAwait(false);
+
+ if (refreshed?.Avatars.Source is { Count: > 0 } sourceAvatars)
+ {
+ HashSet wanted = [.. targetAvatars.Select(static a => a.Id)];
+ ImmutableArray.Builder filtered = ImmutableArray.CreateBuilder();
+ foreach (AvatarView avatar in sourceAvatars)
+ {
+ if (wanted.Contains(avatar.Id))
+ {
+ filtered.Add(avatar);
+ }
+ }
+
+ if (filtered.Count > 0)
+ {
+ avatarsToProcess = filtered.ToImmutable();
+ }
+ }
+ }
+ }
+ }
+
+ if (baseline.SyncInventoryItems)
+ {
+ CultivateProject? project = await cultivationService.GetCurrentProjectAsync().ConfigureAwait(false);
+ if (project is not null)
+ {
+ IMetadataService metadataService = serviceProvider.GetRequiredService();
+ ICultivationMetadataContext cultivationContext = await metadataService
+ .GetContextAsync(cancellationToken)
+ .ConfigureAwait(false);
+
+ IInventoryService inventoryService = serviceProvider.GetRequiredService();
+ await inventoryService
+ .RefreshInventoryAsync(RefreshOptions.CreateForWebCalculator(project, cultivationContext))
+ .ConfigureAwait(false);
+ }
+ }
+
if (baseline.ClearAvatarAndWeaponEntriesBeforeSync)
{
await cultivationService.RemoveAvatarAndWeaponEntriesForCurrentProjectAsync().ConfigureAwait(false);
}
ImmutableArray.Builder deltasBuilder = ImmutableArray.CreateBuilder();
- foreach (AvatarView avatar in targetAvatars)
+ foreach (AvatarView avatar in avatarsToProcess)
{
if (!baseline.Delta.TryGetNonErrorCopy(avatar, out CalculatorAvatarPromotionDelta? copy))
{
@@ -121,6 +181,8 @@ internal sealed partial class AvatarPropertyBatchCultivateService : IAvatarPrope
WeaponLevelTarget = d.Weapon?.LevelTarget ?? 90U,
ConsumptionSaveStrategyIndex = (int)baseline.Strategy,
ClearAvatarAndWeaponEntriesBeforeSync = baseline.ClearAvatarAndWeaponEntriesBeforeSync,
+ SyncInventoryItems = baseline.SyncInventoryItems,
+ SyncCharacterInfo = baseline.SyncCharacterInfo,
};
}
diff --git a/src/Snap.Hutao/Snap.Hutao/UI/Xaml/View/Dialog/CultivatePromotionDeltaBatchDialog.xaml b/src/Snap.Hutao/Snap.Hutao/UI/Xaml/View/Dialog/CultivatePromotionDeltaBatchDialog.xaml
index 639212a..9a8abf0 100644
--- a/src/Snap.Hutao/Snap.Hutao/UI/Xaml/View/Dialog/CultivatePromotionDeltaBatchDialog.xaml
+++ b/src/Snap.Hutao/Snap.Hutao/UI/Xaml/View/Dialog/CultivatePromotionDeltaBatchDialog.xaml
@@ -20,7 +20,9 @@
0
0
-
+
+
+
-
+
+
+
+
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/UI/Xaml/View/Dialog/CultivatePromotionDeltaBatchDialog.xaml.cs b/src/Snap.Hutao/Snap.Hutao/UI/Xaml/View/Dialog/CultivatePromotionDeltaBatchDialog.xaml.cs
index e08a810..18f7b95 100644
--- a/src/Snap.Hutao/Snap.Hutao/UI/Xaml/View/Dialog/CultivatePromotionDeltaBatchDialog.xaml.cs
+++ b/src/Snap.Hutao/Snap.Hutao/UI/Xaml/View/Dialog/CultivatePromotionDeltaBatchDialog.xaml.cs
@@ -12,6 +12,8 @@ namespace Snap.Hutao.UI.Xaml.View.Dialog;
[DependencyProperty("PromotionDelta", NotNull = true, CreateDefaultValueCallbackName = nameof(CreatePromotionDeltaDefaultValue))]
[DependencyProperty("ClearAvatarAndWeaponEntriesBeforeSync", DefaultValue = false, NotNull = true)]
+[DependencyProperty("SyncInventoryItems", DefaultValue = false, NotNull = true)]
+[DependencyProperty("SyncCharacterInfo", DefaultValue = false, NotNull = true)]
internal sealed partial class CultivatePromotionDeltaBatchDialog : ContentDialog
{
private readonly IContentDialogFactory contentDialogFactory;
@@ -56,7 +58,7 @@ internal sealed partial class CultivatePromotionDeltaBatchDialog : ContentDialog
LocalSetting.Set(SettingKeys.CultivationWeapon90LevelTarget, weapon.LevelTarget);
}
- return new(true, new CultivatePromotionDeltaOptions(PromotionDelta, (ConsumptionSaveStrategyKind)SaveModeSelector.SelectedIndex, ClearAvatarAndWeaponEntriesBeforeSync));
+ return new(true, new CultivatePromotionDeltaOptions(PromotionDelta, (ConsumptionSaveStrategyKind)SaveModeSelector.SelectedIndex, ClearAvatarAndWeaponEntriesBeforeSync, SyncInventoryItems, SyncCharacterInfo));
}
private void ApplyInitialPreferences(CultivateProjectAvatarPropertyBatchPreferences p)
@@ -77,6 +79,8 @@ internal sealed partial class CultivatePromotionDeltaBatchDialog : ContentDialog
SaveModeSelector.SelectedIndex = int.Clamp(p.ConsumptionSaveStrategyIndex, 0, 2);
ClearAvatarAndWeaponEntriesBeforeSync = p.ClearAvatarAndWeaponEntriesBeforeSync;
+ SyncInventoryItems = p.SyncInventoryItems;
+ SyncCharacterInfo = p.SyncCharacterInfo;
}
private static object CreatePromotionDeltaDefaultValue()
diff --git a/src/Snap.Hutao/Snap.Hutao/UI/Xaml/View/Dialog/CultivatePromotionDeltaOptions.cs b/src/Snap.Hutao/Snap.Hutao/UI/Xaml/View/Dialog/CultivatePromotionDeltaOptions.cs
index f374f64..3326ccc 100644
--- a/src/Snap.Hutao/Snap.Hutao/UI/Xaml/View/Dialog/CultivatePromotionDeltaOptions.cs
+++ b/src/Snap.Hutao/Snap.Hutao/UI/Xaml/View/Dialog/CultivatePromotionDeltaOptions.cs
@@ -8,7 +8,7 @@ namespace Snap.Hutao.UI.Xaml.View.Dialog;
internal sealed class CultivatePromotionDeltaOptions
{
- public CultivatePromotionDeltaOptions(AvatarPromotionDelta delta, ConsumptionSaveStrategyKind strategy, bool clearAvatarAndWeaponEntriesBeforeSync = false)
+ public CultivatePromotionDeltaOptions(AvatarPromotionDelta delta, ConsumptionSaveStrategyKind strategy, bool clearAvatarAndWeaponEntriesBeforeSync = false, bool syncInventoryItems = false, bool syncCharacterInfo = false)
{
delta.AvatarLevelTarget = delta.AvatarLevelTarget switch
{
@@ -20,6 +20,8 @@ internal sealed class CultivatePromotionDeltaOptions
Delta = delta;
Strategy = strategy;
ClearAvatarAndWeaponEntriesBeforeSync = clearAvatarAndWeaponEntriesBeforeSync;
+ SyncInventoryItems = syncInventoryItems;
+ SyncCharacterInfo = syncCharacterInfo;
}
public AvatarPromotionDelta Delta { get; }
@@ -30,4 +32,8 @@ internal sealed class CultivatePromotionDeltaOptions
/// 批量同步前是否清空当前计划中已有的角色与武器养成条目(不含家具等其它类型)。
///
public bool ClearAvatarAndWeaponEntriesBeforeSync { get; }
+
+ public bool SyncInventoryItems { get; }
+
+ public bool SyncCharacterInfo { get; }
}
\ No newline at end of file