feat(config): LoginBonus section with 15-day shipped normal cycle
Rewards copied verbatim from traffic_prod_tutorial.ndjson capture.
This commit is contained in:
58
SVSim.Database/Models/Config/LoginBonusConfig.cs
Normal file
58
SVSim.Database/Models/Config/LoginBonusConfig.cs
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
using SVSim.Database.Enums;
|
||||||
|
|
||||||
|
namespace SVSim.Database.Models.Config;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Daily login bonus catalog. The Normal cycle is the always-on N-day streak. Total
|
||||||
|
/// (continuous milestones) and Campaign (date-bounded specials) are placeholders — wire
|
||||||
|
/// emits empty arrays for them until a campaign is captured and seeded here.
|
||||||
|
/// </summary>
|
||||||
|
[ConfigSection("LoginBonus")]
|
||||||
|
public class LoginBonusConfig
|
||||||
|
{
|
||||||
|
public int CampaignId { get; set; } = 3;
|
||||||
|
public string Name { get; set; } = "Daily Bonus";
|
||||||
|
|
||||||
|
/// <summary>BG image asset key — wire ships as string. Prod captured value is "0".</summary>
|
||||||
|
public string Img { get; set; } = "0";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Normal-cycle reward entries, 1-based by Day. Defaults to a 15-day cycle copied
|
||||||
|
/// verbatim from the prod tutorial capture (traffic_prod_tutorial.ndjson).
|
||||||
|
/// </summary>
|
||||||
|
public List<NormalBonusEntry> Normal { get; set; } = new();
|
||||||
|
|
||||||
|
public static LoginBonusConfig ShippedDefaults() => new()
|
||||||
|
{
|
||||||
|
CampaignId = 3,
|
||||||
|
Name = "Daily Bonus",
|
||||||
|
Img = "0",
|
||||||
|
Normal = new List<NormalBonusEntry>
|
||||||
|
{
|
||||||
|
new() { Day = 1, EffectId = 1, RewardType = UserGoodsType.Rupy, RewardDetailId = 0, RewardNumber = 20 },
|
||||||
|
new() { Day = 2, EffectId = 1, RewardType = UserGoodsType.Rupy, RewardDetailId = 0, RewardNumber = 20 },
|
||||||
|
new() { Day = 3, EffectId = 1, RewardType = UserGoodsType.Rupy, RewardDetailId = 0, RewardNumber = 20 },
|
||||||
|
new() { Day = 4, EffectId = 1, RewardType = UserGoodsType.Rupy, RewardDetailId = 0, RewardNumber = 20 },
|
||||||
|
new() { Day = 5, EffectId = 2, RewardType = UserGoodsType.Item, RewardDetailId = 80001, RewardNumber = 1 },
|
||||||
|
new() { Day = 6, EffectId = 1, RewardType = UserGoodsType.Rupy, RewardDetailId = 0, RewardNumber = 30 },
|
||||||
|
new() { Day = 7, EffectId = 1, RewardType = UserGoodsType.Rupy, RewardDetailId = 0, RewardNumber = 30 },
|
||||||
|
new() { Day = 8, EffectId = 1, RewardType = UserGoodsType.Rupy, RewardDetailId = 0, RewardNumber = 30 },
|
||||||
|
new() { Day = 9, EffectId = 1, RewardType = UserGoodsType.Rupy, RewardDetailId = 0, RewardNumber = 30 },
|
||||||
|
new() { Day = 10, EffectId = 2, RewardType = UserGoodsType.Item, RewardDetailId = 80001, RewardNumber = 1 },
|
||||||
|
new() { Day = 11, EffectId = 1, RewardType = UserGoodsType.Rupy, RewardDetailId = 0, RewardNumber = 40 },
|
||||||
|
new() { Day = 12, EffectId = 1, RewardType = UserGoodsType.Rupy, RewardDetailId = 0, RewardNumber = 40 },
|
||||||
|
new() { Day = 13, EffectId = 1, RewardType = UserGoodsType.Rupy, RewardDetailId = 0, RewardNumber = 40 },
|
||||||
|
new() { Day = 14, EffectId = 1, RewardType = UserGoodsType.Rupy, RewardDetailId = 0, RewardNumber = 40 },
|
||||||
|
new() { Day = 15, EffectId = 2, RewardType = UserGoodsType.Item, RewardDetailId = 1, RewardNumber = 1 },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public class NormalBonusEntry
|
||||||
|
{
|
||||||
|
public int Day { get; set; }
|
||||||
|
public int EffectId { get; set; } = 1;
|
||||||
|
public UserGoodsType RewardType { get; set; }
|
||||||
|
public long RewardDetailId { get; set; }
|
||||||
|
public int RewardNumber { get; set; }
|
||||||
|
}
|
||||||
37
SVSim.UnitTests/Config/LoginBonusConfigTests.cs
Normal file
37
SVSim.UnitTests/Config/LoginBonusConfigTests.cs
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
using NUnit.Framework;
|
||||||
|
using SVSim.Database.Enums;
|
||||||
|
using SVSim.Database.Models.Config;
|
||||||
|
|
||||||
|
namespace SVSim.UnitTests.Config;
|
||||||
|
|
||||||
|
public class LoginBonusConfigTests
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void ShippedDefaults_matches_prod_normal_cycle()
|
||||||
|
{
|
||||||
|
var cfg = LoginBonusConfig.ShippedDefaults();
|
||||||
|
|
||||||
|
Assert.That(cfg.CampaignId, Is.EqualTo(3));
|
||||||
|
Assert.That(cfg.Name, Is.EqualTo("Daily Bonus"));
|
||||||
|
Assert.That(cfg.Img, Is.EqualTo("0"));
|
||||||
|
Assert.That(cfg.Normal, Has.Count.EqualTo(15));
|
||||||
|
|
||||||
|
// Day 1: 20 Rupy
|
||||||
|
Assert.That(cfg.Normal[0].Day, Is.EqualTo(1));
|
||||||
|
Assert.That(cfg.Normal[0].RewardType, Is.EqualTo(UserGoodsType.Rupy));
|
||||||
|
Assert.That(cfg.Normal[0].RewardDetailId, Is.EqualTo(0));
|
||||||
|
Assert.That(cfg.Normal[0].RewardNumber, Is.EqualTo(20));
|
||||||
|
Assert.That(cfg.Normal[0].EffectId, Is.EqualTo(1));
|
||||||
|
|
||||||
|
// Day 5: Item 80001 ×1 with effect 2 (the highlight ticket)
|
||||||
|
Assert.That(cfg.Normal[4].RewardType, Is.EqualTo(UserGoodsType.Item));
|
||||||
|
Assert.That(cfg.Normal[4].RewardDetailId, Is.EqualTo(80001));
|
||||||
|
Assert.That(cfg.Normal[4].RewardNumber, Is.EqualTo(1));
|
||||||
|
Assert.That(cfg.Normal[4].EffectId, Is.EqualTo(2));
|
||||||
|
|
||||||
|
// Day 15: Item id 1 ×1 with effect 2 (cycle capstone)
|
||||||
|
Assert.That(cfg.Normal[14].RewardType, Is.EqualTo(UserGoodsType.Item));
|
||||||
|
Assert.That(cfg.Normal[14].RewardDetailId, Is.EqualTo(1));
|
||||||
|
Assert.That(cfg.Normal[14].RewardNumber, Is.EqualTo(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user