From 2f3ed2cae97b98b15f2731c403197067364dc300 Mon Sep 17 00:00:00 2001
From: Marko Lindqvist <cazfi74@gmail.com>
Date: Thu, 4 Jan 2024 03:53:03 +0200
Subject: [PATCH 10/10] Let server decide if the other party meets clause
 requirements

Client was blocking clauses when it didn't really know
if the other party meets the requirements.

See RM #123

Signed-off-by: Marko Lindqvist <cazfi74@gmail.com>
---
 client/gui-gtk-3.0/diplodlg.c  |  3 ++-
 client/gui-gtk-3.22/diplodlg.c |  3 ++-
 client/gui-gtk-4.0/diplodlg.c  |  3 ++-
 client/gui-qt/diplodlg.cpp     |  3 ++-
 client/gui-sdl2/diplodlg.c     |  3 ++-
 common/diptreaty.c             | 25 +++++++++++++++++--------
 common/diptreaty.h             |  3 ++-
 server/diplhand.c              | 11 ++++++-----
 server/savegame/savegame2.c    |  2 +-
 server/savegame/savegame3.c    |  2 +-
 10 files changed, 37 insertions(+), 21 deletions(-)

diff --git a/client/gui-gtk-3.0/diplodlg.c b/client/gui-gtk-3.0/diplodlg.c
index 30acd09215..6126f44181 100644
--- a/client/gui-gtk-3.0/diplodlg.c
+++ b/client/gui-gtk-3.0/diplodlg.c
@@ -163,7 +163,8 @@ void handle_diplomacy_create_clause(int counterpart, int giver,
     return;
   }
 
-  add_clause(&pdialog->treaty, player_by_number(giver), type, value);
+  add_clause(&pdialog->treaty, player_by_number(giver), type, value,
+             client_player());
   update_diplomacy_dialog(pdialog);
   gui_dialog_alert(pdialog->dialog);  
 }
diff --git a/client/gui-gtk-3.22/diplodlg.c b/client/gui-gtk-3.22/diplodlg.c
index 63c05dab4c..495fa89f0b 100644
--- a/client/gui-gtk-3.22/diplodlg.c
+++ b/client/gui-gtk-3.22/diplodlg.c
@@ -163,7 +163,8 @@ void handle_diplomacy_create_clause(int counterpart, int giver,
     return;
   }
 
-  add_clause(&pdialog->treaty, player_by_number(giver), type, value);
+  add_clause(&pdialog->treaty, player_by_number(giver), type, value,
+             client_player());
   update_diplomacy_dialog(pdialog);
   gui_dialog_alert(pdialog->dialog);
 }
diff --git a/client/gui-gtk-4.0/diplodlg.c b/client/gui-gtk-4.0/diplodlg.c
index 9163c1aa80..6168063e08 100644
--- a/client/gui-gtk-4.0/diplodlg.c
+++ b/client/gui-gtk-4.0/diplodlg.c
@@ -180,7 +180,8 @@ void handle_diplomacy_create_clause(int counterpart, int giver,
     return;
   }
 
-  add_clause(&pdialog->treaty, player_by_number(giver), type, value);
+  add_clause(&pdialog->treaty, player_by_number(giver), type, value,
+             client_player());
   update_diplomacy_dialog(pdialog);
   gui_dialog_alert(pdialog->dialog);
 }
diff --git a/client/gui-qt/diplodlg.cpp b/client/gui-qt/diplodlg.cpp
index ab74c7ee0c..ca6ef86ae1 100644
--- a/client/gui-qt/diplodlg.cpp
+++ b/client/gui-qt/diplodlg.cpp
@@ -1029,7 +1029,8 @@ void handle_diplomacy_create_clause(int counterpart, int giver,
   w = gui()->game_tab_widget->widget(i);
   dd = qobject_cast<diplo_dlg *>(w);
   dw = dd->find_widget(counterpart);
-  add_clause(&dw->treaty, player_by_number(giver), type, value);
+  add_clause(&dw->treaty, player_by_number(giver), type, value,
+             client_player());
   dw->update_wdg();
 }
 
diff --git a/client/gui-sdl2/diplodlg.c b/client/gui-sdl2/diplodlg.c
index e1c8a80c8d..9d60849ef5 100644
--- a/client/gui-sdl2/diplodlg.c
+++ b/client/gui-sdl2/diplodlg.c
@@ -188,7 +188,8 @@ void handle_diplomacy_create_clause(int counterpart, int giver,
                                    pclause->value);
   } clause_list_iterate_end;
 
-  add_clause(&pdialog->treaty, player_by_number(giver), type, value);
+  add_clause(&pdialog->treaty, player_by_number(giver), type, value,
+             client_player());
 
   update_clauses_list(pdialog);
   update_acceptance_icons(pdialog);
diff --git a/common/diptreaty.c b/common/diptreaty.c
index 9aca71c35d..9ce3f8b413 100644
--- a/common/diptreaty.c
+++ b/common/diptreaty.c
@@ -140,7 +140,8 @@ bool remove_clause(struct Treaty *ptreaty, struct player *pfrom,
   Add clause to treaty.
 **************************************************************************/
 bool add_clause(struct Treaty *ptreaty, struct player *pfrom, 
-                enum clause_type type, int val)
+                enum clause_type type, int val,
+                struct player *client_player)
 {
   struct player *pto = (pfrom == ptreaty->plr0
                         ? ptreaty->plr1 : ptreaty->plr0);
@@ -172,7 +173,7 @@ bool add_clause(struct Treaty *ptreaty, struct player *pfrom,
   }
 
   if (type == CLAUSE_EMBASSY && player_has_real_embassy(pto, pfrom)) {
-    /* we already have embassy */
+    /* We already have embassy */
     log_error("Illegal embassy clause: %s already have embassy with %s.",
               nation_rule_name(nation_of_player(pto)),
               nation_rule_name(nation_of_player(pfrom)));
@@ -183,12 +184,20 @@ bool add_clause(struct Treaty *ptreaty, struct player *pfrom,
     return FALSE;
   }
 
-  if (!are_reqs_active(&(const struct req_context) { .player = pfrom },
-                       pto, &clause_infos[type].giver_reqs, RPT_POSSIBLE)
-      || !are_reqs_active(&(const struct req_context) { .player = pto },
-                          pfrom, &clause_infos[type].receiver_reqs,
-                          RPT_POSSIBLE)) {
-    return FALSE;
+  /* Leave it to the server to decide if the other party can meet
+   * the requirements. */
+  if (client_player == NULL || client_player == pfrom) {
+    if (!are_reqs_active(&(const struct req_context) { .player = pfrom },
+                         pto, &clause_infos[type].giver_reqs, RPT_POSSIBLE)) {
+      return FALSE;
+    }
+  }
+  if (client_player == NULL || client_player == pto) {
+    if (!are_reqs_active(&(const struct req_context) { .player = pto },
+                         pfrom, &clause_infos[type].receiver_reqs,
+                         RPT_POSSIBLE)) {
+      return FALSE;
+    }
   }
 
   clause_list_iterate(ptreaty->clauses, old_clause) {
diff --git a/common/diptreaty.h b/common/diptreaty.h
index 4ecdb45296..c4c14667af 100644
--- a/common/diptreaty.h
+++ b/common/diptreaty.h
@@ -89,7 +89,8 @@ bool could_intel_with_player(const struct player *pplayer,
 void init_treaty(struct Treaty *ptreaty, 
                  struct player *plr0, struct player *plr1);
 bool add_clause(struct Treaty *ptreaty, struct player *pfrom, 
-                enum clause_type type, int val);
+                enum clause_type type, int val,
+                struct player *client_player);
 bool remove_clause(struct Treaty *ptreaty, struct player *pfrom, 
                    enum clause_type type, int val);
 void clear_treaty(struct Treaty *ptreaty);
diff --git a/server/diplhand.c b/server/diplhand.c
index 3aa2d01d73..a78d0c62dc 100644
--- a/server/diplhand.c
+++ b/server/diplhand.c
@@ -794,11 +794,12 @@ void handle_diplomacy_create_clause_req(struct player *pplayer,
 
   ptreaty = find_treaty(pplayer, pother);
 
-  if (ptreaty && add_clause(ptreaty, pgiver, type, value)) {
-    /* 
-     * If we are trading cities, then it is possible that the
-     * dest is unaware of it's existence.  We have 2 choices,
-     * forbid it, or lighten that area.  If we assume that
+  if (ptreaty != NULL
+      && add_clause(ptreaty, pgiver, type, value, NULL)) {
+    /*
+     * If we are trading cities, then it is possible that
+     * the dest is unaware of it's existence. We have 2 choices,
+     * forbid it, or lighten that area. If we assume that
      * the giver knows what they are doing, then 2. is the
      * most powerful option - I'll choose that for now.
      *                           - Kris Bubendorfer
diff --git a/server/savegame/savegame2.c b/server/savegame/savegame2.c
index 4b1908e652..ea68d2c9e2 100644
--- a/server/savegame/savegame2.c
+++ b/server/savegame/savegame2.c
@@ -5128,7 +5128,7 @@ static void sg_load_treaties(struct loaddata *loading)
                                                "treaty%d.clause%d.value",
                                                tidx, cidx);
 
-            add_clause(ptreaty, pgiver, type, value);
+            add_clause(ptreaty, pgiver, type, value, NULL);
           }
         }
       }
diff --git a/server/savegame/savegame3.c b/server/savegame/savegame3.c
index 40d78c4cbb..2fad1b1385 100644
--- a/server/savegame/savegame3.c
+++ b/server/savegame/savegame3.c
@@ -7471,7 +7471,7 @@ static void sg_load_treaties(struct loaddata *loading)
                                                "treaty%d.clause%d.value",
                                                tidx, cidx);
 
-            add_clause(ptreaty, pgiver, type, value);
+            add_clause(ptreaty, pgiver, type, value, NULL);
           }
         }
       }
-- 
2.43.0

