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;
|
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]
|
[MessagePackObject]
|
||||||
public class BattlePassLevel
|
public class BattlePassLevel
|
||||||
{
|
{
|
||||||
[JsonPropertyName("level")]
|
[JsonPropertyName("level")]
|
||||||
[Key("level")]
|
[Key("level")]
|
||||||
public int Level { get; set; }
|
public string Level { get; set; } = "";
|
||||||
|
|
||||||
[JsonPropertyName("required_point")]
|
[JsonPropertyName("required_point")]
|
||||||
[Key("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<PackOpenService>();
|
||||||
builder.Services.AddScoped<ICardAcquisitionService, CardAcquisitionService>();
|
builder.Services.AddScoped<ICardAcquisitionService, CardAcquisitionService>();
|
||||||
builder.Services.AddScoped<RewardGrantService>();
|
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<IStoryMasterRepository, StoryMasterRepository>();
|
||||||
builder.Services.AddScoped<IViewerStoryProgressRepository, ViewerStoryProgressRepository>();
|
builder.Services.AddScoped<IViewerStoryProgressRepository, ViewerStoryProgressRepository>();
|
||||||
builder.Services.AddScoped<IStoryService, StoryService>();
|
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