From 1ba50e96caed0cfba79023b71c2bd6d72e651e35 Mon Sep 17 00:00:00 2001 From: Martin Michelsen Date: Thu, 28 Dec 2023 10:23:13 -0800 Subject: [PATCH] update lobby datas on team master transfer --- src/ReceiveCommands.cc | 11 +++++++++++ src/SendCommands.cc | 11 +++++++++++ src/SendCommands.hh | 1 + src/ServerState.cc | 4 ++++ 4 files changed, 27 insertions(+) diff --git a/src/ReceiveCommands.cc b/src/ReceiveCommands.cc index ce5b9608..5bbca1f9 100644 --- a/src/ReceiveCommands.cc +++ b/src/ReceiveCommands.cc @@ -4845,6 +4845,7 @@ static void on_EA_BB(shared_ptr c, uint16_t command, uint32_t flag, stri // The client only sends this command with flag = 0x00, 0x30, or 0x40 bool send_updates_for_this_m = false; bool send_updates_for_other_m = false; + bool send_master_transfer_updates = false; switch (flag) { case 0x00: // Demote member if (s->team_index->demote_leader(c->license->serial_number, cmd.guild_card_number)) { @@ -4867,11 +4868,21 @@ static void on_EA_BB(shared_ptr c, uint16_t command, uint32_t flag, stri send_command(c, 0x11EA, 0x00000000); send_updates_for_this_m = true; send_updates_for_other_m = true; + send_master_transfer_updates = true; break; default: throw runtime_error("invalid privilege level"); } + if (send_master_transfer_updates) { + for (const auto& it : team->members) { + try { + auto other_c = s->find_client(nullptr, it.second.serial_number); + send_update_lobby_data_bb(other_c); + } catch (const out_of_range&) { + } + } + } if (send_updates_for_this_m) { send_update_team_metadata_for_client(c); send_team_membership_info(c); diff --git a/src/SendCommands.cc b/src/SendCommands.cc index b761796f..abc19729 100644 --- a/src/SendCommands.cc +++ b/src/SendCommands.cc @@ -2181,6 +2181,17 @@ void send_player_join_notification(shared_ptr c, } } +void send_update_lobby_data_bb(std::shared_ptr c) { + auto l = c->require_lobby(); + for (auto lc : l->clients) { + if (lc) { + PlayerLobbyDataBB cmd; + populate_lobby_data_for_client(cmd, c, lc); + send_command_t(lc, 0x00F0, 0x00000000, cmd); + } + } +} + void send_player_leave_notification(shared_ptr l, uint8_t leaving_client_id) { S_LeaveLobby_66_69_Ep3_E9 cmd = {leaving_client_id, l->leader_id, 1, 0}; uint8_t cmd_num; diff --git a/src/SendCommands.hh b/src/SendCommands.hh index c36e3fe3..a24b00f1 100644 --- a/src/SendCommands.hh +++ b/src/SendCommands.hh @@ -268,6 +268,7 @@ void send_lobby_list(std::shared_ptr c); void send_player_records(std::shared_ptr c, std::shared_ptr l, std::shared_ptr joining_client = nullptr); void send_join_lobby(std::shared_ptr c, std::shared_ptr l); +void send_update_lobby_data_bb(std::shared_ptr c); void send_player_join_notification(std::shared_ptr c, std::shared_ptr l, std::shared_ptr joining_client); void send_player_leave_notification(std::shared_ptr l, uint8_t leaving_client_id); void send_self_leave_notification(std::shared_ptr c); diff --git a/src/ServerState.cc b/src/ServerState.cc index 934621cb..74d5be76 100644 --- a/src/ServerState.cc +++ b/src/ServerState.cc @@ -327,6 +327,10 @@ void ServerState::on_player_left_lobby(shared_ptr l, uint8_t leaving_clie } shared_ptr ServerState::find_client(const string* identifier, uint64_t serial_number, shared_ptr l) { + // WARNING: There are multiple callsites where we assume this function never + // returns a client that isn't in any lobby. If this behavior changes, we will + // need to audit all callsites to ensure correctness. + if ((serial_number == 0) && identifier) { try { serial_number = stoull(*identifier, nullptr, 0);