From 45ea21860ddd4c8adafe8d1c31c01c334334f8a2 Mon Sep 17 00:00:00 2001 From: Martin Michelsen Date: Thu, 28 Sep 2023 23:16:16 -0700 Subject: [PATCH] fix spectator list in game details display --- TODO.md | 4 +--- src/CommandFormats.hh | 24 +++++++++++++----------- src/SendCommands.cc | 13 ++++++++++--- 3 files changed, 24 insertions(+), 17 deletions(-) diff --git a/TODO.md b/TODO.md index 07cccbc4..15327a83 100644 --- a/TODO.md +++ b/TODO.md @@ -23,9 +23,7 @@ - Make disconnecting during a tournament match cause you to forfeit the match - Enforce tournament deck restrictions (e.g. rank checks, No Assist option) when populating COMs at tournament start time -- Spectator teams - - Spectator teams sometimes stop receiving commands during live battles? - - It may be possible to send spectators back to the waiting room after a non-tournament battle by sending 6xB4x05 with environment 0x19, then 6xB4x3B again; try this +- It may be possible to send spectators back to the waiting room after a non-tournament battle by sending 6xB4x05 with environment 0x19, then 6xB4x3B again; try this - Add support for recording battles on the proxy server (both in primary and spectator teams) ## PSOBB diff --git a/src/CommandFormats.hh b/src/CommandFormats.hh index ad7ab447..d9fceb3a 100644 --- a/src/CommandFormats.hh +++ b/src/CommandFormats.hh @@ -2829,9 +2829,10 @@ struct S_GameInformation_GC_Ep3_E1 { ptext description; // Usually something like "FOmarl CLv30 J" } __packed__; /* 0024 */ parray player_entries; - /* 00E4 */ parray unknown_a3; + /* 00E4 */ ptext map_name; /* 0104 */ Episode3::Rules rules; /* 0118 */ parray spectator_entries; + /* 0298 */ } __packed__; // E1 (S->C): Team and key config missing? (BB) @@ -2922,9 +2923,9 @@ struct S_TournamentEntryList_GC_Ep3_E2 { struct S_TournamentGameDetails_GC_Ep3_E3 { // These fields are used only if the Rules pane is shown - /* 0004/032C */ ptext name; - /* 0024/034C */ ptext map_name; - /* 0044/036C */ Episode3::Rules rules; + /* 0004 */ ptext name; + /* 0024 */ ptext map_name; + /* 0044 */ Episode3::Rules rules; // This field is used only if the bracket pane is shown struct BracketEntry { @@ -2933,7 +2934,7 @@ struct S_TournamentGameDetails_GC_Ep3_E3 { ptext team_name; parray unused; } __packed__; - /* 0058/0380 */ parray bracket_entries; + /* 0058 */ parray bracket_entries; // This field is used only if the Opponents pane is shown. If players_per_team // is 2, all fields are shown; if player_per_team is 1, team_name and @@ -2946,13 +2947,14 @@ struct S_TournamentGameDetails_GC_Ep3_E3 { ptext team_name; parray players; } __packed__; - /* 04D8/0800 */ parray team_entries; + /* 04D8 */ parray team_entries; - /* 05B8/08E0 */ le_uint16_t num_bracket_entries = 0; - /* 05BA/08E2 */ le_uint16_t players_per_team = 0; - /* 05BC/08E4 */ le_uint16_t unknown_a4 = 0; - /* 05BE/08E6 */ le_uint16_t num_spectators = 0; - /* 05C0/08E8 */ parray spectator_entries; + /* 05B8 */ le_uint16_t num_bracket_entries = 0; + /* 05BA */ le_uint16_t players_per_team = 0; + /* 05BC */ le_uint16_t unknown_a4 = 0; + /* 05BE */ le_uint16_t num_spectators = 0; + /* 05C0 */ parray spectator_entries; + /* 0740 */ } __packed__; // E3 (C->S): Player preview request (BB) diff --git a/src/SendCommands.cc b/src/SendCommands.cc index cf1d9f7a..3992d604 100644 --- a/src/SendCommands.cc +++ b/src/SendCommands.cc @@ -2486,9 +2486,6 @@ void send_ep3_game_details(shared_ptr c, shared_ptr l) { uint8_t flag; if (l != primary_lobby) { - // TODO: This doesn't work (nothing shows up), but it appears to be a - // client bug? There doesn't appear to be a count field in the command - // anywhere...? size_t num_spectators = 0; for (auto spec_c : l->clients) { if (spec_c) { @@ -2497,6 +2494,16 @@ void send_ep3_game_details(shared_ptr c, shared_ptr l) { entry.description = ep3_description_for_client(spec_c); } } + + // There is a client bug that causes the spectators list to always be + // empty when sent with E1, because there's no way for E1 to set the + // spectator count in the info window object. To account for this, we send + // a mostly-blank E3 to set the spectator count, followed by an E1 with + // the correct data. + S_TournamentGameDetails_GC_Ep3_E3 cmd_E3; + cmd_E3.num_spectators = num_spectators; + send_command_t(c, 0xE3, 0x04, cmd_E3); + flag = 0x04; } else if (primary_lobby &&