(svn r8631) -Add: added parameter -l ip[:port] to ./openttd, which redirects DEBUG() to a remote connection over TCP
authortruelight
Thu, 08 Feb 2007 12:27:53 +0000
changeset 6210 717cc12ac0a9
parent 6209 2505d5d90992
child 6211 fd01dad1fe55
(svn r8631) -Add: added parameter -l ip[:port] to ./openttd, which redirects DEBUG() to a remote connection over TCP
For example, launch on 192.168.0.1 with, say, netcat a listener: netcat -l -p 3982
Launch OpenTTD on a remote host (say, PSP): ./openttd -l 192.168.0.1 -d9
And you get all debug information on 192.168.0.1. Very useful for debugging Portable systems.
src/debug.cpp
src/network/core/config.h
src/network/network.cpp
src/network/network.h
src/openttd.cpp
--- a/src/debug.cpp	Thu Feb 08 11:21:10 2007 +0000
+++ b/src/debug.cpp	Thu Feb 08 12:27:53 2007 +0000
@@ -8,6 +8,11 @@
 #include "debug.h"
 #include "functions.h"
 #include "string.h"
+#include "network/core/core.h"
+
+#if defined(ENABLE_NETWORK)
+SOCKET _debug_socket = INVALID_SOCKET;
+#endif /* ENABLE_NETWORK */
 
 int _debug_ai_level;
 int _debug_driver_level;
@@ -78,8 +83,18 @@
 		s = va_arg(va, const char*);
 		vsnprintf(buf, lengthof(buf), s, va);
 		va_end(va);
-		fprintf(stderr, "dbg: [%s] %s\n", dbg, buf);
-		IConsoleDebug(dbg, buf);
+#if defined(ENABLE_NETWORK)
+		if (_debug_socket != INVALID_SOCKET) {
+			char buf2[lengthof(buf) + 32];
+
+			snprintf(buf2, lengthof(buf2), "dbg: [%s] %s\n", dbg, buf);
+			send(_debug_socket, buf2, strlen(buf2), 0);
+		} else
+#endif /* ENABLE_NETWORK */
+		{
+			fprintf(stderr, "dbg: [%s] %s\n", dbg, buf);
+			IConsoleDebug(dbg, buf);
+		}
 	}
 }
 #endif /* NO_DEBUG_MESSAGES */
--- a/src/network/core/config.h	Thu Feb 08 11:21:10 2007 +0000
+++ b/src/network/core/config.h	Thu Feb 08 12:27:53 2007 +0000
@@ -17,6 +17,7 @@
 enum {
 	NETWORK_MASTER_SERVER_PORT    = 3978, ///< The default port of the master server (UDP)
 	NETWORK_DEFAULT_PORT          = 3979, ///< The default port of the game server (TCP & UDP)
+	NETWORK_DEFAULT_DEBUGLOG_PORT = 3982, ///< The default port debug-log is sent too (TCP)
 
 	SEND_MTU                      = 1460, ///< Number of bytes we can pack in a single packet
 
--- a/src/network/network.cpp	Thu Feb 08 11:21:10 2007 +0000
+++ b/src/network/network.cpp	Thu Feb 08 12:27:53 2007 +0000
@@ -1317,6 +1317,37 @@
 	snprintf(_network_unique_id, sizeof(_network_unique_id), "%s", hex_output);
 }
 
+void NetworkStartDebugLog(const char *hostname, uint16 port)
+{
+	extern SOCKET _debug_socket;  // Comes from debug.c
+	SOCKET s;
+	struct sockaddr_in sin;
+
+	DEBUG(net, 0, "Redirecting DEBUG() to %s:%d", hostname, port);
+
+	s = socket(AF_INET, SOCK_STREAM, 0);
+	if (s == INVALID_SOCKET) {
+		DEBUG(net, 0, "Failed to open socket for redirection DEBUG()");
+		return;
+	}
+
+	if (!SetNoDelay(s)) DEBUG(net, 1, "Setting TCP_NODELAY failed");
+
+	sin.sin_family = AF_INET;
+	sin.sin_addr.s_addr = NetworkResolveHost(hostname);
+	sin.sin_port = htons(port);
+
+	if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) != 0) {
+		DEBUG(net, 0, "Failed to redirection DEBUG() to %s:%d", hostname, port);
+		return;
+	}
+
+	if (!SetNonBlocking(s)) DEBUG(net, 0, "Setting non-blocking mode failed");
+	_debug_socket = s;
+
+	DEBUG(net, 0, "DEBUG() is now redirected");
+}
+
 /** This tries to launch the network for a given OS */
 void NetworkStartUp(void)
 {
--- a/src/network/network.h	Thu Feb 08 11:21:10 2007 +0000
+++ b/src/network/network.h	Thu Feb 08 12:27:53 2007 +0000
@@ -166,6 +166,7 @@
 void NetworkPopulateCompanyInfo(void);
 void UpdateNetworkGameWindow(bool unselect);
 void CheckMinPlayers(void);
+void NetworkStartDebugLog(const char *hostname, uint16 port);
 
 void NetworkStartUp(void);
 void NetworkUDPCloseAll();
--- a/src/openttd.cpp	Thu Feb 08 11:21:10 2007 +0000
+++ b/src/openttd.cpp	Thu Feb 08 12:27:53 2007 +0000
@@ -159,6 +159,7 @@
 #if defined(ENABLE_NETWORK)
 		"  -n [ip:port#player] = Start networkgame\n"
 		"  -D [ip][:port]      = Start dedicated server\n"
+		"  -l ip[:port]        = Redirect DEBUG()\n"
 #if !defined(__MORPHOS__) && !defined(__AMIGA__) && !defined(WIN32)
 		"  -f                  = Fork into the background (dedicated only)\n"
 #endif
@@ -344,6 +345,7 @@
 	bool dedicated = false;
 	bool network   = false;
 	char *network_conn = NULL;
+	char *debuglog_conn = NULL;
 	char *dedicated_host = NULL;
 	uint16 dedicated_port = 0;
 #endif /* ENABLE_NETWORK */
@@ -360,7 +362,7 @@
 	//   a letter means: it accepts that param (e.g.: -h)
 	//   a ':' behind it means: it need a param (e.g.: -m<driver>)
 	//   a '::' behind it means: it can optional have a param (e.g.: -d<debug>)
-	optformat = "m:s:v:hD::n::eit:d::r:g::G:c:x"
+	optformat = "m:s:v:hD::n::eit:d::r:g::G:c:xl:"
 #if !defined(__MORPHOS__) && !defined(__AMIGA__) && !defined(WIN32)
 		"f"
 #endif
@@ -394,6 +396,9 @@
 			network = true;
 			network_conn = mgo.opt; // optional IP parameter, NULL if unset
 			break;
+		case 'l':
+			debuglog_conn = mgo.opt;
+			break;
 #endif /* ENABLE_NETWORK */
 		case 'r': ParseResolution(resolution, mgo.opt); break;
 		case 't': startyear = atoi(mgo.opt); break;
@@ -490,6 +495,21 @@
 
 	NetworkStartUp(); // initialize network-core
 
+#if defined(ENABLE_NETWORK)
+	if (debuglog_conn != NULL && _network_available) {
+		const char *not_used = NULL;
+		const char *port = NULL;
+		uint16 rport;
+
+		rport = NETWORK_DEFAULT_DEBUGLOG_PORT;
+
+		ParseConnectionString(&not_used, &port, debuglog_conn);
+		if (port != NULL) rport = atoi(port);
+
+		NetworkStartDebugLog(debuglog_conn, rport);
+	}
+#endif /* ENABLE_NETWORK */
+
 	ScanNewGRFFiles();
 
 	_opt_ptr = &_opt_newgame;