From a076c350647fa62aa381dfa7a05033dd10230b7a Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Wed, 24 Mar 2021 23:29:56 +0200 Subject: [PATCH 22/23] Wait until city is in sane state before sending info packets Don't send city info packets to client in the middle of the city processing when city might be in inconsistent state. See osdn #41851 Signed-off-by: Marko Lindqvist --- server/citytools.c | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/server/citytools.c b/server/citytools.c index 0d9ed2f51f..eb666a7bfd 100644 --- a/server/citytools.c +++ b/server/citytools.c @@ -2108,10 +2108,16 @@ static void broadcast_city_info(struct city *pcity) struct traderoute_packet_list *routes = traderoute_packet_list_new(); /* Send to everyone who can see the city. */ - package_city(pcity, &packet, &web_packet, routes, FALSE); + if (!pcity->server.needs_arrange) { + /* Send city only when it's in sane state. + * If it's not, it will be sent to everyone once + * rearrangement has been finished. */ + package_city(pcity, &packet, &web_packet, routes, FALSE); + } players_iterate(pplayer) { if (can_player_see_city_internals(pplayer, pcity)) { - if (!send_city_suppressed || pplayer != powner) { + if ((!send_city_suppressed || pplayer != powner) + && !pcity->server.needs_arrange) { update_dumb_city(powner, pcity); lsend_packet_city_info(powner->connections, &packet, FALSE); web_lsend_packet(city_info_addition, powner->connections, &web_packet, FALSE); @@ -2130,12 +2136,14 @@ static void broadcast_city_info(struct city *pcity) } players_iterate_end; /* Send to global observers. */ - conn_list_iterate(game.est_connections, pconn) { - if (conn_is_global_observer(pconn)) { - send_packet_city_info(pconn, &packet, FALSE); - web_send_packet(city_info_addition, pconn, &web_packet, FALSE); - } - } conn_list_iterate_end; + if (!pcity->server.needs_arrange) { + conn_list_iterate(game.est_connections, pconn) { + if (conn_is_global_observer(pconn)) { + send_packet_city_info(pconn, &packet, FALSE); + web_send_packet(city_info_addition, pconn, &web_packet, FALSE); + } + } conn_list_iterate_end; + } traderoute_packet_list_iterate(routes, route_packet) { FC_FREE(route_packet); @@ -2257,10 +2265,13 @@ void send_city_info_at_tile(struct player *pviewer, struct conn_list *dest, if (powner && powner == pviewer) { /* send info to owner */ /* This case implies powner non-NULL which means pcity non-NULL */ - if (!send_city_suppressed) { + if (!send_city_suppressed && !pcity->server.needs_arrange) { + /* Wait that city has been rearranged, if it's currently + * not in sane state. */ + routes = traderoute_packet_list_new(); - /* send all info to the owner */ + /* Send all info to the owner */ update_dumb_city(powner, pcity); package_city(pcity, &packet, &web_packet, routes, FALSE); lsend_packet_city_info(dest, &packet, FALSE); @@ -2283,10 +2294,10 @@ void send_city_info_at_tile(struct player *pviewer, struct conn_list *dest, } else { /* send info to non-owner */ if (!pviewer) { /* observer */ - if (pcity) { + if (pcity && !pcity->server.needs_arrange) { routes = traderoute_packet_list_new(); - package_city(pcity, &packet, &web_packet, routes, FALSE); /* should be dumb_city info? */ + package_city(pcity, &packet, &web_packet, routes, FALSE); /* should be dumb_city info? */ lsend_packet_city_info(dest, &packet, FALSE); web_lsend_packet(city_info_addition, dest, &web_packet, FALSE); traderoute_packet_list_iterate(routes, route_packet) { @@ -2332,6 +2343,8 @@ void package_city(struct city *pcity, struct packet_city_info *packet, int i; int ppl = 0; + fc_assert(!pcity->server.needs_arrange); + packet->id = pcity->id; packet->owner = player_number(city_owner(pcity)); packet->tile = tile_index(city_tile(pcity)); -- 2.30.2