From 17507b217cc9fbb2506f5cb8ce87060949f8e94c Mon Sep 17 00:00:00 2001 From: frosch Date: Sun, 3 Aug 2014 15:04:09 +0000 Subject: [PATCH] (svn r26717) [1.4] -Backport from trunk: - Fix: CMD_CLEAR_ORDER_BACKUP should not be suppressed by pause modes (r26716) - Fix: Discard incorrectly saved order backups when clients join [FS#6066] (r26700) --- src/command.cpp | 2 +- src/network/network_server.cpp | 14 ++++++++++++++ src/saveload/order_sl.cpp | 14 ++++++++------ 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/command.cpp b/src/command.cpp index 2891a06af6..8dbd5a47a0 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -246,7 +246,7 @@ static const Command _command_proc_table[] = { DEF_CMD(CmdForceTrainProceed, 0, CMDT_VEHICLE_MANAGEMENT ), // CMD_FORCE_TRAIN_PROCEED DEF_CMD(CmdReverseTrainDirection, 0, CMDT_VEHICLE_MANAGEMENT ), // CMD_REVERSE_TRAIN_DIRECTION - DEF_CMD(CmdClearOrderBackup, CMD_CLIENT_ID, CMDT_ROUTE_MANAGEMENT ), // CMD_CLEAR_ORDER_BACKUP + DEF_CMD(CmdClearOrderBackup, CMD_CLIENT_ID, CMDT_SERVER_SETTING ), // CMD_CLEAR_ORDER_BACKUP DEF_CMD(CmdModifyOrder, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_MODIFY_ORDER DEF_CMD(CmdSkipToOrder, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_SKIP_TO_ORDER DEF_CMD(CmdDeleteOrder, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_DELETE_ORDER diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index 9cb3bcfcae..ee36f1cb8b 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -596,6 +596,20 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendMap() sent_packets = 4; // We start with trying 4 packets + /* The order backups are broken in 1.4, so that joining clients cannot + * restore orders backupped before they joined. + * + * When loading the game on the new client, we have to drop all order backups. + * As such this client will desync, in case an order backup is actually restored. + * + * To lower the desync chance, the server resets all order backups when a client + * joins, so a desync is only possible when the restore command is queued at the server + * while the saving is executed. */ + NetworkClientSocket *cs; + FOR_ALL_CLIENT_SOCKETS(cs) { + OrderBackup::ResetUser(cs->client_id); + } + /* Make a dump of the current game */ if (SaveWithFilter(this->savegame, true) != SL_OK) usererror("network savedump failed"); } diff --git a/src/saveload/order_sl.cpp b/src/saveload/order_sl.cpp index 8234165793..a66c44dcb4 100644 --- a/src/saveload/order_sl.cpp +++ b/src/saveload/order_sl.cpp @@ -13,6 +13,7 @@ #include "../order_backup.h" #include "../settings_type.h" #include "../network/network.h" +#include "../network/network_server.h" #include "saveload_internal.h" @@ -247,9 +248,9 @@ const SaveLoad *GetOrderBackupDescription() SLE_VAR(OrderBackup, user, SLE_UINT32), SLE_VAR(OrderBackup, tile, SLE_UINT32), SLE_VAR(OrderBackup, group, SLE_UINT16), - SLE_VAR(OrderBackup, service_interval, SLE_UINT32), + SLE_VAR(OrderBackup, service_interval, SLE_FILE_U32 | SLE_VAR_U16), SLE_STR(OrderBackup, name, SLE_STR, 0), - SLE_VAR(OrderBackup, clone, SLE_UINT16), + SLE_NULL(2), // clone (2 bytes of pointer, i.e. garbage) SLE_VAR(OrderBackup, cur_real_order_index, SLE_UINT8), SLE_CONDVAR(OrderBackup, cur_implicit_order_index, SLE_UINT8, 176, SL_MAX_VERSION), SLE_CONDVAR(OrderBackup, current_order_time, SLE_UINT32, 176, SL_MAX_VERSION), @@ -289,10 +290,11 @@ void Load_BKOR() } /* Only load order-backups for network clients. - * If we are a network server or not networking, then we just loaded - * a previously saved-by-server savegame. There are - * no clients with a backup anymore, so clear it. */ - if (!_networking || _network_server) { + * If we are a network server or not networking, then we just loaded a previously + * saved-by-server savegame. There are no clients with a backup, so clear it. + * Furthermore before savegame version 192 the actual content was always corrupt. + */ + if (!_networking || _network_server || IsSavegameVersionBefore(192)) { _order_backup_pool.CleanPool(); } }