From ac41f26aac2c8540424aacbfa8bb38db77294f6d 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/Makefile.am b/client/Makefile.am
index a72f0583d6..21d6961c1c 100644
--- a/client/Makefile.am
+++ b/client/Makefile.am
@@ -90,6 +90,8 @@ freeciv_client_src = $(AUDIO_SDL_FILES) \
 	cityrepdata.h	\
 	client_main.c	\
 	client_main.h	\
+	client_counters.c \
+	client_counters.h \
 	chatline_common.c \
 	chatline_common.h \
 	connectdlg_common.c \
diff --git a/client/client_counter.h b/client/client_counter.h
new file mode 100644
index 0000000000..45b7e59d5b
--- /dev/null
+++ b/client/client_counter.h
@@ -0,0 +1,21 @@
+/***********************************************************************
+ Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+***********************************************************************/
+#ifndef FC__CLIENT_COUNTERS_H
+#define FC__CLIENT_COUNTERS_H
+
+/* common */
+#include "packets.h"
+
+void handle_ruleset_counter(const struct packet_ruleset_counter *packet);
+
+#endif
diff --git a/client/client_counters.c b/client/client_counters.c
new file mode 100644
index 0000000000..515a2bcdeb
--- /dev/null
+++ b/client/client_counters.c
@@ -0,0 +1,41 @@
+/***********************************************************************
+ Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+***********************************************************************/
+
+/* common */
+#include "counters.h"
+
+#include "client_counter.h"
+
+
+/**********************************************************************//**
+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/client/packhand.c b/client/packhand.c
index 537e7d84e4..557f65feed 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
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..0976b196bf 100644
--- a/common/fc_types.h
+++ b/common/fc_types.h
@@ -93,6 +93,16 @@ 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 */
+#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 };
+
 /* 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..13058e9272 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

