From 7b59891881f810cd2a18415339ef079a83a2331c Mon Sep 17 00:00:00 2001
From: Marko Lindqvist <cazfi74@gmail.com>
Date: Fri, 18 Oct 2024 18:44:56 +0300
Subject: [PATCH 38/38] Protocol: Add sync-serial packets

See RM #976

Signed-off-by: Marko Lindqvist <cazfi74@gmail.com>
---
 client/options.c              |  6 +++++-
 client/packhand.c             |  7 +++++++
 common/networking/packets.def | 11 ++++++++++-
 server/connecthand.c          |  8 ++++++++
 server/srv_main.c             |  3 ++-
 5 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/client/options.c b/client/options.c
index 74a3bb6217..09e2086a53 100644
--- a/client/options.c
+++ b/client/options.c
@@ -435,6 +435,8 @@ struct client_options gui_options = {
  * of non-initialized datas when calling the changed callback. */
 static bool options_fully_initialized = FALSE;
 
+static int sync_serial = 0;
+
 static const struct strvec *get_mapimg_format_list(const struct option *poption);
 
 /****************************************************************************
@@ -4599,6 +4601,7 @@ void handle_server_setting_const
      * Do now override settings that are already saved to savegame          \
      * and now loaded. */                                                   \
     desired_settable_option_send(OPTION(poption));                          \
+    dsend_packet_sync_serial(&client.conn, ++sync_serial);                  \
     psoption->desired_sent = TRUE;                                          \
   }                                                                         \
                                                                             \
@@ -5924,7 +5927,7 @@ static void desired_settable_option_send(struct option *poption)
 
   if (!settable_options_hash_lookup(settable_options_hash,
                                     option_name(poption), &desired)) {
-    /* No change explicitly  desired. */
+    /* No change explicitly desired. */
     return;
   }
 
@@ -6024,6 +6027,7 @@ void resend_desired_settable_options(void)
           if (psoption->is_visible
               && psoption->is_changeable) {
             desired_settable_option_send(OPTION(poption));
+            dsend_packet_sync_serial(&client.conn, ++sync_serial);
           }
         }
       }
diff --git a/client/packhand.c b/client/packhand.c
index 67cf9353cf..4a8b47a8ea 100644
--- a/client/packhand.c
+++ b/client/packhand.c
@@ -5730,3 +5730,10 @@ void handle_city_update_counters(const struct packet_city_update_counters *packe
 
   city_report_dialog_update_city(pcity);
 }
+
+/**********************************************************************//**
+  Handle servers's reply to request to sync via packet serial number
+**************************************************************************/
+void handle_sync_serial_reply(int serial)
+{
+}
diff --git a/common/networking/packets.def b/common/networking/packets.def
index 42f0523608..b9cdf3cd7d 100644
--- a/common/networking/packets.def
+++ b/common/networking/packets.def
@@ -3,7 +3,7 @@
 Max used id:
 ============
 
-Max id: 516
+Max id: 518
 
 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.
@@ -2406,6 +2406,15 @@ PACKET_POPUP_IMAGE = 515; sc, lsend, handle-via-fields
   STRING tag[MAX_LEN_NAME];
 end
 
+/************** Sync Requests **********************/
+PACKET_SYNC_SERIAL = 517; cs, handle-via-fields, handle-per-conn, dsend
+  UINT32 serial;
+end
+
+PACKET_SYNC_SERIAL_REPLY = 518; sc, handle-via-fields, dsend
+  UINT32 serial;
+end
+
 /*************** Webclient specific packets ****************/
 /* Use range 256:511 for these                             */
 
diff --git a/server/connecthand.c b/server/connecthand.c
index 7642c930ae..39666998e6 100644
--- a/server/connecthand.c
+++ b/server/connecthand.c
@@ -1010,3 +1010,11 @@ void connection_close_server(struct connection *pconn, const char *reason)
   connection_delegate_restore(pconn);
   connection_close(pconn, reason);
 }
+
+/**********************************************************************//**
+  Handle client's request to sync via packet serial number.
+**************************************************************************/
+void handle_sync_serial(struct connection *conn, int serial)
+{
+  dsend_packet_sync_serial_reply(conn, serial);
+}
diff --git a/server/srv_main.c b/server/srv_main.c
index e910add26b..67eab5c154 100644
--- a/server/srv_main.c
+++ b/server/srv_main.c
@@ -2206,7 +2206,8 @@ bool server_packet_input(struct connection *pconn, void *packet, int type)
       && type != PACKET_NATION_SELECT_REQ
       && type != PACKET_PLAYER_READY
       && type != PACKET_VOTE_SUBMIT
-      && type != PACKET_RULESET_SELECT) {
+      && type != PACKET_RULESET_SELECT
+      && type != PACKET_SYNC_SERIAL) {
     if (S_S_OVER == server_state()) {
       /* This can happen by accident, so we don't want to print
        * out lots of error messages. Ie, we use log_debug(). */
-- 
2.45.2

