From: divverent Date: Sun, 8 Jul 2007 13:47:12 +0000 (+0000) Subject: new cvar log_dest_udp to send all console data to one or more specified addresses... X-Git-Tag: xonotic-v0.1.0preview~2994 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=74114c15d518859de79175ce60347ce6d959f81c;p=xonotic%2Fdarkplaces.git new cvar log_dest_udp to send all console data to one or more specified addresses, separated by spaces, in form of QW rcon prints. Should be useful to let external programs communicate with a DP server (like IRC gateways, console web interfaces, stuff like that) git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@7471 d7cf8633-e32d-0410-b094-e92efae38249 --- diff --git a/console.c b/console.c index aeef3e6f..b6f49ee4 100644 --- a/console.c +++ b/console.c @@ -76,6 +76,9 @@ LOGGING */ cvar_t log_file = {0, "log_file","", "filename to log messages to"}; +cvar_t log_dest_udp = {0, "log_dest_udp","", "UDP address to log messages to (in QW rcon compatible format); multiple destinations can be separated by spaces; DO NOT SPECIFY DNS NAMES HERE"}; +char log_dest_buffer[1500]; // UDP packet +size_t log_dest_buffer_pos; char crt_log_file [MAX_OSPATH] = ""; qfile_t* logfile = NULL; @@ -85,6 +88,54 @@ size_t logq_size = 0; void Log_ConPrint (const char *msg); +/* +==================== +Log_DestBuffer_Init +==================== +*/ +static void Log_DestBuffer_Init() +{ + memcpy(log_dest_buffer, "\377\377\377\377n", 5); // QW rcon print + log_dest_buffer_pos = 5; +} + +/* +==================== +Log_DestBuffer_Flush +==================== +*/ +void Log_DestBuffer_Flush() +{ + lhnetaddress_t log_dest_addr; + lhnetsocket_t *log_dest_socket; + const char *s = log_dest_udp.string; + qboolean have_opened_temp_sockets = false; + if(s) if(log_dest_buffer_pos > 5) + { + log_dest_buffer[log_dest_buffer_pos++] = 0; + + if(!NetConn_HaveServerPorts() && !NetConn_HaveClientPorts()) // then temporarily open one + { + have_opened_temp_sockets = true; + NetConn_OpenServerPorts(true); + } + + while(COM_ParseToken_Console(&s)) + if(LHNETADDRESS_FromString(&log_dest_addr, com_token, 26000)) + { + log_dest_socket = NetConn_ChooseClientSocketForAddress(&log_dest_addr); + if(!log_dest_socket) + log_dest_socket = NetConn_ChooseServerSocketForAddress(&log_dest_addr); + if(log_dest_socket) + NetConn_WriteString(log_dest_socket, log_dest_buffer, &log_dest_addr); + } + + if(have_opened_temp_sockets) + NetConn_CloseServerPorts(); + } + log_dest_buffer_pos = 0; +} + /* ==================== Log_Timestamp @@ -156,6 +207,8 @@ Log_Start */ void Log_Start (void) { + size_t pos; + size_t n; Log_Open (); // Dump the contents of the log queue into the log file and free it @@ -163,8 +216,24 @@ void Log_Start (void) { unsigned char *temp = logqueue; logqueue = NULL; - if (logfile != NULL && logq_ind != 0) - FS_Write (logfile, temp, logq_ind); + if(logq_ind != 0) + { + if (logfile != NULL) + FS_Write (logfile, temp, logq_ind); + if(*log_dest_udp.string) + { + for(pos = 0; pos < logq_ind; ) + { + if(log_dest_buffer_pos == 0) + Log_DestBuffer_Init(); + n = min(sizeof(log_dest_buffer) - log_dest_buffer_pos - 1, logq_ind - pos); + memcpy(log_dest_buffer + log_dest_buffer_pos, temp + pos, n); + log_dest_buffer_pos += n; + Log_DestBuffer_Flush(); + pos += n; + } + } + } Mem_Free (temp); logq_ind = 0; logq_size = 0; @@ -223,6 +292,7 @@ void Log_ConPrint (const char *msg) // If a log file is available if (logfile != NULL) FS_Print (logfile, msg); + inprogress = false; } @@ -451,6 +521,7 @@ void Con_Init (void) Cvar_RegisterVariable (&sys_specialcharactertranslation); Cvar_RegisterVariable (&log_file); + Cvar_RegisterVariable (&log_dest_udp); // support for the classic Quake option // COMMANDLINEOPTION: Console: -condebug logs console messages to qconsole.log, see also log_file @@ -621,6 +692,17 @@ void Con_Print(const char *msg) // to the rcon redirect buffer if (rcon_redirect && rcon_redirect_bufferpos < (int)sizeof(rcon_redirect_buffer) - 1) rcon_redirect_buffer[rcon_redirect_bufferpos++] = *msg; + else if(*log_dest_udp.string) // don't duplicate rcon command responses here, these are sent another way + { + if(log_dest_buffer_pos == 0) + Log_DestBuffer_Init(); + log_dest_buffer[log_dest_buffer_pos++] = *msg; + if(log_dest_buffer_pos >= sizeof(log_dest_buffer) - 1) // minus one, to allow for terminating zero + Log_DestBuffer_Flush(); + } + else + log_dest_buffer_pos = 0; + // if this is the beginning of a new line, print timestamp if (index == 0) { diff --git a/console.h b/console.h index 1849f670..4aa3e956 100644 --- a/console.h +++ b/console.h @@ -64,6 +64,7 @@ void Con_DisplayList(const char **list); void Log_Init (void); void Log_Close (void); void Log_Start (void); +void Log_DestBuffer_Flush (void); // call this once per frame to send out replies to rcon streaming clients void Log_Printf(const char *logfilename, const char *fmt, ...) DP_FUNC_PRINTF(2); diff --git a/host.c b/host.c index d8201610..cc1e8015 100644 --- a/host.c +++ b/host.c @@ -612,6 +612,8 @@ void Host_Main(void) NetConn_UpdateSockets(); + Log_DestBuffer_Flush(); + // receive packets on each main loop iteration, as the main loop may // be undersleeping due to select() detecting a new packet if (sv.active) diff --git a/netconn.c b/netconn.c index 9e62d93c..6352cf78 100755 --- a/netconn.c +++ b/netconn.c @@ -711,6 +711,16 @@ int NetConn_SendUnreliableMessage(netconn_t *conn, sizebuf_t *data, protocolvers return 0; } +qboolean NetConn_HaveClientPorts(void) +{ + return !!cl_numsockets; +} + +qboolean NetConn_HaveServerPorts(void) +{ + return !!sv_numsockets; +} + void NetConn_CloseClientPorts(void) { for (;cl_numsockets > 0;cl_numsockets--) diff --git a/netconn.h b/netconn.h index d875e7a8..63df6644 100755 --- a/netconn.h +++ b/netconn.h @@ -351,6 +351,8 @@ extern cvar_t net_address; qboolean NetConn_CanSend(netconn_t *conn); int NetConn_SendUnreliableMessage(netconn_t *conn, sizebuf_t *data, protocolversion_t protocol, int rate, qboolean quakesignon_suppressreliables); +qboolean NetConn_HaveClientPorts(void); +qboolean NetConn_HaveServerPorts(void); void NetConn_CloseClientPorts(void); void NetConn_OpenClientPorts(void); void NetConn_CloseServerPorts(void);