changeset 15008:ee359ca920a8 draft

(svn r19620) -Fix: desync when a command is received and in the queue while a client starts joining, i.e. save the game state. This can happen in two ways: with frame_freq > 1 a command received in a previous frame might not be executed yet or when a command is received in the same frame as the join but before the savegame is made. In both cases the joining client would not get all commands to get in-sync with the server (and the other clients).
author rubidium <rubidium@openttd.org>
date Tue, 13 Apr 2010 18:55:31 +0000
parents fa4ce54f12c3
children 5ed9f0152af6
files src/network/network_command.cpp src/network/network_internal.h src/network/network_server.cpp
diffstat 3 files changed, 20 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/network/network_command.cpp
+++ b/src/network/network_command.cpp
@@ -130,6 +130,24 @@
 }
 
 /**
+ * Sync our local command queue to the command queue of the given
+ * socket. This is needed for the case where we receive a command
+ * before saving the game for a joining client, but without the
+ * execution of those commands. Not syncing those commands means
+ * that the client will never get them and as such will be in a
+ * desynced state from the time it started with joining.
+ * @param cs The client to sync the queue to.
+ */
+void NetworkSyncCommandQueue(NetworkClientSocket *cs)
+{
+	for (CommandPacket *p = _local_command_queue; p != NULL; p = p->next) {
+		CommandPacket c = *p;
+		c.callback = 0;
+		NetworkAddCommandQueue(c, cs);
+	}
+}
+
+/**
  * Execute all commands on the local command queue that ought to be executed this frame.
  */
 void NetworkExecuteLocalCommandQueue()
--- a/src/network/network_internal.h
+++ b/src/network/network_internal.h
@@ -163,6 +163,7 @@
 void NetworkAddCommandQueue(CommandPacket cp, NetworkClientSocket *cs = NULL);
 void NetworkExecuteLocalCommandQueue();
 void NetworkFreeLocalCommandQueue();
+void NetworkSyncCommandQueue(NetworkClientSocket *cs);
 
 /* from network.c */
 NetworkRecvStatus NetworkCloseClient(NetworkClientSocket *cs, NetworkRecvStatus status);
--- a/src/network/network_server.cpp
+++ b/src/network/network_server.cpp
@@ -353,6 +353,7 @@
 
 		sent_packets = 4; // We start with trying 4 packets
 
+		NetworkSyncCommandQueue(cs);
 		cs->status = STATUS_MAP;
 		/* Mark the start of download */
 		cs->last_frame = _frame_counter;