+ if (length >= 9 && !memcmp(string, "getstatus", 9))
+ {
+ const char *challenge = NULL;
+
+ // If there was a challenge in the getinfo message
+ if (length > 10 && string[9] == ' ')
+ challenge = string + 10;
+
+ if (NetConn_BuildStatusResponse(challenge, response, sizeof(response), true))
+ {
+ if (developer.integer)
+ Con_Printf("Sending reply to client %s - %s\n", addressstring2, response);
+ NetConn_WriteString(mysocket, response, peeraddress);
+ }
+ return true;
+ }
+ if (length >= 5 && !memcmp(string, "rcon ", 5))
+ {
+ int i;
+ char *s = string + 5;
+ char password[64];
+ for (i = 0;*s > ' ';s++)
+ if (i < (int)sizeof(password) - 1)
+ password[i++] = *s;
+ password[i] = 0;
+ if (password[0] > ' ' && !strcmp(rcon_password.string, password))
+ {
+ // looks like a legitimate rcon command with the correct password
+ Con_Printf("server received rcon command from %s:\n%s\n", host_client ? host_client->name : addressstring2, s);
+ rcon_redirect = true;
+ rcon_redirect_bufferpos = 0;
+ Cmd_ExecuteString(s, src_command);
+ 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);
+ }
+ }
+ return true;
+ }