Forgot unversioned xd

This commit is contained in:
gamer147
2026-05-23 14:18:18 -04:00
parent 6b70850b7b
commit bf6ddf5428
46 changed files with 43610 additions and 0 deletions

View File

@@ -0,0 +1,14 @@
using MessagePack;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Common;
/// <summary>
/// Shared empty response. Used for endpoints whose spec mock is `"data": {}`
/// (set_deck_redis, update_order, delete_deck_list, etc.). Includes a sentinel
/// nullable field so MessagePack-CSharp emits a string-keyed empty map cleanly.
/// </summary>
[MessagePackObject]
public class EmptyResponse
{
[Key("_")] public object? Reserved { get; set; }
}

View File

@@ -0,0 +1,15 @@
using MessagePack;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Common;
/// <summary>
/// Stub for the Reward shape (spec: common/types.ts.md#reward). Fleshed out when actual
/// reward-granting flows land. Today's endpoints all emit empty reward_list arrays.
/// </summary>
[MessagePackObject]
public class Reward
{
[Key("type")] public int? Type { get; set; }
[Key("value")] public long? Value { get; set; }
[Key("num")] public int? Num { get; set; }
}

View File

@@ -0,0 +1,43 @@
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests.Admin;
/// <summary>
/// Snake-case JSON. Only used by the import endpoint (plain JSON over HTTP, not the
/// Unity msgpack path) so no MessagePack attributes are needed.
/// </summary>
public class ImportViewerRequest
{
[JsonPropertyName("steam_id")] public ulong SteamId { get; set; }
[JsonPropertyName("display_name")] public string? DisplayName { get; set; }
[JsonPropertyName("country_code")] public string? CountryCode { get; set; }
[JsonPropertyName("tutorial_state")] public int? TutorialState { get; set; }
[JsonPropertyName("selected_emblem_id")] public int? SelectedEmblemId { get; set; }
[JsonPropertyName("selected_degree_id")] public int? SelectedDegreeId { get; set; }
[JsonPropertyName("currency")] public ImportCurrency? Currency { get; set; }
[JsonPropertyName("owned_sleeve_ids")] public List<int>? OwnedSleeveIds { get; set; }
[JsonPropertyName("owned_emblem_ids")] public List<int>? OwnedEmblemIds { get; set; }
[JsonPropertyName("owned_degree_ids")] public List<int>? OwnedDegreeIds { get; set; }
[JsonPropertyName("owned_leader_skin_ids")] public List<int>? OwnedLeaderSkinIds { get; set; }
[JsonPropertyName("owned_mypage_background_ids")] public List<int>? OwnedMyPageBackgroundIds { get; set; }
[JsonPropertyName("classes")] public List<ImportClassData>? Classes { get; set; }
}
public class ImportCurrency
{
[JsonPropertyName("crystals")] public ulong? Crystals { get; set; }
[JsonPropertyName("rupees")] public ulong? Rupees { get; set; }
[JsonPropertyName("red_ether")] public ulong? RedEther { get; set; }
}
public class ImportClassData
{
[JsonPropertyName("class_id")] public int ClassId { get; set; }
[JsonPropertyName("level")] public int Level { get; set; }
[JsonPropertyName("exp")] public int Exp { get; set; }
}

View File

@@ -0,0 +1,13 @@
using MessagePack;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests.Common;
/// <summary>
/// Common request shape for endpoints scoped by deck format (`/deck/info`,
/// `/practice/deck_list`, etc.). Spec: common/types.ts.md#deck-format-scoped-requests.
/// </summary>
[MessagePackObject]
public class DeckFormatRequest : BaseRequest
{
[Key("deck_format")] public int DeckFormat { get; set; }
}

View File

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

View File

@@ -0,0 +1,16 @@
using MessagePack;
using SVSim.EmulatedEntrypoint.Models.Dtos.Requests.Common;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests.Deck;
/// <summary>
/// /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
/// ignore create_deck_format and return the standard shape; only matters for the
/// cross-format deck-copy UI flow.
/// </summary>
[MessagePackObject]
public class DeckInfoRequest : DeckFormatRequest
{
[Key("create_deck_format")] public int? CreateDeckFormat { get; set; }
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,10 @@
using System.Text.Json.Serialization;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Responses.Admin;
public class ImportViewerResponse
{
[JsonPropertyName("viewer_id")] public long ViewerId { get; set; }
[JsonPropertyName("short_udid")] public long ShortUdid { get; set; }
[JsonPropertyName("was_created")] public bool WasCreated { get; set; }
}

View File

@@ -0,0 +1,15 @@
using MessagePack;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Responses.Deck;
/// <summary>
/// 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
/// by /practice/deck_list with Format.All).
/// </summary>
[MessagePackObject]
public class DeckListResponse
{
[Key("maintenance_card_list")] public List<long> MaintenanceCardList { get; set; } = new();
[Key("user_deck_list")] public List<UserDeck>? UserDeckList { get; set; }
}

View File

@@ -0,0 +1,17 @@
using MessagePack;
using SVSim.EmulatedEntrypoint.Models.Dtos.Common;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Responses.Deck;
/// <summary>
/// /deck/update response. Minimum-viable per spec is just {achieved_info, reward_list};
/// the full shape also includes the refreshed deck list. We include user_deck_list to
/// save the client a follow-up /deck/info round-trip.
/// </summary>
[MessagePackObject]
public class DeckUpdateResponse
{
[Key("user_deck_list")] public List<UserDeck>? UserDeckList { get; set; }
[Key("achieved_info")] public Dictionary<string, object> AchievedInfo { get; set; } = new();
[Key("reward_list")] public List<Reward> RewardList { get; set; } = new();
}

View File

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

View File

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

View File

@@ -0,0 +1,21 @@
using MessagePack;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Responses.Practice;
/// <summary>
/// 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.
/// </summary>
[MessagePackObject]
public class PracticeDeckListResponse
{
/// <summary>Card ids currently disabled for maintenance (client unions with global list).</summary>
[Key("maintenance_card_list")] public List<long> MaintenanceCardList { get; set; } = new();
[Key("user_deck_rotation")] public List<UserDeck>? UserDeckRotation { 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,
// trial_deck_list, crossover_trial_deck_list, build_deck_list, user_leader_skin_setting_list)
// are all conditional — added when those formats are enabled.
}

View File

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

View File

@@ -0,0 +1,43 @@
using MessagePack;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Responses.Practice;
[MessagePackObject]
public class PracticeOpponent
{
/// <summary>Practice slot id (unique per entry; AI opponent identifier).</summary>
[Key("practice_id")] public int PracticeId { get; set; }
/// <summary>
/// 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.
/// </summary>
[Key("text_id")] public string TextId { get; set; } = string.Empty;
/// <summary>Class (leader) id the AI plays.</summary>
[Key("class_id")] public int ClassId { get; set; }
/// <summary>Portrait / character id (which leader art the AI uses).</summary>
[Key("chara_id")] public int CharaId { get; set; }
/// <summary>Title-degree id shown next to the AI's name.</summary>
[Key("degree_id")] public int DegreeId { get; set; }
/// <summary>AI deck-strength tier (drives which preset deck the AI uses).</summary>
[Key("ai_deck_level")] public int AiDeckLevel { get; set; }
/// <summary>AI decision-making tier.</summary>
[Key("ai_logic_level")] public int AiLogicLevel { get; set; }
/// <summary>Starting HP for the AI side (often 20).</summary>
[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>
[Key("battle3dfield_id")] public string Battle3dFieldId { get; set; } = "1";
/// <summary>Optional. true => entry disabled, client prepends maintenance suffix.</summary>
[Key("is_maintenance")] public bool? IsMaintenance { get; set; }
/// <summary>true => entry is a special "campaign" practice (event-tied).</summary>
[Key("is_campaign_practice")] public bool IsCampaignPractice { get; set; }
}

View File

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