Merge pull request #95 from BjossiAlfreds/flood

Prevented crash or memory corruption when flood_msgs is too high or too low
This commit is contained in:
Yamagi 2022-10-08 15:37:16 +02:00 committed by GitHub
commit d64a15f535
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 74 additions and 35 deletions

View File

@ -1073,14 +1073,81 @@ Cmd_Wave_f(edict_t *ent)
} }
} }
static qboolean
flooded(edict_t *ent)
{
gclient_t *cl;
int i;
int num_msgs;
int mx;
if (!ent)
{
return false;
}
if (!deathmatch->value && !coop->value)
{
return false;
}
num_msgs = flood_msgs->value;
if (num_msgs <= 0)
{
return false;
}
cl = ent->client;
mx = sizeof(cl->flood_when) / sizeof(cl->flood_when[0]);
if (num_msgs > mx)
{
gi.dprintf("flood_msgs lowered to max: 10\n");
num_msgs = mx;
gi.cvar_forceset("flood_msgs", "10");
}
if (level.time < cl->flood_locktill)
{
gi.cprintf(ent, PRINT_HIGH, "You can't talk for %d more seconds\n",
(int)(cl->flood_locktill - level.time));
return true;
}
i = (cl->flood_whenhead - num_msgs) + 1;
if (i < 0)
{
i += mx;
}
if (cl->flood_when[i] &&
(level.time - cl->flood_when[i]) < flood_persecond->value)
{
cl->flood_locktill = level.time + flood_waitdelay->value;
gi.cprintf(ent, PRINT_CHAT,
"Flood protection: You can't talk for %d seconds.\n",
(int)flood_waitdelay->value);
return true;
}
cl->flood_whenhead = (cl->flood_whenhead + 1) % mx;
cl->flood_when[cl->flood_whenhead] = level.time;
return false;
}
void void
Cmd_Say_f(edict_t *ent, qboolean team, qboolean arg0) Cmd_Say_f(edict_t *ent, qboolean team, qboolean arg0)
{ {
int i, j; int j;
edict_t *other; edict_t *other;
char *p; char *p;
char text[2048]; char text[2048];
gclient_t *cl;
if (!ent) if (!ent)
{ {
@ -1092,6 +1159,11 @@ Cmd_Say_f(edict_t *ent, qboolean team, qboolean arg0)
return; return;
} }
if (flooded(ent))
{
return;
}
if (!((int)(dmflags->value) & (DF_MODELTEAMS | DF_SKINTEAMS))) if (!((int)(dmflags->value) & (DF_MODELTEAMS | DF_SKINTEAMS)))
{ {
team = false; team = false;
@ -1133,39 +1205,6 @@ Cmd_Say_f(edict_t *ent, qboolean team, qboolean arg0)
strcat(text, "\n"); strcat(text, "\n");
if (flood_msgs->value)
{
cl = ent->client;
if (level.time < cl->flood_locktill)
{
gi.cprintf(ent, PRINT_HIGH, "You can't talk for %d more seconds\n",
(int)(cl->flood_locktill - level.time));
return;
}
i = cl->flood_whenhead - flood_msgs->value + 1;
if (i < 0)
{
i = (sizeof(cl->flood_when) / sizeof(cl->flood_when[0])) + i;
}
if (cl->flood_when[i] &&
(level.time - cl->flood_when[i] < flood_persecond->value))
{
cl->flood_locktill = level.time + flood_waitdelay->value;
gi.cprintf(ent, PRINT_CHAT,
"Flood protection: You can't talk for %d seconds.\n",
(int)flood_waitdelay->value);
return;
}
cl->flood_whenhead = (cl->flood_whenhead + 1) % (sizeof(cl->flood_when) /
sizeof(cl->flood_when[0]));
cl->flood_when[cl->flood_whenhead] = level.time;
}
if (dedicated->value) if (dedicated->value)
{ {
gi.cprintf(NULL, PRINT_CHAT, "%s", text); gi.cprintf(NULL, PRINT_CHAT, "%s", text);