Pack opening
This commit is contained in:
16
SVSim.EmulatedEntrypoint/Models/Dtos/PackBannerDto.cs
Normal file
16
SVSim.EmulatedEntrypoint/Models/Dtos/PackBannerDto.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using MessagePack;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace SVSim.EmulatedEntrypoint.Models.Dtos;
|
||||
|
||||
[MessagePackObject]
|
||||
public class PackBannerDto
|
||||
{
|
||||
[JsonPropertyName("banner_name")]
|
||||
[Key("banner_name")]
|
||||
public string BannerName { get; set; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("dialog_title")]
|
||||
[Key("dialog_title")]
|
||||
public string DialogTitle { get; set; } = string.Empty;
|
||||
}
|
||||
43
SVSim.EmulatedEntrypoint/Models/Dtos/PackChildGachaDto.cs
Normal file
43
SVSim.EmulatedEntrypoint/Models/Dtos/PackChildGachaDto.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using MessagePack;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace SVSim.EmulatedEntrypoint.Models.Dtos;
|
||||
|
||||
[MessagePackObject]
|
||||
public class PackChildGachaDto
|
||||
{
|
||||
[JsonPropertyName("gacha_id")]
|
||||
[Key("gacha_id")]
|
||||
public int GachaId { get; set; }
|
||||
|
||||
[JsonPropertyName("type_detail")]
|
||||
[Key("type_detail")]
|
||||
public int TypeDetail { get; set; }
|
||||
|
||||
[JsonPropertyName("cost")]
|
||||
[Key("cost")]
|
||||
public int Cost { get; set; }
|
||||
|
||||
[JsonPropertyName("count")]
|
||||
[Key("count")]
|
||||
public int Count { get; set; } = 8;
|
||||
|
||||
/// <summary>Stringified on the wire when present (prod sends "10001" not 10001).</summary>
|
||||
[JsonPropertyName("item_id")]
|
||||
[Key("item_id")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? ItemId { get; set; }
|
||||
|
||||
[JsonPropertyName("item_number")]
|
||||
[Key("item_number")]
|
||||
public int ItemNumber { get; set; }
|
||||
|
||||
[JsonPropertyName("is_daily_single")]
|
||||
[Key("is_daily_single")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
|
||||
public bool IsDailySingle { get; set; }
|
||||
|
||||
[JsonPropertyName("override_increase_gacha_point")]
|
||||
[Key("override_increase_gacha_point")]
|
||||
public string OverrideIncreaseGachaPoint { get; set; } = "0";
|
||||
}
|
||||
110
SVSim.EmulatedEntrypoint/Models/Dtos/PackConfigDto.cs
Normal file
110
SVSim.EmulatedEntrypoint/Models/Dtos/PackConfigDto.cs
Normal file
@@ -0,0 +1,110 @@
|
||||
using MessagePack;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace SVSim.EmulatedEntrypoint.Models.Dtos;
|
||||
|
||||
[MessagePackObject]
|
||||
public class PackConfigDto
|
||||
{
|
||||
[JsonPropertyName("parent_gacha_id")]
|
||||
[Key("parent_gacha_id")]
|
||||
public int ParentGachaId { get; set; }
|
||||
|
||||
[JsonPropertyName("base_pack_id")]
|
||||
[Key("base_pack_id")]
|
||||
public int BasePackId { get; set; }
|
||||
|
||||
[JsonPropertyName("override_draw_effect_pack_id")]
|
||||
[Key("override_draw_effect_pack_id")]
|
||||
public int OverrideDrawEffectPackId { get; set; }
|
||||
|
||||
[JsonPropertyName("override_ui_effect_pack_id")]
|
||||
[Key("override_ui_effect_pack_id")]
|
||||
public int OverrideUiEffectPackId { get; set; }
|
||||
|
||||
[JsonPropertyName("gacha_type")]
|
||||
[Key("gacha_type")]
|
||||
public int GachaType { get; set; }
|
||||
|
||||
[JsonPropertyName("sleeve_id")]
|
||||
[Key("sleeve_id")]
|
||||
public int SleeveId { get; set; } = 3000011;
|
||||
|
||||
[JsonPropertyName("special_sleeve_id")]
|
||||
[Key("special_sleeve_id")]
|
||||
public int SpecialSleeveId { get; set; }
|
||||
|
||||
[JsonPropertyName("commence_date")]
|
||||
[Key("commence_date")]
|
||||
public string CommenceDate { get; set; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("complete_date")]
|
||||
[Key("complete_date")]
|
||||
public string CompleteDate { get; set; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("cardpack_banner_list")]
|
||||
[Key("cardpack_banner_list")]
|
||||
public List<PackBannerDto> CardpackBannerList { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("gacha_detail")]
|
||||
[Key("gacha_detail")]
|
||||
public string GachaDetail { get; set; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("child_gacha_info")]
|
||||
[Key("child_gacha_info")]
|
||||
public List<PackChildGachaDto> ChildGachaInfo { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("open_count")]
|
||||
[Key("open_count")]
|
||||
public int OpenCount { get; set; }
|
||||
|
||||
[JsonPropertyName("open_count_limit")]
|
||||
[Key("open_count_limit")]
|
||||
public int OpenCountLimit { get; set; }
|
||||
|
||||
[JsonPropertyName("is_hide")]
|
||||
[Key("is_hide")]
|
||||
public int IsHide { get; set; }
|
||||
|
||||
[JsonPropertyName("pack_category")]
|
||||
[Key("pack_category")]
|
||||
public int PackCategory { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Null when the pack has no gacha-point participation. The key MUST be present on the wire
|
||||
/// (explicit null) — client at PackInfoTask.cs:126 does <c>if (jsonData2["gacha_point"] != null)</c>,
|
||||
/// a direct LitJson key access that throws KeyNotFoundException when the key is absent
|
||||
/// (only protects against null *value*, not missing *key*). Override the global
|
||||
/// WhenWritingNull per [[project_wire_null_policy]] memory.
|
||||
/// </summary>
|
||||
[JsonPropertyName("gacha_point")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
|
||||
[Key("gacha_point")]
|
||||
public PackGachaPointDto? GachaPoint { get; set; }
|
||||
|
||||
[JsonPropertyName("is_pre_release")]
|
||||
[Key("is_pre_release")]
|
||||
public bool IsPreRelease { get; set; }
|
||||
|
||||
[JsonPropertyName("exists_purchase_reward")]
|
||||
[Key("exists_purchase_reward")]
|
||||
public bool ExistsPurchaseReward { get; set; }
|
||||
|
||||
[JsonPropertyName("is_new")]
|
||||
[Key("is_new")]
|
||||
public bool IsNew { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Prod sends an object <c>{"sales_period_time":"..."}</c> when set and an array <c>[]</c>
|
||||
/// when unset. v1 always emits an empty object when the field is null on the entity —
|
||||
/// matches the active-window case and the client tolerates both shapes via
|
||||
/// <c>ShopExpirtyInfo</c>'s LitJson parser. Revisit if a capture proves otherwise.
|
||||
/// </summary>
|
||||
[JsonPropertyName("sales_period_info")]
|
||||
[Key("sales_period_info")]
|
||||
public Dictionary<string, string?> SalesPeriodInfo { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("poster_type")]
|
||||
[Key("poster_type")]
|
||||
public int PosterType { get; set; }
|
||||
}
|
||||
32
SVSim.EmulatedEntrypoint/Models/Dtos/PackGachaPointDto.cs
Normal file
32
SVSim.EmulatedEntrypoint/Models/Dtos/PackGachaPointDto.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using MessagePack;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace SVSim.EmulatedEntrypoint.Models.Dtos;
|
||||
|
||||
/// <summary>
|
||||
/// gacha_point block inside /pack/info entries. Prod ships strings for pack_id/increase_gacha_point;
|
||||
/// mirror exactly per project_wire_key_serialization.
|
||||
/// </summary>
|
||||
[MessagePackObject]
|
||||
public class PackGachaPointDto
|
||||
{
|
||||
[JsonPropertyName("pack_id")]
|
||||
[Key("pack_id")]
|
||||
public string PackId { get; set; } = "0";
|
||||
|
||||
[JsonPropertyName("gacha_point")]
|
||||
[Key("gacha_point")]
|
||||
public int GachaPoint { get; set; }
|
||||
|
||||
[JsonPropertyName("increase_gacha_point")]
|
||||
[Key("increase_gacha_point")]
|
||||
public string IncreaseGachaPoint { get; set; } = "0";
|
||||
|
||||
[JsonPropertyName("exchangeable_gacha_point")]
|
||||
[Key("exchangeable_gacha_point")]
|
||||
public int ExchangeableGachaPoint { get; set; }
|
||||
|
||||
[JsonPropertyName("is_exchangeable_gacha_point")]
|
||||
[Key("is_exchangeable_gacha_point")]
|
||||
public bool IsExchangeableGachaPoint { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using MessagePack;
|
||||
using SVSim.EmulatedEntrypoint.Models.Dtos.Requests;
|
||||
|
||||
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests.Pack;
|
||||
|
||||
/// <summary>
|
||||
/// Inbound /pack/open body. Accepts ALL three client-side overloads in one DTO — fields
|
||||
/// for Starter (<c>class_id</c>) and Skin (<c>target_card_id</c>) are nullable so we can
|
||||
/// reject those overloads in the controller without a custom binder.
|
||||
/// See <c>Wizard/PackOpenTask.cs</c> for the three SetParameter variants.
|
||||
/// </summary>
|
||||
[MessagePackObject]
|
||||
public class PackOpenRequest : BaseRequest
|
||||
{
|
||||
[JsonPropertyName("parent_gacha_id")]
|
||||
[Key("parent_gacha_id")]
|
||||
public int ParentGachaId { get; set; }
|
||||
|
||||
[JsonPropertyName("gacha_id")]
|
||||
[Key("gacha_id")]
|
||||
public int GachaId { get; set; }
|
||||
|
||||
[JsonPropertyName("gacha_type")]
|
||||
[Key("gacha_type")]
|
||||
public int GachaType { get; set; }
|
||||
|
||||
[JsonPropertyName("pack_number")]
|
||||
[Key("pack_number")]
|
||||
public int PackNumber { get; set; }
|
||||
|
||||
[JsonPropertyName("exclude_card_ids")]
|
||||
[Key("exclude_card_ids")]
|
||||
public long[] ExcludeCardIds { get; set; } = Array.Empty<long>();
|
||||
|
||||
[JsonPropertyName("class_id")]
|
||||
[Key("class_id")]
|
||||
public int? ClassId { get; set; }
|
||||
|
||||
[JsonPropertyName("target_card_id")]
|
||||
[Key("target_card_id")]
|
||||
public long? TargetCardId { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using MessagePack;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Responses.Pack;
|
||||
|
||||
[MessagePackObject]
|
||||
public class PackInfoResponse
|
||||
{
|
||||
[JsonPropertyName("pack_config_list")]
|
||||
[Key("pack_config_list")]
|
||||
public List<PackConfigDto> PackConfigList { get; set; } = new();
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using MessagePack;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Responses.Pack;
|
||||
|
||||
[MessagePackObject]
|
||||
public class PackOpenResponse
|
||||
{
|
||||
[JsonPropertyName("pack_list")]
|
||||
[Key("pack_list")]
|
||||
public List<CardPackEntryDto> PackList { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("reward_list")]
|
||||
[Key("reward_list")]
|
||||
public List<RewardListEntry> RewardList { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("rewards")]
|
||||
[Key("rewards")]
|
||||
public List<object> Rewards { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("is_special_effect")]
|
||||
[Key("is_special_effect")]
|
||||
public bool IsSpecialEffect { get; set; }
|
||||
|
||||
/// <summary>Empty array literal — matches prod when no missions completed.</summary>
|
||||
[JsonPropertyName("mission_result")]
|
||||
[Key("mission_result")]
|
||||
public List<object> MissionResult { get; set; } = new();
|
||||
}
|
||||
|
||||
[MessagePackObject]
|
||||
public class CardPackEntryDto
|
||||
{
|
||||
[JsonPropertyName("card_id")]
|
||||
[Key("card_id")]
|
||||
public long CardId { get; set; }
|
||||
|
||||
[JsonPropertyName("rarity")]
|
||||
[Key("rarity")]
|
||||
public int Rarity { get; set; }
|
||||
|
||||
/// <summary>Always 1 per drawn slot — matches prod sample shape.</summary>
|
||||
[JsonPropertyName("number")]
|
||||
[Key("number")]
|
||||
public int Number { get; set; } = 1;
|
||||
}
|
||||
31
SVSim.EmulatedEntrypoint/Models/Dtos/RewardListEntry.cs
Normal file
31
SVSim.EmulatedEntrypoint/Models/Dtos/RewardListEntry.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using MessagePack;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace SVSim.EmulatedEntrypoint.Models.Dtos;
|
||||
|
||||
/// <summary>
|
||||
/// One entry of <c>reward_list</c> on /pack/open (and other grant-emitting endpoints).
|
||||
/// Client at <c>PlayerStaticData.UpdateHaveUserGoodsNumByJsonData</c> reads these and writes
|
||||
/// <c>UserRupyCount = reward_num</c>, <c>UserCrystalCount = reward_num</c>, etc. —
|
||||
/// <b>reward_num is the NEW POST-STATE TOTAL, not a delta</b>. Without these entries the
|
||||
/// client's cached currency/collection counts stay stale until a full refresh (mypage, restart).
|
||||
///
|
||||
/// reward_type values are <c>Wizard.UserGoods.Type</c>: 1=RedEther, 2=Crystal, 4=Item, 5=Card,
|
||||
/// 6=Sleeve, 7=Emblem, 8=Degree, 9=Rupy, 10=Skin, 11=SpotCard, 12=SpotCardPoint, etc.
|
||||
/// reward_id is 0 for non-instanced goods (Rupy, Crystal, RedEther) and the entity id for cards.
|
||||
/// </summary>
|
||||
[MessagePackObject]
|
||||
public class RewardListEntry
|
||||
{
|
||||
[JsonPropertyName("reward_type")]
|
||||
[Key("reward_type")]
|
||||
public int RewardType { get; set; }
|
||||
|
||||
[JsonPropertyName("reward_id")]
|
||||
[Key("reward_id")]
|
||||
public long RewardId { get; set; }
|
||||
|
||||
[JsonPropertyName("reward_num")]
|
||||
[Key("reward_num")]
|
||||
public int RewardNum { get; set; }
|
||||
}
|
||||
Reference in New Issue
Block a user