diff --git a/src/Client.hh b/src/Client.hh index 993cf8bd..7791f2f1 100644 --- a/src/Client.hh +++ b/src/Client.hh @@ -99,6 +99,8 @@ struct Client : public std::enable_shared_from_this { LOADING_QUEST = 0x00000040, // Client is loading a joinable quest that has already started LOADING_RUNNING_QUEST = 0x00100000, + // Client is waiting for other players to join a tournament game + LOADING_TOURNAMENT = 0x00010000, // Client is in the information menu (login server only) IN_INFORMATION_MENU = 0x00000080, // Client is at the welcome message (login server only) diff --git a/src/ReceiveCommands.cc b/src/ReceiveCommands.cc index 529163c4..ae793a1b 100644 --- a/src/ReceiveCommands.cc +++ b/src/ReceiveCommands.cc @@ -947,6 +947,7 @@ static bool add_next_game_client(shared_ptr l) { // If the game is a tournament match and the client has disconnected before // they could join the match, disband the entire game if (!c && l->tournament_match) { + l->log.info("Client in slot %zu has disconnected before joining the game; disbanding it", target_client_id); send_command(l, 0xED, 0x00); return false; } @@ -978,7 +979,7 @@ static bool add_next_game_client(shared_ptr l) { } s->change_client_lobby(c, l, true, target_client_id); - c->flags |= Client::Flag::LOADING; + c->flags |= (Client::Flag::LOADING | (tourn ? Client::Flag::LOADING_TOURNAMENT : 0)); c->disconnect_hooks.emplace(ADD_NEXT_CLIENT_DISCONNECT_HOOK_NAME, [s, l]() -> void { add_next_game_client(l); }); @@ -1242,17 +1243,10 @@ static void on_DC_Ep3(shared_ptr c, uint16_t, uint32_t flag, const strin } if (flag != 0) { - send_command(c, 0xDC, 0x00); - if (l->tournament_match) { - auto tourn = l->tournament_match->tournament.lock(); - if (tourn) { - send_ep3_set_tournament_player_decks(c); - string data = Episode3::Server::prepare_6xB6x41_map_definition( - tourn->get_map(), l->flags & Lobby::Flag::IS_EP3_TRIAL); - c->channel.send(0x6C, 0x00, data); - } - } + c->flags &= ~(Client::Flag::LOADING_TOURNAMENT); l->flags |= Lobby::Flag::BATTLE_IN_PROGRESS; + send_command(c, 0xDC, 0x00); + send_ep3_start_tournament_deck_select_if_all_clients_ready(l); } else { l->flags &= ~Lobby::Flag::BATTLE_IN_PROGRESS; } diff --git a/src/SendCommands.cc b/src/SendCommands.cc index ef7d62ee..226121d9 100644 --- a/src/SendCommands.cc +++ b/src/SendCommands.cc @@ -2811,6 +2811,42 @@ bool send_quest_barrier_if_all_clients_ready(shared_ptr l) { return true; } +bool send_ep3_start_tournament_deck_select_if_all_clients_ready(shared_ptr l) { + if (!l || !l->is_game() || (l->episode != Episode::EP3) || !l->tournament_match) { + return false; + } + auto tourn = l->tournament_match->tournament.lock(); + if (!tourn) { + return false; + } + + // Check if any client is still loading + size_t x; + for (x = 0; x < l->max_clients; x++) { + if (!l->clients[x]) { + continue; + } + if (l->clients[x]->flags & Client::Flag::LOADING_TOURNAMENT) { + break; + } + } + + // If they're all done, start deck selection + if (x == l->max_clients) { + string data = Episode3::Server::prepare_6xB6x41_map_definition( + tourn->get_map(), l->flags & Lobby::Flag::IS_EP3_TRIAL); + send_command(l, 0x6C, 0x00, data); + for (auto c : l->clients) { + if (c) { + send_ep3_set_tournament_player_decks(c); + } + } + return true; + } else { + return false; + } +} + void send_ep3_card_auction(shared_ptr l) { auto s = l->require_server_state(); if ((s->ep3_card_auction_points == 0) || diff --git a/src/SendCommands.hh b/src/SendCommands.hh index b113648f..89627a23 100644 --- a/src/SendCommands.hh +++ b/src/SendCommands.hh @@ -366,6 +366,7 @@ void send_quest_file_chunk( size_t size, bool is_download_quest); bool send_quest_barrier_if_all_clients_ready(std::shared_ptr l); +bool send_ep3_start_tournament_deck_select_if_all_clients_ready(std::shared_ptr l); void send_server_time(std::shared_ptr c);