diff --git a/src/CommandFormats.hh b/src/CommandFormats.hh index 1eb2e1e3..48bad9a7 100644 --- a/src/CommandFormats.hh +++ b/src/CommandFormats.hh @@ -373,7 +373,7 @@ struct C_LegacyLogin_PC_V3_03 { le_uint64_t unused = 0; // Same as unused field in 9D/9E le_uint32_t sub_version = 0; uint8_t is_extended = 0; - uint8_t language = 0; // Same as 9D/9E + uint8_t language = 0; le_uint16_t unknown_a2 = 0; // Note: These are suffixed with 2 since they come from the same source data // as the corresponding fields in 9D/9E. (Even though serial_number and @@ -420,7 +420,7 @@ struct C_LegacyLogin_PC_V3_04 { le_uint64_t unused1 = 0; // Same as unused field in 9D/9E le_uint32_t sub_version = 0; uint8_t is_extended = 0; - uint8_t language = 0; // Same as 9D/9E + uint8_t language = 0; le_uint16_t unknown_a2 = 0; ptext serial_number; ptext access_key; @@ -5784,18 +5784,24 @@ struct G_TournamentMatchResult_GC_Ep3_6xB4x51 { struct G_SetGameMetadata_GC_Ep3_6xB4x52 { G_CardBattleCommandHeader header = {0xB4, sizeof(G_SetGameMetadata_GC_Ep3_6xB4x52) / 4, 0, 0x52, 0, 0, 0}; - le_uint16_t unknown_a1 = 0; // Clamped to [0, 999] by the client - // If num_spectators is nonzero, an icon appears in the middle of the screen - // during battle when the details view is enabled (by pressing Z). However, - // the number of people visible in the icon doesn't match the actual number of - // spectators. Specifically: + // This field appears before the slash in the spectators' HUD. Presumably this + // is used to indecate how many spectators are in the current spectator team. + // In the primary game (watched lobby), this is presumably unused. + le_uint16_t local_spectators = 0; // Clamped to [0, 999] by the client + // This field appears after the slash in the spectators' HUD. This is used to + // indicate how many spectators there are in all spectator teams attached to + // the same battle. + // This field also controls the icon shown in the primary game. If this field + // is nonzero, an icon appears in the middle of the screen during battle when + // the details view is enabled (by pressing Z). However, the number of people + // visible in the icon doesn't match the value in this field. Specifically: // 0 = no icon // 1 = icon with a single spectator (green) // 2-4 = icon with 3 spectators (blue) // 5-10 = icon with 5 spectators (yellow) // 11-29 = icon with 8 spectators (purple) // 30+ = icon with 12 spectators (red) - le_uint16_t num_spectators = 0; // Clamped to [0, 999] by the client + le_uint16_t total_spectators = 0; // Clamped to [0, 999] by the client le_uint16_t unused = 0; le_uint16_t size = 0; // Number of used bytes in unknown_a2 (clamped to 0xFF) parray unknown_a2; diff --git a/src/SendCommands.cc b/src/SendCommands.cc index 1688f64d..d64c3209 100644 --- a/src/SendCommands.cc +++ b/src/SendCommands.cc @@ -2304,15 +2304,34 @@ void send_ep3_update_spectator_count(shared_ptr l) { G_SetGameMetadata_GC_Ep3_6xB4x52 cmd; for (auto watcher_l : l->watcher_lobbies) { for (auto c : watcher_l->clients) { - if (c) { - cmd.num_spectators++; - } + cmd.total_spectators += (c.get() != nullptr); } } + // TODO: Make s available here so we can apply masking if needed (perhaps by // adding a weak_ptr in Lobby... it'd be dumb to require s to be passed in to // this function just to check a behavior flag) - send_command_t(l, 0xC9, 0x00, cmd); + + // Note: We can't use send_command_t(l, ...) here because that would send the + // same command to l and to all wather lobbies. The commands should have + // different values depending on who's in each watcher lobby, so we have to + // manually send to each client here. + for (auto c : l->clients) { + if (c) { + send_command_t(c, 0xC9, 0x00, cmd); + } + } + for (auto watcher_l : l->watcher_lobbies) { + cmd.local_spectators = 0; + for (auto c : watcher_l->clients) { + cmd.local_spectators += (c.get() != nullptr); + } + for (auto c : watcher_l->clients) { + if (c) { + send_command_t(c, 0xC9, 0x00, cmd); + } + } + } } void set_mask_for_ep3_game_command(void* vdata, size_t size, uint8_t mask_key) {