From bbdd70c4dde3bce538c4cfc2096e7a34bd3688cd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C5=82awomir=20Lach?= <slawek@lach.art.pl>
Date: Mon, 16 Jan 2023 20:52:52 +0100
Subject: [PATCH] =?UTF-8?q?!OSDN:=20TICKET:=20#46496:=20S=C5=82awomir=20La?=
 =?UTF-8?q?ch=20<slawek@lach.art.pl>?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

It solves bug causes sending data, when it is not needed. We ask
lower-layer to sending each counter's value of entity. Lower layer may
optimise it by sending only changed data.

diff --git a/client/packhand.c b/client/packhand.c
index 927846d596..16bb1b0c4e 100644
--- a/client/packhand.c
+++ b/client/packhand.c
@@ -5561,10 +5561,11 @@ void handle_ruleset_counter(const struct packet_ruleset_counter *packet)
 /**********************************************************************//**
 Handle updating city's counter, when server request
 **************************************************************************/
-void handle_city_update_counter(const struct packet_city_update_counter *packet)
+void handle_city_update_counters(const struct packet_city_update_counters *packet)
 {
-  int counter = packet->counter;
-  int counter_count = counters_get_city_counters_count();
+  int i;
+  int counters_count = counters_get_city_counters_count();
+
   struct city *pcity = game_city_by_number(packet->city);
 
   if (NULL == pcity) {
@@ -5572,13 +5573,11 @@ void handle_city_update_counter(const struct packet_city_update_counter *packet)
     return;
   }
 
-  if (counter_count <= counter || 0 > counter) {
-
-    return;
+  counters_count = counters_get_city_counters_count();
+  for (i = 0; i < counters_count; i++) {
+    pcity->counter_values[i] = packet->counters[i];
   }
 
-  pcity->counter_values[counter] = packet->value;
-
   update_city_description(pcity);
   city_report_dialog_update_city(pcity);
 }
diff --git a/common/counters.h b/common/counters.h
index fd332b5033..bf43e32b84 100644
--- a/common/counters.h
+++ b/common/counters.h
@@ -23,8 +23,6 @@ extern "C" {
 /* common */
 #include "name_translation.h"
 
-#define MAX_COUNTERS 20
-
 struct counter
 {
   struct name_translation name;
diff --git a/common/fc_types.h b/common/fc_types.h
index f52a506ab9..428e0fe12b 100644
--- a/common/fc_types.h
+++ b/common/fc_types.h
@@ -105,6 +105,10 @@ enum output_type_id {
   O_FOOD, O_SHIELD, O_TRADE, O_GOLD, O_LUXURY, O_SCIENCE, O_LAST
 };
 
+/* Counters related definitions. See common/counters.h */
+/* Used in the network protocol. */
+#define MAX_COUNTERS 20
+
 /* Counters related types. See common/counters.h */
 /* Used in the network protocol. */
 #define SPECENUM_NAME counter_behaviour
diff --git a/common/networking/packets.def b/common/networking/packets.def
index fd0dd04b04..d0146f1f1c 100644
--- a/common/networking/packets.def
+++ b/common/networking/packets.def
@@ -777,10 +777,9 @@ PACKET_CITY_NATIONALITIES = 46; sc, lsend, is-game-info, force
   CITIZENS nation_citizens[MAX_CITY_NATIONALITIES:nationalities_count];
 end
 
-PACKET_CITY_UPDATE_COUNTER = 514; sc, lsend, is-game-info
-  CITY city;
-  COUNTER counter;
-  UINT32 value;
+PACKET_CITY_UPDATE_COUNTERS = 514; sc, lsend, is-game-info
+  CITY city; key
+  COUNTER counters[MAX_COUNTERS];
 end
 
 PACKET_CITY_SHORT_INFO = 32; sc, lsend, is-game-info, cancel(PACKET_CITY_INFO), cancel(PACKET_WEB_CITY_INFO_ADDITION), cancel(PACKET_CITY_NATIONALITIES), cancel(PACKET_CITY_RALLY_POINT)
diff --git a/server/citytools.c b/server/citytools.c
index e583ab4460..326fb562a4 100644
--- a/server/citytools.c
+++ b/server/citytools.c
@@ -2338,9 +2338,7 @@ void send_city_info(struct player *dest, struct city *pcity)
   }
 
   /* Sending counters */
-  city_counters_iterate(pcount) {
-    city_counter_refresh(pcity, pcount->index);
-  } city_counters_iterate_end;
+  city_counters_refresh(pcity);
 
   if (game.info.team_pooled_research
       && player_list_size(team_members(powner->team)) > 1) {
diff --git a/server/cityturn.c b/server/cityturn.c
index 20efa26c31..3ec2fb9be0 100644
--- a/server/cityturn.c
+++ b/server/cityturn.c
@@ -4420,14 +4420,24 @@ void city_style_refresh(struct city *pcity)
   Send updated (by server) counter information of
   a given city.
 **************************************************************************/
-void city_counter_refresh(struct city *pcity, int number)
+void city_counters_refresh(struct city *pcity)
 {
-  struct packet_city_update_counter packet;
-
+  int i, counter_count;
+  struct packet_city_update_counters packet;
+
+  /* Needed, because we use delta protocol
+   * We do not need to sending seldom data
+   * with seldom possibility.
+   */
+  memset(packet.counters, 0, sizeof(packet.counters));
   packet.city = pcity->id;
-  packet.counter = number;
-  packet.value = pcity->counter_values[number];
 
-  lsend_packet_city_update_counter(pcity->owner->connections, &packet);
-  lsend_packet_city_update_counter(game.glob_observers, &packet);
+  counter_count = counters_get_city_counters_count();
+
+  for (i = 0; i < counter_count; i++) {
+    packet.counters[i] = pcity->counter_values[i];
+  }
+
+  lsend_packet_city_update_counters(pcity->owner->connections, &packet);
+  lsend_packet_city_update_counters(game.glob_observers, &packet);
 }
diff --git a/server/cityturn.h b/server/cityturn.h
index 2cc270b86f..503fa42659 100644
--- a/server/cityturn.h
+++ b/server/cityturn.h
@@ -61,6 +61,6 @@ void city_style_refresh(struct city *pcity);
 bool player_balance_treasury_units_and_buildings(struct player *pplayer);
 bool player_balance_treasury_units(struct player *pplayer);
 
-void city_counter_refresh(struct city *pcity, int number);
+void city_counters_refresh(struct city *pcity);
 
 #endif /* FC__CITYTURN_H */
diff --git a/server/srv_main.c b/server/srv_main.c
index 8265393f1d..22c3237c0b 100644
--- a/server/srv_main.c
+++ b/server/srv_main.c
@@ -1560,17 +1560,11 @@ static void end_turn(void)
   players_iterate(pplayer) {
     city_list_iterate(pplayer->cities, pcity) {
       city_counters_iterate(pcount) {
-        int old_val = pcity->counter_values[pcount->index];
-
         if (pcount->type == CB_CITY_OWNED_TURNS) {
           pcity->counter_values[pcount->index]++;
         }
-
-        if (pcity->counter_values[pcount->index] != old_val) {
-
-          city_counter_refresh(pcity, pcount->index);
-        }
       } city_counters_iterate_end;
+      city_counters_refresh(pcity);
     } city_list_iterate_end;
   } players_iterate_end;
 
-- 
2.39.0

