diff --git a/src/cmdline.c b/src/cmdline.c
index 9f7a45427d..58b233db03 100644
--- a/src/cmdline.c
+++ b/src/cmdline.c
@@ -120,10 +120,19 @@ int cmdline_run(const char **argv, int argc)
#endif // DISABLE_NETWORK
if (argc != 0) {
+ // see comment next to cmdline_call_action for expected return codes
gExitCode = cmdline_call_action(argv, argc);
- if (gExitCode != 0) {
+ if (gExitCode < 0) {
+ // action failed, don't change exit code
+ // and don't start the game
+ return 0;
+ } else if (gExitCode > 0) {
+ // action successful, but don't start the game
+ // change exit code to success
+ gExitCode = 0;
return 0;
}
+ // start the game, so far exit code means success.
}
// Headless mode requires a park to open
@@ -199,6 +208,7 @@ static int cmdline_for_none(const char **argv, int argc)
}
}
+// see comment next to cmdline_call_action for expected return codes
struct { const char *firstArg; cmdline_action action; } cmdline_table[] = {
{ "intro", cmdline_for_intro },
{ "edit", cmdline_for_edit },
@@ -212,6 +222,19 @@ struct { const char *firstArg; cmdline_action action; } cmdline_table[] = {
#endif
};
+/**
+ * This function delegates starting the game to different handlers, if found.
+ *
+ * Three cases of return values are supported:
+ * - result < 0 means failure, will exit with error code
+ * This case is useful when user provided wrong arguments or the requested
+ * action failed
+ * - result > 0 means success, won't start game, will exit program with success code
+ * This case is useful when you want to do some batch action and signalize
+ * success to the user.
+ * - result == 0 means success, will launch the game.
+ * This is default when ran with no arguments.
+ */
static int cmdline_call_action(const char **argv, int argc)
{
for (int i = 0; i < countof(cmdline_table); i++) {
diff --git a/src/cmdline_sprite.c b/src/cmdline_sprite.c
index 0e8f84a83a..789a86fa0a 100644
--- a/src/cmdline_sprite.c
+++ b/src/cmdline_sprite.c
@@ -1,8 +1,29 @@
+/*****************************************************************************
+ * Copyright (c) 2015 Ted John
+ * OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+ *
+ * This file is part of OpenRCT2.
+ *
+ * OpenRCT2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *****************************************************************************/
+
#include
#include "cmdline.h"
#include "drawing/drawing.h"
#include "platform/platform.h"
#include "util/util.h"
+#include "openrct2.h"
#define MODE_DEFAULT 0
#define MODE_CLOSEST 1
@@ -397,6 +418,7 @@ bool sprite_file_import(const char *path, rct_g1_element *outElement, uint8 **ou
int cmdline_for_sprite(const char **argv, int argc)
{
+ gOpenRCT2Headless = true;
if (argc == 0)
return -1;
diff --git a/src/network/network.cpp b/src/network/network.cpp
index 8c566d4ff1..2c0f55047e 100644
--- a/src/network/network.cpp
+++ b/src/network/network.cpp
@@ -438,11 +438,18 @@ bool Network::Init()
wsa_initialized = true;
}
#endif
+ status = NETWORK_STATUS_READY;
return true;
}
void Network::Close()
{
+ if (status == NETWORK_STATUS_NONE)
+ {
+ // Already closed. This prevents a call in ~Network() to gfx_invalidate_screen()
+ // which may no longer be valid on Linux and would cause a segfault.
+ return;
+ }
if (mode == NETWORK_MODE_CLIENT) {
closesocket(server_connection.socket);
} else
@@ -1398,7 +1405,7 @@ int Network::Server_Handle_GAMECMD(NetworkConnection& connection, NetworkPacket&
packet >> tick >> args[0] >> args[1] >> args[2] >> args[3] >> args[4] >> args[5] >> args[6] >> callback;
int commandCommand = args[4];
-
+
// Don't let clients send pause or quit
if (commandCommand != GAME_COMMAND_TOGGLE_PAUSE &&
commandCommand != GAME_COMMAND_LOAD_OR_QUIT
@@ -1406,7 +1413,7 @@ int Network::Server_Handle_GAMECMD(NetworkConnection& connection, NetworkPacket&
Server_Send_GAMECMD(args[0], args[1], args[2], args[3], args[4], args[5], args[6], playerid, callback);
game_do_command(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
}
-
+
return 1;
}
diff --git a/src/network/network.h b/src/network/network.h
index 70992b3feb..0e94b479ca 100644
--- a/src/network/network.h
+++ b/src/network/network.h
@@ -44,6 +44,7 @@ enum {
enum {
NETWORK_STATUS_NONE,
+ NETWORK_STATUS_READY,
NETWORK_STATUS_RESOLVING,
NETWORK_STATUS_CONNECTING,
NETWORK_STATUS_CONNECTED