summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiels Martin Hansen <nielsm@indvikleren.dk>2018-05-24 19:40:54 +0200
committerMichael Lutz <michi@icosahedron.de>2018-06-23 15:22:31 +0200
commit4fb76db42f886ff21a9f60fc89c786de79d79705 (patch)
treee98db0834c6797a1b87a43ccc14479917855c2c3
parent11ba094582ae3eb8ed20f2f47938e18a827d6163 (diff)
downloadopenttd-4fb76db42f886ff21a9f60fc89c786de79d79705.tar.xz
Feature #986: Automatic save when losing connection to a network game
-rw-r--r--src/network/core/tcp_game.cpp2
-rw-r--r--src/network/network_client.cpp21
-rw-r--r--src/settings_type.h1
-rw-r--r--src/table/settings.ini6
4 files changed, 30 insertions, 0 deletions
diff --git a/src/network/core/tcp_game.cpp b/src/network/core/tcp_game.cpp
index 9b3f7b5ef..caa378fc4 100644
--- a/src/network/core/tcp_game.cpp
+++ b/src/network/core/tcp_game.cpp
@@ -45,6 +45,8 @@ NetworkRecvStatus NetworkGameSocketHandler::CloseConnection(bool error)
{
/* Clients drop back to the main menu */
if (!_network_server && _networking) {
+ extern void ClientNetworkEmergencySave(); // from network_client.cpp
+ ClientNetworkEmergencySave();
_switch_mode = SM_MENU;
_networking = false;
ShowErrorMessage(STR_NETWORK_ERROR_LOSTCONNECTION, INVALID_STRING_ID, WL_CRITICAL);
diff --git a/src/network/network_client.cpp b/src/network/network_client.cpp
index e3bcbb2d8..4b066681d 100644
--- a/src/network/network_client.cpp
+++ b/src/network/network_client.cpp
@@ -120,6 +120,19 @@ struct PacketReader : LoadFilter {
/**
+ * Create an emergency savegame when the network connection is lost.
+ */
+void ClientNetworkEmergencySave()
+{
+ if (!_settings_client.gui.autosave_on_network_disconnect) return;
+
+ const char *filename = "netsave.sav";
+ DEBUG(net, 0, "Client: Performing emergency save (%s)", filename);
+ SaveOrLoad(filename, SLO_SAVE, DFT_GAME_FILE, AUTOSAVE_DIR, false);
+}
+
+
+/**
* Create a new socket for the client side of the game connection.
* @param s The socket to connect with.
*/
@@ -670,6 +683,9 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_ERROR(Packet *p
ShowErrorMessage(err, INVALID_STRING_ID, WL_CRITICAL);
+ /* Perform an emergency save if we had already entered the game */
+ if (this->status == STATUS_ACTIVE) ClientNetworkEmergencySave();
+
DeleteWindowById(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN);
return NETWORK_RECV_STATUS_SERVER_ERROR;
@@ -1051,6 +1067,8 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_SHUTDOWN(Packet
ShowErrorMessage(STR_NETWORK_MESSAGE_SERVER_SHUTDOWN, INVALID_STRING_ID, WL_CRITICAL);
}
+ if (this->status == STATUS_ACTIVE) ClientNetworkEmergencySave();
+
return NETWORK_RECV_STATUS_SERVER_ERROR;
}
@@ -1066,6 +1084,8 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_NEWGAME(Packet
ShowErrorMessage(STR_NETWORK_MESSAGE_SERVER_REBOOT, INVALID_STRING_ID, WL_CRITICAL);
}
+ if (this->status == STATUS_ACTIVE) ClientNetworkEmergencySave();
+
return NETWORK_RECV_STATUS_SERVER_ERROR;
}
@@ -1153,6 +1173,7 @@ void ClientNetworkGameSocketHandler::CheckConnection()
if (lag > 20) {
this->NetworkGameSocketHandler::CloseConnection();
ShowErrorMessage(STR_NETWORK_ERROR_LOSTCONNECTION, INVALID_STRING_ID, WL_CRITICAL);
+ ClientNetworkEmergencySave();
return;
}
diff --git a/src/settings_type.h b/src/settings_type.h
index fc4059c7b..f9cc00f3a 100644
--- a/src/settings_type.h
+++ b/src/settings_type.h
@@ -114,6 +114,7 @@ struct GUISettings {
bool threaded_saves; ///< should we do threaded saves?
bool keep_all_autosave; ///< name the autosave in a different way
bool autosave_on_exit; ///< save an autosave when you quit the game, but do not ask "Do you really want to quit?"
+ bool autosave_on_network_disconnect; ///< save an autosave when you get disconnected from a network game with an error?
uint8 date_format_in_default_names; ///< should the default savegame/screenshot name use long dates (31th Dec 2008), short dates (31-12-2008) or ISO dates (2008-12-31)
byte max_num_autosaves; ///< controls how many autosavegames are made before the game starts to overwrite (names them 0 to max_num_autosaves - 1)
bool population_in_label; ///< show the population of a town in his label?
diff --git a/src/table/settings.ini b/src/table/settings.ini
index 693c8246c..c061c394f 100644
--- a/src/table/settings.ini
+++ b/src/table/settings.ini
@@ -2987,6 +2987,12 @@ flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
def = false
cat = SC_BASIC
+[SDTC_BOOL]
+var = gui.autosave_on_network_disconnect
+flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
+def = true
+cat = SC_EXPERT
+
[SDTC_VAR]
var = gui.max_num_autosaves
type = SLE_UINT8