Getting ready to seed more data

This commit is contained in:
gamer147
2026-05-23 15:47:23 -04:00
parent 631e42289a
commit 5f44ee0c7e
74 changed files with 499 additions and 50 deletions

View File

@@ -171,7 +171,6 @@ public class LoadController : SVSimController
MasterPoints = 0 MasterPoints = 0
}).ToList(), }).ToList(),
ArenaConfig = new ArenaConfig(), ArenaConfig = new ArenaConfig(),
ArenaInfos = new List<ArenaInfo>(),
RotationSets = rotationSets, RotationSets = rotationSets,
UserConfig = new UserConfig(), UserConfig = new UserConfig(),
OpenBattlefieldIds = (await _globalsRepository.GetBattlefields(true)) OpenBattlefieldIds = (await _globalsRepository.GetBattlefields(true))

View File

@@ -1,12 +1,15 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos; namespace SVSim.EmulatedEntrypoint.Models.Dtos;
[MessagePackObject] [MessagePackObject]
public class ArenaConfig public class ArenaConfig
{ {
[JsonPropertyName("use_challenge_two_pick_premium_card")]
[Key("use_challenge_two_pick_premium_card")] [Key("use_challenge_two_pick_premium_card")]
public int UseChallengePickTwoPremiumCard { get; set; } public int UseChallengePickTwoPremiumCard { get; set; }
[JsonPropertyName("challenge_two_pick_sleeve_id")]
[Key("challenge_two_pick_sleeve_id")] [Key("challenge_two_pick_sleeve_id")]
public int ChallengePickTwoCardSleeve { get; set; } public int ChallengePickTwoCardSleeve { get; set; }
} }

View File

@@ -1,21 +1,28 @@
using MessagePack; using MessagePack;
using SVSim.Database.Enums; using SVSim.Database.Enums;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos; namespace SVSim.EmulatedEntrypoint.Models.Dtos;
[MessagePackObject] [MessagePackObject]
public class ArenaFormatInfo public class ArenaFormatInfo
{ {
[JsonPropertyName("two_pick_type")]
[Key("two_pick_type")] [Key("two_pick_type")]
public PickTwoFormat PickTwoFormat { get; set; } public PickTwoFormat PickTwoFormat { get; set; }
[JsonPropertyName("card_pool_name")]
[Key("card_pool_name")] [Key("card_pool_name")]
public string CardPoolName { get; set; } = string.Empty; public string CardPoolName { get; set; } = string.Empty;
[JsonPropertyName("announce_id")]
[Key("announce_id")] [Key("announce_id")]
public string AnnounceId { get; set; } = "0"; public string AnnounceId { get; set; } = "0";
[JsonPropertyName("card_pool_url")]
[Key("card_pool_url")] [Key("card_pool_url")]
public string CardPoolUrl { get; set; } = string.Empty; public string CardPoolUrl { get; set; } = string.Empty;
[JsonPropertyName("start_time")]
[Key("start_time")] [Key("start_time")]
public DateTime StartTime { get; set; } public DateTime StartTime { get; set; }
[JsonPropertyName("end_time")]
[Key("end_time")] [Key("end_time")]
public DateTime EndTime { get; set; } public DateTime EndTime { get; set; }
} }

View File

@@ -1,24 +1,33 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos; namespace SVSim.EmulatedEntrypoint.Models.Dtos;
[MessagePackObject] [MessagePackObject]
public class ArenaInfo public class ArenaInfo
{ {
[JsonPropertyName("mode")]
[Key("mode")] [Key("mode")]
public int Mode { get; set; } public int Mode { get; set; }
[JsonPropertyName("enable")]
[Key("enable")] [Key("enable")]
public int Enable { get; set; } public int Enable { get; set; }
[JsonPropertyName("cost")]
[Key("cost")] [Key("cost")]
public ulong Cost { get; set; } public ulong Cost { get; set; }
[JsonPropertyName("rupy_cost")]
[Key("rupy_cost")] [Key("rupy_cost")]
public ulong RupeeCost { get; set; } public ulong RupeeCost { get; set; }
[JsonPropertyName("ticket_cost")]
[Key("ticket_cost")] [Key("ticket_cost")]
public int TicketCost { get; set; } public int TicketCost { get; set; }
[JsonPropertyName("is_join")]
[Key("is_join")] [Key("is_join")]
public bool IsJoin { get; set; } public bool IsJoin { get; set; }
[JsonPropertyName("sales_period_info")]
[Key("sales_period_info")] [Key("sales_period_info")]
public ShopExpiryInfo? SalesPeriodInfo { get; set; } public ShopExpiryInfo? SalesPeriodInfo { get; set; }
[JsonPropertyName("format_info")]
[Key("format_info")] [Key("format_info")]
public ArenaFormatInfo? FormatInfo { get; set; } public ArenaFormatInfo? FormatInfo { get; set; }
} }

View File

@@ -1,26 +1,36 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos; namespace SVSim.EmulatedEntrypoint.Models.Dtos;
[MessagePackObject] [MessagePackObject]
public class AvatarAbility public class AvatarAbility
{ {
[JsonPropertyName("leader_skin_id")]
[Key("leader_skin_id")] [Key("leader_skin_id")]
public int LeaderSkinId { get; set; } public int LeaderSkinId { get; set; }
[JsonPropertyName("battle_start_firstplayerturn_bp")]
[Key("battle_start_firstplayerturn_bp")] [Key("battle_start_firstplayerturn_bp")]
public int BattleStartFirstPlayerBp { get; set; } public int BattleStartFirstPlayerBp { get; set; }
[JsonPropertyName("battle_start_secondplayerturn_bp")]
[Key("battle_start_secondplayerturn_bp")] [Key("battle_start_secondplayerturn_bp")]
public int BattleStartSecondPlayerBp { get; set; } public int BattleStartSecondPlayerBp { get; set; }
[JsonPropertyName("battle_start_max_life")]
[Key("battle_start_max_life")] [Key("battle_start_max_life")]
public int BattleStartMaxLife { get; set; } public int BattleStartMaxLife { get; set; }
[JsonPropertyName("ability_cost")]
[Key("ability_cost")] [Key("ability_cost")]
public string AbilityCost { get; set; } public string AbilityCost { get; set; }
[JsonPropertyName("ability")]
[Key("ability")] [Key("ability")]
public string Ability { get; set; } public string Ability { get; set; }
[JsonPropertyName("passive_ability")]
[Key("passive_ability")] [Key("passive_ability")]
public string PassiveAbility { get; set; } public string PassiveAbility { get; set; }
[JsonPropertyName("ability_desc")]
[Key("ability_desc")] [Key("ability_desc")]
public string AbilityDesc { get; set; } public string AbilityDesc { get; set; }
[JsonPropertyName("passive_ability_desc")]
[Key("passive_ability_desc")] [Key("passive_ability_desc")]
public string PassiveAbilityDesc { get; set; } public string PassiveAbilityDesc { get; set; }
} }

View File

@@ -1,12 +1,15 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos; namespace SVSim.EmulatedEntrypoint.Models.Dtos;
[MessagePackObject] [MessagePackObject]
public class AvatarInfo public class AvatarInfo
{ {
[JsonPropertyName("abilities")]
[Key("abilities")] [Key("abilities")]
public Dictionary<string, AvatarAbility> Abilities { get; set; } = new Dictionary<string, AvatarAbility>(); public Dictionary<string, AvatarAbility> Abilities { get; set; } = new Dictionary<string, AvatarAbility>();
[JsonPropertyName("schedules")]
[Key("schedules")] [Key("schedules")]
public SpecialRotationSchedule Schedules { get; set; } = new SpecialRotationSchedule(); public SpecialRotationSchedule Schedules { get; set; } = new SpecialRotationSchedule();
} }

View File

@@ -1,12 +1,15 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos; namespace SVSim.EmulatedEntrypoint.Models.Dtos;
[MessagePackObject] [MessagePackObject]
public class BattlePassLevel public class BattlePassLevel
{ {
[JsonPropertyName("level")]
[Key("level")] [Key("level")]
public int Level { get; set; } public int Level { get; set; }
[JsonPropertyName("required_point")]
[Key("required_point")] [Key("required_point")]
public int RequiredPoints { get; set; } public int RequiredPoints { get; set; }
} }

View File

@@ -1,4 +1,5 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos; namespace SVSim.EmulatedEntrypoint.Models.Dtos;
@@ -11,6 +12,7 @@ public class CardIdentifier
/// <summary> /// <summary>
/// The identifier of the card. /// The identifier of the card.
/// </summary> /// </summary>
[JsonPropertyName("card_id")]
[Key("card_id")] [Key("card_id")]
public long CardId { get; set; } public long CardId { get; set; }
} }

View File

@@ -1,10 +1,12 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos; namespace SVSim.EmulatedEntrypoint.Models.Dtos;
[MessagePackObject] [MessagePackObject]
public class CardSetIdentifier public class CardSetIdentifier
{ {
[JsonPropertyName("card_set_id")]
[Key("card_set_id")] [Key("card_set_id")]
public int SetId { get; set; } public int SetId { get; set; }
} }

View File

@@ -1,16 +1,21 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos; namespace SVSim.EmulatedEntrypoint.Models.Dtos;
[MessagePackObject] [MessagePackObject]
public class ClassExp public class ClassExp
{ {
[JsonPropertyName("level")]
[Key("level")] [Key("level")]
public int Level { get; set; } public int Level { get; set; }
[JsonPropertyName("necessary_exp")]
[Key("necessary_exp")] [Key("necessary_exp")]
public int NecessaryExp { get; set; } public int NecessaryExp { get; set; }
[JsonPropertyName("diff_exp")]
[Key("diff_exp")] [Key("diff_exp")]
public int DiffExp { get; set; } public int DiffExp { get; set; }
[JsonPropertyName("accumulate_exp")]
[Key("accumulate_exp")] [Key("accumulate_exp")]
public int AccumulateExp { get; set; } public int AccumulateExp { get; set; }
} }

View File

@@ -1,4 +1,5 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Common; namespace SVSim.EmulatedEntrypoint.Models.Dtos.Common;
@@ -10,5 +11,6 @@ namespace SVSim.EmulatedEntrypoint.Models.Dtos.Common;
[MessagePackObject] [MessagePackObject]
public class EmptyResponse public class EmptyResponse
{ {
[JsonPropertyName("_")]
[Key("_")] public object? Reserved { get; set; } [Key("_")] public object? Reserved { get; set; }
} }

View File

@@ -1,4 +1,5 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Common; namespace SVSim.EmulatedEntrypoint.Models.Dtos.Common;
@@ -9,7 +10,10 @@ namespace SVSim.EmulatedEntrypoint.Models.Dtos.Common;
[MessagePackObject] [MessagePackObject]
public class Reward public class Reward
{ {
[JsonPropertyName("type")]
[Key("type")] public int? Type { get; set; } [Key("type")] public int? Type { get; set; }
[JsonPropertyName("value")]
[Key("value")] public long? Value { get; set; } [Key("value")] public long? Value { get; set; }
[JsonPropertyName("num")]
[Key("num")] public int? Num { get; set; } [Key("num")] public int? Num { get; set; }
} }

View File

@@ -1,14 +1,18 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos; namespace SVSim.EmulatedEntrypoint.Models.Dtos;
[MessagePackObject] [MessagePackObject]
public class DailyLoginBonus public class DailyLoginBonus
{ {
[JsonPropertyName("total")]
[Key("total")] [Key("total")]
public LoginBonusCampaign? Total { get; set; } public LoginBonusCampaign? Total { get; set; }
[JsonPropertyName("normal")]
[Key("normal")] [Key("normal")]
public LoginBonusCampaign? Normal { get; set; } public LoginBonusCampaign? Normal { get; set; }
[JsonPropertyName("campaign")]
[Key("campaign")] [Key("campaign")]
public LoginBonusCampaign? Campaign { get; set; } public LoginBonusCampaign? Campaign { get; set; }
} }

View File

@@ -1,12 +1,15 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos; namespace SVSim.EmulatedEntrypoint.Models.Dtos;
[MessagePackObject] [MessagePackObject]
public class DateRange public class DateRange
{ {
[JsonPropertyName("begin_time")]
[Key("begin_time")] [Key("begin_time")]
public DateTime BeginTime { get; set; } public DateTime BeginTime { get; set; }
[JsonPropertyName("end_time")]
[Key("end_time")] [Key("end_time")]
public DateTime EndTime { get; set; } public DateTime EndTime { get; set; }
} }

View File

@@ -1,15 +1,19 @@
using MessagePack; using MessagePack;
using SVSim.Database.Models; using SVSim.Database.Models;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos; namespace SVSim.EmulatedEntrypoint.Models.Dtos;
[MessagePackObject] [MessagePackObject]
public class DefaultSettings public class DefaultSettings
{ {
[JsonPropertyName("default_emblem_id")]
[Key("default_emblem_id")] [Key("default_emblem_id")]
public int DefaultEmblemId { get; set; } public int DefaultEmblemId { get; set; }
[JsonPropertyName("default_degree_id")]
[Key("default_degree_id")] [Key("default_degree_id")]
public int DefaultDegreeId { get; set; } public int DefaultDegreeId { get; set; }
[JsonPropertyName("default_mypage_id")]
[Key("default_mypage_id")] [Key("default_mypage_id")]
public int DefaultMyPageBackground { get; set; } public int DefaultMyPageBackground { get; set; }

View File

@@ -1,10 +1,12 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos; namespace SVSim.EmulatedEntrypoint.Models.Dtos;
[MessagePackObject] [MessagePackObject]
public class DegreeIdentifier public class DegreeIdentifier
{ {
[JsonPropertyName("degree_id")]
[Key("degree_id")] [Key("degree_id")]
public int DegreeId { get; set; } public int DegreeId { get; set; }
} }

View File

@@ -1,10 +1,12 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos; namespace SVSim.EmulatedEntrypoint.Models.Dtos;
[MessagePackObject] [MessagePackObject]
public class EmblemIdentifier public class EmblemIdentifier
{ {
[JsonPropertyName("emblem_id")]
[Key("emblem_id")] [Key("emblem_id")]
public long EmblemId { get; set; } public long EmblemId { get; set; }
} }

View File

@@ -1,10 +1,12 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos; namespace SVSim.EmulatedEntrypoint.Models.Dtos;
[MessagePackObject] [MessagePackObject]
public class GatheringInfo public class GatheringInfo
{ {
[JsonPropertyName("has_invite")]
[Key("has_invite")] [Key("has_invite")]
public int HasInvite { get; set; } public int HasInvite { get; set; }
} }

View File

@@ -1,18 +1,24 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Internal; namespace SVSim.EmulatedEntrypoint.Models.Dtos.Internal;
[MessagePackObject] [MessagePackObject]
public class DataHeaders public class DataHeaders
{ {
[JsonPropertyName("short_udid")]
[Key("short_udid")] [Key("short_udid")]
public long ShortUdid { get; set; } public long ShortUdid { get; set; }
[JsonPropertyName("viewer_id")]
[Key("viewer_id")] [Key("viewer_id")]
public long ViewerId { get; set; } public long ViewerId { get; set; }
[JsonPropertyName("sid")]
[Key("sid")] [Key("sid")]
public string Sid { get; set; } public string Sid { get; set; }
[JsonPropertyName("servertime")]
[Key("servertime")] [Key("servertime")]
public long Servertime { get; set; } public long Servertime { get; set; }
[JsonPropertyName("result_code")]
[Key("result_code")] [Key("result_code")]
public int ResultCode { get; set; } public int ResultCode { get; set; }
} }

View File

@@ -1,4 +1,5 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Internal; namespace SVSim.EmulatedEntrypoint.Models.Dtos.Internal;
@@ -11,12 +12,14 @@ public class DataWrapper
/// <summary> /// <summary>
/// Additional data about the request, response and user. /// Additional data about the request, response and user.
/// </summary> /// </summary>
[JsonPropertyName("data_headers")]
[Key("data_headers")] [Key("data_headers")]
public DataHeaders DataHeaders { get; set; } = new DataHeaders(); public DataHeaders DataHeaders { get; set; } = new DataHeaders();
/// <summary> /// <summary>
/// The response data from the endpoint. /// The response data from the endpoint.
/// </summary> /// </summary>
[JsonPropertyName("data")]
[Key("data")] [Key("data")]
public object Data { get; set; } = new(); public object Data { get; set; } = new();
} }

View File

@@ -1,20 +1,27 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos; namespace SVSim.EmulatedEntrypoint.Models.Dtos;
[MessagePackObject] [MessagePackObject]
public class LoginBonusCampaign public class LoginBonusCampaign
{ {
[JsonPropertyName("name")]
[Key("name")] [Key("name")]
public string Name { get; set; } = string.Empty; public string Name { get; set; } = string.Empty;
[JsonPropertyName("campaign_id")]
[Key("campaign_id")] [Key("campaign_id")]
public int CampaignId { get; set; } public int CampaignId { get; set; }
[JsonPropertyName("img")]
[Key("img")] [Key("img")]
public int Image { get; set; } public int Image { get; set; }
[JsonPropertyName("now_count")]
[Key("now_count")] [Key("now_count")]
public int NowCount { get; set; } public int NowCount { get; set; }
[JsonPropertyName("is_next_reward")]
[Key("is_next_reward")] [Key("is_next_reward")]
public bool IsNextReward { get; set; } public bool IsNextReward { get; set; }
[JsonPropertyName("reward")]
[Key("reward")] [Key("reward")]
public List<LoginBonusReward> Rewards { get; set; } = new List<LoginBonusReward>(); public List<LoginBonusReward> Rewards { get; set; } = new List<LoginBonusReward>();
} }

View File

@@ -1,4 +1,5 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos; namespace SVSim.EmulatedEntrypoint.Models.Dtos;
@@ -8,24 +9,28 @@ public class LoginBonusReward
/// <summary> /// <summary>
/// The effect shown ingame. /// The effect shown ingame.
/// </summary> /// </summary>
[JsonPropertyName("effect_id")]
[Key("effect_id")] [Key("effect_id")]
public int EffectId { get; set; } public int EffectId { get; set; }
/// <summary> /// <summary>
/// The type of reward. /// The type of reward.
/// </summary> /// </summary>
[JsonPropertyName("reward_type")]
[Key("reward_type")] [Key("reward_type")]
public int RewardType { get; set; } public int RewardType { get; set; }
/// <summary> /// <summary>
/// A more specified reward type (ie if a pack, which pack). /// A more specified reward type (ie if a pack, which pack).
/// </summary> /// </summary>
[JsonPropertyName("reward_detail_id")]
[Key("reward_detail_id")] [Key("reward_detail_id")]
public int RewardDetailId { get; set; } public int RewardDetailId { get; set; }
/// <summary> /// <summary>
/// The count of the reward. /// The count of the reward.
/// </summary> /// </summary>
[JsonPropertyName("reward_number")]
[Key("reward_number")] [Key("reward_number")]
public int RewardNumber { get; set; } public int RewardNumber { get; set; }
} }

View File

@@ -1,4 +1,5 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos; namespace SVSim.EmulatedEntrypoint.Models.Dtos;
@@ -8,16 +9,22 @@ namespace SVSim.EmulatedEntrypoint.Models.Dtos;
[MessagePackObject] [MessagePackObject]
public class LootBoxRegulations public class LootBoxRegulations
{ {
[JsonPropertyName("pack")]
[Key("pack")] [Key("pack")]
public int Pack { get; set; } public int Pack { get; set; }
[JsonPropertyName("arena_2pick")]
[Key("arena_2pick")] [Key("arena_2pick")]
public int ArenaPickTwo { get; set; } public int ArenaPickTwo { get; set; }
[JsonPropertyName("arena_sealed")]
[Key("arena_sealed")] [Key("arena_sealed")]
public int ArenaSealed { get; set; } public int ArenaSealed { get; set; }
[JsonPropertyName("arena_colosseum")]
[Key("arena_colosseum")] [Key("arena_colosseum")]
public int ArenaColosseum { get; set; } public int ArenaColosseum { get; set; }
[JsonPropertyName("arena_competition")]
[Key("arena_competition")] [Key("arena_competition")]
public int ArenaCompetition { get; set; } public int ArenaCompetition { get; set; }
[JsonPropertyName("special_shop")]
[Key("special_shop")] [Key("special_shop")]
public int SpecialShop { get; set; } public int SpecialShop { get; set; }
} }

View File

@@ -1,22 +1,30 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos; namespace SVSim.EmulatedEntrypoint.Models.Dtos;
[MessagePackObject()] [MessagePackObject()]
public class MyRotationAbility public class MyRotationAbility
{ {
[JsonPropertyName("ability_id")]
[Key("ability_id")] [Key("ability_id")]
public int AbilityId { get; set; } public int AbilityId { get; set; }
[JsonPropertyName("add_start_pp")]
[Key("add_start_pp")] [Key("add_start_pp")]
public int AddStartPp { get; set; } public int AddStartPp { get; set; }
[JsonPropertyName("add_start_life")]
[Key("add_start_life")] [Key("add_start_life")]
public int AddStartLife { get; set; } public int AddStartLife { get; set; }
[JsonPropertyName("increase_add_pptotal_amount")]
[Key("increase_add_pptotal_amount")] [Key("increase_add_pptotal_amount")]
public int IncreaseAddPpTotalAmount { get; set; } public int IncreaseAddPpTotalAmount { get; set; }
[JsonPropertyName("increase_add_pptotal_turn")]
[Key("increase_add_pptotal_turn")] [Key("increase_add_pptotal_turn")]
public int IncreaseAddPpTotalTurn { get; set; } public int IncreaseAddPpTotalTurn { get; set; }
[JsonPropertyName("ability")]
[Key("ability")] [Key("ability")]
public string Ability { get; set; } = string.Empty; public string Ability { get; set; } = string.Empty;
[JsonPropertyName("ability_desc")]
[Key("ability_desc")] [Key("ability_desc")]
public string AbilityDesc { get; set; } = string.Empty; public string AbilityDesc { get; set; } = string.Empty;
} }

View File

@@ -1,22 +1,28 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos; namespace SVSim.EmulatedEntrypoint.Models.Dtos;
[MessagePackObject] [MessagePackObject]
public class MyRotationInfo public class MyRotationInfo
{ {
[JsonPropertyName("abilities")]
[Key("abilities")] [Key("abilities")]
public Dictionary<string, MyRotationAbility> Abilities { get; set; } = new Dictionary<string, MyRotationAbility>(); public Dictionary<string, MyRotationAbility> Abilities { get; set; } = new Dictionary<string, MyRotationAbility>();
[JsonPropertyName("schedules")]
[Key("schedules")] [Key("schedules")]
public SpecialRotationSchedule Schedules { get; set; } = new SpecialRotationSchedule(); public SpecialRotationSchedule Schedules { get; set; } = new SpecialRotationSchedule();
[JsonPropertyName("setting")]
[Key("setting")] [Key("setting")]
public Dictionary<string, SpecialRotationSetting>? Settings { get; set; } public Dictionary<string, SpecialRotationSetting>? Settings { get; set; }
[JsonPropertyName("disabled_card_set_ids")]
[Key("disabled_card_set_ids")] [Key("disabled_card_set_ids")]
public List<int>? DisabledCardSets { get; set; } public List<int>? DisabledCardSets { get; set; }
/// <summary> /// <summary>
/// Set to card to card reprinted list. /// Set to card to card reprinted list.
/// </summary> /// </summary>
[JsonPropertyName("reprinted_base_card_ids")]
[Key("reprinted_base_card_ids")] [Key("reprinted_base_card_ids")]
public Dictionary<string, Dictionary<string, int>>? ReprintedCards { get; set; } public Dictionary<string, Dictionary<string, int>>? ReprintedCards { get; set; }
@@ -24,6 +30,7 @@ public class MyRotationInfo
/// <summary> /// <summary>
/// Set to card to count banlist. /// Set to card to count banlist.
/// </summary> /// </summary>
[JsonPropertyName("restricted_base_card_id_list")]
[Key("restricted_base_card_id_list")] [Key("restricted_base_card_id_list")]
public Dictionary<string, Dictionary<string, int>>? Banlist { get; set; } public Dictionary<string, Dictionary<string, int>>? Banlist { get; set; }
} }

View File

@@ -1,36 +1,51 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos; namespace SVSim.EmulatedEntrypoint.Models.Dtos;
[MessagePackObject] [MessagePackObject]
public class PreReleaseInfo public class PreReleaseInfo
{ {
[JsonPropertyName("id")]
[Key("id")] [Key("id")]
public int Id { get; set; } public int Id { get; set; }
[JsonPropertyName("start_time")]
[Key("start_time")] [Key("start_time")]
public DateTime StartTime { get; set; } public DateTime StartTime { get; set; }
[JsonPropertyName("end_time")]
[Key("end_time")] [Key("end_time")]
public DateTime EndTime { get; set; } public DateTime EndTime { get; set; }
[JsonPropertyName("display_end_time")]
[Key("display_end_time")] [Key("display_end_time")]
public DateTime DisplayEndTime { get; set; } public DateTime DisplayEndTime { get; set; }
[JsonPropertyName("next_card_set_id")]
[Key("next_card_set_id")] [Key("next_card_set_id")]
public int NextCardSetId { get; set; } public int NextCardSetId { get; set; }
[JsonPropertyName("default_card_master_id")]
[Key("default_card_master_id")] [Key("default_card_master_id")]
public int DefaultCardMasterId { get; set; } public int DefaultCardMasterId { get; set; }
[JsonPropertyName("pre_release_card_master_id")]
[Key("pre_release_card_master_id")] [Key("pre_release_card_master_id")]
public int PreReleaseCardMasterId { get; set; } public int PreReleaseCardMasterId { get; set; }
[JsonPropertyName("free_match_start_time")]
[Key("free_match_start_time")] [Key("free_match_start_time")]
public DateTime FreeMatchStartTime { get; set; } public DateTime FreeMatchStartTime { get; set; }
[JsonPropertyName("card_master_id")]
[Key("card_master_id")] [Key("card_master_id")]
public int CardMasterId { get; set; } public int CardMasterId { get; set; }
[JsonPropertyName("rotation_card_set_id_list")]
[Key("rotation_card_set_id_list")] [Key("rotation_card_set_id_list")]
public List<int> RotationCardSets { get; set; } = new List<int>(); public List<int> RotationCardSets { get; set; } = new List<int>();
[JsonPropertyName("reprinted_base_card_ids")]
[Key("reprinted_base_card_ids")] [Key("reprinted_base_card_ids")]
public Dictionary<string, long> ReprintedCardIds { get; set; } = new Dictionary<string, long>(); public Dictionary<string, long> ReprintedCardIds { get; set; } = new Dictionary<string, long>();
[JsonPropertyName("latest_reprinted_base_card_ids")]
[Key("latest_reprinted_base_card_ids")] [Key("latest_reprinted_base_card_ids")]
public List<int> LatestReprintedCardIds { get; set; } = new List<int>(); public List<int> LatestReprintedCardIds { get; set; } = new List<int>();
[JsonPropertyName("pre_release_status")]
[Key("pre_release_status")] [Key("pre_release_status")]
public int PreReleaseStatus { get; set; } public int PreReleaseStatus { get; set; }
[JsonPropertyName("is_pre_rotation_free_match_term")]
[Key("is_pre_rotation_free_match_term")] [Key("is_pre_rotation_free_match_term")]
public int IsPreRotationFreeMatchTerm { get; set; } public int IsPreRotationFreeMatchTerm { get; set; }
} }

View File

@@ -1,43 +1,61 @@
using MessagePack; using MessagePack;
using SVSim.Database.Models; using SVSim.Database.Models;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos; namespace SVSim.EmulatedEntrypoint.Models.Dtos;
[MessagePackObject] [MessagePackObject]
public class RankInfo public class RankInfo
{ {
[JsonPropertyName("rank_id")]
[Key("rank_id")] [Key("rank_id")]
public int RankId { get; set; } public int RankId { get; set; }
[JsonPropertyName("rank_name")]
[Key("rank_name")] [Key("rank_name")]
public string RankName { get; set; } = string.Empty; public string RankName { get; set; } = string.Empty;
[JsonPropertyName("necessary_point")]
[Key("necessary_point")] [Key("necessary_point")]
public int NecessaryPoints { get; set; } public int NecessaryPoints { get; set; }
[JsonPropertyName("accumulate_point")]
[Key("accumulate_point")] [Key("accumulate_point")]
public int AccumulatePoints { get; set; } public int AccumulatePoints { get; set; }
[JsonPropertyName("lower_limit_point")]
[Key("lower_limit_point")] [Key("lower_limit_point")]
public int LowerLimitPoints { get; set; } public int LowerLimitPoints { get; set; }
[JsonPropertyName("base_add_bp")]
[Key("base_add_bp")] [Key("base_add_bp")]
public int BaseAddBp { get; set; } public int BaseAddBp { get; set; }
[JsonPropertyName("base_drop_bp")]
[Key("base_drop_bp")] [Key("base_drop_bp")]
public int BaseDropBp { get; set; } public int BaseDropBp { get; set; }
[JsonPropertyName("streak_bonus_pt")]
[Key("streak_bonus_pt")] [Key("streak_bonus_pt")]
public int StreakBonusPoints { get; set; } public int StreakBonusPoints { get; set; }
[JsonPropertyName("win_bonus")]
[Key("win_bonus")] [Key("win_bonus")]
public double WinBonus { get; set; } public double WinBonus { get; set; }
[JsonPropertyName("lose_bonus")]
[Key("lose_bonus")] [Key("lose_bonus")]
public double LoseBonus { get; set; } public double LoseBonus { get; set; }
[JsonPropertyName("max_win_bonus")]
[Key("max_win_bonus")] [Key("max_win_bonus")]
public int MaxWinBonus { get; set; } public int MaxWinBonus { get; set; }
[JsonPropertyName("max_lose_bonus")]
[Key("max_lose_bonus")] [Key("max_lose_bonus")]
public int MaxLoseBonus { get; set; } public int MaxLoseBonus { get; set; }
[JsonPropertyName("is_promotion_war")]
[Key("is_promotion_war")] [Key("is_promotion_war")]
public int IsPromotionWar { get; set; } public int IsPromotionWar { get; set; }
[JsonPropertyName("match_count")]
[Key("match_count")] [Key("match_count")]
public int MatchCount { get; set; } public int MatchCount { get; set; }
[JsonPropertyName("necessary_win")]
[Key("necessary_win")] [Key("necessary_win")]
public int NecessaryWins { get; set; } public int NecessaryWins { get; set; }
[JsonPropertyName("reset_lose")]
[Key("reset_lose")] [Key("reset_lose")]
public int ResetLose { get; set; } public int ResetLose { get; set; }
[JsonPropertyName("accumulate_master_point")]
[Key("accumulate_master_point")] [Key("accumulate_master_point")]
public int AccumulateMasterPoints { get; set; } public int AccumulateMasterPoints { get; set; }

View File

@@ -1,4 +1,5 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos; namespace SVSim.EmulatedEntrypoint.Models.Dtos;
@@ -11,18 +12,21 @@ public class RedEtherOverride
/// <summary> /// <summary>
/// The id of the affected card. /// The id of the affected card.
/// </summary> /// </summary>
[JsonPropertyName("card_id")]
[Key("card_id")] [Key("card_id")]
public ulong CardId { get; set; } public ulong CardId { get; set; }
/// <summary> /// <summary>
/// How much red ether is now provided from dusting the card. /// How much red ether is now provided from dusting the card.
/// </summary> /// </summary>
[JsonPropertyName("get_red_ether")]
[Key("get_red_ether")] [Key("get_red_ether")]
public int GetRedEther { get; set; } public int GetRedEther { get; set; }
/// <summary> /// <summary>
/// How much red ether is now required to craft the card. /// How much red ether is now required to craft the card.
/// </summary> /// </summary>
[JsonPropertyName("use_red_ether")]
[Key("use_red_ether")] [Key("use_red_ether")]
public int UseRedEther { get; set; } public int UseRedEther { get; set; }
} }

View File

@@ -1,14 +1,18 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests; namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests;
[MessagePackObject] [MessagePackObject]
public class BaseRequest public class BaseRequest
{ {
[JsonPropertyName("viewer_id")]
[Key("viewer_id")] [Key("viewer_id")]
public string ViewerId { get; set; } public string ViewerId { get; set; }
[JsonPropertyName("steam_id")]
[Key("steam_id")] [Key("steam_id")]
public ulong SteamId { get; set; } public ulong SteamId { get; set; }
[JsonPropertyName("steam_session_ticket")]
[Key("steam_session_ticket")] [Key("steam_session_ticket")]
public string SteamSessionTicket { get; set; } public string SteamSessionTicket { get; set; }
} }

View File

@@ -1,4 +1,5 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests.Common; namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests.Common;
@@ -9,5 +10,6 @@ namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests.Common;
[MessagePackObject] [MessagePackObject]
public class DeckFormatRequest : BaseRequest public class DeckFormatRequest : BaseRequest
{ {
[JsonPropertyName("deck_format")]
[Key("deck_format")] public int DeckFormat { get; set; } [Key("deck_format")] public int DeckFormat { get; set; }
} }

View File

@@ -1,10 +1,13 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests.Deck; namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests.Deck;
[MessagePackObject] [MessagePackObject]
public class DeckDeleteListRequest : BaseRequest public class DeckDeleteListRequest : BaseRequest
{ {
[JsonPropertyName("deck_no_list")]
[Key("deck_no_list")] public List<int>? DeckNoList { get; set; } [Key("deck_no_list")] public List<int>? DeckNoList { get; set; }
[JsonPropertyName("deck_format")]
[Key("deck_format")] public int DeckFormat { get; set; } [Key("deck_format")] public int DeckFormat { get; set; }
} }

View File

@@ -1,10 +1,11 @@
using MessagePack; using MessagePack;
using SVSim.EmulatedEntrypoint.Models.Dtos.Requests.Common; using SVSim.EmulatedEntrypoint.Models.Dtos.Requests.Common;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests.Deck; namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests.Deck;
/// <summary> /// <summary>
/// /deck/info standard request is `DeckFormatRequest`. Copy-source overload adds /// /deck/info 窶・standard request is `DeckFormatRequest`. Copy-source overload adds
/// `create_deck_format` (the format the user is creating the new deck IN). Server can /// `create_deck_format` (the format the user is creating the new deck IN). Server can
/// ignore create_deck_format and return the standard shape; only matters for the /// ignore create_deck_format and return the standard shape; only matters for the
/// cross-format deck-copy UI flow. /// cross-format deck-copy UI flow.
@@ -12,5 +13,6 @@ namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests.Deck;
[MessagePackObject] [MessagePackObject]
public class DeckInfoRequest : DeckFormatRequest public class DeckInfoRequest : DeckFormatRequest
{ {
[JsonPropertyName("create_deck_format")]
[Key("create_deck_format")] public int? CreateDeckFormat { get; set; } [Key("create_deck_format")] public int? CreateDeckFormat { get; set; }
} }

View File

@@ -1,10 +1,13 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests.Deck; namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests.Deck;
[MessagePackObject] [MessagePackObject]
public class DeckOrderRequest : BaseRequest public class DeckOrderRequest : BaseRequest
{ {
[JsonPropertyName("deck_order")]
[Key("deck_order")] public List<int>? DeckOrder { get; set; } [Key("deck_order")] public List<int>? DeckOrder { get; set; }
[JsonPropertyName("deck_format")]
[Key("deck_format")] public int DeckFormat { get; set; } [Key("deck_format")] public int DeckFormat { get; set; }
} }

View File

@@ -1,11 +1,15 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests.Deck; namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests.Deck;
[MessagePackObject] [MessagePackObject]
public class DeckUpdateLeaderSkinRequest : BaseRequest public class DeckUpdateLeaderSkinRequest : BaseRequest
{ {
[JsonPropertyName("deck_no")]
[Key("deck_no")] public int DeckNo { get; set; } [Key("deck_no")] public int DeckNo { get; set; }
[JsonPropertyName("leader_skin_id")]
[Key("leader_skin_id")] public int LeaderSkinId { get; set; } [Key("leader_skin_id")] public int LeaderSkinId { get; set; }
[JsonPropertyName("deck_format")]
[Key("deck_format")] public int DeckFormat { get; set; } [Key("deck_format")] public int DeckFormat { get; set; }
} }

View File

@@ -1,11 +1,15 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests.Deck; namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests.Deck;
[MessagePackObject] [MessagePackObject]
public class DeckUpdateNameRequest : BaseRequest public class DeckUpdateNameRequest : BaseRequest
{ {
[JsonPropertyName("deck_no")]
[Key("deck_no")] public int DeckNo { get; set; } [Key("deck_no")] public int DeckNo { get; set; }
[JsonPropertyName("deck_name")]
[Key("deck_name")] public string? DeckName { get; set; } [Key("deck_name")] public string? DeckName { get; set; }
[JsonPropertyName("deck_format")]
[Key("deck_format")] public int DeckFormat { get; set; } [Key("deck_format")] public int DeckFormat { get; set; }
} }

View File

@@ -1,11 +1,15 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests.Deck; namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests.Deck;
[MessagePackObject] [MessagePackObject]
public class DeckUpdateRandomLeaderSkinRequest : BaseRequest public class DeckUpdateRandomLeaderSkinRequest : BaseRequest
{ {
[JsonPropertyName("deck_format")]
[Key("deck_format")] public int DeckFormat { get; set; } [Key("deck_format")] public int DeckFormat { get; set; }
[JsonPropertyName("deck_no")]
[Key("deck_no")] public int DeckNo { get; set; } [Key("deck_no")] public int DeckNo { get; set; }
[JsonPropertyName("leader_skin_id_list")]
[Key("leader_skin_id_list")] public List<int>? LeaderSkinIdList { get; set; } [Key("leader_skin_id_list")] public List<int>? LeaderSkinIdList { get; set; }
} }

View File

@@ -1,27 +1,40 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests.Deck; namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests.Deck;
[MessagePackObject] [MessagePackObject]
public class DeckUpdateRequest : BaseRequest public class DeckUpdateRequest : BaseRequest
{ {
[JsonPropertyName("deck_no")]
[Key("deck_no")] public int DeckNo { get; set; } [Key("deck_no")] public int DeckNo { get; set; }
[JsonPropertyName("class_id")]
[Key("class_id")] public int ClassId { get; set; } [Key("class_id")] public int ClassId { get; set; }
[JsonPropertyName("leader_skin_id")]
[Key("leader_skin_id")] public int LeaderSkinId { get; set; } [Key("leader_skin_id")] public int LeaderSkinId { get; set; }
[JsonPropertyName("is_random_leader_skin")]
[Key("is_random_leader_skin")] public bool IsRandomLeaderSkin { get; set; } [Key("is_random_leader_skin")] public bool IsRandomLeaderSkin { get; set; }
[JsonPropertyName("leader_skin_id_list")]
[Key("leader_skin_id_list")] public List<int>? LeaderSkinIdList { get; set; } [Key("leader_skin_id_list")] public List<int>? LeaderSkinIdList { get; set; }
[JsonPropertyName("sleeve_id")]
[Key("sleeve_id")] public long SleeveId { get; set; } [Key("sleeve_id")] public long SleeveId { get; set; }
[JsonPropertyName("deck_name")]
[Key("deck_name")] public string? DeckName { get; set; } [Key("deck_name")] public string? DeckName { get; set; }
/// <summary>0 = save the deck, 1 = delete this deck slot.</summary> /// <summary>0 = save the deck, 1 = delete this deck slot.</summary>
[JsonPropertyName("is_delete")]
[Key("is_delete")] public int IsDelete { get; set; } [Key("is_delete")] public int IsDelete { get; set; }
[JsonPropertyName("card_id_array")]
[Key("card_id_array")] public List<long>? CardIdArray { get; set; } [Key("card_id_array")] public List<long>? CardIdArray { get; set; }
[JsonPropertyName("deck_format")]
[Key("deck_format")] public int DeckFormat { get; set; } [Key("deck_format")] public int DeckFormat { get; set; }
/// <summary>MyRotation rule-set id (only when deck_format = MyRotation).</summary> /// <summary>MyRotation rule-set id (only when deck_format = MyRotation).</summary>
[JsonPropertyName("rotation_id")]
[Key("rotation_id")] public string? RotationId { get; set; } [Key("rotation_id")] public string? RotationId { get; set; }
/// <summary>Crossover sub-class id (only when deck_format = Crossover).</summary> /// <summary>Crossover sub-class id (only when deck_format = Crossover).</summary>
[JsonPropertyName("sub_class_id")]
[Key("sub_class_id")] public int? SubClassId { get; set; } [Key("sub_class_id")] public int? SubClassId { get; set; }
} }

View File

@@ -1,11 +1,15 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests.Deck; namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests.Deck;
[MessagePackObject] [MessagePackObject]
public class DeckUpdateSleeveRequest : BaseRequest public class DeckUpdateSleeveRequest : BaseRequest
{ {
[JsonPropertyName("deck_no")]
[Key("deck_no")] public int DeckNo { get; set; } [Key("deck_no")] public int DeckNo { get; set; }
[JsonPropertyName("sleeve_id")]
[Key("sleeve_id")] public long SleeveId { get; set; } [Key("sleeve_id")] public long SleeveId { get; set; }
[JsonPropertyName("deck_format")]
[Key("deck_format")] public int DeckFormat { get; set; } [Key("deck_format")] public int DeckFormat { get; set; }
} }

View File

@@ -1,10 +1,13 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests.Deck; namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests.Deck;
[MessagePackObject] [MessagePackObject]
public class SetDeckRedisRequest : BaseRequest public class SetDeckRedisRequest : BaseRequest
{ {
[JsonPropertyName("deck_no")]
[Key("deck_no")] public int DeckNo { get; set; } [Key("deck_no")] public int DeckNo { get; set; }
[JsonPropertyName("class_id")]
[Key("class_id")] public int ClassId { get; set; } [Key("class_id")] public int ClassId { get; set; }
} }

View File

@@ -1,16 +1,21 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests; namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests;
[MessagePackObject] [MessagePackObject]
public class GameStartRequest : BaseRequest public class GameStartRequest : BaseRequest
{ {
[JsonPropertyName("app_type")]
[Key("app_type")] [Key("app_type")]
public int AppType { get; set; } public int AppType { get; set; }
[JsonPropertyName("campaign_data")]
[Key("campaign_data")] [Key("campaign_data")]
public string CampaignData { get; set; } public string CampaignData { get; set; }
[JsonPropertyName("campaign_sign")]
[Key("campaign_sign")] [Key("campaign_sign")]
public string CampaignSign { get; set; } public string CampaignSign { get; set; }
[JsonPropertyName("campaign_user")]
[Key("campaign_user")] [Key("campaign_user")]
public int CampaignUser { get; set; } public int CampaignUser { get; set; }
} }

View File

@@ -1,13 +1,16 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests; namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests;
[MessagePackObject] [MessagePackObject]
public class IndexRequest : BaseRequest public class IndexRequest : BaseRequest
{ {
[JsonPropertyName("carrier")]
[Key("carrier")] [Key("carrier")]
public string Carrier { get; set; } public string Carrier { get; set; }
[JsonPropertyName("card_master_hash")]
[Key("card_master_hash")] [Key("card_master_hash")]
public string CardMasterHash { get; set; } public string CardMasterHash { get; set; }
} }

View File

@@ -1,30 +1,42 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests.Practice; namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests.Practice;
[MessagePackObject] [MessagePackObject]
public class PracticeFinishRequest : BaseRequest public class PracticeFinishRequest : BaseRequest
{ {
[JsonPropertyName("deck_no")]
[Key("deck_no")] public int DeckNo { get; set; } [Key("deck_no")] public int DeckNo { get; set; }
[JsonPropertyName("is_win")]
[Key("is_win")] public int IsWin { get; set; } [Key("is_win")] public int IsWin { get; set; }
[JsonPropertyName("evolve_count")]
[Key("evolve_count")] public int EvolveCount { get; set; } [Key("evolve_count")] public int EvolveCount { get; set; }
[JsonPropertyName("total_turn")]
[Key("total_turn")] public int TotalTurn { get; set; } [Key("total_turn")] public int TotalTurn { get; set; }
[JsonPropertyName("enemy_class_id")]
[Key("enemy_class_id")] public int EnemyClassId { get; set; } [Key("enemy_class_id")] public int EnemyClassId { get; set; }
[JsonPropertyName("difficulty")]
[Key("difficulty")] public int Difficulty { get; set; } [Key("difficulty")] public int Difficulty { get; set; }
[JsonPropertyName("deck_format")]
[Key("deck_format")] public int DeckFormat { get; set; } [Key("deck_format")] public int DeckFormat { get; set; }
[JsonPropertyName("class_id")]
[Key("class_id")] public int ClassId { get; set; } [Key("class_id")] public int ClassId { get; set; }
[JsonPropertyName("mission")]
[Key("mission")] public Dictionary<string, int>? Mission { get; set; } [Key("mission")] public Dictionary<string, int>? Mission { get; set; }
/// <summary> /// <summary>
/// JSON blob `recovery_single.json` serialized to string. Always present; not validated /// JSON blob 窶・`recovery_single.json` serialized to string. Always present; not validated
/// server-side (audit-flagged as out of scope for v1). /// server-side (audit-flagged as out of scope for v1).
/// </summary> /// </summary>
[JsonPropertyName("recovery_data")]
[Key("recovery_data")] public string? RecoveryData { get; set; } [Key("recovery_data")] public string? RecoveryData { get; set; }
/// <summary> /// <summary>
/// Misspelled the same way in every solo finish endpoint preserved on the wire. /// Misspelled the same way in every solo finish endpoint 窶・preserved on the wire.
/// See spec note on practice-finish.md. /// See spec note on practice-finish.md.
/// </summary> /// </summary>
[JsonPropertyName("prosessing_time_data")]
[Key("prosessing_time_data")] public List<string>? ProsessingTimeData { get; set; } [Key("prosessing_time_data")] public List<string>? ProsessingTimeData { get; set; }
} }

View File

@@ -1,15 +1,17 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Responses.Deck; namespace SVSim.EmulatedEntrypoint.Models.Dtos.Responses.Deck;
/// <summary> /// <summary>
/// Shape consumed by `DeckGroupListData(jsonData, format)` for a single-format call /// Shape consumed by `DeckGroupListData(jsonData, format)` for a single-format call 窶・/// the format-scoped decks land under `user_deck_list` (vs. the per-format keys used
/// the format-scoped decks land under `user_deck_list` (vs. the per-format keys used
/// by /practice/deck_list with Format.All). /// by /practice/deck_list with Format.All).
/// </summary> /// </summary>
[MessagePackObject] [MessagePackObject]
public class DeckListResponse public class DeckListResponse
{ {
[JsonPropertyName("maintenance_card_list")]
[Key("maintenance_card_list")] public List<long> MaintenanceCardList { get; set; } = new(); [Key("maintenance_card_list")] public List<long> MaintenanceCardList { get; set; } = new();
[JsonPropertyName("user_deck_list")]
[Key("user_deck_list")] public List<UserDeck>? UserDeckList { get; set; } [Key("user_deck_list")] public List<UserDeck>? UserDeckList { get; set; }
} }

View File

@@ -1,5 +1,6 @@
using MessagePack; using MessagePack;
using SVSim.EmulatedEntrypoint.Models.Dtos.Common; using SVSim.EmulatedEntrypoint.Models.Dtos.Common;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Responses.Deck; namespace SVSim.EmulatedEntrypoint.Models.Dtos.Responses.Deck;
@@ -11,7 +12,10 @@ namespace SVSim.EmulatedEntrypoint.Models.Dtos.Responses.Deck;
[MessagePackObject] [MessagePackObject]
public class DeckUpdateResponse public class DeckUpdateResponse
{ {
[JsonPropertyName("user_deck_list")]
[Key("user_deck_list")] public List<UserDeck>? UserDeckList { get; set; } [Key("user_deck_list")] public List<UserDeck>? UserDeckList { get; set; }
[JsonPropertyName("achieved_info")]
[Key("achieved_info")] public Dictionary<string, object> AchievedInfo { get; set; } = new(); [Key("achieved_info")] public Dictionary<string, object> AchievedInfo { get; set; } = new();
[JsonPropertyName("reward_list")]
[Key("reward_list")] public List<Reward> RewardList { get; set; } = new(); [Key("reward_list")] public List<Reward> RewardList { get; set; } = new();
} }

View File

@@ -1,4 +1,5 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Responses.Deck; namespace SVSim.EmulatedEntrypoint.Models.Dtos.Responses.Deck;
@@ -6,5 +7,6 @@ namespace SVSim.EmulatedEntrypoint.Models.Dtos.Responses.Deck;
public class EmptyDeckNumberResponse public class EmptyDeckNumberResponse
{ {
/// <summary>The next free deck slot number. 0 indicates "no slots available".</summary> /// <summary>The next free deck slot number. 0 indicates "no slots available".</summary>
[JsonPropertyName("empty_deck_num")]
[Key("empty_deck_num")] public int EmptyDeckNum { get; set; } [Key("empty_deck_num")] public int EmptyDeckNum { get; set; }
} }

View File

@@ -1,15 +1,17 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Responses.Deck; namespace SVSim.EmulatedEntrypoint.Models.Dtos.Responses.Deck;
/// <summary> /// <summary>
/// Single-deck-update response. Consumed by DeckListUtility.DeckUpdate(user_deck, /// Single-deck-update response. Consumed by DeckListUtility.DeckUpdate(user_deck,
/// format, DeckAttributeType.CustomDeck). Shape is "one UserDeck wrapped under /// format, DeckAttributeType.CustomDeck). Shape is "one UserDeck wrapped under
/// `user_deck` key" same for update_name, update_sleeve, update_leader_skin, /// `user_deck` key" 窶・same for update_name, update_sleeve, update_leader_skin,
/// update_random_leader_skin. /// update_random_leader_skin.
/// </summary> /// </summary>
[MessagePackObject] [MessagePackObject]
public class SingleDeckResponse public class SingleDeckResponse
{ {
[JsonPropertyName("user_deck")]
[Key("user_deck")] public UserDeck? UserDeck { get; set; } [Key("user_deck")] public UserDeck? UserDeck { get; set; }
} }

View File

@@ -1,11 +1,12 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Responses; namespace SVSim.EmulatedEntrypoint.Models.Dtos.Responses;
/// <summary> /// <summary>
/// Wire-shape mirrors production's <c>/check/game_start</c> response. Several fields here are /// Wire-shape mirrors production's <c>/check/game_start</c> response. Several fields here are
/// NOT read by <c>Cute/GameStartCheckTask.Parse</c> (<c>now_viewer_id</c>, <c>now_name</c>, /// NOT read by <c>Cute/GameStartCheckTask.Parse</c> (<c>now_viewer_id</c>, <c>now_name</c>,
/// <c>now_rank</c> those are consumed by sibling tasks); they're included because prod sends /// <c>now_rank</c> 窶・those are consumed by sibling tasks); they're included because prod sends
/// them and the boot worked when we matched prod exactly. Removing them is a regression risk /// them and the boot worked when we matched prod exactly. Removing them is a regression risk
/// even though the parse-time decompile says they're unused. /// even though the parse-time decompile says they're unused.
/// </summary> /// </summary>
@@ -13,6 +14,7 @@ namespace SVSim.EmulatedEntrypoint.Models.Dtos.Responses;
public class GameStartResponse public class GameStartResponse
{ {
/// <summary>The signed-in viewer's internal id. Prod always sends.</summary> /// <summary>The signed-in viewer's internal id. Prod always sends.</summary>
[JsonPropertyName("now_viewer_id")]
[Key("now_viewer_id")] [Key("now_viewer_id")]
public long NowViewerId { get; set; } public long NowViewerId { get; set; }
@@ -20,10 +22,12 @@ public class GameStartResponse
/// Whether the user has set a data-transfer password. Prod sends a non-null bool; /// Whether the user has set a data-transfer password. Prod sends a non-null bool;
/// <c>GameStartCheckTask.Parse</c> gates the read with <c>Keys.Contains</c>. /// <c>GameStartCheckTask.Parse</c> gates the read with <c>Keys.Contains</c>.
/// </summary> /// </summary>
[JsonPropertyName("is_set_transition_password")]
[Key("is_set_transition_password")] [Key("is_set_transition_password")]
public bool IsSetTransitionPassword { get; set; } public bool IsSetTransitionPassword { get; set; }
/// <summary>Viewer display name. Not read by GameStartCheckTask but sent by prod.</summary> /// <summary>Viewer display name. Not read by GameStartCheckTask but sent by prod.</summary>
[JsonPropertyName("now_name")]
[Key("now_name")] [Key("now_name")]
public string NowName { get; set; } = string.Empty; public string NowName { get; set; } = string.Empty;
@@ -32,60 +36,71 @@ public class GameStartResponse
/// Stub for now until rank state is persisted; pinned to RankName_010 / RankName_017 /// Stub for now until rank state is persisted; pinned to RankName_010 / RankName_017
/// (matches prod's shape). /// (matches prod's shape).
/// </summary> /// </summary>
[JsonPropertyName("now_rank")]
[Key("now_rank")] [Key("now_rank")]
public Dictionary<string, string> NowRank { get; set; } = new(); public Dictionary<string, string> NowRank { get; set; } = new();
/// <summary> /// <summary>
/// Tutorial progress **sent as a string on the wire** ("100" = tutorial complete). /// Tutorial progress 窶・**sent as a string on the wire** ("100" = tutorial complete).
/// <c>GameStartCheckTask.Parse</c> calls <c>.ToInt()</c> so LitJson coerces. /// <c>GameStartCheckTask.Parse</c> calls <c>.ToInt()</c> so LitJson coerces.
/// </summary> /// </summary>
[JsonPropertyName("now_tutorial_step")]
[Key("now_tutorial_step")] [Key("now_tutorial_step")]
public string NowTutorialStep { get; set; } = "100"; public string NowTutorialStep { get; set; } = "100";
/// <summary> /// <summary>
/// Linked social accounts. Per-entry shape in <see cref="TransitionAccountData"/>. /// Linked social accounts. Per-entry shape in <see cref="TransitionAccountData"/>.
/// </summary> /// </summary>
[JsonPropertyName("transition_account_data")]
[Key("transition_account_data")] [Key("transition_account_data")]
public List<TransitionAccountData> TransitionAccountData { get; set; } = new(); public List<TransitionAccountData> TransitionAccountData { get; set; } = new();
/// <summary> /// <summary>
/// When present, client overwrites <c>Certification.ViewerId</c> with this value. Optional /// When present, client overwrites <c>Certification.ViewerId</c> with this value. Optional
/// leave null to omit. The serialization pipeline (JSON + msgpack via the translation /// 窶・leave null to omit. The serialization pipeline (JSON + msgpack via the translation
/// middleware) drops null properties end-to-end, so the client sees the key as absent. /// middleware) drops null properties end-to-end, so the client sees the key as absent.
/// </summary> /// </summary>
[JsonPropertyName("rewrite_viewer_id")]
[Key("rewrite_viewer_id")] [Key("rewrite_viewer_id")]
public long? RewriteViewerId { get; set; } public long? RewriteViewerId { get; set; }
/// <summary> /// <summary>
/// Presence indicates the user has applied for account deletion (value ignored by client at /// Presence indicates the user has applied for account deletion (value ignored by client at
/// this stage). Optional leave null to omit. /// this stage). Optional 窶・leave null to omit.
/// </summary> /// </summary>
[JsonPropertyName("account_delete_reservation_status")]
[Key("account_delete_reservation_status")] [Key("account_delete_reservation_status")]
public int? AccountDeleteReservationStatus { get; set; } public int? AccountDeleteReservationStatus { get; set; }
// --- Agreement / consent state (all required) --- // --- Agreement / consent state (all required) ---
/// <summary><c>PlayerStaticData.AgreementState</c> enum.</summary> /// <summary><c>PlayerStaticData.AgreementState</c> enum.</summary>
[JsonPropertyName("tos_state")]
[Key("tos_state")] [Key("tos_state")]
public int TosState { get; set; } public int TosState { get; set; }
/// <summary><c>PlayerStaticData.AgreementState</c> enum.</summary> /// <summary><c>PlayerStaticData.AgreementState</c> enum.</summary>
[JsonPropertyName("policy_state")]
[Key("policy_state")] [Key("policy_state")]
public int PolicyState { get; set; } public int PolicyState { get; set; }
/// <summary><c>PlayerStaticData.AgreementState</c> enum.</summary> /// <summary><c>PlayerStaticData.AgreementState</c> enum.</summary>
[JsonPropertyName("kor_authority_state")]
[Key("kor_authority_state")] [Key("kor_authority_state")]
public int KorAuthorityState { get; set; } public int KorAuthorityState { get; set; }
/// <summary>Current Terms of Service document id.</summary> /// <summary>Current Terms of Service document id.</summary>
[JsonPropertyName("tos_id")]
[Key("tos_id")] [Key("tos_id")]
public int TosId { get; set; } public int TosId { get; set; }
/// <summary>Current Privacy Policy document id.</summary> /// <summary>Current Privacy Policy document id.</summary>
[JsonPropertyName("policy_id")]
[Key("policy_id")] [Key("policy_id")]
public int PolicyId { get; set; } public int PolicyId { get; set; }
/// <summary>Current Korean authority consent document id.</summary> /// <summary>Current Korean authority consent document id.</summary>
[JsonPropertyName("kor_authority_id")]
[Key("kor_authority_id")] [Key("kor_authority_id")]
public int KorAuthorityId { get; set; } public int KorAuthorityId { get; set; }
} }

View File

@@ -1,5 +1,6 @@
using MessagePack; using MessagePack;
using SVSim.Database.Enums; using SVSim.Database.Enums;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Responses; namespace SVSim.EmulatedEntrypoint.Models.Dtos.Responses;
@@ -8,20 +9,28 @@ public class IndexResponse
{ {
#region Primitive Returns #region Primitive Returns
[JsonPropertyName("spot_point")]
[Key("spot_point")] [Key("spot_point")]
public int SpotPoint { get; set; } public int SpotPoint { get; set; }
[JsonPropertyName("is_available_colosseum_free_entry")]
[Key("is_available_colosseum_free_entry")] [Key("is_available_colosseum_free_entry")]
public bool IsAvailableColosseumFreeEntry { get; set; } public bool IsAvailableColosseumFreeEntry { get; set; }
[JsonPropertyName("friend_battle_invite_count")]
[Key("friend_battle_invite_count")] [Key("friend_battle_invite_count")]
public int FriendBattleInviteCount { get; set; } public int FriendBattleInviteCount { get; set; }
[JsonPropertyName("battle_recovery_status")]
[Key("battle_recovery_status")] [Key("battle_recovery_status")]
public int BattleRecoveryStatus { get; set; } public int BattleRecoveryStatus { get; set; }
[JsonPropertyName("room_recovery_status")]
[Key("room_recovery_status")] [Key("room_recovery_status")]
public int RoomRecoveryStatus { get; set; } public int RoomRecoveryStatus { get; set; }
[JsonPropertyName("is_battle_pass_period")]
[Key("is_battle_pass_period")] [Key("is_battle_pass_period")]
public int IsBattlePassPeriod { get; set; } public int IsBattlePassPeriod { get; set; }
[JsonPropertyName("card_set_id_for_resource_dl_view")]
[Key("card_set_id_for_resource_dl_view")] [Key("card_set_id_for_resource_dl_view")]
public int CardSetIdForResourceDlView { get; set; } public int CardSetIdForResourceDlView { get; set; }
[JsonPropertyName("deck_format")]
[Key("deck_format")] [Key("deck_format")]
public int DeckFormat { get; set; } = 1; public int DeckFormat { get; set; } = 1;
@@ -29,12 +38,15 @@ public class IndexResponse
#region Basic User Data #region Basic User Data
[JsonPropertyName("user_tutorial")]
[Key("user_tutorial")] [Key("user_tutorial")]
public UserTutorial UserTutorial { get; set; } = new UserTutorial(); public UserTutorial UserTutorial { get; set; } = new UserTutorial();
[JsonPropertyName("user_info")]
[Key("user_info")] [Key("user_info")]
public UserInfo UserInfo { get; set; } = new UserInfo(); public UserInfo UserInfo { get; set; } = new UserInfo();
[JsonPropertyName("user_crystal_count")]
[Key("user_crystal_count")] [Key("user_crystal_count")]
public UserCurrency UserCurrency { get; set; } = new UserCurrency(); public UserCurrency UserCurrency { get; set; } = new UserCurrency();
@@ -42,45 +54,56 @@ public class IndexResponse
#region Inventory Data #region Inventory Data
[JsonPropertyName("user_item_list")]
[Key("user_item_list")] [Key("user_item_list")]
public List<UserItem> UserItems { get; set; } = new(); public List<UserItem> UserItems { get; set; } = new();
[JsonPropertyName("user_deck_rotation")]
[Key("user_deck_rotation")] [Key("user_deck_rotation")]
public UserFormatDeckInfo UserRotationDecks { get; set; } = new(); public UserFormatDeckInfo UserRotationDecks { get; set; } = new();
[JsonPropertyName("user_deck_unlimited")]
[Key("user_deck_unlimited")] [Key("user_deck_unlimited")]
public UserFormatDeckInfo UserUnlimitedDecks { get; set; } = new(); public UserFormatDeckInfo UserUnlimitedDecks { get; set; } = new();
[JsonPropertyName("user_deck_my_rotation")]
[Key("user_deck_my_rotation")] [Key("user_deck_my_rotation")]
public UserFormatDeckInfo UserMyRotationDecks { get; set; } = new(); public UserFormatDeckInfo UserMyRotationDecks { get; set; } = new();
[JsonPropertyName("user_card_list")]
[Key("user_card_list")] [Key("user_card_list")]
public List<UserCard> UserCards { get; set; } = new(); public List<UserCard> UserCards { get; set; } = new();
[JsonPropertyName("user_class_list")]
[Key("user_class_list")] [Key("user_class_list")]
public List<UserClass> UserClasses { get; set; } = new(); public List<UserClass> UserClasses { get; set; } = new();
/// <summary> /// <summary>
/// Wire is an array; parser iterates by index (LoadDetail.cs:358-360). /// Wire is an array; parser iterates by index (LoadDetail.cs:358-360).
/// </summary> /// </summary>
[JsonPropertyName("user_sleeve_list")]
[Key("user_sleeve_list")] [Key("user_sleeve_list")]
public List<SleeveIdentifier> Sleeves { get; set; } = new(); public List<SleeveIdentifier> Sleeves { get; set; } = new();
[JsonPropertyName("user_emblem_list")]
[Key("user_emblem_list")] [Key("user_emblem_list")]
public List<EmblemIdentifier> UserEmblems { get; set; } = new(); public List<EmblemIdentifier> UserEmblems { get; set; } = new();
[JsonPropertyName("user_degree_list")]
[Key("user_degree_list")] [Key("user_degree_list")]
public List<DegreeIdentifier> UserDegrees { get; set; } = new(); public List<DegreeIdentifier> UserDegrees { get; set; } = new();
/// <summary> /// <summary>
/// Wire is an array; parser iterates by index (LoadDetail.cs:348-356). /// Wire is an array; parser iterates by index (LoadDetail.cs:348-356).
/// </summary> /// </summary>
[JsonPropertyName("user_leader_skin_list")]
[Key("user_leader_skin_list")] [Key("user_leader_skin_list")]
public List<UserLeaderSkin> LeaderSkins { get; set; } = new(); public List<UserLeaderSkin> LeaderSkins { get; set; } = new();
/// <summary> /// <summary>
/// Wire is string[]; parser calls .ToString() on each element (LoadDetail.cs:387-392). /// Wire is string[]; parser calls .ToString() on each element (LoadDetail.cs:387-392).
/// </summary> /// </summary>
[JsonPropertyName("user_mypage_list")]
[Key("user_mypage_list")] [Key("user_mypage_list")]
public List<string> MyPageBackgrounds { get; set; } = new(); public List<string> MyPageBackgrounds { get; set; } = new();
@@ -92,15 +115,19 @@ public class IndexResponse
/// Wire is an array of 5 entries; parser uses deck_format as discriminator /// Wire is an array of 5 entries; parser uses deck_format as discriminator
/// (LoadDetail.cs:527-538). /// (LoadDetail.cs:527-538).
/// </summary> /// </summary>
[JsonPropertyName("user_rank")]
[Key("user_rank")] [Key("user_rank")]
public List<UserRankInfo> UserRankInfo { get; set; } = new(); public List<UserRankInfo> UserRankInfo { get; set; } = new();
[JsonPropertyName("user_rank_match_list")]
[Key("user_rank_match_list")] [Key("user_rank_match_list")]
public List<UserRankedMatches> UserRankedMatches { get; set; } = new(); public List<UserRankedMatches> UserRankedMatches { get; set; } = new();
[JsonPropertyName("daily_login_bonus")]
[Key("daily_login_bonus")] [Key("daily_login_bonus")]
public DailyLoginBonus DailyLoginBonus { get; set; } = new(); public DailyLoginBonus DailyLoginBonus { get; set; } = new();
[JsonPropertyName("challenge_config")]
[Key("challenge_config")] [Key("challenge_config")]
public ArenaConfig ArenaConfig { get; set; } = new(); public ArenaConfig ArenaConfig { get; set; } = new();
@@ -108,6 +135,7 @@ public class IndexResponse
#region Global Data #region Global Data
[JsonPropertyName("red_ether_overwrite_list")]
[Key("red_ether_overwrite_list")] [Key("red_ether_overwrite_list")]
public List<RedEtherOverride> RedEtherOverrides { get; set; } = new(); public List<RedEtherOverride> RedEtherOverrides { get; set; } = new();
@@ -115,71 +143,94 @@ public class IndexResponse
/// Wire is a flat number[]; parser passes it straight to SetMaintenanceCardIds /// Wire is a flat number[]; parser passes it straight to SetMaintenanceCardIds
/// (LoadDetail.cs:165). /// (LoadDetail.cs:165).
/// </summary> /// </summary>
[JsonPropertyName("maintenance_card_list")]
[Key("maintenance_card_list")] [Key("maintenance_card_list")]
public List<long> MaintenanceCards { get; set; } = new(); public List<long> MaintenanceCards { get; set; } = new();
/// <summary>
/// Client's ArenaData(JsonData) ctor reads data[0] unconditionally inside the
/// LoadDetail.cs:261 Keys.Contains("arena_info") branch — an empty list crashes
/// /load/index with ArgumentOutOfRangeException. Send null (omitted on wire) when
/// there's no arena to advertise.
/// </summary>
[JsonPropertyName("arena_info")]
[Key("arena_info")] [Key("arena_info")]
public List<ArenaInfo> ArenaInfos { get; set; } = new(); public List<ArenaInfo>? ArenaInfos { get; set; }
/// <summary> /// <summary>
/// Wire is an array; client uses POSITIONAL logic (index >= 24 = master ranks, /// Wire is an array; client uses POSITIONAL logic (index >= 24 = master ranks,
/// LoadDetail.cs:417-422). Order must match repository's ordering. /// LoadDetail.cs:417-422). Order must match repository's ordering.
/// </summary> /// </summary>
[JsonPropertyName("rank_info")]
[Key("rank_info")] [Key("rank_info")]
public List<RankInfo> RankInfo { get; set; } = new(); public List<RankInfo> RankInfo { get; set; } = new();
/// <summary> /// <summary>
/// Wire is an array; parser iterates by index (LoadDetail.cs:425-434). /// Wire is an array; parser iterates by index (LoadDetail.cs:425-434).
/// </summary> /// </summary>
[JsonPropertyName("class_exp")]
[Key("class_exp")] [Key("class_exp")]
public List<ClassExp> ClassExp { get; set; } = new(); public List<ClassExp> ClassExp { get; set; } = new();
[JsonPropertyName("loading_exclusion_card_list")]
[Key("loading_exclusion_card_list")] [Key("loading_exclusion_card_list")]
public List<long> LoadingTipCardExclusions { get; set; } = new(); public List<long> LoadingTipCardExclusions { get; set; } = new();
[JsonPropertyName("default_setting")]
[Key("default_setting")] [Key("default_setting")]
public DefaultSettings DefaultSettings { get; set; } = new(); public DefaultSettings DefaultSettings { get; set; } = new();
[JsonPropertyName("unlimited_restricted_base_card_id_list")]
[Key("unlimited_restricted_base_card_id_list")] [Key("unlimited_restricted_base_card_id_list")]
public Dictionary<string, int> UnlimitedBanList { get; set; } = new(); public Dictionary<string, int> UnlimitedBanList { get; set; } = new();
/// <summary> /// <summary>
/// Client unconditionally accesses [1] and [Count-1] (LoadDetail.cs:184) list MUST /// Client unconditionally accesses [1] and [Count-1] (LoadDetail.cs:184) 窶・list MUST
/// have at least 2 entries or the client crashes. /// have at least 2 entries or the client crashes.
/// </summary> /// </summary>
[JsonPropertyName("rotation_card_set_id_list")]
[Key("rotation_card_set_id_list")] [Key("rotation_card_set_id_list")]
public List<CardSetIdentifier> RotationSets { get; set; } = new(); public List<CardSetIdentifier> RotationSets { get; set; } = new();
/// <summary> /// <summary>
/// Wire is a flat number[]; parser iterates and reads .ToInt() (LoadDetail.cs:463-468). /// Wire is a flat number[]; parser iterates and reads .ToInt() (LoadDetail.cs:463-468).
/// </summary> /// </summary>
[JsonPropertyName("reprinted_base_card_ids")]
[Key("reprinted_base_card_ids")] [Key("reprinted_base_card_ids")]
public List<long> ReprintedCards { get; set; } = new(); public List<long> ReprintedCards { get; set; } = new();
[JsonPropertyName("spot_cards")]
[Key("spot_cards")] [Key("spot_cards")]
public Dictionary<string, int> SpotCards { get; set; } = new(); public Dictionary<string, int> SpotCards { get; set; } = new();
[JsonPropertyName("pre_release_info")]
[Key("pre_release_info")] [Key("pre_release_info")]
public PreReleaseInfo? PreReleaseInfo { get; set; } public PreReleaseInfo? PreReleaseInfo { get; set; }
[JsonPropertyName("my_rotation_info")]
[Key("my_rotation_info")] [Key("my_rotation_info")]
public MyRotationInfo? MyRotationInfo { get; set; } public MyRotationInfo? MyRotationInfo { get; set; }
[JsonPropertyName("avatar_info")]
[Key("avatar_info")] [Key("avatar_info")]
public MyRotationInfo? AvatarRotationInfo { get; set; } public MyRotationInfo? AvatarRotationInfo { get; set; }
[JsonPropertyName("feature_maintenance_list")]
[Key("feature_maintenance_list")] [Key("feature_maintenance_list")]
public List<FeatureMaintenance> FeatureMaintenances { get; set; } = new(); public List<FeatureMaintenance> FeatureMaintenances { get; set; } = new();
[JsonPropertyName("special_crystal_info")]
[Key("special_crystal_info")] [Key("special_crystal_info")]
public List<SpecialCrystalInfo> SpecialCrystalInfos { get; set; } = new(); public List<SpecialCrystalInfo> SpecialCrystalInfos { get; set; } = new();
[JsonPropertyName("battle_pass_level_info")]
[Key("battle_pass_level_info")] [Key("battle_pass_level_info")]
public Dictionary<string, BattlePassLevel>? BattlePassLevelInfo { get; set; } public Dictionary<string, BattlePassLevel>? BattlePassLevelInfo { get; set; }
/// <summary> /// <summary>
/// Wire is string[]; parser calls .ToString() on each element (LoadDetail.cs:493-499). /// Wire is string[]; parser calls .ToString() on each element (LoadDetail.cs:493-499).
/// </summary> /// </summary>
[JsonPropertyName("open_battle_field_id_list")]
[Key("open_battle_field_id_list")] [Key("open_battle_field_id_list")]
public List<string> OpenBattlefieldIds { get; set; } = new(); public List<string> OpenBattlefieldIds { get; set; } = new();
@@ -187,9 +238,11 @@ public class IndexResponse
#region Misc Data #region Misc Data
[JsonPropertyName("loot_box_regulation")]
[Key("loot_box_regulation")] [Key("loot_box_regulation")]
public LootBoxRegulations LootBoxRegulations { get; set; } = new(); public LootBoxRegulations LootBoxRegulations { get; set; } = new();
[JsonPropertyName("gathering_info")]
[Key("gathering_info")] [Key("gathering_info")]
public GatheringInfo GatheringInfo { get; set; } = new(); public GatheringInfo GatheringInfo { get; set; } = new();
@@ -197,6 +250,7 @@ public class IndexResponse
/// Spec is unclear whether this is returned at /load/index or only at /config/* endpoints /// Spec is unclear whether this is returned at /load/index or only at /config/* endpoints
/// (load-index.md line 390). Pending live-capture confirmation; harmless extra. /// (load-index.md line 390). Pending live-capture confirmation; harmless extra.
/// </summary> /// </summary>
[JsonPropertyName("user_config")]
[Key("user_config")] [Key("user_config")]
public UserConfig UserConfig { get; set; } = new(); public UserConfig UserConfig { get; set; } = new();

View File

@@ -1,21 +1,25 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Responses.Practice; namespace SVSim.EmulatedEntrypoint.Models.Dtos.Responses.Practice;
/// <summary> /// <summary>
/// Same shape consumed by DeckGroupListData(jsonData, Format.All). Per-format keys are /// Same shape consumed by DeckGroupListData(jsonData, Format.All). Per-format keys are
/// conditional omit (don't send empty arrays) for formats the server doesn't enable. /// conditional 窶・omit (don't send empty arrays) for formats the server doesn't enable.
/// </summary> /// </summary>
[MessagePackObject] [MessagePackObject]
public class PracticeDeckListResponse public class PracticeDeckListResponse
{ {
/// <summary>Card ids currently disabled for maintenance (client unions with global list).</summary> /// <summary>Card ids currently disabled for maintenance (client unions with global list).</summary>
[JsonPropertyName("maintenance_card_list")]
[Key("maintenance_card_list")] public List<long> MaintenanceCardList { get; set; } = new(); [Key("maintenance_card_list")] public List<long> MaintenanceCardList { get; set; } = new();
[JsonPropertyName("user_deck_rotation")]
[Key("user_deck_rotation")] public List<UserDeck>? UserDeckRotation { get; set; } [Key("user_deck_rotation")] public List<UserDeck>? UserDeckRotation { get; set; }
[JsonPropertyName("user_deck_unlimited")]
[Key("user_deck_unlimited")] public List<UserDeck>? UserDeckUnlimited { get; set; } [Key("user_deck_unlimited")] public List<UserDeck>? UserDeckUnlimited { get; set; }
// The remaining format keys (pre_rotation, crossover, my_rotation, avatar, default_deck_list, // The remaining format keys (pre_rotation, crossover, my_rotation, avatar, default_deck_list,
// trial_deck_list, crossover_trial_deck_list, build_deck_list, user_leader_skin_setting_list) // trial_deck_list, crossover_trial_deck_list, build_deck_list, user_leader_skin_setting_list)
// are all conditional added when those formats are enabled. // are all conditional 窶・added when those formats are enabled.
} }

View File

@@ -1,5 +1,6 @@
using MessagePack; using MessagePack;
using SVSim.EmulatedEntrypoint.Models.Dtos.Common; using SVSim.EmulatedEntrypoint.Models.Dtos.Common;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Responses.Practice; namespace SVSim.EmulatedEntrypoint.Models.Dtos.Responses.Practice;
@@ -7,20 +8,25 @@ namespace SVSim.EmulatedEntrypoint.Models.Dtos.Responses.Practice;
public class PracticeFinishResponse public class PracticeFinishResponse
{ {
/// <summary>Class XP gained this match.</summary> /// <summary>Class XP gained this match.</summary>
[JsonPropertyName("get_class_experience")]
[Key("get_class_experience")] public int GetClassExperience { get; set; } [Key("get_class_experience")] public int GetClassExperience { get; set; }
/// <summary>Total accumulated class XP for the played class after this match.</summary> /// <summary>Total accumulated class XP for the played class after this match.</summary>
[JsonPropertyName("class_experience")]
[Key("class_experience")] public int ClassExperience { get; set; } [Key("class_experience")] public int ClassExperience { get; set; }
/// <summary>Class level after this match (post-promotion if XP rolled over).</summary> /// <summary>Class level after this match (post-promotion if XP rolled over).</summary>
[JsonPropertyName("class_level")]
[Key("class_level")] public int ClassLevel { get; set; } = 1; [Key("class_level")] public int ClassLevel { get; set; } = 1;
/// <summary> /// <summary>
/// Missions / achievements / rewards rollup. Empty dict means "nothing accumulated" /// Missions / achievements / rewards rollup. Empty dict means "nothing accumulated"
/// (spec: parser tolerates empty object). /// (spec: parser tolerates empty object).
/// </summary> /// </summary>
[JsonPropertyName("achieved_info")]
[Key("achieved_info")] public Dictionary<string, object> AchievedInfo { get; set; } = new(); [Key("achieved_info")] public Dictionary<string, object> AchievedInfo { get; set; } = new();
/// <summary>Standard reward grants applied to user's inventory. Empty by default.</summary> /// <summary>Standard reward grants applied to user's inventory. Empty by default.</summary>
[JsonPropertyName("reward_list")]
[Key("reward_list")] public List<Reward> RewardList { get; set; } = new(); [Key("reward_list")] public List<Reward> RewardList { get; set; } = new();
} }

View File

@@ -1,4 +1,5 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Responses.Practice; namespace SVSim.EmulatedEntrypoint.Models.Dtos.Responses.Practice;
@@ -6,38 +7,49 @@ namespace SVSim.EmulatedEntrypoint.Models.Dtos.Responses.Practice;
public class PracticeOpponent public class PracticeOpponent
{ {
/// <summary>Practice slot id (unique per entry; AI opponent identifier).</summary> /// <summary>Practice slot id (unique per entry; AI opponent identifier).</summary>
[JsonPropertyName("practice_id")]
[Key("practice_id")] public int PracticeId { get; set; } [Key("practice_id")] public int PracticeId { get; set; }
/// <summary> /// <summary>
/// Text-table id resolved client-side via Data.Master.GetPracticeText(text_id). /// Text-table id resolved client-side via Data.Master.GetPracticeText(text_id).
/// Stringified int client calls .ToString() before lookup. Sent as string to be safe. /// Stringified int 窶・client calls .ToString() before lookup. Sent as string to be safe.
/// </summary> /// </summary>
[JsonPropertyName("text_id")]
[Key("text_id")] public string TextId { get; set; } = string.Empty; [Key("text_id")] public string TextId { get; set; } = string.Empty;
/// <summary>Class (leader) id the AI plays.</summary> /// <summary>Class (leader) id the AI plays.</summary>
[JsonPropertyName("class_id")]
[Key("class_id")] public int ClassId { get; set; } [Key("class_id")] public int ClassId { get; set; }
/// <summary>Portrait / character id (which leader art the AI uses).</summary> /// <summary>Portrait / character id (which leader art the AI uses).</summary>
[JsonPropertyName("chara_id")]
[Key("chara_id")] public int CharaId { get; set; } [Key("chara_id")] public int CharaId { get; set; }
/// <summary>Title-degree id shown next to the AI's name.</summary> /// <summary>Title-degree id shown next to the AI's name.</summary>
[JsonPropertyName("degree_id")]
[Key("degree_id")] public int DegreeId { get; set; } [Key("degree_id")] public int DegreeId { get; set; }
/// <summary>AI deck-strength tier (drives which preset deck the AI uses).</summary> /// <summary>AI deck-strength tier (drives which preset deck the AI uses).</summary>
[JsonPropertyName("ai_deck_level")]
[Key("ai_deck_level")] public int AiDeckLevel { get; set; } [Key("ai_deck_level")] public int AiDeckLevel { get; set; }
/// <summary>AI decision-making tier.</summary> /// <summary>AI decision-making tier.</summary>
[JsonPropertyName("ai_logic_level")]
[Key("ai_logic_level")] public int AiLogicLevel { get; set; } [Key("ai_logic_level")] public int AiLogicLevel { get; set; }
/// <summary>Starting HP for the AI side (often 20).</summary> /// <summary>Starting HP for the AI side (often 20).</summary>
[JsonPropertyName("ai_max_life")]
[Key("ai_max_life")] public int AiMaxLife { get; set; } = 20; [Key("ai_max_life")] public int AiMaxLife { get; set; } = 20;
/// <summary>3D battle-field asset id (string on the wire; client int.TryParse's it).</summary> /// <summary>3D battle-field asset id (string on the wire; client int.TryParse's it).</summary>
[JsonPropertyName("battle3dfield_id")]
[Key("battle3dfield_id")] public string Battle3dFieldId { get; set; } = "1"; [Key("battle3dfield_id")] public string Battle3dFieldId { get; set; } = "1";
/// <summary>Optional. true => entry disabled, client prepends maintenance suffix.</summary> /// <summary>Optional. true => entry disabled, client prepends maintenance suffix.</summary>
[JsonPropertyName("is_maintenance")]
[Key("is_maintenance")] public bool? IsMaintenance { get; set; } [Key("is_maintenance")] public bool? IsMaintenance { get; set; }
/// <summary>true => entry is a special "campaign" practice (event-tied).</summary> /// <summary>true => entry is a special "campaign" practice (event-tied).</summary>
[JsonPropertyName("is_campaign_practice")]
[Key("is_campaign_practice")] public bool IsCampaignPractice { get; set; } [Key("is_campaign_practice")] public bool IsCampaignPractice { get; set; }
} }

View File

@@ -1,4 +1,5 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Responses.Practice; namespace SVSim.EmulatedEntrypoint.Models.Dtos.Responses.Practice;
@@ -8,7 +9,8 @@ public class PracticeStartResponse
/// <summary> /// <summary>
/// Optional mission/achievement evaluation snapshot. Spec: safe to omit entirely; /// Optional mission/achievement evaluation snapshot. Spec: safe to omit entirely;
/// client tolerates absence (defensive `Keys.Contains` check). Always null in our /// client tolerates absence (defensive `Keys.Contains` check). Always null in our
/// minimal impl we don't model missions. /// minimal impl 窶・we don't model missions.
/// </summary> /// </summary>
[JsonPropertyName("mission_parameter")]
[Key("mission_parameter")] public object? MissionParameter { get; set; } [Key("mission_parameter")] public object? MissionParameter { get; set; }
} }

View File

@@ -1,4 +1,5 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Responses; namespace SVSim.EmulatedEntrypoint.Models.Dtos.Responses;
@@ -9,6 +10,7 @@ public class SpecialTitleCheckResponse
/// Numeric string. "0"/"1" are the built-in default title screens; any other value /// Numeric string. "0"/"1" are the built-in default title screens; any other value
/// is treated as an asset-bundle id. When omitted, the client defaults to "0". /// is treated as an asset-bundle id. When omitted, the client defaults to "0".
/// </summary> /// </summary>
[JsonPropertyName("title_image_id")]
[Key("title_image_id")] [Key("title_image_id")]
public string? TitleImageId { get; set; } public string? TitleImageId { get; set; }
} }

View File

@@ -1,12 +1,15 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos; namespace SVSim.EmulatedEntrypoint.Models.Dtos;
[MessagePackObject] [MessagePackObject]
public class ShopExpiryInfo public class ShopExpiryInfo
{ {
[JsonPropertyName("sales_period_time")]
[Key("sales_period_time")] [Key("sales_period_time")]
public DateTime? SalesPeriodTime { get; set; } public DateTime? SalesPeriodTime { get; set; }
[JsonPropertyName("sales_period_series")]
[Key("sales_period_series")] [Key("sales_period_series")]
public int? SalesPeriodSeries { get; set; } public int? SalesPeriodSeries { get; set; }
} }

View File

@@ -1,4 +1,5 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos; namespace SVSim.EmulatedEntrypoint.Models.Dtos;
@@ -11,6 +12,7 @@ public class SleeveIdentifier
/// <summary> /// <summary>
/// The id of the sleeve. /// The id of the sleeve.
/// </summary> /// </summary>
[JsonPropertyName("sleeve_id")]
[Key("sleeve_id")] [Key("sleeve_id")]
public long SleeveId { get; set; } public long SleeveId { get; set; }
} }

View File

@@ -1,12 +1,15 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos; namespace SVSim.EmulatedEntrypoint.Models.Dtos;
[MessagePackObject] [MessagePackObject]
public class SpecialRotationSchedule public class SpecialRotationSchedule
{ {
[JsonPropertyName("gathering")]
[Key("gathering")] [Key("gathering")]
public DateRange Gathering { get; set; } = new DateRange(); public DateRange Gathering { get; set; } = new DateRange();
[JsonPropertyName("free_battle")]
[Key("free_battle")] [Key("free_battle")]
public DateRange FreeBattle { get; set; } = new DateRange(); public DateRange FreeBattle { get; set; } = new DateRange();
} }

View File

@@ -1,22 +1,26 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos; namespace SVSim.EmulatedEntrypoint.Models.Dtos;
[MessagePackObject] [MessagePackObject]
public class SpecialRotationSetting public class SpecialRotationSetting
{ {
[JsonPropertyName("rotation_id")]
[Key("rotation_id")] [Key("rotation_id")]
public int RotationId { get; set; } public int RotationId { get; set; }
/// <summary> /// <summary>
/// Formatted as 'setid|setid|setid...'. /// Formatted as 'setid|setid|setid...'.
/// </summary> /// </summary>
[JsonPropertyName("card_set_ids")]
[Key("card_set_ids")] [Key("card_set_ids")]
public string CardSetIds { get; set; } public string CardSetIds { get; set; }
/// <summary> /// <summary>
/// Formatted as 'abilityid|abilityid|abilityid...'. /// Formatted as 'abilityid|abilityid|abilityid...'.
/// </summary> /// </summary>
[JsonPropertyName("abilities")]
[Key("abilities")] [Key("abilities")]
public string Abilities { get; set; } public string Abilities { get; set; }
} }

View File

@@ -1,4 +1,5 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos; namespace SVSim.EmulatedEntrypoint.Models.Dtos;
@@ -6,7 +7,7 @@ namespace SVSim.EmulatedEntrypoint.Models.Dtos;
/// Per-link entry in <c>transition_account_data</c>. Production sends three string fields per /// Per-link entry in <c>transition_account_data</c>. Production sends three string fields per
/// entry even though <c>GameStartCheckTask.Parse</c> only reads <c>social_account_type</c>. /// entry even though <c>GameStartCheckTask.Parse</c> only reads <c>social_account_type</c>.
/// The extra two are read by adjacent tasks (<c>GetGameDataByTransitionCode</c>, /// The extra two are read by adjacent tasks (<c>GetGameDataByTransitionCode</c>,
/// <c>GetGameDataBySocialAccountTask</c>) kept here so the wire matches prod regardless of /// <c>GetGameDataBySocialAccountTask</c>) 窶・kept here so the wire matches prod regardless of
/// which task ends up consuming the payload. /// which task ends up consuming the payload.
/// </summary> /// </summary>
[MessagePackObject] [MessagePackObject]
@@ -15,22 +16,25 @@ public class TransitionAccountData
/// <summary> /// <summary>
/// The social provider's account id (e.g. SteamID as a string). Sent as string on the wire. /// The social provider's account id (e.g. SteamID as a string). Sent as string on the wire.
/// </summary> /// </summary>
[JsonPropertyName("social_account_id")]
[Key("social_account_id")] [Key("social_account_id")]
public string? SocialAccountId { get; set; } public string? SocialAccountId { get; set; }
/// <summary> /// <summary>
/// <c>Cute/CuteNetworkDefine.ACCOUNT_TYPE</c> enum, **sent as string** on the wire even /// <c>Cute/CuteNetworkDefine.ACCOUNT_TYPE</c> enum, **sent as string** on the wire even
/// though it's numeric. <c>GameStartCheckTask.Parse</c> calls <c>.ToInt()</c> on it so /// though it's numeric. <c>GameStartCheckTask.Parse</c> calls <c>.ToInt()</c> on it so
/// LitJson coerces transparently but matching prod's string form makes us safer against /// LitJson coerces transparently 窶・but matching prod's string form makes us safer against
/// future client paths that might compare it as a literal. /// future client paths that might compare it as a literal.
/// 1=GooglePlay, 2=GameCenter, 3=Facebook, 4=DMM, 5=Steam, 6=AppleID. /// 1=GooglePlay, 2=GameCenter, 3=Facebook, 4=DMM, 5=Steam, 6=AppleID.
/// </summary> /// </summary>
[JsonPropertyName("social_account_type")]
[Key("social_account_type")] [Key("social_account_type")]
public string? SocialAccountType { get; set; } public string? SocialAccountType { get; set; }
/// <summary> /// <summary>
/// The viewer id this social connection is linked to. Sent as string. /// The viewer id this social connection is linked to. Sent as string.
/// </summary> /// </summary>
[JsonPropertyName("connected_viewer_id")]
[Key("connected_viewer_id")] [Key("connected_viewer_id")]
public string? ConnectedViewerId { get; set; } public string? ConnectedViewerId { get; set; }
} }

View File

@@ -1,5 +1,6 @@
using MessagePack; using MessagePack;
using SVSim.Database.Models; using SVSim.Database.Models;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos; namespace SVSim.EmulatedEntrypoint.Models.Dtos;
@@ -12,12 +13,14 @@ public class UserCard : CardIdentifier
/// <summary> /// <summary>
/// The number of the specified card the user has. /// The number of the specified card the user has.
/// </summary> /// </summary>
[JsonPropertyName("number")]
[Key("number")] [Key("number")]
public int Count { get; set; } public int Count { get; set; }
/// <summary> /// <summary>
/// Whether the card is protected from dusting. /// Whether the card is protected from dusting.
/// </summary> /// </summary>
[JsonPropertyName("is_protected")]
[Key("is_protected")] [Key("is_protected")]
public int IsProtected { get; set; } public int IsProtected { get; set; }

View File

@@ -1,32 +1,41 @@
using MessagePack; using MessagePack;
using SVSim.Database.Models; using SVSim.Database.Models;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos; namespace SVSim.EmulatedEntrypoint.Models.Dtos;
[MessagePackObject] [MessagePackObject]
public class UserClass public class UserClass
{ {
[JsonPropertyName("class_id")]
[Key("class_id")] [Key("class_id")]
public int ClassId { get; set; } public int ClassId { get; set; }
[JsonPropertyName("is_available")]
[Key("is_available")] [Key("is_available")]
public int IsAvailable { get; set; } public int IsAvailable { get; set; }
[JsonPropertyName("level")]
[Key("level")] [Key("level")]
public int Level { get; set; } public int Level { get; set; }
[JsonPropertyName("exp")]
[Key("exp")] [Key("exp")]
public int Exp { get; set; } public int Exp { get; set; }
[JsonPropertyName("is_random_leader_skin")]
[Key("is_random_leader_skin")] [Key("is_random_leader_skin")]
public int IsRandomLeaderSkin { get; set; } public int IsRandomLeaderSkin { get; set; }
[JsonPropertyName("leader_skin_id")]
[Key("leader_skin_id")] [Key("leader_skin_id")]
public int LeaderSkinId { get; set; } public int LeaderSkinId { get; set; }
[JsonPropertyName("leader_skin_id_list")]
[Key("leader_skin_id_list")] [Key("leader_skin_id_list")]
public List<int> LeaderSkinIds { get; set; } = new List<int>(); public List<int> LeaderSkinIds { get; set; } = new List<int>();
[JsonPropertyName("default_leader_skin_id")]
[Key("default_leader_skin_id")] [Key("default_leader_skin_id")]
public int DefaultLeaderSkinId { get; set; } public int DefaultLeaderSkinId { get; set; }

View File

@@ -1,22 +1,30 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos; namespace SVSim.EmulatedEntrypoint.Models.Dtos;
[MessagePackObject] [MessagePackObject]
public class UserConfig public class UserConfig
{ {
[JsonPropertyName("receive_invitation")]
[Key("receive_invitation")] [Key("receive_invitation")]
public int ReceiveInvitation { get; set; } public int ReceiveInvitation { get; set; }
[JsonPropertyName("receive_invitation_in_battle")]
[Key("receive_invitation_in_battle")] [Key("receive_invitation_in_battle")]
public int ReceiveInvitationInBattle { get; set; } public int ReceiveInvitationInBattle { get; set; }
[JsonPropertyName("receive_invitation_in_offline")]
[Key("receive_invitation_in_offline")] [Key("receive_invitation_in_offline")]
public int ReceiveInvitationInOffline { get; set; } public int ReceiveInvitationInOffline { get; set; }
[JsonPropertyName("receive_friend_apply")]
[Key("receive_friend_apply")] [Key("receive_friend_apply")]
public int ReceiveFriendApply { get; set; } public int ReceiveFriendApply { get; set; }
[JsonPropertyName("is_allow_send_adjust")]
[Key("is_allow_send_adjust")] [Key("is_allow_send_adjust")]
public int IsAllowSendAdjust { get; set; } public int IsAllowSendAdjust { get; set; }
[JsonPropertyName("is_foil_preferred")]
[Key("is_foil_preferred")] [Key("is_foil_preferred")]
public int IsFoilPreferred { get; set; } public int IsFoilPreferred { get; set; }
[JsonPropertyName("is_prize_preferred")]
[Key("is_prize_preferred")] [Key("is_prize_preferred")]
public int IsPrizePreferred { get; set; } public int IsPrizePreferred { get; set; }
} }

View File

@@ -1,31 +1,43 @@
using MessagePack; using MessagePack;
using SVSim.Database.Models; using SVSim.Database.Models;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos; namespace SVSim.EmulatedEntrypoint.Models.Dtos;
[MessagePackObject] [MessagePackObject]
public class UserCurrency public class UserCurrency
{ {
[JsonPropertyName("viewer_id")]
[Key("viewer_id")] [Key("viewer_id")]
public long ViewerId { get; set; } public long ViewerId { get; set; }
[JsonPropertyName("crystal")]
[Key("crystal")] [Key("crystal")]
public ulong Crystals { get; set; } public ulong Crystals { get; set; }
[JsonPropertyName("crystal_android")]
[Key("crystal_android")] [Key("crystal_android")]
public ulong AndroidCrystals { get; set; } public ulong AndroidCrystals { get; set; }
[JsonPropertyName("crystal_ios")]
[Key("crystal_ios")] [Key("crystal_ios")]
public ulong IosCrystals { get; set; } public ulong IosCrystals { get; set; }
[JsonPropertyName("crystal_steam")]
[Key("crystal_steam")] [Key("crystal_steam")]
public ulong SteamCrystals { get; set; } public ulong SteamCrystals { get; set; }
[JsonPropertyName("crystal_dmm")]
[Key("crystal_dmm")] [Key("crystal_dmm")]
public ulong DmmCrystals { get; set; } public ulong DmmCrystals { get; set; }
[JsonPropertyName("free_crystal")]
[Key("free_crystal")] [Key("free_crystal")]
public ulong FreeCrystals { get; set; } public ulong FreeCrystals { get; set; }
[JsonPropertyName("total_crystal")]
[Key("total_crystal")] [Key("total_crystal")]
public ulong TotalCrystals { get; set; } public ulong TotalCrystals { get; set; }
[JsonPropertyName("life_total_crystal")]
[Key("life_total_crystal")] [Key("life_total_crystal")]
public ulong LifeTotalCrystals { get; set; } public ulong LifeTotalCrystals { get; set; }
[JsonPropertyName("red_ether")]
[Key("red_ether")] [Key("red_ether")]
public ulong RedEther { get; set; } public ulong RedEther { get; set; }
[JsonPropertyName("rupy")]
[Key("rupy")] [Key("rupy")]
public ulong Rupees { get; set; } public ulong Rupees { get; set; }

View File

@@ -1,5 +1,6 @@
using MessagePack; using MessagePack;
using SVSim.Database.Models; using SVSim.Database.Models;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos; namespace SVSim.EmulatedEntrypoint.Models.Dtos;
@@ -9,34 +10,49 @@ namespace SVSim.EmulatedEntrypoint.Models.Dtos;
[MessagePackObject] [MessagePackObject]
public class UserDeck public class UserDeck
{ {
[JsonPropertyName("deck_no")]
[Key("deck_no")] [Key("deck_no")]
public int DeckNumber { get; set; } public int DeckNumber { get; set; }
[JsonPropertyName("class_id")]
[Key("class_id")] [Key("class_id")]
public int ClassId { get; set; } public int ClassId { get; set; }
[JsonPropertyName("sleeve_id")]
[Key("sleeve_id")] [Key("sleeve_id")]
public int SleeveId { get; set; } public int SleeveId { get; set; }
[JsonPropertyName("leader_skin_id")]
[Key("leader_skin_id")] [Key("leader_skin_id")]
public int LeaderSkinId { get; set; } public int LeaderSkinId { get; set; }
[JsonPropertyName("deck_name")]
[Key("deck_name")] [Key("deck_name")]
public string Name { get; set; } = string.Empty; public string Name { get; set; } = string.Empty;
[JsonPropertyName("card_id_array")]
[Key("card_id_array")] [Key("card_id_array")]
public List<long> Cards { get; set; } = new List<long>(); public List<long> Cards { get; set; } = new List<long>();
[JsonPropertyName("is_complete_deck")]
[Key("is_complete_deck")] [Key("is_complete_deck")]
public int IsCompleteDeck { get; set; } public int IsCompleteDeck { get; set; }
[JsonPropertyName("restricted_card_exists")]
[Key("restricted_card_exists")] [Key("restricted_card_exists")]
public bool RestrictedCardExists { get; set; } public bool RestrictedCardExists { get; set; }
[JsonPropertyName("is_available_deck")]
[Key("is_available_deck")] [Key("is_available_deck")]
public int IsAvailable { get; set; } public int IsAvailable { get; set; }
[JsonPropertyName("maintenance_card_ids")]
[Key("maintenance_card_ids")] [Key("maintenance_card_ids")]
public List<long> MaintenanceCards { get; set; } = new List<long>(); public List<long> MaintenanceCards { get; set; } = new List<long>();
[JsonPropertyName("is_include_un_possession_card")]
[Key("is_include_un_possession_card")] [Key("is_include_un_possession_card")]
public bool IncludesNonCollectibleCards { get; set; } public bool IncludesNonCollectibleCards { get; set; }
[JsonPropertyName("is_random_leader_skin")]
[Key("is_random_leader_skin")] [Key("is_random_leader_skin")]
public int IsRandomLeaderSkin { get; set; } public int IsRandomLeaderSkin { get; set; }
[JsonPropertyName("leader_skin_id_list")]
[Key("leader_skin_id_list")] [Key("leader_skin_id_list")]
public List<int> LeaderSkinIds { get; set; } = new List<int> { 0 }; public List<int> LeaderSkinIds { get; set; } = new List<int> { 0 };
[JsonPropertyName("order_num")]
[Key("order_num")] [Key("order_num")]
public int Order { get; set; } public int Order { get; set; }
[JsonPropertyName("create_deck_time")]
[Key("create_deck_time")] [Key("create_deck_time")]
public DateTime DeckCreateTime { get; set; } public DateTime DeckCreateTime { get; set; }

View File

@@ -1,13 +1,16 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos; namespace SVSim.EmulatedEntrypoint.Models.Dtos;
[MessagePackObject] [MessagePackObject]
public class UserFormatDeckInfo public class UserFormatDeckInfo
{ {
[JsonPropertyName("format")]
[Key("format")] [Key("format")]
public string Format { get; set; } = string.Empty; public string Format { get; set; } = string.Empty;
[JsonPropertyName("user_deck_list")]
[Key("user_deck_list")] [Key("user_deck_list")]
public List<UserDeck> UserDecks { get; set; } = new List<UserDeck>(); public List<UserDeck> UserDecks { get; set; } = new List<UserDeck>();
} }

View File

@@ -1,39 +1,53 @@
using MessagePack; using MessagePack;
using SVSim.Database.Models; using SVSim.Database.Models;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos; namespace SVSim.EmulatedEntrypoint.Models.Dtos;
[MessagePackObject] [MessagePackObject]
public class UserInfo public class UserInfo
{ {
[JsonPropertyName("device_type")]
[Key("device_type")] [Key("device_type")]
public int DeviceType { get; set; } public int DeviceType { get; set; }
[JsonPropertyName("name")]
[Key("name")] [Key("name")]
public string Name { get; set; } = string.Empty; public string Name { get; set; } = string.Empty;
[JsonPropertyName("country_code")]
[Key("country_code")] [Key("country_code")]
public string CountryCode { get; set; } = string.Empty; public string CountryCode { get; set; } = string.Empty;
[JsonPropertyName("max_friend")]
[Key("max_friend")] [Key("max_friend")]
public int MaxFriend { get; set; } public int MaxFriend { get; set; }
[JsonPropertyName("last_play_time")]
[Key("last_play_time")] [Key("last_play_time")]
public DateTime LastPlayTime { get; set; } public DateTime LastPlayTime { get; set; }
[JsonPropertyName("is_received_two_pick_mission")]
[Key("is_received_two_pick_mission")] [Key("is_received_two_pick_mission")]
public int HasReceivedPickTwoMission { get; set; } public int HasReceivedPickTwoMission { get; set; }
/// <summary> /// <summary>
/// Birth date as yyyy-MM-dd. Parser does .ToString() on this field (LoadDetail.cs:203). /// Birth date as yyyy-MM-dd. Parser does .ToString() on this field (LoadDetail.cs:203).
/// Format verified against live capture pending. /// Format verified against live capture pending.
/// </summary> /// </summary>
[JsonPropertyName("birth")]
[Key("birth")] [Key("birth")]
public string Birthday { get; set; } = string.Empty; public string Birthday { get; set; } = string.Empty;
[JsonPropertyName("selected_emblem_id")]
[Key("selected_emblem_id")] [Key("selected_emblem_id")]
public long SelectedEmblemId { get; set; } public long SelectedEmblemId { get; set; }
[JsonPropertyName("selected_degree_id")]
[Key("selected_degree_id")] [Key("selected_degree_id")]
public int SelectedDegreeId { get; set; } public int SelectedDegreeId { get; set; }
[JsonPropertyName("mission_change_time")]
[Key("mission_change_time")] [Key("mission_change_time")]
public DateTime MissionChangeTime { get; set; } public DateTime MissionChangeTime { get; set; }
[JsonPropertyName("mission_receive_type")]
[Key("mission_receive_type")] [Key("mission_receive_type")]
public int MissionReceiveType { get; set; } public int MissionReceiveType { get; set; }
[JsonPropertyName("is_official")]
[Key("is_official")] [Key("is_official")]
public int IsOfficial { get; set; } public int IsOfficial { get; set; }
[JsonPropertyName("is_official_mark_displayed")]
[Key("is_official_mark_displayed")] [Key("is_official_mark_displayed")]
public int IsOfficialMarkDisplayed { get; set; } public int IsOfficialMarkDisplayed { get; set; }

View File

@@ -1,14 +1,17 @@
using MessagePack; using MessagePack;
using SVSim.Database.Models; using SVSim.Database.Models;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos; namespace SVSim.EmulatedEntrypoint.Models.Dtos;
[MessagePackObject] [MessagePackObject]
public class UserItem public class UserItem
{ {
[JsonPropertyName("item_id")]
[Key("item_id")] [Key("item_id")]
public int ItemId { get; set; } public int ItemId { get; set; }
[JsonPropertyName("number")]
[Key("number")] [Key("number")]
public int Number { get; set; } public int Number { get; set; }

View File

@@ -1,19 +1,25 @@
using MessagePack; using MessagePack;
using SVSim.Database.Models; using SVSim.Database.Models;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos; namespace SVSim.EmulatedEntrypoint.Models.Dtos;
[MessagePackObject] [MessagePackObject]
public class UserLeaderSkin public class UserLeaderSkin
{ {
[JsonPropertyName("leader_skin_id")]
[Key("leader_skin_id")] [Key("leader_skin_id")]
public int Id { get; set; } public int Id { get; set; }
[JsonPropertyName("leader_skin_name")]
[Key("leader_skin_name")] [Key("leader_skin_name")]
public string Name { get; set; } = string.Empty; public string Name { get; set; } = string.Empty;
[JsonPropertyName("class_id")]
[Key("class_id")] [Key("class_id")]
public int ClassId { get; set; } public int ClassId { get; set; }
[JsonPropertyName("emote_id")]
[Key("emote_id")] [Key("emote_id")]
public int EmoteId { get; set; } public int EmoteId { get; set; }
[JsonPropertyName("is_owned")]
[Key("is_owned")] [Key("is_owned")]
public bool IsOwned { get; set; } public bool IsOwned { get; set; }
@@ -21,7 +27,7 @@ public class UserLeaderSkin
{ {
this.Id = leaderSkin.Id; this.Id = leaderSkin.Id;
this.Name = leaderSkin.Name; this.Name = leaderSkin.Name;
// Class is nullable BaseDataSeeder maps CSV class_chara_id=0 to null. Fall back to // Class is nullable 窶・BaseDataSeeder maps CSV class_chara_id=0 to null. Fall back to
// the FK column (also nullable) and finally 0 for class-agnostic skins. // the FK column (also nullable) and finally 0 for class-agnostic skins.
this.ClassId = leaderSkin.Class?.Id ?? leaderSkin.ClassId ?? 0; this.ClassId = leaderSkin.Class?.Id ?? leaderSkin.ClassId ?? 0;
this.EmoteId = leaderSkin.EmoteId; this.EmoteId = leaderSkin.EmoteId;

View File

@@ -1,16 +1,21 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos; namespace SVSim.EmulatedEntrypoint.Models.Dtos;
[MessagePackObject] [MessagePackObject]
public class UserPromotionMatch public class UserPromotionMatch
{ {
[JsonPropertyName("match_count")]
[Key("match_count")] [Key("match_count")]
public int MatchCount { get; set; } public int MatchCount { get; set; }
[JsonPropertyName("battle_result")]
[Key("battle_result")] [Key("battle_result")]
public int BattleResult { get; set; } public int BattleResult { get; set; }
[JsonPropertyName("win")]
[Key("win")] [Key("win")]
public int Wins { get; set; } public int Wins { get; set; }
[JsonPropertyName("lose")]
[Key("lose")] [Key("lose")]
public int Losses { get; set; } public int Losses { get; set; }
} }

View File

@@ -1,34 +1,48 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos; namespace SVSim.EmulatedEntrypoint.Models.Dtos;
[MessagePackObject] [MessagePackObject]
public class UserRankInfo public class UserRankInfo
{ {
[JsonPropertyName("deck_format")]
[Key("deck_format")] [Key("deck_format")]
public int DeckFormat { get; set; } public int DeckFormat { get; set; }
[JsonPropertyName("rank")]
[Key("rank")] [Key("rank")]
public int Rank { get; set; } public int Rank { get; set; }
[JsonPropertyName("battle_point")]
[Key("battle_point")] [Key("battle_point")]
public int BattlePoints { get; set; } public int BattlePoints { get; set; }
[JsonPropertyName("successive_win_number")]
[Key("successive_win_number")] [Key("successive_win_number")]
public int WinStreak { get; set; } public int WinStreak { get; set; }
[JsonPropertyName("successive_losses_number")]
[Key("successive_losses_number")] [Key("successive_losses_number")]
public int LossStreak { get; set; } public int LossStreak { get; set; }
[JsonPropertyName("is_promotion")]
[Key("is_promotion")] [Key("is_promotion")]
public int IsPromotion { get; set; } public int IsPromotion { get; set; }
[JsonPropertyName("is_master_rank")]
[Key("is_master_rank")] [Key("is_master_rank")]
public int IsMasterRank { get; set; } public int IsMasterRank { get; set; }
[JsonPropertyName("is_grand_master_rank")]
[Key("is_grand_master_rank")] [Key("is_grand_master_rank")]
public int IsGrandMasterRank { get; set; } public int IsGrandMasterRank { get; set; }
[JsonPropertyName("master_point")]
[Key("master_point")] [Key("master_point")]
public int MasterPoints { get; set; } public int MasterPoints { get; set; }
[JsonPropertyName("period_grand_master_point")]
[Key("period_grand_master_point")] [Key("period_grand_master_point")]
public int PeriodGrandMasterPoints { get; set; } public int PeriodGrandMasterPoints { get; set; }
[JsonPropertyName("target_grand_master_point")]
[Key("target_grand_master_point")] [Key("target_grand_master_point")]
public int TargetGrandMasterPoints { get; set; } public int TargetGrandMasterPoints { get; set; }
[JsonPropertyName("current_grand_master_point")]
[Key("current_grand_master_point")] [Key("current_grand_master_point")]
public int CurrentGrandMasterPoints { get; set; } public int CurrentGrandMasterPoints { get; set; }
[JsonPropertyName("user_promotion_match")]
[Key("user_promotion_match")] [Key("user_promotion_match")]
public UserPromotionMatch? UserPromotionMatch { get; set; } public UserPromotionMatch? UserPromotionMatch { get; set; }
} }

View File

@@ -1,18 +1,24 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos; namespace SVSim.EmulatedEntrypoint.Models.Dtos;
[MessagePackObject] [MessagePackObject]
public class UserRankedMatches public class UserRankedMatches
{ {
[JsonPropertyName("class_id")]
[Key("class_id")] [Key("class_id")]
public int ClassId { get; set; } public int ClassId { get; set; }
[JsonPropertyName("match_count")]
[Key("match_count")] [Key("match_count")]
public int MatchCount { get; set; } public int MatchCount { get; set; }
[JsonPropertyName("win")]
[Key("win")] [Key("win")]
public int Wins { get; set; } public int Wins { get; set; }
[JsonPropertyName("lose")]
[Key("lose")] [Key("lose")]
public int Losses { get; set; } public int Losses { get; set; }
[JsonPropertyName("viewer_id")]
[Key("viewer_id")] [Key("viewer_id")]
public ulong ViewerId { get; set; } public ulong ViewerId { get; set; }
} }

View File

@@ -1,4 +1,5 @@
using MessagePack; using MessagePack;
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos; namespace SVSim.EmulatedEntrypoint.Models.Dtos;
@@ -11,6 +12,7 @@ public class UserTutorial
/// <summary> /// <summary>
/// The current tutorial step they are on. /// The current tutorial step they are on.
/// </summary> /// </summary>
[JsonPropertyName("tutorial_step")]
[Key("tutorial_step")] [Key("tutorial_step")]
public int TutorialStep { get; set; } public int TutorialStep { get; set; }
} }

View File

@@ -10,9 +10,9 @@ using SVSim.UnitTests.Infrastructure;
namespace SVSim.UnitTests.Controllers; namespace SVSim.UnitTests.Controllers;
/// <summary> /// <summary>
/// Coverage for <c>/deck/*</c> — the deck-editor CRUD surface. Plain-JSON path; the /// Coverage for <c>/deck/*</c> — the deck-editor CRUD surface. Tests assert against the
/// camelCase'd C# property names are what tests see (see the note on Phase 6 / encrypted /// <c>[Key("...")]</c>-driven wire keys (mirrored to <c>[JsonPropertyName]</c>); these are
/// pipeline for the msgpack contract). /// the names the decompiled client actually parses, NOT <c>SnakeCaseLower(C# property)</c>.
/// </summary> /// </summary>
public class DeckControllerTests public class DeckControllerTests
{ {
@@ -53,7 +53,7 @@ public class DeckControllerTests
Assert.That(decks.GetArrayLength(), Is.EqualTo(2), Assert.That(decks.GetArrayLength(), Is.EqualTo(2),
"Only Rotation-format decks should be returned for a Rotation request."); "Only Rotation-format decks should be returned for a Rotation request.");
var names = Enumerable.Range(0, decks.GetArrayLength()) var names = Enumerable.Range(0, decks.GetArrayLength())
.Select(i => decks[i].GetProperty("name").GetString()) .Select(i => decks[i].GetProperty("deck_name").GetString())
.ToList(); .ToList();
Assert.That(names, Is.EquivalentTo(new[] { "Slot 1", "Slot 2" })); Assert.That(names, Is.EquivalentTo(new[] { "Slot 1", "Slot 2" }));
} }
@@ -74,7 +74,7 @@ public class DeckControllerTests
using var doc = JsonDocument.Parse(body); using var doc = JsonDocument.Parse(body);
var decks = doc.RootElement.GetProperty("user_deck_list"); var decks = doc.RootElement.GetProperty("user_deck_list");
Assert.That(decks.GetArrayLength(), Is.EqualTo(1)); Assert.That(decks.GetArrayLength(), Is.EqualTo(1));
Assert.That(decks[0].GetProperty("name").GetString(), Is.EqualTo("Unlimited Deck")); Assert.That(decks[0].GetProperty("deck_name").GetString(), Is.EqualTo("Unlimited Deck"));
} }
[Test] [Test]
@@ -232,7 +232,7 @@ public class DeckControllerTests
Assert.That(decks.GetArrayLength(), Is.EqualTo(2), Assert.That(decks.GetArrayLength(), Is.EqualTo(2),
"/deck/update should hand back the full refreshed list, saving the client a follow-up."); "/deck/update should hand back the full refreshed list, saving the client a follow-up.");
var names = Enumerable.Range(0, decks.GetArrayLength()) var names = Enumerable.Range(0, decks.GetArrayLength())
.Select(i => decks[i].GetProperty("name").GetString()) .Select(i => decks[i].GetProperty("deck_name").GetString())
.ToList(); .ToList();
Assert.That(names, Is.EquivalentTo(new[] { "Existing", "Second" })); Assert.That(names, Is.EquivalentTo(new[] { "Existing", "Second" }));
} }
@@ -252,7 +252,7 @@ public class DeckControllerTests
var body = await response.Content.ReadAsStringAsync(); var body = await response.Content.ReadAsStringAsync();
using var doc = JsonDocument.Parse(body); using var doc = JsonDocument.Parse(body);
Assert.That(doc.RootElement.GetProperty("user_deck").GetProperty("name").GetString(), Assert.That(doc.RootElement.GetProperty("user_deck").GetProperty("deck_name").GetString(),
Is.EqualTo("New Name")); Is.EqualTo("New Name"));
using var scope = factory.Services.CreateScope(); using var scope = factory.Services.CreateScope();

View File

@@ -17,24 +17,23 @@ public class LoadControllerTests
"""{"viewer_id":"0","steam_id":0,"steam_session_ticket":"","carrier":"steam","card_master_hash":""}"""; """{"viewer_id":"0","steam_id":0,"steam_session_ticket":"","carrier":"steam","card_master_hash":""}""";
/// <summary> /// <summary>
/// JSON keys (camelCased C# property names) for fields the client reads unconditionally. /// Wire keys (from <c>[Key("...")]</c> / mirrored <c>[JsonPropertyName]</c>) for fields the
/// These come from the plain-JSON path; the wire-format snake_case keys /// client reads unconditionally in <c>LoadDetail.ConvertJsonData</c>. These are the names
/// (<c>user_rank</c>, <c>rotation_card_set_id_list</c>, ...) only apply when the /// the decompiled client actually looks up — NOT <c>SnakeCaseLower(C# property name)</c>.
/// encrypted msgpack pipeline is in play — see <c>EncryptedPipelineTests</c> (Phase 6). /// Missing any of these crashes the client with <c>KeyNotFoundException</c> on /load/index.
/// Missing any of these is a wire-shape regression in either path.
/// </summary> /// </summary>
private static readonly string[] RequiredIndexKeys = private static readonly string[] RequiredIndexKeys =
{ {
"user_tutorial", "user_info", "user_currency", "user_items", "user_tutorial", "user_info", "user_crystal_count", "user_item_list",
"user_rotation_decks", "user_unlimited_decks", "user_my_rotation_decks", "user_deck_rotation", "user_deck_unlimited", "user_deck_my_rotation",
"user_cards", "user_classes", "sleeves", "user_emblems", "user_card_list", "user_class_list", "user_sleeve_list", "user_emblem_list",
"user_degrees", "leader_skins", "my_page_backgrounds", "user_degree_list", "user_leader_skin_list", "user_mypage_list",
"user_rank_info", "user_ranked_matches", "daily_login_bonus", "arena_config", "user_rank", "user_rank_match_list", "daily_login_bonus", "challenge_config",
"red_ether_overrides", "maintenance_cards", "arena_infos", "rank_info", "red_ether_overwrite_list", "maintenance_card_list", "rank_info",
"class_exp", "loading_tip_card_exclusions", "default_settings", "class_exp", "loading_exclusion_card_list", "default_setting",
"unlimited_ban_list", "rotation_sets", "unlimited_restricted_base_card_id_list", "rotation_card_set_id_list",
"reprinted_cards", "spot_cards", "feature_maintenances", "reprinted_base_card_ids", "spot_cards", "feature_maintenance_list",
"special_crystal_infos", "open_battlefield_ids", "loot_box_regulations", "special_crystal_info", "open_battle_field_id_list", "loot_box_regulation",
"gathering_info", "user_config", "deck_format", "card_set_id_for_resource_dl_view" "gathering_info", "user_config", "deck_format", "card_set_id_for_resource_dl_view"
}; };
@@ -100,7 +99,7 @@ public class LoadControllerTests
var root = await PostIndexAndReadBody(factory, viewerId); var root = await PostIndexAndReadBody(factory, viewerId);
Assert.That(root.GetProperty("user_rank_info").ValueKind, Is.EqualTo(JsonValueKind.Array)); Assert.That(root.GetProperty("user_rank").ValueKind, Is.EqualTo(JsonValueKind.Array));
} }
[Test] [Test]
@@ -114,7 +113,7 @@ public class LoadControllerTests
var root = await PostIndexAndReadBody(factory, viewerId); var root = await PostIndexAndReadBody(factory, viewerId);
Assert.That(root.GetProperty("user_rank_info").GetArrayLength(), Is.EqualTo(5)); Assert.That(root.GetProperty("user_rank").GetArrayLength(), Is.EqualTo(5));
} }
[Test] [Test]
@@ -127,10 +126,26 @@ public class LoadControllerTests
var root = await PostIndexAndReadBody(factory, viewerId); var root = await PostIndexAndReadBody(factory, viewerId);
Assert.That(root.GetProperty("rotation_sets").GetArrayLength(), Assert.That(root.GetProperty("rotation_card_set_id_list").GetArrayLength(),
Is.GreaterThanOrEqualTo(2)); Is.GreaterThanOrEqualTo(2));
} }
[Test]
public async Task Index_omits_arena_info_when_empty()
{
// ArenaData(JsonData) ctor reads data[0] inside the Keys.Contains("arena_info")
// branch (LoadDetail.cs:261 → ArenaData.cs:48) — an empty array crashes the client
// with ArgumentOutOfRangeException. Field must be absent when there's no arena.
using var factory = new SVSimTestFactory();
long viewerId = await factory.SeedViewerAsync();
var root = await PostIndexAndReadBody(factory, viewerId);
Assert.That(root.TryGetProperty("arena_info", out _), Is.False,
"arena_info must be omitted when empty; the client crashes on []. " +
"If you re-add it, populate at least one entry with a valid format_info.");
}
[Test] [Test]
public async Task Index_when_viewer_has_no_decks_returns_empty_format_lists() public async Task Index_when_viewer_has_no_decks_returns_empty_format_lists()
{ {
@@ -141,15 +156,15 @@ public class LoadControllerTests
var root = await PostIndexAndReadBody(factory, viewerId); var root = await PostIndexAndReadBody(factory, viewerId);
foreach (var key in new[] { "user_rotation_decks", "user_unlimited_decks", "user_my_rotation_decks" }) foreach (var key in new[] { "user_deck_rotation", "user_deck_unlimited", "user_deck_my_rotation" })
{ {
var container = root.GetProperty(key); var container = root.GetProperty(key);
Assert.That(container.ValueKind, Is.EqualTo(JsonValueKind.Object), Assert.That(container.ValueKind, Is.EqualTo(JsonValueKind.Object),
$"{key} should be the UserFormatDeckInfo object wrapper, not a raw array."); $"{key} should be the UserFormatDeckInfo object wrapper, not a raw array.");
var inner = container.GetProperty("user_decks"); var inner = container.GetProperty("user_deck_list");
Assert.That(inner.ValueKind, Is.EqualTo(JsonValueKind.Array)); Assert.That(inner.ValueKind, Is.EqualTo(JsonValueKind.Array));
Assert.That(inner.GetArrayLength(), Is.EqualTo(0), Assert.That(inner.GetArrayLength(), Is.EqualTo(0),
$"{key}.userDecks must be an empty array for a deckless viewer, not null."); $"{key}.user_deck_list must be an empty array for a deckless viewer, not null.");
} }
} }
} }

View File

@@ -58,9 +58,9 @@ public class PracticeControllerTests
var rotation = doc.RootElement.GetProperty("user_deck_rotation"); var rotation = doc.RootElement.GetProperty("user_deck_rotation");
var unlimited = doc.RootElement.GetProperty("user_deck_unlimited"); var unlimited = doc.RootElement.GetProperty("user_deck_unlimited");
Assert.That(rotation.GetArrayLength(), Is.EqualTo(1)); Assert.That(rotation.GetArrayLength(), Is.EqualTo(1));
Assert.That(rotation[0].GetProperty("name").GetString(), Is.EqualTo("Rotation Deck")); Assert.That(rotation[0].GetProperty("deck_name").GetString(), Is.EqualTo("Rotation Deck"));
Assert.That(unlimited.GetArrayLength(), Is.EqualTo(1)); Assert.That(unlimited.GetArrayLength(), Is.EqualTo(1));
Assert.That(unlimited[0].GetProperty("name").GetString(), Is.EqualTo("Unlimited Deck")); Assert.That(unlimited[0].GetProperty("deck_name").GetString(), Is.EqualTo("Unlimited Deck"));
} }
[Test] [Test]