feat(bp): IBattlePassService skeleton + level-curve method + DI
This commit is contained in:
@@ -3,13 +3,18 @@ using System.Text.Json.Serialization;
|
||||
|
||||
namespace SVSim.EmulatedEntrypoint.Models.Dtos;
|
||||
|
||||
/// <summary>
|
||||
/// One entry under <c>/load/index.battle_pass_level_info</c>. Per memory
|
||||
/// project_wire_key_serialization, wire ints are strings here — client parses them via .ToInt().
|
||||
/// </summary>
|
||||
[MessagePackObject]
|
||||
public class BattlePassLevel
|
||||
{
|
||||
[JsonPropertyName("level")]
|
||||
[Key("level")]
|
||||
public int Level { get; set; }
|
||||
public string Level { get; set; } = "";
|
||||
|
||||
[JsonPropertyName("required_point")]
|
||||
[Key("required_point")]
|
||||
public int RequiredPoints { get; set; }
|
||||
}
|
||||
public string RequiredPoint { get; set; } = "";
|
||||
}
|
||||
|
||||
@@ -83,6 +83,12 @@ public class Program
|
||||
builder.Services.AddScoped<PackOpenService>();
|
||||
builder.Services.AddScoped<ICardAcquisitionService, CardAcquisitionService>();
|
||||
builder.Services.AddScoped<RewardGrantService>();
|
||||
builder.Services.AddScoped<SVSim.Database.Repositories.BattlePass.IBattlePassRepository,
|
||||
SVSim.Database.Repositories.BattlePass.BattlePassRepository>();
|
||||
builder.Services.AddScoped<SVSim.Database.Repositories.BattlePass.IViewerBattlePassRepository,
|
||||
SVSim.Database.Repositories.BattlePass.ViewerBattlePassRepository>();
|
||||
builder.Services.AddScoped<IBattlePassService, BattlePassService>();
|
||||
builder.Services.AddSingleton<TimeProvider>(TimeProvider.System);
|
||||
builder.Services.AddScoped<IStoryMasterRepository, StoryMasterRepository>();
|
||||
builder.Services.AddScoped<IViewerStoryProgressRepository, ViewerStoryProgressRepository>();
|
||||
builder.Services.AddScoped<IStoryService, StoryService>();
|
||||
|
||||
14
SVSim.EmulatedEntrypoint/Services/BattlePassBuyOutcome.cs
Normal file
14
SVSim.EmulatedEntrypoint/Services/BattlePassBuyOutcome.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using SVSim.Database.Services;
|
||||
|
||||
namespace SVSim.EmulatedEntrypoint.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Result of <see cref="IBattlePassService.BuyPremiumAsync"/>. <c>AchievedRewards</c> = the
|
||||
/// delta that was just granted (goes into <c>achieved_info.battle_pass_reward_list</c>);
|
||||
/// <c>PostStateTotals</c> = post-state totals for affected goods (goes into <c>reward_list</c>),
|
||||
/// including the crystal deduction per memory project_wire_reward_list_post_state.
|
||||
/// </summary>
|
||||
public sealed record BattlePassBuyOutcome(
|
||||
int ResultCode,
|
||||
IReadOnlyList<GrantedReward> AchievedRewards,
|
||||
IReadOnlyList<GrantedReward> PostStateTotals);
|
||||
17
SVSim.EmulatedEntrypoint/Services/BattlePassPointGrant.cs
Normal file
17
SVSim.EmulatedEntrypoint/Services/BattlePassPointGrant.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using SVSim.Database.Services;
|
||||
|
||||
namespace SVSim.EmulatedEntrypoint.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Result of <see cref="IBattlePassService.AddPointsAsync"/>. Future point-source endpoints
|
||||
/// (mission/retire, battle finish handlers) translate this into the embedded
|
||||
/// <c>battle_pass_gauge_info</c> block on their response.
|
||||
/// </summary>
|
||||
public sealed record BattlePassPointGrant(
|
||||
int BeforePoint,
|
||||
int BeforeLevel,
|
||||
int AfterPoint,
|
||||
int AfterLevel,
|
||||
int PointAdd,
|
||||
BattlePassPointSource Source,
|
||||
IReadOnlyList<GrantedReward> NewlyClaimed);
|
||||
12
SVSim.EmulatedEntrypoint/Services/BattlePassPointSource.cs
Normal file
12
SVSim.EmulatedEntrypoint/Services/BattlePassPointSource.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
namespace SVSim.EmulatedEntrypoint.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Which categorized field on <c>battle_pass_gauge_info</c> a point grant feeds. Mirrors the
|
||||
/// breakdown shown by <c>BattlePassResultPanel</c> after a win.
|
||||
/// </summary>
|
||||
public enum BattlePassPointSource
|
||||
{
|
||||
BattleResult,
|
||||
DailyMission,
|
||||
BattlePassMission,
|
||||
}
|
||||
28
SVSim.EmulatedEntrypoint/Services/BattlePassService.cs
Normal file
28
SVSim.EmulatedEntrypoint/Services/BattlePassService.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using System.Globalization;
|
||||
using SVSim.Database.Repositories.BattlePass;
|
||||
using SVSim.EmulatedEntrypoint.Models.Dtos;
|
||||
|
||||
namespace SVSim.EmulatedEntrypoint.Services;
|
||||
|
||||
public sealed class BattlePassService : IBattlePassService
|
||||
{
|
||||
private readonly IBattlePassRepository _bp;
|
||||
|
||||
public BattlePassService(IBattlePassRepository bp)
|
||||
{
|
||||
_bp = bp;
|
||||
}
|
||||
|
||||
public async Task<IReadOnlyDictionary<string, BattlePassLevel>?> GetLevelCurveAsync(CancellationToken ct)
|
||||
{
|
||||
var rows = await _bp.GetLevelCurveAsync(ct);
|
||||
if (rows.Count == 0) return null;
|
||||
return rows.ToDictionary(
|
||||
r => r.Level.ToString(CultureInfo.InvariantCulture),
|
||||
r => new BattlePassLevel
|
||||
{
|
||||
Level = r.Level.ToString(CultureInfo.InvariantCulture),
|
||||
RequiredPoint = r.RequiredPoint.ToString(CultureInfo.InvariantCulture),
|
||||
});
|
||||
}
|
||||
}
|
||||
11
SVSim.EmulatedEntrypoint/Services/IBattlePassService.cs
Normal file
11
SVSim.EmulatedEntrypoint/Services/IBattlePassService.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using SVSim.EmulatedEntrypoint.Models.Dtos;
|
||||
|
||||
namespace SVSim.EmulatedEntrypoint.Services;
|
||||
|
||||
public interface IBattlePassService
|
||||
{
|
||||
/// <summary>Global level curve as wire-string dictionary; null if no levels seeded.</summary>
|
||||
Task<IReadOnlyDictionary<string, BattlePassLevel>?> GetLevelCurveAsync(CancellationToken ct);
|
||||
|
||||
// The Info / ItemList / Buy / AddPoints methods are added in later tasks (11, 12, 13, 14).
|
||||
}
|
||||
Reference in New Issue
Block a user