migrate all v2 api to v3 api

This commit is contained in:
qhy040404
2024-06-10 13:54:22 +08:00
parent eceef17628
commit 21050c1595
6 changed files with 95 additions and 88 deletions

View File

@@ -3,28 +3,26 @@
using Snap.Hutao.Core.Database;
using Snap.Hutao.Core.ExceptionService;
using Snap.Hutao.Model;
using Snap.Hutao.Model.Entity;
using Snap.Hutao.Model.Entity.Primitive;
using Snap.Hutao.Model.Metadata.Abstraction;
using Snap.Hutao.Model.Metadata.Avatar;
using Snap.Hutao.Model.Metadata.Item;
using Snap.Hutao.Model.Metadata.Weapon;
using Snap.Hutao.Model.Primitive;
using Snap.Hutao.Service.Inventory;
using Snap.Hutao.Service.Metadata;
using Snap.Hutao.Service.Metadata.ContextAbstraction;
using Snap.Hutao.Service.Notification;
using Snap.Hutao.Service.User;
using Snap.Hutao.ViewModel.Cultivation;
using Snap.Hutao.ViewModel.User;
using Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate;
using Snap.Hutao.Web.Response;
using System.Collections.ObjectModel;
using System.Runtime.InteropServices;
using AvatarPromotionDelta = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.AvatarPromotionDelta;
using BatchConsumption = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.BatchConsumption;
using CalculateClient = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.CalculateClient;
using CalculateItem = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.Item;
using PromotionDelta = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.PromotionDelta;
using MetadataAvatar = Snap.Hutao.Model.Metadata.Avatar.Avatar;
using MetadataWeapon = Snap.Hutao.Model.Metadata.Weapon.Weapon;
using ModelItem = Snap.Hutao.Model.Item;
namespace Snap.Hutao.Service.Cultivation;
@@ -41,6 +39,7 @@ internal sealed partial class CultivationService : ICultivationService
private readonly IServiceScopeFactory serviceScopeFactory;
private readonly IInventoryDbService inventoryDbService;
private readonly IMetadataService metadataService;
private readonly IInfoBarService infoBarService;
private readonly IUserService userService;
private readonly ITaskContext taskContext;
@@ -103,7 +102,7 @@ internal sealed partial class CultivationService : ICultivationService
entryItems.Add(new(cultivateItem, context.GetMaterial(cultivateItem.ItemId)));
}
Item item = entry.Type switch
ModelItem item = entry.Type switch
{
CultivateType.AvatarAndSkill => context.GetAvatar(entry.Id).ToItem(),
CultivateType.Weapon => context.GetWeapon(entry.Id).ToItem(),
@@ -272,21 +271,24 @@ internal sealed partial class CultivationService : ICultivationService
BatchConsumption? batchConsumption = default;
using (IServiceScope scope = serviceScopeFactory.CreateScope())
{
if (UserAndUid.TryFromUser(userService.Current, out UserAndUid? userAndUid))
if (!UserAndUid.TryFromUser(userService.Current, out UserAndUid? userAndUid))
{
CalculateClient calculateClient = scope.ServiceProvider.GetRequiredService<CalculateClient>();
Response<BatchConsumption>? resp = await calculateClient
.BatchComputeAsync(userAndUid, GeneratePromotionDeltas(cultivatables))
.ConfigureAwait(false);
if (!resp.IsOk())
{
return;
}
batchConsumption = resp.Data;
infoBarService.Warning(SH.MustSelectUserAndUid);
return;
}
CalculateClient calculateClient = scope.ServiceProvider.GetRequiredService<CalculateClient>();
Response<BatchConsumption>? resp = await calculateClient
.BatchComputeAsync(userAndUid, GeneratePromotionDeltas(cultivatables), true)
.ConfigureAwait(false);
if (!resp.IsOk())
{
return;
}
batchConsumption = resp.Data;
}
if (batchConsumption is { OverallConsume: { } items })
@@ -298,8 +300,8 @@ internal sealed partial class CultivationService : ICultivationService
private static List<AvatarPromotionDelta> GeneratePromotionDeltas(List<ICultivatable> cultivatables)
{
List<Avatar> avatars = [];
List<Weapon> weapons = [];
List<MetadataAvatar> avatars = [];
List<MetadataWeapon> weapons = [];
HashSet<MaterialId> materialIds = [];
while (cultivatables.Count > 0)
@@ -313,10 +315,10 @@ internal sealed partial class CultivationService : ICultivationService
switch (bestItem)
{
case Avatar avatar:
case MetadataAvatar avatar:
avatars.Add(avatar);
break;
case Weapon weapon:
case MetadataWeapon weapon:
weapons.Add(weapon);
break;
default:
@@ -335,8 +337,8 @@ internal sealed partial class CultivationService : ICultivationService
for (int i = 0; i < Math.Max(avatars.Count, weapons.Count); i++)
{
Avatar? avatar = avatars.ElementAtOrDefault(i);
Weapon? weapon = weapons.ElementAtOrDefault(i);
MetadataAvatar? avatar = avatars.ElementAtOrDefault(i);
MetadataWeapon? weapon = weapons.ElementAtOrDefault(i);
if (avatar is not null)
{

View File

@@ -25,6 +25,7 @@ using Windows.Graphics.Imaging;
using Windows.Storage.Streams;
using Windows.UI;
using CalculatorAvatarPromotionDelta = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.AvatarPromotionDelta;
using CalculatorBatchConsumption = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.BatchConsumption;
using CalculatorClient = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.CalculateClient;
using CalculatorConsumption = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.Consumption;
using CalculatorItem = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.Item;
@@ -175,7 +176,7 @@ internal sealed partial class AvatarPropertyViewModel : Abstraction.ViewModel, I
return;
}
if (userService.Current is null)
if (!UserAndUid.TryFromUser(userService.Current, out UserAndUid? userAndUid))
{
infoBarService.Warning(SH.MustSelectUserAndUid);
return;
@@ -196,17 +197,25 @@ internal sealed partial class AvatarPropertyViewModel : Abstraction.ViewModel, I
return;
}
CultivateCoreResult result = await CultivateCoreAsync(userService.Current.Entity, delta, avatar).ConfigureAwait(false);
Response<CalculatorBatchConsumption> consumptionResponse = await calculatorClient.BatchComputeAsync(userAndUid, delta).ConfigureAwait(false);
switch (result)
if (!consumptionResponse.IsOk())
{
case CultivateCoreResult.Ok:
infoBarService.Success(SH.ViewModelCultivationEntryAddSuccess);
break;
case CultivateCoreResult.SaveConsumptionFailed:
infoBarService.Warning(SH.ViewModelCultivationEntryAddWarning);
break;
return;
}
CalculatorBatchConsumption batchConsumption = consumptionResponse.Data;
CalculatorConsumption? consumption = batchConsumption.Items.FirstOrDefault();
ArgumentNullException.ThrowIfNull(consumption);
if (!await SaveCultivationAsync(consumption, delta).ConfigureAwait(false))
{
infoBarService.Warning(SH.ViewModelCultivationEntryAddWarning);
return;
}
infoBarService.Success(SH.ViewModelCultivationEntryAddSuccess);
}
[Command("BatchCultivateCommand")]
@@ -217,7 +226,7 @@ internal sealed partial class AvatarPropertyViewModel : Abstraction.ViewModel, I
return;
}
if (userService.Current is null)
if (!UserAndUid.TryFromUser(userService.Current, out UserAndUid? userAndUid))
{
infoBarService.Warning(SH.MustSelectUserAndUid);
return;
@@ -240,6 +249,7 @@ internal sealed partial class AvatarPropertyViewModel : Abstraction.ViewModel, I
using (await progressDialog.BlockAsync(taskContext).ConfigureAwait(false))
{
BatchCultivateResult result = default;
List<CalculatorAvatarPromotionDelta> deltas = [];
foreach (AvatarView avatar in avatars)
{
if (!baseline.TryGetNonErrorCopy(avatar, out CalculatorAvatarPromotionDelta? copy))
@@ -248,25 +258,27 @@ internal sealed partial class AvatarPropertyViewModel : Abstraction.ViewModel, I
continue;
}
CultivateCoreResult coreResult = await CultivateCoreAsync(userService.Current.Entity, copy, avatar).ConfigureAwait(false);
deltas.Add(copy);
}
switch (coreResult)
{
case CultivateCoreResult.Ok:
++result.SucceedCount;
break;
case CultivateCoreResult.ComputeConsumptionFailed:
result.Interrupted = true;
break;
case CultivateCoreResult.SaveConsumptionFailed:
result.Interrupted = true;
break;
}
Response<CalculatorBatchConsumption> consumptionResponse = await calculatorClient.BatchComputeAsync(userAndUid, deltas).ConfigureAwait(false);
if (result.Interrupted)
if (!consumptionResponse.IsOk())
{
return;
}
CalculatorBatchConsumption batchConsumption = consumptionResponse.Data;
foreach ((CalculatorConsumption consumption, CalculatorAvatarPromotionDelta delta) in batchConsumption.Items.Zip(deltas))
{
if (!await SaveCultivationAsync(consumption, delta).ConfigureAwait(false))
{
result.Interrupted = true;
break;
}
++result.SucceedCount;
}
if (result.Interrupted)
@@ -280,43 +292,32 @@ internal sealed partial class AvatarPropertyViewModel : Abstraction.ViewModel, I
}
}
private async ValueTask<CultivateCoreResult> CultivateCoreAsync(Model.Entity.User user, CalculatorAvatarPromotionDelta delta, AvatarView avatar)
private async ValueTask<bool> SaveCultivationAsync(CalculatorConsumption consumption, CalculatorAvatarPromotionDelta delta)
{
Response<CalculatorConsumption> consumptionResponse = await calculatorClient.ComputeAsync(user, delta).ConfigureAwait(false);
if (!consumptionResponse.IsOk())
{
return CultivateCoreResult.ComputeConsumptionFailed;
}
CalculatorConsumption consumption = consumptionResponse.Data;
LevelInformation levelInformation = LevelInformation.From(delta);
List<CalculatorItem> items = CalculatorItemHelper.Merge(consumption.AvatarConsume, consumption.AvatarSkillConsume);
bool avatarSaved = await cultivationService
.SaveConsumptionAsync(CultivateType.AvatarAndSkill, avatar.Id, items, levelInformation)
.SaveConsumptionAsync(CultivateType.AvatarAndSkill, delta.AvatarId, items, levelInformation)
.ConfigureAwait(false);
try
{
ArgumentNullException.ThrowIfNull(avatar.Weapon);
ArgumentNullException.ThrowIfNull(delta.Weapon);
// Take a hot path if avatar is not saved.
bool avatarAndWeaponSaved = avatarSaved && await cultivationService
.SaveConsumptionAsync(CultivateType.Weapon, avatar.Weapon.Id, consumption.WeaponConsume.EmptyIfNull(), levelInformation)
.SaveConsumptionAsync(CultivateType.Weapon, delta.Weapon.Id, consumption.WeaponConsume.EmptyIfNull(), levelInformation)
.ConfigureAwait(false);
if (!avatarAndWeaponSaved)
{
return CultivateCoreResult.SaveConsumptionFailed;
}
return avatarAndWeaponSaved;
}
catch (HutaoException ex)
{
infoBarService.Error(ex, SH.ViewModelCultivationAddWarning);
}
return CultivateCoreResult.Ok;
return true;
}
[Command("ExportAsImageCommand")]

View File

@@ -20,15 +20,14 @@ using Snap.Hutao.Service.Metadata;
using Snap.Hutao.Service.Notification;
using Snap.Hutao.Service.User;
using Snap.Hutao.View.Dialog;
using Snap.Hutao.ViewModel.User;
using Snap.Hutao.Web.Response;
using System.Collections.Frozen;
using System.Collections.ObjectModel;
using System.Runtime.InteropServices;
using CalculateAvatarPromotionDelta = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.AvatarPromotionDelta;
using CalculateBatchConsumption = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.BatchConsumption;
using CalculateClient = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.CalculateClient;
using CalculateConsumption = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.Consumption;
using CalculateItem = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.Item;
using CalculateItemHelper = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.ItemHelper;
namespace Snap.Hutao.ViewModel.Wiki;
@@ -163,7 +162,7 @@ internal sealed partial class WikiAvatarViewModel : Abstraction.ViewModel
return;
}
if (userService.Current is null)
if (!UserAndUid.TryFromUser(userService.Current, out UserAndUid? userAndUid))
{
infoBarService.Warning(SH.MustSelectUserAndUid);
return;
@@ -178,8 +177,8 @@ internal sealed partial class WikiAvatarViewModel : Abstraction.ViewModel
return;
}
Response<CalculateConsumption> consumptionResponse = await calculateClient
.ComputeAsync(userService.Current.Entity, delta)
Response<CalculateBatchConsumption> consumptionResponse = await calculateClient
.BatchComputeAsync(userAndUid, delta)
.ConfigureAwait(false);
if (!consumptionResponse.IsOk())
@@ -187,13 +186,12 @@ internal sealed partial class WikiAvatarViewModel : Abstraction.ViewModel
return;
}
CalculateConsumption consumption = consumptionResponse.Data;
CalculateBatchConsumption batchConsumption = consumptionResponse.Data;
LevelInformation levelInformation = LevelInformation.From(delta);
List<CalculateItem> items = CalculateItemHelper.Merge(consumption.AvatarConsume, consumption.AvatarSkillConsume);
try
{
bool saved = await cultivationService
.SaveConsumptionAsync(CultivateType.AvatarAndSkill, avatar.Id, items, levelInformation)
.SaveConsumptionAsync(CultivateType.AvatarAndSkill, avatar.Id, batchConsumption.OverallConsume, levelInformation)
.ConfigureAwait(false);
if (saved)

View File

@@ -20,13 +20,14 @@ using Snap.Hutao.Service.Metadata;
using Snap.Hutao.Service.Notification;
using Snap.Hutao.Service.User;
using Snap.Hutao.View.Dialog;
using Snap.Hutao.ViewModel.User;
using Snap.Hutao.Web.Response;
using System.Collections.Frozen;
using System.Collections.ObjectModel;
using System.Runtime.InteropServices;
using CalculateAvatarPromotionDelta = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.AvatarPromotionDelta;
using CalculateBatchConsumption = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.BatchConsumption;
using CalculateClient = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.CalculateClient;
using CalculateConsumption = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.Consumption;
namespace Snap.Hutao.ViewModel.Wiki;
@@ -154,7 +155,7 @@ internal sealed partial class WikiWeaponViewModel : Abstraction.ViewModel
return;
}
if (userService.Current is null)
if (!UserAndUid.TryFromUser(userService.Current, out UserAndUid? userAndUid))
{
infoBarService.Warning(SH.MustSelectUserAndUid);
return;
@@ -169,8 +170,8 @@ internal sealed partial class WikiWeaponViewModel : Abstraction.ViewModel
return;
}
Response<CalculateConsumption> consumptionResponse = await calculateClient
.ComputeAsync(userService.Current.Entity, delta)
Response<CalculateBatchConsumption> consumptionResponse = await calculateClient
.BatchComputeAsync(userAndUid, delta)
.ConfigureAwait(false);
if (!consumptionResponse.IsOk())
@@ -178,12 +179,12 @@ internal sealed partial class WikiWeaponViewModel : Abstraction.ViewModel
return;
}
CalculateConsumption consumption = consumptionResponse.Data;
CalculateBatchConsumption batchConsumption = consumptionResponse.Data;
LevelInformation levelInformation = LevelInformation.From(delta);
try
{
bool saved = await cultivationService
.SaveConsumptionAsync(CultivateType.Weapon, weapon.Id, consumption.WeaponConsume.EmptyIfNull(), levelInformation)
.SaveConsumptionAsync(CultivateType.Weapon, weapon.Id, batchConsumption.OverallConsume, levelInformation)
.ConfigureAwait(false);
if (saved)

View File

@@ -6,13 +6,13 @@ namespace Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate;
internal sealed class BatchConsumption
{
[JsonPropertyName("items")]
public List<Consumption>? Items { get; set; }
public List<Consumption> Items { get; set; } = default!;
[JsonPropertyName("available_material")]
public List<Item>? AvailableMaterial { get; set; }
[JsonPropertyName("overall_consume")]
public List<Item>? OverallConsume { get; set; }
public List<Item> OverallConsume { get; set; } = default!;
[JsonPropertyName("has_user_info")]
public bool HasUserInfo { get; set; }

View File

@@ -34,15 +34,20 @@ internal sealed partial class CalculateClient
return Response.Response.DefaultIfNull(resp);
}
public async ValueTask<Response<BatchConsumption>> BatchComputeAsync(UserAndUid userAndUid, List<AvatarPromotionDelta> deltas, CancellationToken token = default)
public async ValueTask<Response<BatchConsumption>> BatchComputeAsync(UserAndUid userAndUid, AvatarPromotionDelta delta, bool syncMaterials = false, CancellationToken token = default)
{
return await BatchComputeAsync(userAndUid, [delta], syncMaterials, token).ConfigureAwait(false);
}
public async ValueTask<Response<BatchConsumption>> BatchComputeAsync(UserAndUid userAndUid, List<AvatarPromotionDelta> deltas, bool syncMaterials = false, CancellationToken token = default)
{
//ArgumentOutOfRangeException.ThrowIfGreaterThan(deltas.Count, 8);
BatchConsumptionData data = new()
{
Items = deltas,
Region = userAndUid.Uid.Region,
Uid = userAndUid.Uid.ToString(),
Region = syncMaterials ? userAndUid.Uid.Region : default!,
Uid = syncMaterials ? userAndUid.Uid.ToString() : default!,
};
HttpRequestMessageBuilder builder = httpRequestMessageBuilderFactory.Create()