// (div0) build the full response only if possible; better a getinfo response than no response at all if getstatus won't fit
static qboolean NetConn_BuildStatusResponse(const char* challenge, char* out_msg, size_t out_size, qboolean fullstatus)
{
- const char *qcstatus = NULL;
+ char qcstatus[256];
unsigned int nb_clients = 0, nb_bots = 0, i;
int length;
+ char teambuf[3];
SV_VM_Begin();
}
}
+ *qcstatus = 0;
if(prog->globaloffsets.worldstatus >= 0)
{
const char *str = PRVM_G_STRING(prog->globaloffsets.worldstatus);
{
char *p;
const char *q;
- qcstatus = p = Mem_Alloc(tempmempool, strlen(str) + 1);
+ p = qcstatus;
for(q = str; *q; ++q)
- if(*q != '\\')
+ if(*q != '\\' && *q != '\n')
*p++ = *q;
*p = 0;
}
fullstatus ? "statusResponse" : "infoResponse",
gamename, com_modname, gameversion.integer, svs.maxclients,
nb_clients, nb_bots, sv.name, hostname.string, NET_PROTOCOL_VERSION,
- qcstatus ? "\\qcstatus\\" : "", qcstatus ? qcstatus : "",
+ *qcstatus ? "\\qcstatus\\" : "", qcstatus,
challenge ? "\\challenge\\" : "", challenge ? challenge : "",
fullstatus ? "\n" : "");
- if(qcstatus)
- {
- Mem_Free((char *)qcstatus);
- qcstatus = NULL;
- }
-
// Make sure it fits in the buffer
if (length < 0)
goto bad;
break;
}
} while (curchar != '\0');
+ cleanname[cleanind] = 0; // cleanind is always a valid index even at this point
pingvalue = (int)(cl->ping * 1000.0f);
if(cl->netconnection)
else
pingvalue = 0;
+ *qcstatus = 0;
if(prog->fieldoffsets.clientstatus >= 0)
{
const char *str = PRVM_E_STRING(PRVM_EDICT_NUM(i + 1), prog->fieldoffsets.clientstatus);
{
char *p;
const char *q;
- qcstatus = p = Mem_Alloc(tempmempool, strlen(str) + 1);
- for(q = str; *q; ++q)
- if(*q != '\\' && *q != ' ')
+ p = qcstatus;
+ for(q = str; *q && p != qcstatus + sizeof(qcstatus) - 1; ++q)
+ if(*q != '\\' && *q != '"' && !ISWHITESPACE(*q))
*p++ = *q;
*p = 0;
}
}
- if(qcstatus)
+ if ((gamemode == GAME_NEXUIZ) && (teamplay.integer > 0))
{
- length = dpsnprintf(ptr, left, "%s %d \"%s\"\n",
+ if(cl->frags == -666) // spectator
+ strlcpy(teambuf, " 0", sizeof(teambuf));
+ else if(cl->colors == 0x44) // red team
+ strlcpy(teambuf, " 1", sizeof(teambuf));
+ else if(cl->colors == 0xDD) // blue team
+ strlcpy(teambuf, " 2", sizeof(teambuf));
+ else if(cl->colors == 0xCC) // yellow team
+ strlcpy(teambuf, " 3", sizeof(teambuf));
+ else if(cl->colors == 0x99) // pink team
+ strlcpy(teambuf, " 4", sizeof(teambuf));
+ else
+ strlcpy(teambuf, " 0", sizeof(teambuf));
+ }
+ else
+ *teambuf = 0;
+
+ // note: team number is inserted according to SoF2 protocol
+ if(*qcstatus)
+ length = dpsnprintf(ptr, left, "%s %d%s \"%s\"\n",
qcstatus,
pingvalue,
+ teambuf,
cleanname);
- Mem_Free((char *)qcstatus);
- qcstatus = NULL;
- }
else
- length = dpsnprintf(ptr, left, "%d %d \"%s\"\n",
+ length = dpsnprintf(ptr, left, "%d %d%s \"%s\"\n",
cl->frags,
pingvalue,
+ teambuf,
cleanname);
if(length < 0)
return NULL;
for(text = s; text != endpos; ++text)
- if(*text > 0 && (*text < ' ' || *text == ';'))
+ if((signed char) *text > 0 && ((signed char) *text < (signed char) ' ' || *text == ';'))
return NULL; // block possible exploits against the parser/alias expansion
while(s != endpos)
char *s = string + 5;
char *endpos = string + length + 1; // one behind the NUL, so adding strlen+1 will eventually reach it
char password[64];
- for (i = 0;*s > ' ';s++)
+ for (i = 0;!ISWHITESPACE(*s);s++)
if (i < (int)sizeof(password) - 1)
password[i++] = *s;
- if(*s <= ' ' && s != endpos) // skip leading ugly space
+ if(ISWHITESPACE(*s) && s != endpos) // skip leading ugly space
++s;
password[i] = 0;
- if (password[0] > ' ')
+ if (!ISWHITESPACE(password[0]))
{
const char *userlevel = RCon_Authenticate(password, s, endpos);
if(userlevel)