From ad426b56faa07807e97ee3b6899a917f3ed4746c Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Wed, 10 May 2023 06:37:05 +0300 Subject: [PATCH 15/15] Keep observes in sync with city investigation See osdn #46186 Signed-off-by: Marko Lindqvist --- client/packhand.c | 60 ++++++++++++++++++++++++++++------- common/networking/packets.def | 10 ++++++ fc_version | 2 +- server/diplomats.c | 17 ++++++++-- 4 files changed, 74 insertions(+), 15 deletions(-) diff --git a/client/packhand.c b/client/packhand.c index 1ad853befb..30b915514f 100644 --- a/client/packhand.c +++ b/client/packhand.c @@ -1073,12 +1073,12 @@ static void city_packet_common(struct city *pcity, struct tile *pcenter, unit_list_destroy(pcity->client.info_units_present); pcity->client.info_units_present = - pcity->client.collecting_info_units_present; + pcity->client.collecting_info_units_present; pcity->client.collecting_info_units_present = NULL; unit_list_destroy(pcity->client.info_units_supported); pcity->client.info_units_supported = - pcity->client.collecting_info_units_supported; + pcity->client.collecting_info_units_supported; pcity->client.collecting_info_units_supported = NULL; } else { /* We didn't get any unit, let's clear the unit lists. */ @@ -2111,6 +2111,40 @@ static bool handle_unit_packet_common(struct unit *packet_unit) return ret; } +/************************************************************************//** + Receive an investigate_started packet + + Can't rely on generic packet_processing_started, as that works for + the requesting connection only, and not for observers. +****************************************************************************/ +void handle_investigate_started(int unit_id, int city_id) +{ + struct city *pcity = game_city_by_number(city_id); + + if (!pcity) { + log_error("Investigate city: unknown city id %d!", + city_id); + return; + } + + /* Start collecting supported and present units. */ + + /* Ensure we are not already in an investigate cycle. */ + fc_assert(pcity->client.collecting_info_units_supported == NULL); + fc_assert(pcity->client.collecting_info_units_present == NULL); + pcity->client.collecting_info_units_supported = + unit_list_new_full(unit_virtual_destroy); + pcity->client.collecting_info_units_present = + unit_list_new_full(unit_virtual_destroy); +} + +/************************************************************************//** + Receive an investigate_finished packet +****************************************************************************/ +void handle_investigate_finished(int unit_id, int city_id) +{ +} + /************************************************************************//** Receive a short_unit info packet. ****************************************************************************/ @@ -2134,21 +2168,23 @@ void handle_unit_short_info(const struct packet_unit_short_info *packet) return; } - /* New serial number: start collecting supported and present units. */ - if (last_serial_num - != client.conn.client.request_id_of_currently_handled_packet) { - last_serial_num = + if (!has_capability("obsinv", client.conn.capability)) { + /* New serial number: start collecting supported and present units. */ + if (last_serial_num + != client.conn.client.request_id_of_currently_handled_packet) { + last_serial_num = client.conn.client.request_id_of_currently_handled_packet; - /* Ensure we are not already in an investigate cycle. */ - fc_assert(pcity->client.collecting_info_units_supported == NULL); - fc_assert(pcity->client.collecting_info_units_present == NULL); - pcity->client.collecting_info_units_supported = + /* Ensure we are not already in an investigate cycle. */ + fc_assert(pcity->client.collecting_info_units_supported == NULL); + fc_assert(pcity->client.collecting_info_units_present == NULL); + pcity->client.collecting_info_units_supported = unit_list_new_full(unit_virtual_destroy); - pcity->client.collecting_info_units_present = + pcity->client.collecting_info_units_present = unit_list_new_full(unit_virtual_destroy); + } } - /* Okay, append a unit struct to the proper list. */ + /* Append a unit struct to the proper list. */ punit = unpackage_short_unit(packet); if (packet->packet_use == UNIT_INFO_CITY_SUPPORTED) { fc_assert(pcity->client.collecting_info_units_supported != NULL); diff --git a/common/networking/packets.def b/common/networking/packets.def index e5e5323a25..446ab18c47 100644 --- a/common/networking/packets.def +++ b/common/networking/packets.def @@ -372,6 +372,16 @@ end PACKET_PROCESSING_FINISHED = 1; sc end +PACKET_INVESTIGATE_STARTED = 21; sc, dsend + UNIT unit_id; + CITY city_id; +end + +PACKET_INVESTIGATE_FINISHED = 22; sc, dsend + UNIT unit_id; + CITY city_id; +end + /************** Login/pregame/endgame packets **********************/ # This packet is the first real (freeciv specific) packet send by the diff --git a/fc_version b/fc_version index 334f2c9d8b..b31b3567b3 100755 --- a/fc_version +++ b/fc_version @@ -74,7 +74,7 @@ DEFAULT_FOLLOW_TAG=S3_1 # - No new mandatory capabilities can be added to the release branch; doing # so would break network capability of supposedly "compatible" releases. # -NETWORK_CAPSTRING="+Freeciv-3.1-network city-original rsdesc32" +NETWORK_CAPSTRING="+Freeciv-3.1-network city-original rsdesc32 obsinv" FREECIV_DISTRIBUTOR="" if test "x$FREECIV_LABEL_FORCE" != "x" ; then diff --git a/server/diplomats.c b/server/diplomats.c index 1fc3e73f95..6c03dd8940 100644 --- a/server/diplomats.c +++ b/server/diplomats.c @@ -19,6 +19,7 @@ /* utility */ #include "bitvector.h" +#include "capability.h" #include "fcintl.h" #include "log.h" #include "rand.h" @@ -353,13 +354,19 @@ bool diplomat_investigate(struct player *pplayer, struct unit *pdiplomat, log_debug("investigate: unit: %d", pdiplomat->id); + conn_list_iterate(pplayer->connections, pconn) { + if (has_capability("obsinv", pconn->capability)) { + dsend_packet_investigate_started(pconn, pdiplomat->id, pcity->id); + } + } conn_list_iterate_end; + /* Do It... */ update_dumb_city(pplayer, pcity); /* Special case for a diplomat/spy investigating a city: The investigator needs to know the supported and present units of a city, whether or not they are fogged. So, we send a list of them all before sending the city info. - As this is a special case we bypass send_unit_info. */ + As this is a special case we bypass send_unit_info(). */ unit_list_iterate(pcity->units_supported, punit) { package_short_unit(punit, &unit_packet, UNIT_INFO_CITY_SUPPORTED, pcity->id); @@ -392,7 +399,7 @@ bool diplomat_investigate(struct player *pplayer, struct unit *pdiplomat, } traderoute_packet_list_iterate_end; traderoute_packet_list_destroy(routes); - /* this may cause a diplomatic incident */ + /* This may cause a diplomatic incident */ action_consequence_success(paction, pplayer, act_utype, cplayer, city_tile(pcity), city_link(pcity)); @@ -404,6 +411,12 @@ bool diplomat_investigate(struct player *pplayer, struct unit *pdiplomat, send_unit_info(NULL, pdiplomat); } + conn_list_iterate(pplayer->connections, pconn) { + if (has_capability("obsinv", pconn->capability)) { + dsend_packet_investigate_finished(pconn, pdiplomat->id, pcity->id); + } + } conn_list_iterate_end; + return TRUE; } -- 2.39.2