From 52987147cd3ec80016f4234ad4647a4571857575 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C5=82awomir=20Lach?= <slawek@lach.art.pl>
Date: Thu, 18 Aug 2022 15:52:15 +0200
Subject: [PATCH] =?UTF-8?q?!OSND=2041123:=20S=C5=82awomir=20Lach=20<slawek?=
 =?UTF-8?q?@lach.art.pl>?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Add support for counters packet

diff --git a/client/packhand.c b/client/packhand.c
index 537e7d84e4..e6f8069e87 100644
--- a/client/packhand.c
+++ b/client/packhand.c
@@ -32,6 +32,7 @@
 #include "actions.h"
 #include "capstr.h"
 #include "citizens.h"
+#include "counters.h"
 #include "events.h"
 #include "extras.h"
 #include "game.h"
@@ -3354,6 +3355,7 @@ void handle_ruleset_control(const struct packet_ruleset_control *packet)
   VALIDATE(num_resource_types,	MAX_RESOURCE_TYPES,     "resources");
   VALIDATE(num_disaster_types,  MAX_DISASTER_TYPES,     "disasters");
   VALIDATE(num_achievement_types, MAX_ACHIEVEMENT_TYPES, "achievements");
+  VALIDATE(num_counters, MAX_COUNTERS, "counters");
 
   /* game.control.government_count, game.control.nation_count and
    * game.control.num_city_styles are allocated dynamically, and does
@@ -5452,3 +5454,27 @@ void handle_diplomacy_remove_clause(int counterpart, int giver,
 {
   client_recv_remove_clause(counterpart, giver, type, value);
 }
+
+/**********************************************************************//**
+Handle each counter ruleset's packet send from server instance to this
+client.
+**************************************************************************/
+void handle_ruleset_counter(const struct packet_ruleset_counter *packet)
+{
+  int counter_count = counters_get_city_counters_count();
+  struct counter *curr = counter_by_id(counter_count);
+
+  names_set(&curr->name, NULL, packet->name, packet->rule_name);
+  curr->checkpoint = packet->checkpoint;
+  curr->type = packet->behaviour;
+  curr->target = packet->type;
+  curr->def = packet->def;
+
+  if (curr->type != CB_CITY_OWNED_TURNS
+    || curr->target != CTGT_CITY) {
+
+    return;
+  }
+
+  attach_city_counter(curr);
+}
diff --git a/common/counters.h b/common/counters.h
index a5ea3f7286..3ae191ec8e 100644
--- a/common/counters.h
+++ b/common/counters.h
@@ -20,15 +20,6 @@ extern "C" {
 /* common */
 #include "name_translation.h"
 
-#define SPECENUM_NAME counter_behaviour
-#define SPECENUM_VALUE1 CB_CITY_OWNED_TURNS
-#define SPECENUM_VALUE1NAME "Owned"
-
-#define SPECENUM_COUNT COUNTER_BEHAVIOUR_LAST
-#include "specenum_gen.h"
-
-enum counter_target { CTGT_CITY };
-
 #define MAX_COUNTERS 20
 
 struct counter
diff --git a/common/fc_types.h b/common/fc_types.h
index d7052e0f54..065ed96e69 100644
--- a/common/fc_types.h
+++ b/common/fc_types.h
@@ -93,6 +93,18 @@ enum output_type_id {
   O_FOOD, O_SHIELD, O_TRADE, O_GOLD, O_LUXURY, O_SCIENCE, O_LAST
 };
 
+/* Counters related types. See common/counters.h */
+/* Used in the network protocol. */
+#define SPECENUM_NAME counter_behaviour
+#define SPECENUM_VALUE1 CB_CITY_OWNED_TURNS
+#define SPECENUM_VALUE1NAME "Owned"
+
+#define SPECENUM_COUNT COUNTER_BEHAVIOUR_LAST
+#include "specenum_gen.h"
+
+/* Used in the network protocol. */
+enum counter_target { CTGT_CITY };
+
 /* Changing this enum will break savegame and network compatibility. */
 /* When changing this, also update the list of valid requirement "Activity"
  * values in doc/README.effects and the list of invalid requirement
diff --git a/common/networking/packets.def b/common/networking/packets.def
index ce44d9fcfa..d14136c100 100644
--- a/common/networking/packets.def
+++ b/common/networking/packets.def
@@ -3,7 +3,7 @@
 Max used id:
 ============
 
-Max id: 255
+Max id: 513
 
 Packets are not ordered by their id, but by their category. New packet
 with higher id may get added to existing category, and not to the end of file.
@@ -267,6 +267,8 @@ type CAPITAL            = uint8(enum capital_type)
 type WONDER_VISIB       = uint8(enum wonder_visib_type)
 type TRANSP_DEF_TYPE    = uint8(enum transp_def_type)
 type AI_LEVEL           = uint8(enum ai_level)
+type COUNTER_TARGET       = uint8(enum counter_target)
+type COUNTER_BEHAVIOUR       = uint8(enum counter_behaviour)
 
 # typedefs for bit vectors
 type BV_ACTIONS         = bitvector(bv_actions)
@@ -1867,6 +1869,15 @@ PACKET_RULESET_ACTION_AUTO = 252; sc, lsend
   ACTION_ID         alternatives[MAX_NUM_ACTIONS:alternatives_count];
 end
 
+PACKET_RULESET_COUNTER = 513; sc, lsend
+  STRING name[MAX_LEN_NAME];
+  STRING rule_name[MAX_LEN_NAME];
+  UINT32 def;
+  UINT32 checkpoint;
+  COUNTER_TARGET type;
+  COUNTER_BEHAVIOUR behaviour;
+end
+
 PACKET_RULESET_MUSIC = 240; sc, lsend
   UINT8  id; 
   STRING music_peaceful[MAX_LEN_NAME];
diff --git a/server/ruleset.c b/server/ruleset.c
index 7b6a34c4d2..68e1e25481 100644
--- a/server/ruleset.c
+++ b/server/ruleset.c
@@ -8084,6 +8084,25 @@ static void send_ruleset_techs(struct conn_list *dest)
   } advance_iterate_end;
 }
 
+/**********************************************************************//**
+Send the counters ruleset information  to the specified connections.
+**************************************************************************/
+static void send_ruleset_counters(struct conn_list *dest)
+{
+  city_counters_iterate(pcount) {
+    struct packet_ruleset_counter packet;
+
+    sz_strlcpy(packet.name, untranslated_name(&pcount->name));
+    sz_strlcpy(packet.rule_name, rule_name_get(&pcount->name));
+    packet.checkpoint = pcount->checkpoint;
+    packet.behaviour = pcount->type;
+    packet.type = pcount->target;
+    packet.def = pcount->def;
+
+    lsend_packet_ruleset_counter(dest, &packet);
+  } city_counters_iterate_end;
+}
+
 /**********************************************************************//**
   Send the buildings ruleset information (all individual improvements and
   wonders) to the specified connections.
@@ -9383,6 +9402,7 @@ void send_rulesets(struct conn_list *dest)
   send_ruleset_game(dest);
   send_ruleset_disasters(dest);
   send_ruleset_achievements(dest);
+  send_ruleset_counters(dest);
   send_ruleset_trade_routes(dest);
   send_ruleset_team_names(dest);
   send_ruleset_actions(dest);
-- 
2.37.3

