Complete.Org: Mailing Lists: Archives: freeciv-dev: August 2005:
[Freeciv-Dev] (PR#13704) sanity checking for the orders packet
Home

[Freeciv-Dev] (PR#13704) sanity checking for the orders packet

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [Freeciv-Dev] (PR#13704) sanity checking for the orders packet
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Thu, 18 Aug 2005 18:41:06 -0700
Reply-to: bugs@xxxxxxxxxxx

<URL: http://bugs.freeciv.org/Ticket/Display.html?id=13704 >

This patch includes a src tile for the orders packet.  If this tile 
doesn't match the unit's tile the orders are discarded.

This happens fairly often in large games with a timeout.  You issue move 
or goto orders for a unit, but the server doesn't receive them until the 
next turn and thus the goto route gets out of sync.

-jason

Index: client/goto.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/goto.c,v
retrieving revision 1.90
diff -p -u -r1.90 goto.c
--- client/goto.c       14 Jul 2005 19:25:44 -0000      1.90
+++ client/goto.c       19 Aug 2005 01:35:26 -0000
@@ -805,6 +805,8 @@ void request_orders_cleared(struct unit 
   /* Clear the orders by sending an empty orders path. */
   freelog(PACKET_LOG_LEVEL, "Clearing orders for unit %d.", punit->id);
   p.unit_id = punit->id;
+  p.src_x = punit->tile->x;
+  p.src_y = punit->tile->y;
   p.repeat = p.vigilant = FALSE;
   p.length = 0;
   p.dest_x = punit->tile->x;
@@ -824,6 +826,8 @@ static void send_path_orders(struct unit
   struct tile *old_tile;
 
   p.unit_id = punit->id;
+  p.src_x = punit->tile->x;
+  p.src_y = punit->tile->y;
   p.repeat = repeat;
   p.vigilant = vigilant;
 
@@ -969,6 +973,8 @@ void send_connect_route(struct unit *pun
   }
 
   p.unit_id = punit->id;
+  p.src_x = punit->tile->x;
+  p.src_y = punit->tile->y;
   p.repeat = FALSE;
   p.vigilant = FALSE; /* Should be TRUE? */
 
Index: common/packets.def
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/packets.def,v
retrieving revision 1.152
diff -p -u -r1.152 packets.def
--- common/packets.def  18 Aug 2005 06:53:30 -0000      1.152
+++ common/packets.def  19 Aug 2005 01:35:27 -0000
@@ -800,6 +800,8 @@ end
 # used for client orders: currently client-side goto and patrol
 PACKET_UNIT_ORDERS=59;cs
   UNIT unit_id;
+  COORD src_x, src_y; # Origin tile, included for sanity checking
+
   UINT16 length;
   BOOL repeat, vigilant;
   ORDERS orders[MAX_LEN_ROUTE:length];
Index: server/unithand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/unithand.c,v
retrieving revision 1.346
diff -p -u -r1.346 unithand.c
--- server/unithand.c   26 Jul 2005 16:36:00 -0000      1.346
+++ server/unithand.c   19 Aug 2005 01:35:27 -0000
@@ -1621,12 +1621,21 @@ void handle_unit_orders(struct player *p
                        struct packet_unit_orders *packet)
 {
   struct unit *punit = player_find_unit_by_id(pplayer, packet->unit_id);
+  struct tile *src_tile = map_pos_to_tile(packet->src_x, packet->src_y);
   int i;
 
   if (!punit || packet->length < 0 || punit->activity != ACTIVITY_IDLE) {
     return;
   }
 
+  if (src_tile != punit->tile) {
+    /* Failed sanity check.  Usually this happens if the orders were sent
+     * in the previous turn, and the client thought the unit was in a
+     * different position than it's actually in.  The easy solution is to
+     * discard the packet.  We don't send an error message to the client
+     * here (though maybe we should?). */
+    return;
+  }
 
   for (i = 0; i < packet->length; i++) {
     if (packet->orders[i] < 0 || packet->orders[i] > ORDER_LAST) {

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#13704) sanity checking for the orders packet, Jason Short <=