+// look for anything interesting like player IP addresses or ping reports
+qboolean CL_ExaminePrintString(const char *text)
+{
+ const char *t;
+ if (!strcmp(text, "Client ping times:\n"))
+ {
+ cl.parsingtextmode = CL_PARSETEXTMODE_PING;
+ for(cl.parsingtextplayerindex = 0; cl.parsingtextplayerindex < cl.maxclients && !cl.scores[cl.parsingtextplayerindex].name[0]; cl.parsingtextplayerindex++)
+ ;
+ if (cl.parsingtextplayerindex >= cl.maxclients) // should never happen, since the client itself should be in cl.scores
+ {
+ Con_Printf("ping reply but empty scoreboard?!?\n");
+ cl.parsingtextmode = CL_PARSETEXTMODE_NONE;
+ cl.parsingtextexpectingpingforscores = 0;
+ }
+ cl.parsingtextexpectingpingforscores = cl.parsingtextexpectingpingforscores ? 2 : 0;
+ return !cl.parsingtextexpectingpingforscores;
+ }
+ if (!strncmp(text, "host: ", 9))
+ {
+ // cl.parsingtextexpectingpingforscores = false; // really?
+ cl.parsingtextmode = CL_PARSETEXTMODE_STATUS;
+ cl.parsingtextplayerindex = 0;
+ return true;
+ }
+ if (cl.parsingtextmode == CL_PARSETEXTMODE_PING)
+ {
+ // if anything goes wrong, we'll assume this is not a ping report
+ qboolean expected = cl.parsingtextexpectingpingforscores;
+ cl.parsingtextexpectingpingforscores = 0;
+ cl.parsingtextmode = CL_PARSETEXTMODE_NONE;
+ t = text;
+ while (*t == ' ')
+ t++;
+ if ((*t >= '0' && *t <= '9') || *t == '-')
+ {
+ int ping = atoi(t);
+ while ((*t >= '0' && *t <= '9') || *t == '-')
+ t++;
+ if (*t == ' ')
+ {
+ int charindex = 0;
+ t++;
+ if(cl.parsingtextplayerindex < cl.maxclients)
+ {
+ for (charindex = 0;cl.scores[cl.parsingtextplayerindex].name[charindex] == t[charindex];charindex++)
+ ;
+ if (cl.scores[cl.parsingtextplayerindex].name[charindex] == 0 && t[charindex] == '\n')
+ {
+ cl.scores[cl.parsingtextplayerindex].qw_ping = bound(0, ping, 9999);
+ for (cl.parsingtextplayerindex++;cl.parsingtextplayerindex < cl.maxclients && !cl.scores[cl.parsingtextplayerindex].name[0];cl.parsingtextplayerindex++)
+ ;
+ //if (cl.parsingtextplayerindex < cl.maxclients) // we could still get unconnecteds!
+ {
+ // we parsed a valid ping entry, so expect another to follow
+ cl.parsingtextmode = CL_PARSETEXTMODE_PING;
+ cl.parsingtextexpectingpingforscores = expected;
+ }
+ return !expected;
+ }
+ }
+ if (!strncmp(t, "unconnected\n", 12))
+ {
+ // just ignore
+ cl.parsingtextmode = CL_PARSETEXTMODE_PING;
+ cl.parsingtextexpectingpingforscores = expected;
+ return !expected;
+ }
+ else
+ Con_DPrintf("player names '%s' and '%s' didn't match\n", cl.scores[cl.parsingtextplayerindex].name, t);
+ }
+ }
+ }
+ if (cl.parsingtextmode == CL_PARSETEXTMODE_STATUS)
+ {
+ if (!strncmp(text, "players: ", 9))
+ {
+ cl.parsingtextmode = CL_PARSETEXTMODE_STATUS_PLAYERID;
+ cl.parsingtextplayerindex = 0;
+ return true;
+ }
+ else if (!strstr(text, ": "))
+ {
+ cl.parsingtextmode = CL_PARSETEXTMODE_NONE; // status report ended
+ return true;
+ }
+ }
+ if (cl.parsingtextmode == CL_PARSETEXTMODE_STATUS_PLAYERID)
+ {
+ // if anything goes wrong, we'll assume this is not a status report
+ cl.parsingtextmode = CL_PARSETEXTMODE_NONE;
+ if (text[0] == '#' && text[1] >= '0' && text[1] <= '9')
+ {
+ t = text + 1;
+ cl.parsingtextplayerindex = atoi(t);
+ while (*t >= '0' && *t <= '9')
+ t++;
+ if (*t == ' ')
+ {
+ cl.parsingtextmode = CL_PARSETEXTMODE_STATUS_PLAYERIP;
+ return true;
+ }
+ }
+ }
+ if (cl.parsingtextmode == CL_PARSETEXTMODE_STATUS_PLAYERIP)
+ {
+ // if anything goes wrong, we'll assume this is not a status report
+ cl.parsingtextmode = CL_PARSETEXTMODE_NONE;
+ if (text[0] == ' ')
+ {
+ t = text;
+ while (*t == ' ')
+ t++;
+ // botclient is perfectly valid, but we don't care about bots
+ if (strcmp(t, "botclient\n"))
+ {
+ lhnetaddress_t address;
+ LHNETADDRESS_FromString(&address, t, 0);
+ // TODO: log the IP address and player name?
+ }
+ cl.parsingtextmode = CL_PARSETEXTMODE_STATUS_PLAYERID;
+ return true;
+ }
+ }
+ return true;
+}
+