From: divverent Date: Sun, 24 Aug 2008 19:50:08 +0000 (+0000) Subject: rcon: use multiple reply packets to fit any size (where "any" means "as big as the... X-Git-Tag: xonotic-v0.1.0preview~2106 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=a346c169ee4fe6934963a4e82417417c2c991b5d;p=xonotic%2Fdarkplaces.git rcon: use multiple reply packets to fit any size (where "any" means "as big as the OS's socket buffer, about 32k on Linux) git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@8478 d7cf8633-e32d-0410-b094-e92efae38249 --- diff --git a/console.c b/console.c index 14642f1b..07e65de3 100644 --- a/console.c +++ b/console.c @@ -106,7 +106,8 @@ int con_vislines; qboolean con_initialized; // used for server replies to rcon command -qboolean rcon_redirect = false; +lhnetsocket_t *rcon_redirect_sock = NULL; +lhnetaddress_t *rcon_redirect_dest = NULL; int rcon_redirect_bufferpos = 0; char rcon_redirect_buffer[1400]; @@ -791,6 +792,35 @@ static char qfont_table[256] = { 'x', 'y', 'z', '{', '|', '}', '~', '<' }; +void Con_Rcon_Redirect_Init(lhnetsocket_t *sock, lhnetaddress_t *dest) +{ + rcon_redirect_sock = sock; + rcon_redirect_dest = dest; + memcpy(rcon_redirect_buffer, "\377\377\377\377n", 5); // QW rcon print + rcon_redirect_bufferpos = 5; +} + +void Con_Rcon_Redirect_Flush() +{ + rcon_redirect_buffer[rcon_redirect_bufferpos] = 0; + NetConn_WriteString(rcon_redirect_sock, rcon_redirect_buffer, rcon_redirect_dest); + memcpy(rcon_redirect_buffer, "\377\377\377\377n", 5); // QW rcon print + rcon_redirect_bufferpos = 5; +} + +void Con_Rcon_Redirect_End() +{ + Con_Rcon_Redirect_Flush(); + rcon_redirect_dest = NULL; + rcon_redirect_sock = NULL; +} + +void Con_Rcon_Redirect_Abort() +{ + rcon_redirect_dest = NULL; + rcon_redirect_sock = NULL; +} + /* ================ Con_Rcon_AddChar @@ -807,8 +837,12 @@ void Con_Rcon_AddChar(char c) // if this print is in response to an rcon command, add the character // to the rcon redirect buffer - if (rcon_redirect && rcon_redirect_bufferpos < (int)sizeof(rcon_redirect_buffer) - 1) + if (rcon_redirect_dest) + { rcon_redirect_buffer[rcon_redirect_bufferpos++] = c; + if(rcon_redirect_bufferpos >= (int)sizeof(rcon_redirect_buffer) - 1) + Con_Rcon_Redirect_Flush(); + } else if(*log_dest_udp.string) // don't duplicate rcon command responses here, these are sent another way { if(log_dest_buffer_pos == 0) diff --git a/console.h b/console.h index 4aa3e956..009b05bd 100644 --- a/console.h +++ b/console.h @@ -28,9 +28,9 @@ extern int con_totallines; extern int con_backscroll; extern qboolean con_initialized; -extern qboolean rcon_redirect; -extern int rcon_redirect_bufferpos; -extern char rcon_redirect_buffer[1400]; +void Con_Rcon_Redirect_Init(lhnetsocket_t *sock, lhnetaddress_t *dest); +void Con_Rcon_Redirect_End(); +void Con_Rcon_Redirect_Abort(); void Con_CheckResize (void); void Con_Init (void); diff --git a/host.c b/host.c index f4ee0b41..1e62ec9e 100644 --- a/host.c +++ b/host.c @@ -103,7 +103,8 @@ void Host_Error (const char *error, ...) va_list argptr; // turn off rcon redirect if it was active when the crash occurred - rcon_redirect = false; + // to prevent loops when it is a networking problem + Con_Rcon_Redirect_Abort(); va_start (argptr,error); dpvsnprintf (hosterrorstring1,sizeof(hosterrorstring1),error,argptr); diff --git a/netconn.c b/netconn.c index 661455b9..43327ace 100755 --- a/netconn.c +++ b/netconn.c @@ -2383,8 +2383,9 @@ static int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, unsigned char *dat s_ptr += l + 1; } Con_Printf("\n"); - rcon_redirect = true; - rcon_redirect_bufferpos = 0; + + if (!host_client || !host_client->netconnection || LHNETADDRESS_GetAddressType(&host_client->netconnection->peeraddress) != LHNETADDRESSTYPE_LOOP) + Con_Rcon_Redirect_Init(mysocket, peeraddress); while(s != endpos) { size_t l = strlen(s); @@ -2397,27 +2398,7 @@ static int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, unsigned char *dat } s += l + 1; } - rcon_redirect_buffer[rcon_redirect_bufferpos] = 0; - rcon_redirect = false; - // print resulting text to client - // if client is playing, send a reliable reply instead of - // a command packet - if (host_client) - { - // if the netconnection is loop, then this is the - // local player on a listen mode server, and it would - // result in duplicate printing to the console - // (not that the local player should be using rcon - // when they have the console) - if (host_client->netconnection && LHNETADDRESS_GetAddressType(&host_client->netconnection->peeraddress) != LHNETADDRESSTYPE_LOOP) - SV_ClientPrintf("%s", rcon_redirect_buffer); - } - else - { - // qw print command - dpsnprintf(response, sizeof(response), "\377\377\377\377n%s", rcon_redirect_buffer); - NetConn_WriteString(mysocket, response, peeraddress); - } + Con_Rcon_Redirect_End(); } else {