From c4026cd1ec85bdbf119413a2f9f143aa8a45ce99 Mon Sep 17 00:00:00 2001 From: ebbit1q Date: Tue, 2 Sep 2025 13:52:30 +0200 Subject: [PATCH] protocol changes for drafting --- common/pb/CMakeLists.txt | 7 ++ common/pb/command_draft_options_select.proto | 11 ++++ common/pb/command_draft_pick_select.proto | 19 ++++++ common/pb/command_move_card.proto | 3 + common/pb/draft_options.proto | 66 +++++++++++++++++++ common/pb/event_draft_pack.proto | 16 +++++ common/pb/event_draft_pick_select.proto | 27 ++++++++ common/pb/event_game_state_changed.proto | 6 +- common/pb/event_move_card.proto | 3 + common/pb/game_commands.proto | 2 + common/pb/game_event.proto | 2 + common/pb/response.proto | 2 + common/pb/response_draft_deck_invalid.proto | 16 +++++ ...esponse_draft_pick_selection_invalid.proto | 20 ++++++ common/pb/room_commands.proto | 3 + common/pb/serverinfo_card.proto | 6 ++ common/pb/serverinfo_game.proto | 5 +- 17 files changed, 212 insertions(+), 2 deletions(-) create mode 100644 common/pb/command_draft_options_select.proto create mode 100644 common/pb/command_draft_pick_select.proto create mode 100644 common/pb/draft_options.proto create mode 100644 common/pb/event_draft_pack.proto create mode 100644 common/pb/event_draft_pick_select.proto create mode 100644 common/pb/response_draft_deck_invalid.proto create mode 100644 common/pb/response_draft_pick_selection_invalid.proto diff --git a/common/pb/CMakeLists.txt b/common/pb/CMakeLists.txt index dc48823fd..39ffc4f09 100644 --- a/common/pb/CMakeLists.txt +++ b/common/pb/CMakeLists.txt @@ -21,6 +21,8 @@ set(PROTO_FILES command_deck_upload.proto command_del_counter.proto command_delete_arrow.proto + command_draft_options_select.proto + command_draft_pick_select.proto command_draw_cards.proto command_dump_zone.proto command_flip_card.proto @@ -60,6 +62,7 @@ set(PROTO_FILES context_ready_start.proto context_set_sideboard_lock.proto context_undo_draw.proto + draft_options.proto event_add_to_list.proto event_attach_card.proto event_change_zone_properties.proto @@ -70,6 +73,8 @@ set(PROTO_FILES event_del_counter.proto event_delete_arrow.proto event_destroy_card.proto + event_draft_pack.proto + event_draft_pick_select.proto event_draw_cards.proto event_dump_zone.proto event_flip_card.proto @@ -124,6 +129,8 @@ set(PROTO_FILES response_deck_download.proto response_deck_list.proto response_deck_upload.proto + response_draft_deck_invalid.proto + response_draft_pick_selection_invalid.proto response_dump_zone.proto response_forgotpasswordrequest.proto response_get_admin_notes.proto diff --git a/common/pb/command_draft_options_select.proto b/common/pb/command_draft_options_select.proto new file mode 100644 index 000000000..2bab28620 --- /dev/null +++ b/common/pb/command_draft_options_select.proto @@ -0,0 +1,11 @@ +syntax = "proto2"; +import "game_commands.proto"; +import "draft_options.proto"; + +// Sends the options to use to draft before the draft starts. +message Command_DraftOptionsSelect { + extend GameCommand { + optional Command_DraftOptionsSelect ext = 1035; + } + optional Draft_Options options = 1; +} diff --git a/common/pb/command_draft_pick_select.proto b/common/pb/command_draft_pick_select.proto new file mode 100644 index 000000000..f8ba331a7 --- /dev/null +++ b/common/pb/command_draft_pick_select.proto @@ -0,0 +1,19 @@ +syntax = "proto2"; +import "game_commands.proto"; + +// Confirms the previously sent actions to the server and signals the next pack. +message Command_DraftPickSelect { + extend GameCommand { + optional Command_DraftPickSelect ext = 1036; + } + + // Index in the sequence of pick selections made, important to keep track of in case the pack is invalidated with a + // new one by the server during transit. + optional sint32 selection_index = 1 [default = -1]; + + // Confirms that the player desires to leave an unexpected amount of cards in the pack + optional bool is_overpicking = 2; + + // Confirms that the player desires to place cards into the pack + optional bool is_returning = 3; +} diff --git a/common/pb/command_move_card.proto b/common/pb/command_move_card.proto index 6e9301d27..8eda23e83 100644 --- a/common/pb/command_move_card.proto +++ b/common/pb/command_move_card.proto @@ -50,4 +50,7 @@ message Command_MoveCard { // Inverts the x coordinate to apply from the end of the target zone instead of the start optional bool is_reversed = 8 [default = false]; + + // During a draft this is the index of the pick selection + optional sint32 draft_selection_index = 9 [default = -1]; } diff --git a/common/pb/draft_options.proto b/common/pb/draft_options.proto new file mode 100644 index 000000000..dda2e01da --- /dev/null +++ b/common/pb/draft_options.proto @@ -0,0 +1,66 @@ +syntax = "proto2"; +import "command_deck_select.proto"; + +// Types of draft gamemodes available +enum Draft_Type { + Booster_Draft = 1; + Sealed = 2; +} + +// Container for options related to drafting shared in the game state +message Draft_Options { + // The draft gamemode + optional Draft_Type type = 1; + + // The cards to draft from as cockatrice decklist + optional string draft_list = 2; + + // The cards to draft from as a decklist stored on the server + optional sint32 draft_list_id = 3 [default = -1]; + + // The cards that can be freely added to the deck before deck submission as cockatrice decklist + optional string addable_card_list = 4; + + // The cards that can be freely added to the deck before deck submission as a decklist stored on the server + optional sint32 addable_card_list_id = 5 [default = -1]; + + // The amount of cards in each pack when using a cube, for example this is commonly 15 in boosterdrafts + optional uint32 cards_per_pack = 6; + + // The amount of packs that will be drafted by each player when using a cube, for example this is commonly 3 in + // boosterdrafts + optional uint32 packs_per_player = 7; + + // The minimum amount of cards in the mainboard of submitted decklists, often 40, -1 means any size + optional sint32 minimum_deck_size = 8 [default = -1]; + + // The amount of cards to pick every time a pack is passed, usually 1 + optional uint32 picks_per_selection = 9 [default = 1]; + + // The amount of cards picked for removal every time a pack is passed, usually 0 + optional uint32 burns_per_selection = 10; + + // Amount of seconds before the server will decide picks automatically, -1 means no limit + optional sint32 selection_timer = 11 [default = -1]; + + // Amount of pick selections that can be made without having to wait on other players, this means that the slowest + // player can never have more than this amount of packs waiting for them and the fastest player can never be more + // than this amount of pick selections ahead of the slowest player, -1 means to never wait, 0 means to wait for all + // players to confirm their picks before showing the next pack + optional sint32 max_selections_ahead = 12 [default = -1]; + + // Amount of new packs that can be opened without having to wait on other players, only after all that player's pick + // selections in the current round of opened packs are finished can a new pack be opened, -1 means to never wait, 0 + // means to wait for all players to finish their packs before showing the next pack when the player finished all + // picks + optional sint32 max_new_packs_ahead = 13 [default = -1]; + + // Allow players to interact using normal card actions on a table zone + optional bool enable_table = 32; + + // Allow players to take more or less cards from packs with confirmation + optional bool enable_overpicking = 33; + + // Allow players to return cards back into a pack with confirmation + optional bool enable_returning = 34; +} diff --git a/common/pb/event_draft_pack.proto b/common/pb/event_draft_pack.proto new file mode 100644 index 000000000..4598bb7e9 --- /dev/null +++ b/common/pb/event_draft_pack.proto @@ -0,0 +1,16 @@ +syntax = "proto2"; +import "game_event.proto"; +import "serverinfo_card.proto"; + +// Sent out by the server when a new pack is available, implicitly signals the start of the round timer +message Event_DraftPack { + extend GameEvent { + optional Event_DraftPack ext = 2022; + } + + // Index in the sequence of pick selections made + optional sint32 selection_index = 1 [default = -1]; + + // sequence of cards in the pack by index + repeated ServerInfo_Card cards = 2; +} diff --git a/common/pb/event_draft_pick_select.proto b/common/pb/event_draft_pick_select.proto new file mode 100644 index 000000000..c8206203f --- /dev/null +++ b/common/pb/event_draft_pick_select.proto @@ -0,0 +1,27 @@ +syntax = "proto2"; +import "game_event.proto"; + +// Sent by the server to confirm a player's picks that round +message Event_DraftPickSelect { + extend GameEvent { + optional Event_DraftPickSelect ext = 2023; + } + + // Index in the sequence of pick selections made + optional sint32 selection_index = 1 [default = -1]; + + // Amount of cards picked + optional sint32 picked_cards = 2 [default = -1]; + + // Amount of cards picked to destroy + optional sint32 burned_cards = 3 [default = -1]; + + // Amount of cards placed into the pack + optional sint32 returned_cards = 4 [default = -1]; + + // Amount of cards in the pack after picks + optional sint32 remaining_cards = 5 [default = -1]; + + // Next player receiving the pack + optional sint32 passed_to_user_id = 6 [default = -1]; +} diff --git a/common/pb/event_game_state_changed.proto b/common/pb/event_game_state_changed.proto index 5c8aee3fe..f7452d1ec 100644 --- a/common/pb/event_game_state_changed.proto +++ b/common/pb/event_game_state_changed.proto @@ -1,6 +1,7 @@ syntax = "proto2"; import "game_event.proto"; import "serverinfo_player.proto"; +import "draft_options.proto"; // Signals that the game state has changed. // If a field is present in this message, it will overwrite the client's game state. @@ -10,7 +11,7 @@ message Event_GameStateChanged { optional Event_GameStateChanged ext = 1005; } - // the list of players. Players contain their zones which contain all cards in the game + // The list of players. Players contain their zones which contain all cards in the game repeated ServerInfo_Player player_list = 1; // if the game has started @@ -24,4 +25,7 @@ message Event_GameStateChanged { // the amount of seconds since the game started optional uint32 seconds_elapsed = 5; + + // the options for the draft if this is a draft game + optional Draft_Options options = 6; } diff --git a/common/pb/event_move_card.proto b/common/pb/event_move_card.proto index e8e60066a..967debf58 100644 --- a/common/pb/event_move_card.proto +++ b/common/pb/event_move_card.proto @@ -45,4 +45,7 @@ message Event_MoveCard { // The provider id of the card in case it was not known yet. // Extends the name to supply a specific printing of that type of card. optional string new_card_provider_id = 12; + + // During a draft this is the index of the pick selection + optional sint32 draft_selection_index = 13 [default = -1]; } diff --git a/common/pb/game_commands.proto b/common/pb/game_commands.proto index 796f4fc68..a732997c2 100644 --- a/common/pb/game_commands.proto +++ b/common/pb/game_commands.proto @@ -38,6 +38,8 @@ message GameCommand { UNCONCEDE = 1032; JUDGE = 1033; REVERSE_TURN = 1034; + DRAFT_OPTIONS_SELECT = 1035; + DRAFT_PICK_SELECT = 1036; } extensions 100 to max; } diff --git a/common/pb/game_event.proto b/common/pb/game_event.proto index 8682128af..1f9d15e71 100644 --- a/common/pb/game_event.proto +++ b/common/pb/game_event.proto @@ -33,6 +33,8 @@ message GameEvent { // STOP_DUMP_ZONE = 2019; // obsolete CHANGE_ZONE_PROPERTIES = 2020; REVERSE_TURN = 2021; + DRAFT_PACK = 2022; + DRAFT_PICK_SELECT = 2023; } optional sint32 player_id = 1 [default = -1]; extensions 100 to max; diff --git a/common/pb/response.proto b/common/pb/response.proto index dece8ae17..76929196f 100644 --- a/common/pb/response.proto +++ b/common/pb/response.proto @@ -68,6 +68,8 @@ message Response { REPLAY_LIST = 1100; REPLAY_DOWNLOAD = 1101; REPLAY_GET_CODE = 1102; + DRAFT_PICK_SELECTION_INVALID = 1200; + DRAFT_DECK_INVALID = 1201; } required uint64 cmd_id = 1; optional ResponseCode response_code = 2; diff --git a/common/pb/response_draft_deck_invalid.proto b/common/pb/response_draft_deck_invalid.proto new file mode 100644 index 000000000..db25ab468 --- /dev/null +++ b/common/pb/response_draft_deck_invalid.proto @@ -0,0 +1,16 @@ +syntax = "proto2"; +import "response.proto"; + +// Sent in response to selecting a deck during a draft that does not meet the requirements. Clients are already aware of +// what the requirements are but the fields in this serve as an extra validation. +message Response_DraftDeckInvalid { + extend Response { + optional Response_DraftDeckInvalid ext = 1201; + } + + // amount of cards that should be in the deck but aren't + optional uint32 missing_cards = 1; + + // amount of cards that are in the deck but shouldn't + optional uint32 additional_cards = 2; +} diff --git a/common/pb/response_draft_pick_selection_invalid.proto b/common/pb/response_draft_pick_selection_invalid.proto new file mode 100644 index 000000000..6ce046167 --- /dev/null +++ b/common/pb/response_draft_pick_selection_invalid.proto @@ -0,0 +1,20 @@ +syntax = "proto2"; +import "response.proto"; + +// Response sent to a draft pick selection command when it isn't following the draft options or didn't confirm it's +// actions. Clients are already aware of the options so the fields in this message just serve as an additional +// validation. +message Response_DraftPickSelectionInvalid { + extend Response { + optional Response_DraftPickSelectionInvalid ext = 1200; + } + + // amount of picks performed that exceed the picks per selection, negative means too few picks were performed + optional sint32 too_many_picks = 1; + + // amount of burns performed that exceed the burns per selection, negative means too few burns were performed + optional sint32 too_many_burns = 2; + + // amount of cards that were returned to the pack + optional sint32 cards_returned_to_pack = 3; +} diff --git a/common/pb/room_commands.proto b/common/pb/room_commands.proto index a8c90ec6c..40bbcbf85 100644 --- a/common/pb/room_commands.proto +++ b/common/pb/room_commands.proto @@ -69,6 +69,9 @@ message Command_CreateGame { // share decklists with all players when selected optional bool share_decklists_on_load = 14; + + // if the game is a draft game + optional bool is_draft = 15; } message Command_JoinGame { diff --git a/common/pb/serverinfo_card.proto b/common/pb/serverinfo_card.proto index a9a8b5c9d..0164f4178 100644 --- a/common/pb/serverinfo_card.proto +++ b/common/pb/serverinfo_card.proto @@ -53,4 +53,10 @@ message ServerInfo_Card { // unique id of this kind of card, extends the name to specify a specific printing of a card optional string provider_id = 17; + + // index of the selection this card was picked in + optional sint32 draft_pick_selection_index = 64 [default = -1]; + + // user that picked this card + optional sint32 draft_pick_by_user_id = 65 [default = -1]; } diff --git a/common/pb/serverinfo_game.proto b/common/pb/serverinfo_game.proto index 9a56e034c..35b814eb9 100644 --- a/common/pb/serverinfo_game.proto +++ b/common/pb/serverinfo_game.proto @@ -48,6 +48,9 @@ message ServerInfo_Game { // decklists are sent to all players when loaded optional bool share_decklists_on_load = 15; + // the game is a draft game + optional bool is_draft = 16; + // the current player count optional uint32 player_count = 30; @@ -60,6 +63,6 @@ message ServerInfo_Game { // time that the game started at optional uint32 start_time = 51; - // whether the game is closed. Closed games are finished and can't be interacted with + // Whether the game is closed. Closed games are finished and can't be interacted with optional bool closed = 52; }