Deck list work

This commit is contained in:
gamer147
2026-05-23 19:57:34 -04:00
parent 66184b3685
commit d3b2970e11
41 changed files with 70683 additions and 81 deletions

View File

@@ -89,6 +89,48 @@ public class MyPageIndexResponse
[Key("is_available_colosseum_free_entry")]
public bool IsAvailableColosseumFreeEntry { get; set; }
// ── Sealed Arena season ────────────────────────────────────────────────
/// <summary>
/// sealed_info is consumed by ArenaData.SetSealedMyPageResponseData (Keys.Contains-guarded),
/// but post-parse-consumer policy says we emit anyway. Defaults to a zeroed-out SealedInfo
/// when no current season is seeded — Enable=0 means the UI treats Sealed as inactive.
/// </summary>
[JsonPropertyName("sealed_info")]
[Key("sealed_info")]
public SealedInfo SealedInfo { get; set; } = new();
// ── Mypage banner carousel ─────────────────────────────────────────────
/// <summary>
/// banner is consumed by per-entry parsing inside a TryGetValue guard
/// (Wizard/MyPageBannerBase.BannerInfo.Parse iterates the array if present). We always emit
/// the list — empty when no rows have been imported. See SVSim.Bootstrap.GlobalsImporter.ImportBanners.
/// </summary>
[JsonPropertyName("banner")]
[Key("banner")]
public List<BannerInfo> Banner { get; set; } = new();
/// <summary>Prod sends explicit null. Override WhenWritingNull so the key survives serialization.</summary>
[JsonPropertyName("sub_banner")]
[Key("sub_banner")]
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public object? SubBanner { get; set; }
[JsonPropertyName("sub_banner_list")]
[Key("sub_banner_list")]
public List<object> SubBannerList { get; set; } = new();
[JsonPropertyName("home_dialog_list")]
[Key("home_dialog_list")]
public List<object> HomeDialogList { get; set; } = new();
// ── Room type in session (Special-format windows) ──────────────────────
[JsonPropertyName("room_type_in_session")]
[Key("room_type_in_session")]
public RoomTypeInSession RoomTypeInSession { get; set; } = new();
/// <summary>
/// Required — ColosseumEntryInfoTask.SetColosseumInfo indexes this key
/// directly (Wizard/ColosseumEntryInfoTask.cs:102) and reads
@@ -104,25 +146,37 @@ public class MyPageIndexResponse
[Key("convention")]
public Convention Convention { get; set; } = new();
// ── Battle / room recovery (optional) ─────────────────────────────────
/// <summary>
/// Required — MyPageTask.cs:110 constructs ArenaCompetition(responseData)
/// which indexes data.competition_info.is_competition_period unconditionally
/// (ArenaCompetition.cs:232-233). When false, the rest of the block is
/// skipped, so a default-constructed CompetitionInfo is sufficient.
/// </summary>
[JsonPropertyName("competition_info")]
[Key("competition_info")]
public CompetitionInfo CompetitionInfo { get; set; } = new();
// ── Battle / room recovery ─────────────────────────────────────────────
/// <summary>Prod always sends concrete bool here even for fresh viewers — emit always.</summary>
[JsonPropertyName("unfinished_battle_exists")]
[Key("unfinished_battle_exists")]
public bool? UnfinishedBattleExists { get; set; }
public bool UnfinishedBattleExists { get; set; }
/// <summary>Only meaningful when UnfinishedBattleExists is true. Keep nullable + omitted otherwise — prod also omits it for fresh viewers.</summary>
[JsonPropertyName("battle_finish_wait_time")]
[Key("battle_finish_wait_time")]
public int? BattleFinishWaitTime { get; set; }
[JsonPropertyName("is_joined_room")]
[Key("is_joined_room")]
public bool? IsJoinedRoom { get; set; }
public bool IsJoinedRoom { get; set; }
// ── Login bonus (optional) ─────────────────────────────────────────────
// ── Login bonus ────────────────────────────────────────────────────────
[JsonPropertyName("can_give_daily_login_bonus")]
[Key("can_give_daily_login_bonus")]
public bool? CanGiveDailyLoginBonus { get; set; }
public bool CanGiveDailyLoginBonus { get; set; }
// ── User config (settings echo) ────────────────────────────────────────
@@ -210,14 +264,45 @@ public class MyPageIndexResponse
[Key("story_notification")]
public StoryNotification StoryNotification { get; set; } = new();
// ── Optional UI surface area ───────────────────────────────────────────
// ── Per-viewer / event state ───────────────────────────────────────────
/// <summary>Updated item counts. Refreshes Data.Load.data._userItemDict when present.</summary>
/// <summary>
/// Updated item counts. Empty list = "no items to update" (client iterates 0 times, no UI change).
/// Per-viewer state — populate from viewer.Items when that wiring lands.
/// </summary>
[JsonPropertyName("user_item_list")]
[Key("user_item_list")]
public List<UserItem>? UserItemList { get; set; }
public List<UserItem> UserItemList { get; set; } = new();
[JsonPropertyName("gathering_info")]
[Key("gathering_info")]
public GatheringInfo? GatheringInfo { get; set; }
public GatheringInfo GatheringInfo { get; set; } = new();
/// <summary>Per-viewer offline-event participation. Empty for fresh viewers; prod also sends [].</summary>
[JsonPropertyName("user_offline_event")]
[Key("user_offline_event")]
public List<object> UserOfflineEvent { get; set; } = new();
// ── Fields prod sends as explicit null ─────────────────────────────────
/// <summary>
/// CRITICAL — emitting this field (even as null) routes MyPageTask.Parse through
/// CampaignBattleWin.Clear() which initializes RewardList = new List&lt;...&gt;(). Without it,
/// RewardList stays null and MyPageMenu.GetMyPageInfo NREs on its foreach iteration.
/// See [[project-wire-null-policy]] for the broader "post-parse-consumer" rationale.
/// </summary>
[JsonPropertyName("treasure_info")]
[Key("treasure_info")]
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public object? TreasureInfo { get; set; }
[JsonPropertyName("lottery_period_info")]
[Key("lottery_period_info")]
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public object? LotteryPeriodInfo { get; set; }
[JsonPropertyName("all_card_enabled_period")]
[Key("all_card_enabled_period")]
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public object? AllCardEnabledPeriod { get; set; }
}