Files
FractumSeraphandClaude Opus 5.5 62379e5614 A client is not started before the map it downloads is there
A client that joins a lobby on a Custom Edition map it does not have
downloads it by map sharing. When the host started the game meanwhile, the
host held the client's players out, as it should, but the client, whose
download began in the lobby, did not know the game had started and asked
for its player again; the host took the request as a late joiner's and
started it at once. The client then loaded a map it did not have yet:
cache_files_precache_map_begin's damaged disc error, which stops the game
for good. Stock build-201 does the same with its own host.

- The host (network_server_manager.c): a player asked for by a machine
  still downloading the map waits with those held at the start
  (network_game_server_hold_requested_player), and joins with them, the
  machine started as a late joiner, once its download is done
  (network_game_server_release_map_fetchers).
- The client (network_client_manager.c): a start that comes while the
  map is still being downloaded, from a host of an earlier build, is put
  off until the map is there (network_game_client_begin_game,
  network_game_client_idle_pregame), and dropped if the game it was for is
  over by then (another map, or another game).
- NETCODE.md's "Map sharing" says what happens when a host starts during a
  download (it said the host waited, which it has not since version 28).

Nothing sent changes: no network version.

Checked: the Linux CI steps, the web build and its tests, and the Windows
release build. End to end on Linux in Docker, the host starting the lobby
game at once while the client downloads (the case that stopped the game):
this build both ends (the host held the player and started it at game tick
296 once the map was there); build-201 hosting this build's client (the
start put off until the map was there); this build hosting build-201's
client (held, then played). Each client played the game.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 08:41:59 -05:00

169 lines
5.9 KiB
C

/*
NETWORK_CLIENT_MANAGER.H
header included in hcex build.
*/
#ifndef __NETWORK_CLIENT_MANAGER_H
#define __NETWORK_CLIENT_MANAGER_H
#pragma once
/* ---------- constants */
/* ---------- macros */
/* ---------- structures */
struct network_advertised_game;
struct network_connection;
struct network_game;
struct network_game_client;
struct network_join_parameters;
struct network_machine;
struct network_player;
struct transport_address;
struct message_server_game_advertise;
struct message_server_machine_accepted;
struct message_server_game_update;
/* ---------- prototypes/NETWORK_CLIENT_MANAGER.C */
void network_game_client_dispose(
struct network_game_client *client);
void network_game_client_keep_alive(
struct network_game_client *client);
short network_game_client_get_state(
struct network_game_client *client,
short *state_data);
boolean network_game_client_join_first_available_game(
void);
boolean network_game_client_set_team(
char team_index);
/* whether the advertised game's host has this machine's network version
(else the player is told, and it is not to be joined) */
/* port: whether the advertised game is under way, not in its lobby */
boolean network_game_client_advertised_game_in_progress(
struct network_game_client *client,
struct network_advertised_game const *game);
boolean network_game_client_advertised_game_compatible(
struct network_game_client *client,
struct network_advertised_game const *game,
boolean tell);
boolean network_game_client_initiate_join_game(
struct network_game_client *client,
struct network_advertised_game *game,
struct network_join_parameters *join_parameters,
struct transport_address *address);
boolean network_game_client_set_machine(
struct network_game_client *client,
struct network_machine *machine);
struct network_machine *network_game_client_get_machine(
struct network_game_client *client);
short network_game_client_get_machine_index(
struct network_game_client *client);
boolean network_game_client_advertised_game_is_valid(
struct network_advertised_game *advertised_game);
struct network_advertised_game *network_game_client_get_available_games(
struct network_game_client *client);
short network_game_client_get_error(
struct network_game_client *client);
short network_game_client_get_seconds_to_game_start(
struct network_game_client *client);
boolean network_game_client_write(
struct network_connection *connection,
word *message,
word message_size,
struct transport_address *address,
boolean reliable);
boolean network_game_client_idle(
struct network_game_client *client);
boolean network_game_client_add_player(
struct network_game_client *client,
short local_player_index);
boolean network_game_client_address_matches_server(
struct network_game_client *client,
struct transport_address *address);
void network_game_client_new_advertised_game(
struct network_game_client *client,
struct message_server_game_advertise *message_packet);
void network_game_client_ponged(
struct network_game_client *client,
struct transport_address *source_address,
long timestamp);
void network_game_client_accepted_into_game(
struct network_game_client *client,
struct transport_address *source_address,
struct message_server_machine_accepted *message_packet);
void network_game_client_rejected_by_game(
struct network_game_client *client,
struct transport_address *source_address,
word rejection_code);
boolean network_game_client_game_settings_updated(
struct network_game_client *client,
struct network_game *message_packet);
void network_game_client_countdown_timer_update(
struct network_game_client *client,
short seconds_to_game_start);
boolean network_game_client_game_has_started(
struct network_game_client *client);
void network_game_client_game_shutdown(
struct network_game_client *client);
boolean network_game_client_handle_game_update(
struct network_game_client *client,
struct message_server_game_update *game_update);
boolean network_game_client_add_player_to_game(
struct network_game_client *client,
struct network_player *player);
boolean network_game_client_remove_player(
struct network_game_client *client,
struct network_player *player,
long reason);
boolean network_game_client_update_local_player_data(
struct network_game_client *client,
struct network_player *player);
boolean network_game_client_request_remove_player(
struct network_game_client *client,
struct network_player *player);
boolean network_game_client_request_start_time_change(
struct network_game_client *client,
short request_type);
void network_game_client_switch_to_postgame(
struct network_game_client *client);
boolean network_game_client_switch_to_pregame(
struct network_game_client *client);
void network_game_client_reset(
struct network_game_client *client,
boolean teardown_connection);
struct network_game_client *network_game_client_create(
void);
struct network_connection *network_game_client_get_connection(
struct network_game_client *client);
void network_game_client_get_remote_server_address(
struct network_game_client *client,
struct transport_address *address);
struct network_game *network_game_client_get_game(
struct network_game_client *client);
boolean network_game_client_server_has_started_game(
struct network_game_client *client);
long network_game_client_get_next_update_number(
struct network_game_client *client);
long unstrip_player_index(
long player_index);
/* ---------- globals */
extern boolean allow_out_of_sync;
/* the host's game time when it told this client to start a game in progress,
16 bits of it (network_client_message_handler.c sets it) */
extern long network_game_client_late_join_time;
/* port: the host's start: the game loaded now, or once the map is there if it
is being downloaded (map sharing) */
boolean network_game_client_begin_game(
struct network_game_client *client);
extern boolean network_game_client_dont_use_directly_in_use;
extern struct network_game_client network_game_client_dont_use_directly;
/* ---------- public code */
#endif // __NETWORK_CLIENT_MANAGER_H